Chumby の夢を別の DNA で生まれ直す  Canby 誕生

Chumby の夢を、別の DNA で生まれ直す —— Canby 誕生

 

音声ガイド(サーバー描画で蘇るChumbyの夢)



Canby は Chumby の改造でも復活でもない。
Chumby の「夢」を、別の DNA で生まれ直させた存在である。

ハードもソフトも全く別だが、あの画面、あの動き、あの常時表示される情報体験だけは確かに受け継いでいる。 血はつながっていなくても、Canby は Chumby の「夢の兄弟」と呼ぶにふさわしい。

目に見えない情報の灯りを宿す端末

Chumby が静かに姿を消して久しい。しかし、その「常に何かを語り続ける存在感」は今も記憶に残る。 Canby は、過去の Chumby の精神を再解釈し、別の形で現代に再生させた。 単なる表示端末ではなく、画面そのものが語る情報体験を宿す装置である。

Canby の画面では、Chumby の SWF が動く限り、ほとんどの画像表示系アプリが再現可能だ。 つまり、過去の夢をコピーするのではなく、新しい DNA で再生している。 そのため、血統やハードウェアの継承はないが、体験の継承は確かにある。

Canby(クライアント)の仕様

  • ESP32-3248S035C 3.5インチ容量性タッチスクリーン、320×480 TFT LCD
  • Arduino IDE で独自プログラムを開発
  • サーバー上のデータを 1 秒ごとに取得して画面更新
  • 初期は JPG 形式 → 展開に時間がかかり、更新は約 5 秒ごと
  • .bin 形式に変更 → 1 秒以内の高速更新を実現
  • 画像サイズに応じたバックライト制御
    • 100B 以下:消灯
    • 500B 以下:約 50% 減光
  • SWF の再生により、ほとんどの Chumby 画像表示系アプリを再現可能
  • 表示の細部まで再現することで、「画面が情報を語り続ける体験」を完全に維持

サーバー側の仕組み

  • 高速ローカルサーバー上で稼働
  • Chumby の .swf を仮想ディスプレイで再生
  • ffmpeg で毎秒キャプチャ → Canby が 1 秒ごとに取得
  • 指定時間(デフォルト 23:00~8:00)にはバックライトを自動オフ
  • Linux Mint 22 上の bash プログラムで稼働
  • この仕組みにより、過去の Chumby の動きや画面の雰囲気をほぼ完全に再現
  • config 設定により、夜間はバックライトオフ設定可能

技術的工夫と発想の源

JPG では高速更新ができない → そこで .bin 形式を導入 ESP32 の描画能力に制約 → 画像容量によるバックライト制御を採用 SWF をそのまま表示 → 互換性と「Chumbyらしさ」を保持。こうした技術的制約と工夫が、単なる表示端末ではない、「夢を再現する端末」という発想を突き上げた。

誰も喜ばなくても

そして、誰も喜ばない。それでも画面は 1 秒ごとに更新され、SWF は淡々と動き続ける。 それは、誰のためでもなく、「作者自身のためだけの情報体験」である。 時間や労力の対価を求めず、純粋に画面に没入する行為──それが Canby の本質だ。

まとめ

Canby は Chumby ではない。血統は別だ。DNA も違う。 しかし、画面を見ればわかる。SWF が動き、情報が絶えず流れ続ける。 それこそが Chumby が目指していた 「常時情報を灯す存在」である。


血はつながっていないが、夢を共にした兄弟。
Canby は、Chumby の夢を別の DNA で再現した存在である。

 

SWF to Binary 連続キャプチャシステム 動作仕様書

本システムは、Adobe Flash (SWF) ファイルを Linux 上で実行し、その描画画面をリアルタイムにキャプチャして、マイコン(ESP32等)が直接読み取り可能な RGB565 形式のバイナリファイル へ変換・更新し続けるものです。

1. システム概要

本システムは、物理的なモニターを必要としない「仮想画面」をメモリ上に作成し(Xvfb)、そこで再生されるFlashアニメーション(Ruffle)をFFmpegで高速に連写することで、バイナリデータとして抽出します。

2. コンポーネント構成

  • Xvfb (仮想ディスプレイ): 物理的なモニターを必要としないメモリ上の画面を作成します。
  • Ruffle (Flashプレイヤー): SWFファイルを読み込み、Xvfb上の画面に描画します。
  • FFmpeg (レコーダー): 仮想画面をキャプチャし、指定のピクセル形式に変換して保存します。
  • CC.sh (オーケストレーター): 上記3つの起動・停止・ループ・ファイル管理を制御するメインスクリプト。

