ブログ

  • TS-112にpicoclawを入れてDiscordと連携させた話

    いまだ現役で使ってるTS-112ではopenclawが入れられないだろうということで超軽量のpicoclawを入れてDiscordと連携させてみた

    geminiとやりとりしながら動作まで漕ぎ着けたので他の賢いAIならもっとスマートな方法を教えてくれるのかも、、

    • 手元のPCでTS-112の実行ファイルを作成、SSHでアップロード
    • picoclaw onboardでconfig.jsonを作成
    • 必要な情報を追加してpicoclaw agentで動かしてみる
    • picoclaw gatewayでdiscordで会話できるか確認
    • picoclaw gatewayをTS-112起動時に動かすように変更

    まずはpicoclaw( https://docs.picoclaw.io/ https://github.com/sipeed/picoclaw/blob/main/docs/project/README.ja.md )、TS-112で動くものをゲットする必要あり

    pico clawをqnap nas ts-112にインストールしたい

    QNAP TS-112(Marvell Kirkwood / 32-bit ARMv5 世代 CPU、メモリ 256MB)への PicoClaw インストール手順と注意点について解説します。

    PicoClaw は Go 言語で書かれた超軽量な AI アシスタント(実行時のメモリ消費 10MB 未満)のため、リソースが非常に限られた TS-112 でも動作する最適なツールです。

    ただし、TS-112 の CPU は古めの ARMv5 (soft-float) アーキテクチャであるため、GitHub などで配布されている一般的な Linux ARM64 / ARMv7 用のビルド済みバイナリをそのまま実行すると Illegal instruction エラーになります。PC 上で ARMv5 向けにクロスコンパイル して転送するのが確実で最も簡単な方法です。


    1. PC側でのクロスコンパイル

    NAS 上でコンパイルを行うとメモリ不足になるため、手元の PC(Windows/Mac/Linux)に Go 言語環境(Go 1.22 以降推奨)を用意してビルドします。

    ターミナル(または PowerShell / Command Prompt)で以下を実行します。

    # 1. リポジトリの取得
    git clone https://github.com/sipeed/picoclaw.git
    cd picoclaw
    
    # 2. ARMv5向けにクロスコンパイル(CGO無効化 & GOARM=5 を指定)
    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -o picoclaw .
    
    • GOARM=5 を指定することで、TS-112 の CPU(Marvell Kirkwood)に対応したバイナリが生成されます。

    2. QNAP TS-112 へのバイナリ転送

    生成された picoclaw バイナリを SCP や WinSCP、または Win 共有(SAMBA)経由で TS-112 の永続ディレクトリに配置します。

    # 例: SCPでNASのパブリックフォルダに転送
    scp picoclaw admin@<NASのIPアドレス>:/share/HDA_DATA/Public/
    

    (※ ストレージ構成により /share/CACHEDEV1_DATA/Public/ や /share/HDA_DATA/Public/ などパスが異なる場合があります)


    3. TS-112 での初期設定と実行

    SSH で TS-112 にログインして実行権限を付与し、初期セットアップを行います。

    # SSHでログイン
    ssh admin@<NASのIPアドレス>
    
    # 転送先に移動
    cd /share/HDA_DATA/Public/
    
    # 実行権限の付与
    chmod +x picoclaw
    
    # 初期化(オンボーディング)
    ./picoclaw onboard
    

    画面の指示に従い、利用する LLM プロバイダ(OpenRouter、DeepSeek、OpenAI、Anthropic 等)の API キーやモデル名を入力・設定します。

    注意(TLS/SSLルート証明書について): QTS 4.3.3 等の古い QNAP OS では、LLM 側の API 通信時に SSL 証明書エラーが発生することがあります。エラーが出た場合は Entware を導入し、opkg install ca-certificates で最新のルート証明書をインストールしてください。


    4. バックグラウンド永続化と自動起動

    SSH セッションを切断しても動作し続けるよう、バックグラウンド実行を設定します。

    簡易起動(nohup を使用)

    nohup ./picoclaw agent > picoclaw.log 2>&1 &
    

    NAS 再起動時の自動起動(Entware 等の init スクリプト)

    QNAP の /opt/etc/init.d/ (Entware 導入時)に起動スクリプトを配置することで、NAS 起動時に自動で立ち上がるように設定できます。

    geminiのいうとおりMac 上にコンパイル環境を作ってできた実行ファイルをsshでts-112へコピー。念の為QNAP TS-112 に Entware をインストールして ca-certificates などのパッケージを入れて、PUBLICフォルダを提示してきた理由などを確かめつつ、永続的に存在する場所へコピーしました。ここまではまぁまぁ想定内の手間

    パブリックフォルダを例に挙げたのは、PC(Windows/Mac)からファイル共有(SAMBA)経由でファイルを転送する際に、最初から存在するアクセスしやすい場所だからです。

    書き込み・実行権限があり、HDD上に保存される場所であれば、お好みのフォルダに配置して構いません。


    おすすめの配置場所

    1. Entware の実行ファイルフォルダ(一番おすすめ)

    Entware を導入済みであれば、/opt/bin/ に配置するのが最もスマートです。 ここに置くと環境変数(PATH)が通るため、どのディレクトリに移動してもコマンド名だけで picoclaw を呼び出せるようになります。

    # 例: パブリック等に置いたバイナリを /opt/bin/ に移動
    mv /share/HDA_DATA/Public/picoclaw /opt/bin/
    chmod +x /opt/bin/picoclaw
    
    # これでどの場所にいても直接起動できます
    picoclaw onboard
    

    2. 自分で作成した任意の共有フォルダ

    QTS のコントロールパネルで作成した共有フォルダ(例: Apps や Tools など)の中でも問題ありません。

    • 例: /share/HDA_DATA/Tools/
    • 例: /share/CACHEDEV1_DATA/Apps/

    ⚠️ QNAP TS-112 での注意点(保存してはいけない場所)

    QNAP の OS (QTS) は、システム根幹部分が RAM(メモリ)上に展開されて動作する仕組みになっています。そのため、以下の場所にファイルを置くと、NAS を再起動した際にファイルが消えてしまいます。

    • ❌ /root/ や /tmp/
    • ❌ /usr/bin/ や /bin/ などの OS 直下システムフォルダ

    バイナリや設定ファイルは、必ず /share/...(HDD上の領域)または /opt/...(Entwareの領域)の中に保存・配置してください。

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -o picoclaw . でコンパイルできるのですか

    はい、Go 言語がインストールされている PC 上であれば、そのコマンドで QNAP TS-112(ARMv5)向けにコンパイルできます。

    Go 言語は標準で強力なクロスコンパイル機能を備えているため、C 言語のような複雑なクロスコンパイル環境(ツールチェーン)を整えなくても、環境変数を指定するだけで異なる OS / CPU 向けのバイナリを生成できます。


    コマンドの意味と動く理由

    指定項目役割・理由
    CGO_ENABLED=0C 言語依存を完全に切り離し、Pure Go(完全静的バイナリ) としてコンパイルします。これにより、TS-112 側の glibc などのライブラリバージョンが古くても動作するようになります。
    GOOS=linuxターゲット OS を Linux に指定します。
    GOARCH=armターゲット CPU アーキテクチャを 32-bit ARM に指定します。
    GOARM=5最重要ポイントです。 ARMv5(ソフトフロート/FPUなし)を指定します。TS-112 に搭載されている CPU(Marvell Kirkwood)は FPU(浮動小数点演算ユニット)を持たない古めの CPU のため、この指定がないと実行時に Illegal instruction エラーで落ちます。

    コンパイル時の注意点(ハマりどころ)

    もし実行時にエラーが出る場合は、以下の 2 点を確認してください。

    1. main.go の位置(リポジトリ構造)

    リポジトリの直下に main.go がない構成(cmd/picoclaw/main.go などになっている場合)は、末尾の . をパスに変更する必要があります。

    # ルート直下に main.go がない場合
    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -o picoclaw ./cmd/picoclaw
    

    2. コンパイル結果の確認

    PC 上でビルドが完了したら、生成されたファイルが本当に ARMv5 用になっているか確認できます(Linux / macOS の場合)。

    file picoclaw
    # 出力例: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked...
    

    ARM, EABI5 や statically linked と表示されていれば、TS-112 で動くバイナリの完成です。

    package github.com/sipeed/picoclaw/cmd/picoclaw imports github.com/sipeed/picoclaw/cmd/picoclaw/internal/gateway imports github.com/sipeed/picoclaw/pkg/gateway imports github.com/sipeed/picoclaw/pkg/channels/matrix imports maunium.net/go/mautrix/crypto/cryptohelper imports maunium.net/go/mautrix/crypto imports maunium.net/go/mautrix/crypto/libolm: build constraints exclude all Go files

    このエラーは、PicoClaw に含まれる Matrix(チャットツール)連携機能の暗号化ライブラリ(libolm)が C 言語のライブラリ(CGO)に依存していること が原因です。

    CGO_ENABLED=0 を指定してビルドしたため、CGO を必要とする libolm 内の Go ファイルがすべて対象外となり、「ビルド対象のファイルが存在しない」というエラーが発生しました。

    macOS 上で ARMv5 向けの C クロスコンパイラを用意するのは非常に煩雑なため、Matrix 機能を使わない場合はソースコードから Matrix チャンネルの読み込みを外してビルドする のが最も確実で簡単な解決策です。


    解決手順:Matrix の読み込みを無効化してビルドする

    1. ソースコードのインポート文をコメントアウト

    PC 上でクローンした picoclaw のフォルダを開き、Matrix を読み込んでいるファイルをテキストエディタで開きます。

    主に以下のファイル(または pkg/channels/ 配下のファイル)に記述があります。

    • pkg/channels/all/all.go または pkg/gateway/gateway.go(または cmd/picoclaw/main.go

    該当ファイル内の Matrix に関連するインポート行をスラッシュ(//)でコメントアウトします。

    // 変更前
    import (
        "github.com/sipeed/picoclaw/pkg/channels/telegram"
        "github.com/sipeed/picoclaw/pkg/channels/discord"
        "github.com/sipeed/picoclaw/pkg/channels/matrix" // ← これをコメントアウト
    )
    
    // 変更後
    import (
        "github.com/sipeed/picoclaw/pkg/channels/telegram"
        "github.com/sipeed/picoclaw/pkg/channels/discord"
        // "github.com/sipeed/picoclaw/pkg/channels/matrix"
    )
    

    ※ もし matrix の初期化コード(matrix.New(...) など)が同じファイル内にある場合は、そちらも併せてコメントアウトしてください。


    2. 再度クロスコンパイルを実行

    コメントアウト後、ターミナルで再度ビルドコマンドを実行します。

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -o picoclaw ./cmd/picoclaw
    

    CGO 依存の libolm が読み込まれなくなるため、エラーなく picoclaw バイナリが生成されます。


    (参考)ビルドタグが用意されている場合

    PicoClaw のバージョンによっては、ビルドタグで回避できる場合もあります。先に以下のコマンドを試すことも可能です。

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -tags nomatrix -o picoclaw ./cmd/picoclaw

    この時はnohup入れてなかった(後から入れたので)。Entware-stdはts-112のAppCenterの歯車からアプリリポジトリタブを選んで、追加画面のURLにhttps://www.myqnap.org/repo.xml をいれてOKして Entware-std をインストールすれば準備完了

    QNAP TS-112 の標準環境(BusyBox)には nohup コマンドが搭載されていないため、そのエラーが発生します。

    対処法は 「① Entware で nohup を追加インストールする」 か 「② nohup なしでバックグラウンド実行する」 の 2 つがあります。


    方法 1:Entware で nohup をインストールする(推奨)

    すでに Entware を導入済みですので、以下のコマンドで nohup を追加できます。

    opkg update
    opkg install coreutils-nohup
    

    インストール完了後、再度元のコマンドを実行してください。

    GODEBUG=http2client=0 nohup ./picoclaw agent > picoclaw.log 2>&1 &
    

    方法 2:nohup を使わずにバックグラウンド実行する(追加不要)

    何もインストールせずに、シェル(サブシェル)の機能だけで SSH を切断しても止めないように起動する方法です。

    (GODEBUG=http2client=0 ./picoclaw agent > picoclaw.log 2>&1 &)
    
    • コマンド全体をカッコ () で囲んで末尾に & をつけることで、現在の SSH セッションからプロセスを切り離してバックグラウンド実行します。

    どちらの方法でも実行後、ps | grep picoclaw でプロセスが起動していれば成功です。

    この後config.jsonをgeminiにゼロから作ってもらおうとしてめちゃくちゃ時間を浪費した。それとpicoclawで使うAIをgeminiにしようとした事もめちゃくちゃ後悔してる。config.jsonはpicoclaw onboardで出てくるものの行数を恐れず自分でいじったほうが多分早かったしpicoclawおすすめのopenrouterにしておけばよかった

    次にやったのはdiscordのtokenとopenrouterのkeyを取得すること。この辺の情報はあちこちに転がっているのでそれをみながらスムーズに取得できた

    で~/config.jsonの完成版

    {
      "agents": {
        "defaults": {
          "provider": "openrouter",
          "model_name": "openrouter-auto"
        }
      },
      "channel_list": {
        "discord": {
          "enabled": true,
          "type": "discord",
          "settings": {
            "token": "YOUR_DISCORD_BOT_TOKEN"
          }
        }
      },
      "model_list": [
        {
          "model_name": "openrouter-auto",
          "provider": "openrouter",
          "model": "auto",
          "api_key": "YOUR_OPENROUTER_API_KEY"
        }
      ]
    }
    

    これを既存のconfig.jsonを置き換えてpicoclawを起動すると、全部入りのconfig.jsonと.security.ymlに変換してくれる。ちゃんと動いているか確認するには

    ./picoclaw agent -m "hello"

    とかで、答えが返ってくればOK

    次は自動起動

    ts-112でpicoclawを起動時に動かすには

    QNAP TS-112(QTS OS)は一般的な Linux と異なり systemd や標準の rc.local が再起動時にリセットされる仕様になっています。

    そのため、TS-112 で PicoClaw を OS 起動時に自動実行させるには、「ダミー QPKG(App Center 疑似登録)方式」 を使うのが最も確実で安定した方法です。この方法ならファームウェア更新後も設定が保持されます。

    以下に設定の手順をまとめました。


    設定手順(ダミー QPKG 方式)

    1. 起動スクリプトの作成

    SSH で TS-112 にログインし、PicoClaw が置いてあるディレクトリ(例: /share/HDA_DATA/picoclaw または /share/Public/picoclaw)に起動・停止制御用のスクリプトを作成します。

    ここでは例として /share/HDA_DATA/picoclaw に設置する手順で説明します。

    # PicoClaw のディレクトリへ移動
    cd /share/HDA_DATA/picoclaw
    
    # 起動スクリプトを作成
    vi picoclaw_service.sh
    

    picoclaw_service.sh の内容を以下のように記述します:

    #!/bin/sh
    
    CONF=/etc/config/qpkg.conf
    QPKG_NAME="PicoClaw"
    QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f $CONF)
    
    case "$1" in
      start)
        ENABLED=$(/sbin/getcfg $QPKG_NAME Enable -u -f $CONF)
        if [ "$ENABLED" != "TRUE" ]; then
            echo "$QPKG_NAME is disabled."
            exit 0
        fi
        
        # 既に動作中か確認
        if pidof picoclaw > /dev/null; then
            echo "$QPKG_NAME is already running."
            exit 0
        fi
    
        # バックグラウンドで PicoClaw を起動
        cd "$QPKG_DIR"
        nohup ./picoclaw > "$QPKG_DIR/picoclaw.log" 2>&1 &
        echo "$QPKG_NAME started."
        ;;
    
      stop)
        echo "Stopping $QPKG_NAME..."
        killall picoclaw 2>/dev/null
        ;;
    
      restart)
        $0 stop
        sleep 2
        $0 start
        ;;
    
      *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
    esac
    
    exit 0
    

    保存したら、実行権限を付与します:

    chmod +x picoclaw_service.sh
    

    2. 手動での動作テスト

    作成したスクリプトで起動・停止ができるか確認します。

    # 起動テスト
    ./picoclaw_service.sh start
    
    # ログで正常起動したか確認
    cat picoclaw.log
    
    # 停止テスト
    ./picoclaw_service.sh stop
    

    3. QTS の起動タスク(qpkg.conf)に登録

    QNAP に「PicoClaw」をシステムアプリとして認識させ、起動時にスクリプトを呼ばせます。

    /etc/config/qpkg.conf を編集します:

    vi /etc/config/qpkg.conf
    

    ファイルの最下部に以下のブロックを追加して保存します:

    [PicoClaw]
    Name = PicoClaw
    Class = null
    Status = complete
    Enable = TRUE
    Date = 2026-08-01
    Shell = /share/HDA_DATA/picoclaw/picoclaw_service.sh
    Install_Path = /share/HDA_DATA/picoclaw
    

    ※ Shell と Install_Path のパスは、実際の PicoClaw 設置場所に書き換えてください(1 ベイモデルの TS-112 では通常 /share/HDA_DATA/... です)。


    4. 動作確認

    TS-112 を再起動し、自動起動するか確認します。

    reboot
    

    再起動完了後、SSH でログインしてプロセスが走っているかチェックします:

    ps | grep picoclaw
    

    nohup ./picoclaw が表示されていれば、無事に自動起動設定は完了です!


    補足(TS-112 での注意点) TS-112 は CPU(Marvell 1.2GHz)とメモリ(256MB)が限られているため、起動直後は QTS 本体の初期化で負荷が高くなります。PicoClaw がうまく起動しない場合は、picoclaw_service.sh の start 処理内に sleep 10 などを入れて少し待ってから起動するように調整してみてください。

    TS-112の自動起動はrootで動くらしいけど、/rootはファイルが残らないので設定ファイルの置き場としてはふさわしくない。agents.mdやSOUL.mdなどを編集して保持するなら、環境変数PICOCLAW_CONFIGとPICOCLAW_HOMEを設定してconfig.jsonの中にも.picoclawフォルダの置き場設定する必要がある

    ついでにconfig.jsonの中のagents-defaults-workspaceのパスもpicoclawと同じフォルダを指すように変更する必要あり

    TS-112の自動起動は PICOCLAW_CONFIGとPICOCLAW_HOMEという環境変数セットすることも考えて自動起動させ方を教えて

    PICOCLAW_CONFIG と PICOCLAW_HOME の環境変数を正しく設定し、実行ファイルのあるディレクトリを指す方針は完璧です。

    QNAP TS-112 などの BusyBox 環境では nohup コマンドが同梱されていないケースが多いため、nohup があれば使い、無ければ trap で HUP シグナルを無視してバックグラウンド実行する」 という自動判別型の起動スクリプトを作成するのが最も確実です。

    以下に、環境変数対応および nohup あり/なし 両方の環境で動作する自動起動の手順をまとめました。

    1

    配置と構成の確認

    /share/HDA_DATA/picoclaw にファイルをまとめます

    以下のように実行ファイルと設定ファイルが同じディレクトリに配置されていることを確認してください。

    Plaintext

    /share/HDA_DATA/picoclaw/
    ├── picoclaw             (実行ファイル)
    └── config.json          (設定ファイル)
    

    2

    起動スクリプトの作成

    環境変数と nohup 自動判別ロジックを含めたスクリプトを作成します

    SSH で TS-112 にログインし、/share/HDA_DATA/picoclaw/picoclaw_service.sh を作成します。

    Bash

    cd /share/HDA_DATA/picoclaw
    vi picoclaw_service.sh
    

    以下の内容を貼り付けて保存します:

    Bash

    #!/bin/sh
    
    CONF=/etc/config/qpkg.conf
    QPKG_NAME="PicoClaw"
    QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f $CONF)
    
    # 環境変数の明示的セット
    export PICOCLAW_HOME="$QPKG_DIR"
    export PICOCLAW_CONFIG="$QPKG_DIR/config.json"
    
    case "$1" in
      start)
        ENABLED=$(/sbin/getcfg $QPKG_NAME Enable -u -f $CONF)
        if [ "$ENABLED" != "TRUE" ]; then
            echo "$QPKG_NAME is disabled."
            exit 0
        fi
        
        # 二重起動チェック
        if pidof picoclaw > /dev/null; then
            echo "$QPKG_NAME is already running."
            exit 0
        fi
    
        cd "$QPKG_DIR"
    
        # nohup の有無に応じて起動処理を分岐
        if command -v nohup >/dev/null 2>&1; then
            # 【nohup がある場合】
            nohup ./picoclaw gateway > "$QPKG_DIR/picoclaw.log" 2>&1 &
        else
            # 【nohup がない場合】SIGHUPを無視するサブシェルでバックグラウンド実行
            (trap '' HUP; ./picoclaw gateway > "$QPKG_DIR/picoclaw.log" 2>&1 &)
        fi
    
        echo "$QPKG_NAME started."
        ;;
    
      stop)
        echo "Stopping $QPKG_NAME..."
        killall picoclaw 2>/dev/null
        ;;
    
      restart)
        $0 stop
        sleep 2
        $0 start
        ;;
    
      *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
    esac
    
    exit 0
    

    nohup がない場合の仕組み:

    (trap '' HUP; ... &) という記述により、親プロセス(スクリプト)が終了しても、PicoClaw に「ハングアップ(切断)信号」が届かなくなるため、nohup と同等の常駐動作が可能になります。

    3

    権限付与と手動動作テスト

    自動起動登録の前に手動で起動・停止をテストします

    実行権限を付与し、実際にテストを行います。

    Bash

    # 実行権限の付与
    chmod +x /share/HDA_DATA/picoclaw/picoclaw_service.sh
    
    # 手動起動テスト
    /share/HDA_DATA/picoclaw/picoclaw_service.sh start
    
    # プロセスが残っているか確認
    ps | grep picoclaw
    
    # ログが出力され、環境変数が効いているか確認
    cat /share/HDA_DATA/picoclaw/picoclaw.log
    
    # 停止テスト
    /share/HDA_DATA/picoclaw/picoclaw_service.sh stop
    

    4

    qpkg.conf への自動起動登録

    QNAP OS (QTS) の起動タスクに組み込みます

    /etc/config/qpkg.conf を編集します。

    Bash

    vi /etc/config/qpkg.conf
    

    ファイルの末尾に以下のブロックを追加します。

    Ini, TOML

    [PicoClaw]
    Name = PicoClaw
    Class = null
    Status = complete
    Enable = TRUE
    Date = 2026-08-02
    Shell = /share/HDA_DATA/picoclaw/picoclaw_service.sh
    Install_Path = /share/HDA_DATA/picoclaw
    

    これで設定は完了です。NAS 再起動時にも自動的に picoclaw_service.sh start が呼び出され、環境変数を保持した状態で背景起動するようになります。

    autorun.sh方式との違い気になったので

    この方法はautorun.shに設定するより安定ですか 

    はい、ダミーQPKG方式(qpkg.conf)の方が autorun.sh よりもはるかに安定しており、間違いなくおすすめです。

    TS-112 を含む QNAP NAS において、autorun.sh ではなくダミーQPKG方式を使うべき理由は主に 4 つ あります。

    ダミーQPKG方式が優れている 4 つの理由

    1. HDD(/share)のマウントタイミング(★最大の理由)

    • autorun.sh の問題: システム起動の「超初期段階」で実行されます。この時点ではまだハードディスク(/share/HDA_DATA)がマウントされておらず、PicoClaw のフォルダが存在しないため 「ファイルが見つかりません」エラーで起動に失敗する ことが頻繁に起こります(無理に動かすには sleep 60 などを入れてディスクが立ち上がるのを待つ泥臭い処理が必要です)。
    • ダミーQPKG方式: システムが HDD を完全に認識・マウントした後の安全なタイミングで実行されるため、確実にファイルを読み込むことができます。

    2. 設定の安全性と手間の少なさ

    • autorun.sh の問題: TS-112 で autorun.sh を書き換えるには、隠されたフラッシュメモリ(DOM領域)を /tmp/config などに手動で mount して書き換える必要があり、操作ミスで NAS が起動しなくなるリスクがあります。
    • ダミーQPKG方式: 通常のファイルシステム上にある /etc/config/qpkg.conf を 1 ファイル編集するだけなので安全です。

    3. ファームウェア更新時の耐久性

    • autorun.sh の問題: QTS のファームウェアアップデートを行うと、フラッシュメモリ領域が初期化されて autorun.sh の記述が消えてしまうことがあります。
    • ダミーQPKG方式: /etc/config/qpkg.conf は「インストール済みアプリ一覧」として保存されるため、アップデート後も設定が保持されます。

    4. 停止・再起動などの管理のしやすさ

    • ダミーQPKG方式: スクリプトに start / stop / restart の分岐を作っているため、設定変更時などに NAS 全体を再起動しなくても、コマンド一発(./picoclaw_service.sh restart)で PicoClaw だけを再起動・ログ確認できます。

    まとめ

    autorun.sh は「HDDマウント前に動かしたい極小のシステムスクリプト」向けの仕組みです。

    PicoClaw のように HDD 上の実行ファイルや config.json を読み込んで動くアプリケーション にとっては、今回紹介した ダミーQPKG方式(qpkg.conf)が QNAP におけるベストプラクティス です。安心してお使いください!

    ということで、自動起動まで完了

    Discordでchatできてます。何をやってもらおうかな

    参考サイト

    https://lexia-hp.com/blog/sipeed-picoclaw-beginner-guide-10usd-ai-agent#h4331e7a99e

    Discordのconfig.jsonに”allow_from”: [ “YOUR_DISCORD_ID” ]をつけたほうがよいらしい

  • M1MacBookProでopen-notebook+ローカルLLM

    notebookLMが便利だけど、個人情報などを含む公開したくない情報を登録したくなった場合を考えて、NotebookLMではなくPC上で完結する構成を試してみました

    PCはM1MacBookPro,Docker上でopen-notebook,ollamaでqwen3.5入れて、open-notebookからqwenを呼び出す。

    ほぼこちらと同じことをやってます https://note.com/minamotomasaru/n/nc57c260e2a6d

    https://github.com/lfnovo/open-notebook に従ってopen-notebookを入れる

    Ollamaを入れてqweb3.5:4bをpull

    open-notebookのmodelの設定でbaseurlはDocker内からなのでhttp://host.docker.internal:11434 とする

    で、試してみたのですが、とにかく重い。ここで終了

    qwenをやめてgemini-3.5flashにしたら結構いい感じに帰ってきたので、ローカルLLMがものすごく大変。NotebookLMの素晴らしさを思い知りました

  • qnap(arm)でtomcat(vol3)swap領域作成

    TS-112はメモリ256Mで、tomcatが起動してもすぐに強制終了させられるので、実質使い物にならないため、swapを作成しました

    SWAP領域の確認と作成古いTS-212-E nasにswapを追加 を参考に

    freeでswap領域を確認

    sudo dd if=/dev/zero of=/path/to/swapfile bs=1M count=1024 # 1GBのファイルを作成
    sudo mkswap /path/to/swapfile


    sudo swapon /path/to/swapfile

    swaponをautorun.shにも記入

    でswapできるので、再度tomcatを起動させたら一応終了せずにうごいてます


    https://www.reddit.com/r/qnap/comments/kogo3f/add_swap_to_old_ts212e_nas/?tl=ja

    https://zenn.dev/haru_iida/articles/change_swapfile_size

    https://zenn.dev/wsuzume/articles/3ef4b2d3caf203

  • qnap(arm)でtomcat(vol2)

    前にqnap(arm)でtomcatという記事を書きましたが、後から見直しても何を書きたかったのかよく分からないのと、一応満足できて状態で動かすことができたので再度書いてみようと思います

    うちのQnapはTS-112でQTSは最新(といっても。。)にしています

    手順

    まずはQnap公式のAppStoreからJREを二つともインストール(どちらかで良いのかもしれませんが、そこは検証していません)

    JREのバージョンに合わせたapache-tomcatをhttps://archive.apache.org/dist/tomcat/からダウンロードします。(私の場合はTomcat8)

    展開してQnapへアップロードします。アップロードして展開でも同じですよね

    sshでQnapに接続します

    bin/catalina.sh

    を実行してエラーなく起動するか確認します

    tomcatがlocalhostならこれで使えるみたいですが、他のPCからアクセスするのとポート8080はQnapが使っているので追加の設定が必要になります

    ポートの変更はconf/server/xmlの8080を変更する

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

    他のPCからアクセスできるようにするにはtomcatのwebapps/host-manager/META-INF/context.xmlとwebapps/manager/META-INF/context.xmlの修正

    allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
      ↓↓↓
    allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192.168.10.*" /><!- 192.168.10.*からアクセスする-->

    conf/tomcat-users.xmlにmanager-guiのユーザーを追加する。

    <user username="USERNAME" password="PASSWORD" roles="manager-gui"/>

    Qnap起動時にTomcatも動かすにはQnapの設定でautorun.shを使ってtomcatのstartup.shを呼び出す

    Running Your Own Application at Startup – QNAPedia
    https://wiki.qnap.com/wiki/Running_Your_Own_Application_at_Startup

    参考サイト

    Raspberry PiにApache-Tomcatを入れてローカルサーバーをたてる|イワシ銀行
    https://note.com/python_beginner/n/na9eb267ce68b

    RaspberryPi に Tomcat をインストール #RaspberryPi – Qiita
    https://qiita.com/ekzemplaro/items/b6dd39daeb027227234d

    How to Install Apache Tomcat on Debian 11 (Step by Step)
    https://www.linuxtechi.com/how-to-install-apache-tomcat-on-debian/

    【Tomcat】他PCからのアクセス、アクセス制限 – アルパカノフン
    https://vist764.hatenablog.com/entry/2024/02/19/014447#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E9%99%90%E3%81%AE%E6%96%B9%E6%B3%95%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E9%85%8D%E7%BD%AE%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

    お金をかけずにサーバーの勉強をしよう – TomcatをGUIで管理する –
    https://subro.mokuren.ne.jp/0980.html

  • ネットブック(死語)にantixをインストールして日本語

    AcerのネットブックでAspire Oneというのがあったのですが、使わなくなって数年。日本語入力できてLibreOfficeが使えるモバイル環境が必要になり、手持ちの PCで使えそうなのでLinuxを入れて現役復帰してもらうことにしました

    OSは何でも良かったのですが、元々入っているWindowsはXPなのでそのまま使うのは気が引けてLinuxにすることにしたのですが、32ビット PCなので使えるOSが限られ、そのうちの一つがantix23.2でした

    1. USBメモリにLive版を入れてそれを使って起動
    2. インストールの言語は日本語にして、インストール後にhttp://ponzu840w.starfree.jp/blog/blog.html?id=00063 で示してあるスクリプトを実行
    3. LibreOfficeはパッケージマネージャーでそれっぽいのを入れて再起動したら日本語になりました

    ついでに二本指でスクロールの向きが逆なのでhttps://www.maketecheasier.com/reverse-mouse-scrolling-direction-in-ubuntu/に書かれてある内容を~/.Xmodmapに記入(なければ新規作成)しました

    ちょっと(結構)遅いのですが、一時的に使うだけなのでまぁいいかなと思います

  • jupyter lab(notebook)でipynbをpyで出力

    pythonの開発環境でブラウザだけで使えるので最近お世話になっているJupyter notebook, jupyter lab で最終的にpyを出力するのはメニューのexportでやるとして、ipynbからpyファイルを出力してそのpyファイルでバージョン管理をするときに、jupyter_lab_config.py(notebookの場合はjupyter_notebook_config.py)を編集する方法が簡単便利みたいだけど、to_api_pathのところでエラーが出たので、ネットに出ているサンプルを書き換えたメモ

    import io
    import os
    #from notebook.utils import to_api_path #to_api_pathのfromを書き換える
    from jupyter_server.utils import to_api_path
    
    _script_exporter = None
    
    def script_post_save(model, os_path, contents_manager, **kwargs):
        """convert notebooks to Python script after save with nbconvert
    
        replaces `ipython notebook --script`
        """
        from nbconvert.exporters.script import ScriptExporter
    
        if model['type'] != 'notebook':
            return
        # https://qiita.com/shiho_h/items/6f1dd3fb1b9136416ec6
        if model['last_modified'] - model['created'] < datetime.timedelta(seconds=1):
            return # 【追加】createとlast_modifiedの差が小さければ, 新規作成と判断してなにもしない
        global _script_exporter
        if _script_exporter is None:
            _script_exporter = ScriptExporter(parent=contents_manager)
        log = contents_manager.log
    
        base, ext = os.path.splitext(os_path)
        py_fname = base + '.py'
        script, resources = _script_exporter.from_filename(os_path)
        script_fname = base + resources.get('output_extension', '.txt')
    #    log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir))
        with io.open(script_fname, 'w', encoding='utf-8') as f:
            f.write(script)
    c.FileContentsManager.post_save_hook = script_post_save
    
    
    
    ## Python callable or importstring thereof
    #  See also: ContentsManager.pre_save_hook
    # c.FileContentsManager.pre_save_hook = None
    def scrub_output_pre_save(model, **kwargs):
        """scrub output before saving notebooks"""
        # only run on notebooks
        if model['type'] != 'notebook':
            return
        # only run on nbformat v4
        if model['content']['nbformat'] != 4:
            return
    
        for cell in model['content']['cells']:
            if cell['cell_type'] != 'code':
                continue
            cell['outputs'] = []
            cell['execution_count'] = None
    
    c.FileContentsManager.pre_save_hook = scrub_output_pre_save
    

  • fly.ioで苦労した話

    Herokuの無料枠がなくなって一年ぐらいになりますが、自分用のサービス(pythonのpyramidフレームワークを使って大昔に作ったもの)をとりあえずrenderに移したあと放置してたものを、再度fly.ioで動くようにしたときの事

    fly.io への登録からflyctl launch までは順調に(https://zenn.dev/hokawa/articles/65ddcd9974448c を参考に)。ローカルディレクトリにできたProcfileはherokuに使ったものをそのまま。flyctl deployってgitに関係なくアップロードするんですね。

    deployでファイルのアップロード後に泣かされたのは

    sqlalchemy.exc.NoSuchModuleError: Can’t load plugin: sqlalchemy.dialects:postgresが出る

    https://zenn.dev/3w36zj6/scraps/ebb3a8bf494aa4

    この内容を反映させるために、アプリの最初の方で

    os.environ['DATABASE_URL'] = os.environ["DATABASE_URL"].replace("postgres://", "postgresql://")

    を挿入

    もう一点、postgresqlのテーブル作成とデータ挿入をコードからではなく、fly postgres connect -a <postgresqlアプリ名>で接続してSQLを流し込んで行ったのですが、そのテーブルが見つかりません(relation does not exist)エラー

    http://【PostgreSQL】テーブルが存在するのにリレーション存在しません(relation does not exist)と表示される – buralog https://buralog.jp/postgresql-relation-does-not-exist-error/

    に書かれてる、大文字小文字やサーチパスは問題なかったのですが、

    fly.io postgres: relation “table_name” does not exist. の解決
    https://zenn.dev/yutorse/articles/0a7dfcef4b0d05

    の別のデータベースにテーブルを登録してしまっている。が該当したので、こちらのサイトにはflyctl proxy~なるコマンドが書かれてますが、ここはうまくいかなかったため、普通にfly postgres connectしたあとでpsqlのコマンド\c を使ってデータベースを切り替えたあとで再度SQLを流したところ、うまく動き出しました

    あ、あとはrequirement.txtでpsycopg2がうまく入れられなかったのでpsycopg2-binaryに変更したような気がします

  • Python Embeddable 準備メモ

    私の今の環境はWindowsなのでPythonEmbeddableが使えるようなので、準備メモ。あちこちのサイトに書かれてるのでそれでいいと思うのですけど

    • pythonのサイトからembeddable版をダウンロード https://www.python.org/downloads/windows/
    • zipファイルを展開
    • pipを使えるように
      • python~~.pthファイルを探して、
        #import site 行の#を削除
      • https://bootstrap.pypa.io/get-pip.py からダウンロードしたget-pip.pyを展開したディレクトリに保存
      • カレントディレクトリをここにしてコマンドプロンプトを開く
      • ./python.exe get-pip.pyと実行する(他のpythonで実行しないように./をつける)
    • PATHを通す
      set PATH=%~dp0Scripts;%~dp0;%PATH%

  • C27セレナでYoutube(USB,HDMI)

    自宅で使っていたGoogleChromeCastをGoogleTV付きのに変えたので、余ったChromeCastを車でYoutubeのために使おうと思います

    走行中のテレビキャンセルは納車時にディーラーオプションで済ませてあり、純正ナビにHDMIのケーブルをつなげるディーラーオプションもあるのですが、ディーラーに聞いたところ部品込み2万円との事。いやいやそれはちょっと出せないので、自分で作業しました。スマホを直接つなぐつもりはないので標準HDMI端子だけでいいのです

    使ったケーブルは

    (機種別取説付)カーナビ用HDMI Eタイプ雄-Aタイプ雌 トヨタ ホンダ 日産純正ナビNSZT-Y68T Y66T W68T Z68T Y64T VXM-217 227 VFNi 187 185 VFNi VFEi jusby :1999964:ジャスビー – 通販 – Yahoo!ショッピング
    https://store.shopping.yahoo.co.jp/jusby-auto/1999964.html

    日産 純正カーナビ 互換USBケーブル ノート セレナ キックス デイズ他 MM521D-L MM520D-L MM320D-L MJ320 MJ120 519 318 118 MM518D MM317 MJ117 :J-nissan-usb:ジャスビー – 通販 – Yahoo!ショッピング
    https://store.shopping.yahoo.co.jp/jusby-auto/j-nissan-usb.html

    の二種類です

    作業するために調べた事前の情報は

    C27 純正ナビHDMI入力(ケーブル社外品)(日産 セレナ e-POWER・C27)by bousaiyasan – みんカラ
    https://minkara.carview.co.jp/userid/2708673/car/2286337/3999003/note.aspx

    車用埋め込み型USB充電2ポート|穴開け〜取り付けレポート
    https://tatsu8.jp/rasuto/souko/USB-car/Power.html

    アッパーボックス内にHDMI・USBポートの取り付け(日産 セレナ e-POWER・C27)by kota.u – みんカラ
    https://minkara.carview.co.jp/userid/2552367/car/3121354/6455284/note.aspx

    https://www-small-car-mechanic.com/wp-content/uploads/2019/10/img_4587-768×1024.jpg

    https://minkara.carview.co.jp/userid/3388566/car/3162172/6539345/note.aspx

    これらの資料を見ててもスムーズにできなかった点は、一番最初のパネルをはずすところ。テープを貼って引っ張る!を何度も何度もやったのですがさっぱり駄目。結局爪の場所を確認して内張り剥がしでパネルを外しました。ナビにHDMIケーブルとUSBケーブルを差して、助手席側のアッパーボックスなどを外して、アッパーボックス内にケーブルが出てくるように、アッパーボックス上にリーマーで穴を開けて、ケーブルを通したグロメットを嵌めて、アッパーボックスでChromeCastにHDMIとUSBを繋いで完成

    一番最後に全部もとに戻して車を動かそうとしたらエラー!。ディーラーに連絡してください。と、これは作業中にバッテリーが減ったことによるものだったようで、ディーラーの指示どおりバッテリーを充電したら直りました。

    今は快適にYoutubeなど見てます。助手席と後部座席の人たちは快適みたいです

    カロッツェリア車種別JUST FIT
    https://justfit.carrozzeria.pioneer/disasm/NS0003210_201608-201907#

    【C27】助手席アッパーボックス・グローブボックスの取り外し方法①(日産 セレナハイブリッド・C27)by tacoma@ひさし – みんカラ
    https://minkara.carview.co.jp/userid/177799/car/2279351/3982292/note.aspx

  • 無垢床のオイル塗装

    いよいよ床にオイルを塗ったときの事を書きます

    こちらの記事に準拠→ 無垢フローリングにオイル塗装をする | 99% DIY -DIYブログ-

    最初に必要なのは塗装面にサンダーをかけること。このために購入したのはDEKOのランダムサンダーです。最初力を入れて使って暴れて困っていましたが、正しくは力を入れずに使うようですね。


    前も書きましたが、たっぷり塗ってしまうのは厳禁。スポンジにたっぷり吸い込ませてしまった時は塗る前にしっかり扱(しご)いてから!厚く塗っても乾燥に時間がかかったりベタついたりでいいことありません

    今回2度塗り目の一部の拭き取りが甘かったので、個人的にはちょっともやもやした仕上がりになってしまいましたが、時間切れなので終了としました

    最後に使った量についてですが、今回塗った範囲は20m2で、ユーロオイルクリアは2回塗りで10m2/Lのため、2回塗りで2L必要となるのですが、お得と言っても大量に余らせるわけにもいかず、100ml/0.7L/3.5L/14Lのラインナップだったため0.7Lを3缶購入しました。

    結果として自分の場合は1缶とちょっとで2度塗り終わりました。思っていた半分で済んだということですね

    次回までしっかり蓋をして保存しておきます