3. 動作フロー

■ ステップ1:初期化(クリーンアップ)

以前の実行で残ってしまったプロセスを pkill で強制終了し、ロックファイルを削除します。これにより、多重起動によるエラーを防ぎます。

■ ステップ2:仮想環境の構築

  1. Xvfb 起動: ディスプレイ番号 :99 に、480x320などの仮想画面を展開します。
  2. Ruffle 起動: DISPLAY=:99 をターゲットに、SWFファイルを再生します。

■ ステップ3:キャプチャループ(メイン処理)

以下の処理を while true で繰り返します。

  1. キャプチャ: FFmpeg が画面を抽出し、一時ファイル(.tmp)に書き出します。
  2. 整合性チェック: ファイルサイズが期待通りか確認します。
  3. アトミック更新: チェック後、mv コマンドで本番ファイル(.bin)へ一瞬で置き換えます。
※重要: mv を使うことで、クライアント側が書き込み途中の不完全なデータを読むのを防ぎます。

4. プロセス管理と強制終了について

スクリプトを終了する際、Ctrl+C で止めれば trap により stop_all 関数が呼ばれ、裏側のプロセスも掃除されます。居残った場合は以下のコマンドで掃除が必要です。

pkill -9 -f "Xvfb :99"
pkill -9 -f "ruffle"
pkill -9 -f "ffmpeg"

5. 主要パラメータ

  • FPS: フレームレート。高いと滑らかになりますが、CPU負荷が増大します。
  • PIX_FMT: rgb565be(多くのマイコン用液晶が採用している Big Endian 形式)。

 

Canyby のアルバイト(笑)

Canby はまあまあの速度(0.9秒毎)で(ローカル)サーバーに画像データを取りに行けます。
ということは、Canby のプログラムは改造なしで:
    o サーバ側で仮想画面を立ち上げる。
    o その画面で Chrome を立ち上げ、任意のURLを表示させる。(当然、コンテンツは変化していてよい)
    o それをキャプチャして .bin フォーマット画像を生成する。
    o Canbyは、それを取りに行く。

下記は、温度表示一覧を縦型に表示させてみたもです。(縦画像に変換するのは、サーバー側で処理している)

IMG 5863

 

 

■ WW.sh のソース

  • URL は google になっています。
  • ../Canby ディレクトリにデーターを送っています。
  • 起動と停止などは、 -help で確認してください。

     

    
    #!/bin/bash
    # WW.sh - Chrome画面キャプチャスクリプト(ステータス機能なし版)
    # ステータス確認は status.sh を使用してください
    
    # --- 設定項目 ---
    TARGET_URL="https://www.google.com/"
    LOGICAL_WIDTH=320
    LOGICAL_HEIGHT=480
    OUTPUT_WIDTH=480
    OUTPUT_HEIGHT=320
    
    DISPLAY_NUM=":99"
    FPS=2
    PIX_FMT="rgb565be"
    OUTPUT_FILE="../Canby/XV1900CU.bin"
    PNG_FILE="../Canby/XV1900CU.png"
    TMP_FILE="${OUTPUT_FILE}.tmp"
    CHROME_PROFILE="/tmp/chrome-profile-web2bin"
    CHROME_PID_FILE="/tmp/chrome_web2bin.pid"
    MAIN_PID_FILE="/tmp/WW_main.pid"
    LOCK_FILE="/tmp/WW.lock"
    LOG_FILE="/var/log/WW.log"
    
    # 計算
    EXPECTED_SIZE=$((OUTPUT_WIDTH * OUTPUT_HEIGHT * 2))  # rgb565: 2バイト/ピクセル
    
    # --- 関数定義 ---
    
    # ログ記録
    log_message() {
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" > /dev/null 2>&1
    }
    
    # すべてのプロセスを停止
    stop_all() {
        log_message "停止中... プロセスを掃除します。"
        
        # メインプロセスの停止
        if [ -f "$MAIN_PID_FILE" ]; then
            MAIN_PID=$(cat "$MAIN_PID_FILE")
            if kill -0 "$MAIN_PID" 2>/dev/null; then
                kill -TERM "$MAIN_PID" 2>/dev/null
                sleep 2
                kill -9 "$MAIN_PID" 2>/dev/null > /dev/null 2>&1
                log_message "メインプロセスを停止しました (PID: $MAIN_PID)"
            fi
            rm -f "$MAIN_PID_FILE"
        fi
        
        # Chromeプロセスの停止(プロファイルベースで検索)
        pkill -9 -f "chrome.*$CHROME_PROFILE" 2>/dev/null
        log_message "Chromeプロセスを停止しました"
        
        # その他のプロセス停止
        pkill -9 -f "Xvfb $DISPLAY_NUM" 2>/dev/null
        pkill -9 -f "ffmpeg.*DISPLAY=$DISPLAY_NUM" 2>/dev/null
        pkill -9 -f "WW.sh.*--daemon" 2>/dev/null
        
        # ファイル掃除
        rm -rf "$CHROME_PROFILE" 2>/dev/null
        rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null
        rm -f "$LOCK_FILE" 2>/dev/null
        rm -f "$TMP_FILE" 2>/dev/null
        rm -f "$CHROME_PID_FILE" 2>/dev/null
        
        log_message "すべてのプロセスを停止しました。"
        echo "WW.sh を停止しました。"
    }
    
    # スクリプトの使用方法を表示
    show_usage() {
        echo "使用方法: $0 [オプション]"
        echo "オプション:"
        echo "  -start     デーモンとして起動(ログアウト後も継続)"
        echo "  -stop      実行中のデーモンを停止"
        echo "  -png       単一PNGスナップショットを作成"
        echo "  -log       ログファイルを表示"
        echo "  -help      このヘルプを表示"
        echo ""
        echo "ステータス確認: ./status.sh を使用してください"
        echo "引数を指定しない場合は、対話型で起動します。"
    }
    
    # ログ表示
    show_log() {
        if [ -f "$LOG_FILE" ]; then
            echo "=== WW.sh ログファイル (最新20行) ==="
            tail -20 "$LOG_FILE"
        else
            echo "ログファイルが存在しません: $LOG_FILE"
        fi
    }
    
    # PNGスナップショット作成
    create_png() {
        echo "PNGスナップショットを作成します..."
        
        # 一時的なXvfb起動
        Xvfb $DISPLAY_NUM -screen 0 ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT}x24+32 -ac -nolisten tcp &
        XVFB_PID=$!
        sleep 3
        
        # Chrome起動(一時的)
        export DISPLAY=$DISPLAY_NUM
        export GNOME_KEYRING_CONTROL=""
        export GNOME_KEYRING_PID=""
        
        google-chrome \
          --user-data-dir="/tmp/chrome-snapshot" \
          --password-store=basic \
          --no-first-run \
          --no-default-browser-check \
          --app="$TARGET_URL" \
          --window-size=$LOGICAL_WIDTH,$LOGICAL_HEIGHT \
          --window-position=0,0 \
          --disable-infobars \
          --hide-scrollbars \
          --disable-gpu \
          --disable-software-rasterizer \
          --no-sandbox \
          --disable-dev-shm-usage \
          --silent-launch \
          --test-type > /dev/null 2>&1 &
        
        CHROME_PID=$!
        sleep 5
        
        # PNGキャプチャ
        echo "キャプチャ中..."
        ffmpeg -loglevel quiet -f x11grab -draw_mouse 0 -video_size ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT} -i ${DISPLAY_NUM}.0 \
            -vframes 1 -vf "transpose=1" -y "$PNG_FILE"
        
        # 後処理
        kill -9 "$CHROME_PID" 2>/dev/null
        kill -9 "$XVFB_PID" 2>/dev/null
        pkill -f "Xvfb $DISPLAY_NUM" 2>/dev/null
        rm -rf "/tmp/chrome-snapshot" 2>/dev/null
        rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null
        
        if [ -f "$PNG_FILE" ]; then
            echo "完了: $PNG_FILE"
        else
            echo "エラー: PNGファイルの作成に失敗しました"
            exit 1
        fi
    }
    
    # 完全なデーモン化関数
    daemonize() {
        # 既存のファイルディスクリプタを閉じる
        exec 0</dev/null
        exec 1>/dev/null
        exec 2>/dev/null
        
        # 新しいセッションを作成(完全に親プロセスから分離)
        setsid "$0" --real-daemon "$@" &
        exit 0
    }
    
    # 実際のデーモン処理(完全に分離された環境で実行)
    run_real_daemon() {
        log_message "=== WW.sh デーモン起動 ==="
        
        # 自身のPIDを保存
        echo $$ > "$MAIN_PID_FILE"
        log_message "メインプロセスPID: $$"
        
        # ロックファイルを作成
        touch "$LOCK_FILE"
        
        # 終了時の処理を設定
        trap 'log_message "終了シグナルを受信しました。掃除します..."; stop_all; exit 0' SIGINT SIGTERM EXIT
        
        # ログディレクトリ作成
        mkdir -p "$(dirname "$LOG_FILE")"
        
        # 掃除と準備
        log_message "1. 既存プロセスを掃除中..."
        pkill -9 -f "Xvfb $DISPLAY_NUM" 2>/dev/null
        pkill -9 -f "chrome.*$CHROME_PROFILE" 2>/dev/null
        pkill -9 -f "ffmpeg.*DISPLAY=$DISPLAY_NUM" 2>/dev/null
        rm -rf "$CHROME_PROFILE" 2>/dev/null
        rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null
        sleep 3
        
        # 1. 仮想画面の作成
        log_message "2. Xvfbを起動中..."
        nohup Xvfb $DISPLAY_NUM -screen 0 ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT}x24+32 -ac -nolisten tcp > /dev/null 2>&1 &
        sleep 5
        
        # Xvfbの起動確認
        if ! pgrep -f "Xvfb $DISPLAY_NUM" > /dev/null; then
            log_message "エラー: Xvfbの起動に失敗しました"
            stop_all
            exit 1
        fi
        log_message "Xvfb起動完了"
        
        # 2. ブラウザ起動
        log_message "3. Chromeを起動中..."
        export DISPLAY=$DISPLAY_NUM
        export GNOME_KEYRING_CONTROL=""
        export GNOME_KEYRING_PID=""
        
        # Chrome起動(簡易オプションで)
        nohup google-chrome \
          --user-data-dir="$CHROME_PROFILE" \
          --app="$TARGET_URL" \
          --window-size=$LOGICAL_WIDTH,$LOGICAL_HEIGHT \
          --no-first-run \
          --disable-infobars \
          --hide-scrollbars \
          --no-sandbox \
          --disable-gpu \
          --disable-software-rasterizer \
          --silent-launch \
          --test-type > /dev/null 2>&1 &
        
        CHROME_PID=$!
        # PIDファイルは作成するが、プロセスが変わっても問題ないようにする
        echo $CHROME_PID > "$CHROME_PID_FILE"
        log_message "Chrome起動完了。初期PID: $CHROME_PID"
        
        # Chromeの起動を確実にする
        sleep 10
        
        # Chromeプロセスの生存確認(プロファイルベースで)
        CHROME_COUNT=$(pgrep -f "chrome.*$CHROME_PROFILE" | wc -l)
        if [ "$CHROME_COUNT" -eq 0 ]; then
            log_message "エラー: Chromeの起動に失敗しました"
            stop_all
            exit 1
        fi
        
        log_message "4. キャプチャ設定"
        log_message "  フォーマット: $PIX_FMT"
        log_message "  期待サイズ: $EXPECTED_SIZE バイト"
        log_message "  ループ間隔: 0.9秒"
        log_message "連続キャプチャ開始"
        
        # メインキャプチャループ
        FRAME_COUNT=0
        START_TIME=$(date +%s)
        LAST_LOG_TIME=$START_TIME
        
        while true; do
            FRAME_COUNT=$((FRAME_COUNT + 1))
            CURRENT_TIME=$(date +%s)
            
            # 一時ファイル名
            TEMP_FILE="/tmp/frame_$$_${FRAME_COUNT}.bin"
            
            # 単一フレームをキャプチャ
            ffmpeg -loglevel error -f x11grab -draw_mouse 0 \
                -video_size ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT} \
                -i ${DISPLAY_NUM}.0 \
                -vf "transpose=1,format=rgb24" \
                -sws_flags neighbor \
                -pix_fmt rgb565be \
                -vcodec rawvideo \
                -f rawvideo \
                -frames 1 \
                -y "$TEMP_FILE" 2>&1
            
            if [ -f "$TEMP_FILE" ]; then
                ACTUAL_SIZE=$(stat -c%s "$TEMP_FILE" 2>/dev/null || echo 0)
                
                if [ "$ACTUAL_SIZE" -eq "$EXPECTED_SIZE" ]; then
                    # 正しいサイズの場合、アトミックに上書き
                    mv -f "$TEMP_FILE" "$OUTPUT_FILE"
                    
                    # 定期的なログ出力(2分ごと)
                    if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 120 ]; then
                        ELAPSED=$((CURRENT_TIME - START_TIME))
                        if [ $ELAPSED -gt 0 ]; then
                            ACTUAL_FPS=$(echo "scale=1; $FRAME_COUNT / $ELAPSED" | bc -l)
                            log_message "動作中: $FRAME_COUNT フレーム処理 (平均FPS: $ACTUAL_FPS)"
                            
                            # プロセス状態もログに記録
                            CHROME_COUNT=$(pgrep -f "chrome.*$CHROME_PROFILE" | wc -l)
                            FFMPEG_COUNT=$(pgrep -f "ffmpeg.*x11grab.*:99" | wc -l)
                            log_message "  プロセス状態: Chrome($CHROME_COUNT), FFmpeg($FFMPEG_COUNT)"
                            LAST_LOG_TIME=$CURRENT_TIME
                        fi
                    fi
                else
                    # サイズが異なる場合
                    if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 300 ]; then  # 5分ごと
                        log_message "警告: フレームサイズ異常 ($ACTUAL_SIZEバイト, 期待: $EXPECTED_SIZEバイト)"
                        LAST_LOG_TIME=$CURRENT_TIME
                    fi
                    
                    # それでも最初の1フレーム分を抽出
                    if [ "$ACTUAL_SIZE" -ge "$EXPECTED_SIZE" ]; then
                        dd if="$TEMP_FILE" of="$OUTPUT_FILE" bs=$EXPECTED_SIZE count=1 2>/dev/null
                    fi
                    rm -f "$TEMP_FILE"
                fi
            else
                if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 300 ]; then  # 5分ごと
                    log_message "警告: フレームキャプチャ失敗"
                    LAST_LOG_TIME=$CURRENT_TIME
                fi
            fi
            
            # 指定した間隔で待機(0.9秒)
            sleep 0.9
        done
    }
    
    # --- メイン処理 ---
    
    case "$1" in
        -start|--start|start)
            # 既に実行中かチェック
            if [ -f "$LOCK_FILE" ] && [ -f "$MAIN_PID_FILE" ]; then
                PID=$(cat "$MAIN_PID_FILE")
                if kill -0 "$PID" 2>/dev/null; then
                    echo "WW.sh は既に実行中です (PID: $PID)"
                    echo "停止するには: $0 -stop"
                    echo "状態確認: ./status.sh"
                    exit 1
                else
                    # プロセスは死んでいるがロックファイルが残っている場合
                    rm -f "$LOCK_FILE" "$MAIN_PID_FILE"
                fi
            fi
            
            # 完全にデーモン化して起動
            echo "WW.sh をデーモンとして起動します..."
            echo "ログファイル: $LOG_FILE"
            echo "出力ファイル: $OUTPUT_FILE"
            echo ""
            echo "ログアウトしても動作を継続します。"
            echo "停止するには: $0 -stop"
            echo "状態確認: ./status.sh"
            
            # デーモン化して起動
            daemonize
            
            # 少し待ってからステータスを表示
            sleep 3
            echo "起動処理を開始しました。"
            echo "詳細はログファイルを確認してください:"
            echo "tail -f $LOG_FILE"
            ;;
        
        --real-daemon)
            # 実際のデーモンプロセス(完全に分離された環境)
            run_real_daemon
            ;;
        
        -stop|--stop|stop)
            if [ ! -f "$LOCK_FILE" ] && [ ! -f "$MAIN_PID_FILE" ]; then
                echo "WW.sh は実行中ではありません。"
                exit 1
            fi
            
            echo "WW.sh を停止します..."
            stop_all
            ;;
        
        -png|--png|png)
            create_png
            ;;
        
        -log|--log|log)
            show_log
            ;;
        
        -help|--help|help)
            show_usage
            ;;
        
        *)
            # 引数がない場合は対話型メニュー
            if [ $# -eq 0 ]; then
                echo "=== WW.sh 画面キャプチャスクリプト ==="
                echo "ステータス確認: ./status.sh を使用してください"
                echo ""
                echo "現在の状態(簡易表示):"
                if [ -f "$LOCK_FILE" ]; then
                    echo "- システム: 実行中(ロックファイルあり)"
                else
                    echo "- システム: 停止中"
                fi
                
                if [ -f "$OUTPUT_FILE" ]; then
                    FILE_AGE=$(($(date +%s) - $(stat -c %Y "$OUTPUT_FILE" 2>/dev/null || echo 0)))
                    if [ "$FILE_AGE" -lt 10 ]; then
                        echo "- 出力ファイル: 最新 ($FILE_AGE秒前)"
                    else
                        echo "- 出力ファイル: 更新あり ($FILE_AGE秒前)"
                    fi
                fi
                echo ""
                echo "操作を選択してください:"
                echo "1) 起動 (-start)"
                echo "2) 停止 (-stop)"
                echo "3) PNGスナップショット (-png)"
                echo "4) ログ表示 (-log)"
                echo "5) 状態確認 (./status.sh を実行)"
                echo "6) ヘルプ (-help)"
                echo "7) 終了"
                echo ""
                read -p "選択 [1-7]: " choice
                
                case $choice in
                    1) 
                        bash "$0" -start
                        ;;
                    2)
                        bash "$0" -stop
                        ;;
                    3)
                        bash "$0" -png
                        ;;
                    4)
                        bash "$0" -log
                        ;;
                    5)
                        echo "状態確認は ./status.sh を実行してください"
                        if [ -f "./status.sh" ]; then
                            read -p "今すぐ実行しますか? (y/N): " exec_status
                            if [[ "$exec_status" =~ ^[Yy]$ ]]; then
                                ./status.sh
                            fi
                        else
                            echo "status.sh が見つかりません。作成してください。"
                        fi
                        ;;
                    6)
                        bash "$0" -help
                        ;;
                    7)
                        exit 0
                        ;;
                    *)
                        echo "無効な選択です。"
                        exit 1
                        ;;
                esac
            else
                echo "不明なオプション: $1"
                show_usage
                exit 1
            fi
            ;;
    esac
    
    exit 0
    
    
    
    
    ========================================
     WW.sh 実行環境 
    ========================================
    
    [ OS ]
    Name        : Pearl
    Version     : 11 (Cade)
    Pretty      : Pearl Desktop 11 (PDE)
    Kernel      : Linux 5.15.0-101-generic x86_64 GNU/Linux
    Init        : systemd
    
    [ CPU ]
    アーキテクチャ:                        x86_64
      CPU 操作モード:                      32-bit, 64-bit
      Address sizes:                       39 bits physical, 48 bits virtual
      バイト順序:                          Little Endian
    CPU:                                   4
      オンラインになっている CPU のリスト: 0-3
    ベンダー ID:                           GenuineIntel
      モデル名:                            Intel(R) Core(TM) i5-6500T CPU @ 2.50GHz
        CPU ファミリー:                    6
        モデル:                            94
        コアあたりのスレッド数:            1
        ソケットあたりのコア数:            4
        ソケット数:                        1
        ステッピング:                      3
        CPU 最大 MHz:                      3100.0000
        CPU 最小 MHz:                      800.0000
    
    [ Memory ]
                   total        used        free      shared  buff/cache   available
    Mem:            15Gi       2.3Gi       2.1Gi       283Mi        11Gi        12Gi
    Swap:          1.7Gi          0B       1.7Gi
    
    [ Storage ]
    NAME   TYPE   SIZE MODEL
    sda    disk 953.9G SA66001TBY
    ├─sda1 part     1M
    ├─sda2 part   513M
    └─sda3 part 953.4G
    
    [ Virtualization ]
    none
    none (bare metal)
    
    [ Software ]
    bash        : GNU bash, バージョン 5.1.16(1)-release (x86_64-pc-linux-gnu)
    ffmpeg      : ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
    Xvfb        : Unrecognized option: -version
    chrome      : Google Chrome 144.0.7559.96
    
    [ Generated ]
    2026年  1月 26日 月曜日 18:21:43 JST
    


    DIM(ナイトモード)バージョン

    download WW.sh をダウンロード (URLは Google になっている)
    download ww_config をダウンロード (.shを削除して使用する)

    ガーデンカメラの映像も数秒毎で表示可能。

    (rtsp://admin:@192.168.X.Y:10553 のようなアクセスが可能なカメラに限る)

    ガーデンカメラ映像
    download WW.py をダウンロード (Python .sh を削除して使用)

このサイトについて

このサイトは、文鎮化していた Chumby の復活を願って開発されたプログラムを紹介して、Chumby の果たせなかった夢も 1mm でも前進させることを目的にしています。可能な限りの開発をしていますが、Chumby 自体と開発者の能力の限界があるとすれば、それが今日の姿です。

-- Good Luck !