Skip to content
EN

変更履歴 — デバイスファームウェア

This content is not available in your language yet.

バージョン運用 (2026-05-10 改定): FIRMWARE_VERSIONscripts/build_version.py が git 状態から自動生成する。

  • リリースタグ commit (例: v0.1.1): suffix なし — 0.1.1
  • 開発 commit: <NEXT_RELEASE_VERSION>d<N> — N は直近 v* タグからの commit 数 (例: 0.1.2d3)

開発期間中の手動 bump 不要。リリース時は CHANGELOG にエントリ追加 → git tag vX.Y.Z → push のみ。 次リリース予定 version の更新だけ src/hapbeat_config.hNEXT_RELEASE_VERSION を 1 行書き換える (リリース直後に 1 回)。

追加 — ESP-NOW 受信機の省電力オンデマンド UI (DEC-033)

Section titled “追加 — ESP-NOW 受信機の省電力オンデマンド UI (DEC-033)”

ESP-NOW stream 受信機(necklace_v3_stream_espnow)に、Wi-Fi/UDP 機とは別系統の 省電力 UI を実装。60 台 2 時間のウェアラブル運用を想定し、表示・電力を最小化する。 contracts/specs/serial-config.md §4.19 準拠。

  • OLED 常時消灯 + LED 常時 offボタン押下 or ボリューム変更で、低輝度の 音量オーバーレイ(全幅 20+ 段セグメントバー + レベル + 電池% + FW)を数秒表示後、 自動スリープ。スリープは SSD1306 DISPLAYOFF コマンドのみ(EN 電源は切らず、 瞬時・再 init 不要で復帰)。
  • 固定レイアウト(Studio の display grid 編集対象外)。表示は drawEspnowScreen で bespoke 描画。輝度の既定は espnow ビルドのみ低(level 1)。
  • 挙動ポリシーを serial 設定化set_espnow_ui、NVS espnow_ui 永続): auto_off_ms / wake_on_button / wake_on_volume / led_enabled / low_batt_pct。 輝度は既存 set_oled_brightness。低電池(既定 ≤15%)で表示を自動点灯(dither 防止のヒステリシス付き)。
  • stream デバッグ readout: get_info の stream object でライブ統計(損失率・ 最大連続欠落・piggyback 復元・drop・handoff・lock 状態・推定遅延)を返す。 RSSI は legacy callback で取れないため損失率を強度の代理指標にする。
  • Wi-Fi/UDP ビルドの UI は無改変(専用 taskUIEspnow#ifdef で分離)。

修正 — ESP-NOW 受信の遅延を参照 firmware 並みに短縮

Section titled “修正 — ESP-NOW 受信の遅延を参照 firmware 並みに短縮”

受信→再生のレイテンシが体感で「ワンテンポ」遅かったのを根治。原因は audio が loop()(最低優先度)にあり、それを誤魔化すための大 DMA(4×128=512 frame=32ms)。 参照 firmware(hapbeat-wireless-firmware)の構成に整合させた(espnow ビルドのみ):

  • audio を 専用高優先度タスク taskAudioEspnow(prio 19, Core 1)に分離。loop() から audioPlayerUpdate() を撤去(serial/UI と別経路に)。
  • DMA を 2×16=32 frame=2ms、mix 粒度を 32 frame(2ms)、ring prebuffer を 32 frame に縮小(いずれも espnow のみ gate、Wi-Fi/UDP は 32ms DMA のまま無改変)。
  • stream 受信機は 0xAA 音声のみ処理(固定長コマンド経路を排除)→ 最短経路 + g_voices 競合の排除。受信→スピーカ ~40-50ms → ~6-8ms(参照 firmware 並み)。

改良 — ESP-NOW UI の細部(実機調整)

Section titled “改良 — ESP-NOW UI の細部(実機調整)”
  • 自動消灯既定を 4s → 8s に延長。
  • ボリュームウェイク閾値 vol_wake_step(既定 1、≥1)でノブ揺れを無視可能に。
  • ボリューム段数 volume_steps(1〜64)を serial 設定化 + NVS 永続化 (volume_control 自体は永続しないため espnow_ui が保持)。
  • 既定画面 2 行目を VOL n BAT xxx% に(FW 版は既定画面から削除)。
  • いずれかのボタン長押し中だけデバッグ画面(FW 版 + ch/loss%/sources/delay)。
  • 競合修正(self-review): serial 起点 wake の s_display 競合を UI タスクへ遅延、 FW 版表示の truncation 修正。get_info の serial 応答は実機で全コマンド確認済み。

追加 — ESP-NOW ストリーミング受信のマルチソース化 (DEC-033)

Section titled “追加 — ESP-NOW ストリーミング受信のマルチソース化 (DEC-033)”

会場同報(PA ライブ音声を ESP-NOW broadcast → 観客の Hapbeat が同時触覚)の 受信機(necklace_v3_stream_espnow)を、複数 transmitter(音声ソース機 + リピータ機)構成に対応させた。contracts/specs/espnow-stream.md §3.2 / §7 準拠。

  • piggyback 単発ロス回復(§3.2): seq 欠番 1 個 + piggyback prev_seq 一致で 欠落パケットを継ぎ目なく復元。2 個以上の欠番は有界の無音(最大 64 frame)で埋める。
  • マルチソース MAC ロック選択(§7.1): 複数送信元 MAC を同時受信しても 常に 1 つにロックして再生(ミキシング禁止 = 二重再生防止)。最先着ロック + ロック喪失(150ms 途絶)で次の生存ソースへ切替、切替時 3ms クロスフェード。 RSSI ヒステリシス経路を実装(arduino-esp32 2.0.x の legacy callback は RSSI 非提供のため現状は inert、将来の toolchain で「最強ロック」が有効化)。
  • 低遅延ピン留め: ESP-NOW 経路は audio_stream の opt-in 低遅延モードで ring を ~8ms に保ち、超過分を破棄して遅延累積を防止(UDP 経路は無改変)。
  • 純 ESP-NOW 運用: stream 受信ビルドは Wi-Fi STA に接続しない(同チャンネル 同居で >80% ロスする問題を回避、§5)。設定は USB serial 経由。
  • StreamStats: 損失率 / 最大連続欠落 / piggyback 復元数 / drop / handoff / 推定遅延を get_info(stream_*)と定期 serial ログで取得(DEC-033 検証用)。

v0.1.x(UDP 受信機のみ)から、施設アラート用途・通信モード別ノード・周辺機器・ legacy ハードまでをカバーする大型リリース。Studio はこの Release を集約して ファームウェアライブラリに表示する。

追加 — 施設アラート (facility-alert / MQTT)

Section titled “追加 — 施設アラート (facility-alert / MQTT)”
  • MQTT 経路のアラート配信: sensor → broker → 受信機の end-to-end。
  • アラート episode の aid lifecycle(同一 aid 再送は 1 回のみ作用 / 新 aid で再アラート)、 OLED 永続表示(ack まで保持)、意図的 button-ack(release→約 1s hold で誤停止防止)、 receiver multi-topic 購読(recv_topics)。
  • restricted / critical alert mode(critical payload + receiver 制限トグル)、 CUSTOM_TEXT / ALERT_LIMIT_MODE / mqtt_status の OLED 表示要素。

追加 — ノード役割・通信モード (DEC-034)

Section titled “追加 — ノード役割・通信モード (DEC-034)”
  • 役割アプリ: MQTT broker / color-sensor sender(M5 ATOM Lite, classic ESP32)。
  • 受信機 transport: MQTT receiver、ESP-NOW audio stream receiver。
  • get_info で role / transport / board を報告。ビルドは variant.json + manifest fragment を出力。

追加 — ハードウェアバリアント

Section titled “追加 — ハードウェアバリアント”
  • BandWL v2 (legacy) 対応: 2 ボタン(中央 SW4=GPIO0/BOOT は実行時入力に使用不可)、 MCP4018 なしのため PAM8003 VOLUME を PWM 駆動、BQ27220 自動検出。
  • band_v2 / band_v3 / band_v4 の MQTT receiver env。
  • loopTask スタックオーバーフロー根治: フル ui-config 書き込み時の reboot を解消。 volume_changed broadcast を同期呼び出しから loop() へ遅延、applyUiConfig の display-layout ディープコピーを直接 serialize に置換、ARDUINO_LOOP_STACK_SIZE=16384。
  • broker mDNS 再解決をループから分離(他通信のスタベーション根治)。
  • device_name 表示 variant を 4 サイズ(4/5/8/16)化し既定幅 8→5(DuoWL レイアウト整合)。
  • 開発中(dirty tree)は tag 上でも dN を付与する版管理修正。

Bug fix: TCP / OTA 安定性の 2 段階修正

Section titled “Bug fix: TCP / OTA 安定性の 2 段階修正”

リリース v0.1.0 で発覚した「OTA を連続実行すると詰まる + 途中で json parse error: InvalidInput が出る」現象を完全に解消。

1. lwIP socket fd リーク (s_client.stop() 漏れ)

  • processOtaData() の disconnect / validation 失敗 / write エラー / finalize 失敗 / boot-partition flip 失敗の 全 return パスs_client.stop() を呼ぶよう修正
  • accept displacement で s_client.stop()unconditional 化 (!connected() でも fd を release)
  • OTA 中に accept queue を drain (helper の log_tail supervisor が 2s 周期で投げてくる SYN が lwIP socket pool を枯渇させていた)
  • netstatFIN_WAIT_2 が累積する症状を解消

2. cmdOtaBegin 後の dispatch race

  • tcpServerUpdate() の JSON dispatch while ループが cmdOtaBegin 後の binary mode 遷移を尊重せず、helper の第 1 chunk バイトを JSON として誤食する race condition を修正
  • processLine 後に s_ota_active || s_kit_active || s_file_active をチェックして即 return。次の tcpServerUpdate() で適切な process*Data() short-circuit に入る
  • OTA / kit install / file transfer の 3 経路すべてで同時にカバー

影響範囲: OTA / kit install / file transfer を行うすべてのデバイス。v0.1.0 ユーザーは v0.1.1 への更新を強く推奨。

(開発中は 0.1.0→0.1.1→0.1.2 と 2 段階で bump したが、リリース時に 0.1.1 に集約)

Tooling: バージョン違いを物理的に防ぐビルド検証 (CI / post-build)

Section titled “Tooling: バージョン違いを物理的に防ぐビルド検証 (CI / post-build)”
  • merge_firmware.py post-build に「ソース FIRMWARE_VERSION が生成バイナリ内のバイト列に含まれているか」検証を追加。stale build を即 fail させる。
  • .github/workflows/release.yml を改修: env 名を実在値 (necklace_v3 / band_v3 / band_v4) に修正、master push でもビルド + artifact 保存 (10 日)、tag push 時のみ GitHub Release publish。

(firmware バイナリ自体の機能変更は無し — bump rule に従う patch +1)

UX: Wi-Fi 選択画面のレイアウト改善

Section titled “UX: Wi-Fi 選択画面のレイアウト改善”
  • drawWifiSelect() を改修。SSID をできる限り長く表示するため:
    • Line 1 (y=0): SSID の先頭 16 文字(旧: SSID: プレフィックスで 11 文字しか入らなかった)
    • Line 2 (y=16): SSID の 17 文字目以降を左詰め + "N/M" カウンターを右詰めで配置
    • 最大約 27 文字の SSID が表示可能。"N/M" は文字幅に応じて x 座標を動的計算(5/12 でも 1/3 でも常に右端揃え)
  • “Exit” エントリは Line 1 に “Exit”、Line 2 右下に "N/M" のみ。

Bug fix: OTA rollback バグの根治 (Update.end 失敗時の force-set を撤去)

Section titled “Bug fix: OTA rollback バグの根治 (Update.end 失敗時の force-set を撤去)”
  • 真因: Update.end(true) が false を返した際 (MD5/SHA256 検証失敗) に無条件で esp_ota_set_boot_partition() を呼んでいた。bootloader が起動時に image SHA256 を弾いて旧スロットに rollback → 「古い版で起動」の root cause だった。
  • 修正: Update.end(true) 失敗時は force-set を一切行わず、旧スロットを維持してエラー報告のみ。Studio から即再試行可能。Update.end(true) 成功時のみ boot partition mismatch チェック + force-set を行う (image 検証通過済みなので rollback リスクなし)。
  • magic byte 検証: 受信開始チャンクで chunk[0] == 0xE9 (ESP32 image magic) + chunk[12] == 0x09 (ESP32-S3 chip ID) を検証。bootloader.bin など誤ったファイルを送ると即停止し partition を汚さない。
  • サイズ検証: cmdOtaBegin で OTA サイズが 100KB 未満 / partition サイズ超過なら拒否。
  • s_ota_first_chunk_validated を全 error / disconnect / reconnect path で確実にリセット。

Feature: Hold 発火予告を線形 fade-out に変更 + brightness 独立化

Section titled “Feature: Hold 発火予告を線形 fade-out に変更 + brightness 独立化”
  • Hold 予告 LED を固定色 flash → 線形 fade-out に刷新。押下 hold_feedback_start_ms から hold_ms にかけて feedback_color × brightness × (1 - progress) で 0 まで落ちる。
  • ledControllerSetFadeOverride(r, g, b, brightness, progress) / ledControllerClearFadeOverride() を新設(fade は flash より高優先)。
  • hold 発火時 / ボタン release 時に ledControllerClearFadeOverride() を呼び rule engine に即復帰。
  • hold_feedback_brightness (default 30, 0–255) を button_handler + applyUiConfig に追加(色と輝度を独立調整可能に)。
  • デフォルト色 {0,30,30}{0,255,255} (純 cyan) に変更(brightness=30 で実際の輝度は約12%)。

Feature: Hold 発火予告のタイミング・色を ui-config で可変に

Section titled “Feature: Hold 発火予告のタイミング・色を ui-config で可変に”
  • hold_feedback_start_ms (default 300ms) と hold_feedback_color (default [0,30,30]) を applyUiConfigui セクションで受け入れ。
  • button_handlerbuttonSetHoldFeedbackStartMs() / buttonHoldFeedbackStartMs() / buttonSetHoldFeedbackColor() / buttonHoldFeedbackColor() を追加。
  • main.cpp の hold pending 処理を runtime 値 (buttonHoldFeedbackStartMs() / buttonHoldFeedbackColor()) で書き換え。旧 HOLD_FEEDBACK_MS=500 const を撤廃。

UX: LED リフレッシュレート 5Hz → 30Hz(fade 滑らか化)

Section titled “UX: LED リフレッシュレート 5Hz → 30Hz(fade 滑らか化)”
  • main.cpp の LED update 間隔を 200ms → 33ms に変更(ledControllerUpdate() 呼出し頻度 5Hz → 30Hz)。
  • app_connected breathe や battery_low fade のサイン波が階段状に見えた問題を解消。
  • 変数名 last_battery_checklast_led_update に改名(誤称の修正)。

Bug fix: LED 設定が Wi-Fi 接続後に無効化される問題を修正

Section titled “Bug fix: LED 設定が Wi-Fi 接続後に無効化される問題を修正”
  • checkWifiServices() 内で Wi-Fi 接続確立 / 切断時に s_led[0] を直書き + FastLED.show() していたため、毎ループ Studio の LED config が上書きされていた。該当 2 箇所を削除し、LED 状態管理を ledControllerUpdate() の rule engine に完全委譲。
  • 起動直後 (Wi-Fi 未接続) は正常で、Wi-Fi 接続後のみ色が固定されていた症状と一致。

Feature: ledControllerInit() デフォルト rules を Studio DEFAULT_LED_RULES (9 件) に揃える

Section titled “Feature: ledControllerInit() デフォルト rules を Studio DEFAULT_LED_RULES (9 件) に揃える”
  • 旧: battery_critical / battery_low / app_connected / idle_fix / idle_volume の 5 件のみ。idle_wifi / wifi_disconnected / volume_mute / always が欠けていたため、ui-config deploy 前は LED が反応しない領域があった。
  • 新: priority 1–9 の 9 ルール (Studio と同一セット)。idle_wifi=dim green / wifi_disconnected=dim yellow / volume_mute=dim red / always=off を追加。

Feature: applyUiConfig ログを TCP log stream に tee

Section titled “Feature: applyUiConfig ログを TCP log stream に tee”
  • [UiConfig] sections: display=N led=N volume=N ui=N および [UiConfig] led.rules=N global=NNN を Serial + tcpLogSend 両方に出力。Studio LogDrawer から apply 状況を直接確認できるようになった。
  • ledControllerLoadConfig[LED] Loaded N rule(s) も tcpLogSend に tee。

Feature: ui-config セクション (hold_ms / oled_brightness / hold_show_oled_indicator) 受け入れ

Section titled “Feature: ui-config セクション (hold_ms / oled_brightness / hold_show_oled_indicator) 受け入れ”
  • applyUiConfigconfig.ui セクション処理を追加。Studio UI 設定モーダルから hold 時間・輝度・OLED インジケーターを runtime 変更可能に。
  • buttonSetHoldFireMs(ms) / buttonHoldFireMs() / buttonSetHoldShowOledIndicator(bool) / buttonHoldShowOledIndicator()button_handler に追加。

UX: Hold タイミング変更 + OLED “Hold…” インジケーターをデフォルト無効化

Section titled “UX: Hold タイミング変更 + OLED “Hold…” インジケーターをデフォルト無効化”
  • HOLD_FEEDBACK_MS: 200ms → 500ms(LED 点滅開始タイミング)
  • hold_fire_ms デフォルト: 400ms → 1000ms(短押し誤発火を解消)
  • OLED “Hold…” 表示をデフォルト無効 (hold_show_oled_indicator: false)。LED 点滅のみで通知するため、短押し直後の pos/group 切替表示が遮られなくなった。

UX: OLED コントラスト Mid / High の差を拡大

Section titled “UX: OLED コントラスト Mid / High の差を拡大”
  • displaySetBrightness(): mid の contrast 値を 0x80 (50%) → 0x40 (25%) に変更。High=0xFF との比が 2× → 4× になり、肉眼で明確に差がわかるようになった。

UX: FW_VERSION を右詰め描画に変更

Section titled “UX: FW_VERSION を右詰め描画に変更”
  • 任意幅の FW_VERSION スロットに対応:
    • n ≤ w: 左側スペース pad で右詰め (例 width=8 で " v0.0.14")
    • n > w: 右端 w 文字を残して左を truncate (例 width=6 で "v0.0.13""0.0.13")
  • 6-cell の旧レイアウトでも patch 番号を残せるようになる。

UX: FW_VERSION 表示桁を 6 → 8 に拡張

Section titled “UX: FW_VERSION 表示桁を 6 → 8 に拡張”
  • patch-only バージョンスキームで 2 桁 patch (v0.0.10 以降 7 文字) が 6 セルに収まらず “v0.0.1” と truncate されていた問題を修正。
  • default_size[8, 1] に変更、renderer は elem.width を honor。
  • v0.0.123 / v9.99.9 / v10.10.5 まで余裕を持って表示できる。

Bug fix: OTA 後 otadata 切替失敗の防御的対応

Section titled “Bug fix: OTA 後 otadata 切替失敗の防御的対応”
  • Update.end(true) 成功後に boot partition を明示検証し、期待と不一致ならば esp_ota_set_boot_partition() で強制上書き。症状: Update.end() が true を返すが otadata が書き込まれず再起動後に旧バージョンのまま残る。
  • pre/post finalize の partition 状態ログを拡充 ([OTA] Pre-finalize: running=? target=? / Post-finalize: boot=? expected ? / [OTA] Success! boot=? — rebooting)。

Feature: hold 閾値延長 (150ms → 400ms) + 待機フィードバック

Section titled “Feature: hold 閾値延長 (150ms → 400ms) + 待機フィードバック”
  • hold 発火閾値を 150 ms → 400 ms に延長(意図しない hold 誤発動を解消)。
  • 待機ウィンドウ (200–400 ms): OLED に "Hold..." toast を表示 + LED を dim cyan でフラッシュ。「今 hold 中、もう少しで発動」の可視化。
  • ledControllerFlash(r, g, b, duration_ms) を新設(一時的な色オーバーライド API)。ルール優先度より常に上位。
  • long_press (1000 ms) と AP combo (3000 ms) には影響なし。

Feature: display 要素の variant 4/8/16 対応 + address prefix-only

Section titled “Feature: display 要素の variant 4/8/16 対応 + address prefix-only”
  • address 要素: /player_ の前半 prefix のみを表示するように変更(MyHapbeatGroup/player_5/pos_r_armMyHapbeatGroup)。variant 4/8/16 でそれぞれ左切出し + 右パディング。
  • wifi_ssid: variant 4/8/16 で左切出し + 右パディング。
  • ip_address: variant 4/6/13 で 右切出し + 左パディング(末尾オクテット重視)。
  • position: NVS の pos_xxx 名を表示する仕様に変更。compact=4 (“l_wr”), standard=8 (“pos:l_wr”), wide=16 (“pos: l_wrist____”)。
  • display_layout_loader"wide" variant パーサを追加(既存の compact / percent / bar と並列)。DisplayElement::variant の意味を 0=standard / 1=compact / 2=wide に拡張。
  • getDefaultSize 更新: ip_address 15→6 / position 7→8 / address 10→8。
  • element-registry.jsondefault_size も追従。

Feature: button action position_inc/decgroup_inc/dec に置換

Section titled “Feature: button action position_inc/dec を group_inc/dec に置換”
  • actionPositionInc / actionPositionDec を削除し、actionGroupInc / actionGroupDec を追加(getDeviceGroup() ± 1、wrap 0–255、NVS group_id 即時保存)。
  • s_action_table / legacy aliases / NECKLACE デフォルト割当 / 3-button fix mode を group ベースに更新。
  • element-registry.jsonbutton_actionsdevice_layouts.necklace_v3group_inc/dec に置換。
  • position_inc/dec を含むレイアウトは unknown action として黙ってスキップされるので壊れない(既存の handler 仕様)。

Bug fix: 初回 deploy 失敗の根本対応(TCP 7701 single-slot pre-empt)

Section titled “Bug fix: 初回 deploy 失敗の根本対応(TCP 7701 single-slot pre-empt)”
  • tcpServerUpdate の accept ロジックを変更: 既存 s_client長期セッション中でなく 1.5s 以上 idle の場合、新規接続が来たら既存を pre-empt して新規を即 accept する。
  • 症状: Wi-Fi 接続済み Hapbeat に 後から Helper を起動すると、起動直後の LAN scanner / mDNS conformance test 等が TCP 7701 を「stuck connected」させ、Helper deploy が IDLE_TIMEOUT 5 秒経過まで失敗する。
  • これにより Helper 側の RECOVERY_SLEEP=6.0s workaround は撤去可能。
  • NVS フラグ + restart 切替 で boot 時に STA / AP モードを選択(hot switch しない)。Arduino-ESP32 の channel jump や ESP-NOW peer state 残留問題を構造的に回避。
  • AP SSID は MAC ベース自動生成: Hapbeat-XXXXXX(MAC 末尾 6 桁 hex)。
  • AP password は NVS ap_pass: デフォルトオープン(pass 無し)、Studio から set_ap_pass で WPA2 設定可能(8-63 chars)。
  • mDNS は STA と共通: _hapbeat._tcp をそのまま AP IP (192.168.4.1) で publish。
  • 自動 timeout: STA クライアント associated している間は無期限。全 disconnect 後 10 分で STA mode に restart。
  • ボタン combo で双方向切替:
    • BAND v3 / v4: SW0 + SW2 を 3 秒同時長押し
    • NECKLACE v3: SW0 + SW4 を 3 秒同時長押し
    • 押下中は OLED にカウントダウン表示(AP in 3...)。combo 中は対象ボタンの long_press / hold アクションは抑制。
  • 新コマンド (TCP / Serial 共通):
    • enter_ap_mode / enter_sta_mode: NVS フラグを書いて restart
    • set_ap_pass {pass}: WPA2 pass 設定(空文字で open に戻す)
    • clear_ap_pass: open AP に戻す
    • get_ap_status: 現在のモード / SSID / IP / has_pass / client_count
  • get_info 拡張: mode (“sta” | “ap”) + AP mode 時は ap_ssid / ap_ip / ap_has_pass / ap_client_count を追加。
  • LED: AP モード中は magenta (5, 0, 5)。
  • AP モード中は ESP-NOW 無効(MVP では co-existence 未実装)。AP channel 固定なので将来追加可能。
  • Studio / Helper 側 UI 対応は別指示書 (hapbeat-studio/instructions/instructions-softap-mode-202605071800.md)。
  • app_name 要素の未接続 placeholder を幅対応に変更(旧: ---- / -- のみ)。
    • width 16: App: unconnected(16 文字 exact)
    • width 8: App N.C.(8 文字)
    • width 4: N.C.(4 文字)
    • width 1-3: --
    • 4 / 8 / 16 がレイアウトプリセット幅。中間幅は次に小さい bucket に fallback。
  • ディスプレイレイアウトに app_name 要素を追加(DEC-029)。Unity SDK が CONNECT_STATUS で送ってくる appName を独立要素として配置可能になった。device_name の隣に Unity アプリ名を表示するなどのレイアウトが可能。
    • 未接続 / タイムアウト時は -- (compact) または ---- を表示。
    • デフォルトサイズは 8x1(contracts spec 準拠)。"size": [16, 1] 等で 16 文字まで拡張可能。
  • 副作用: connection_status 要素から appName 埋め込みを削除(責務分離)。標準時 [OK]<appname>[OK] のみ表示。Wi-Fi 接続中で Hapbeat client から CONNECT_STATUS が来ていない場合の表示を [OK][--] に修正(意味的に正しい)。
  • TCP 7701 の障害・復旧状態を OLED に表示するようにした。
    • watchdog 発火(listen socket が runtime に落ちた場合)で "TCP LOST" を表示(tcpServerUpdate() 内)。
    • tcpServerStart() が 3 回以上連続失敗した場合に "TCP retry N..." を表示(checkWifiServices() 内)。
    • 障害後に TCP が正常起動した場合に "TCP OK" を表示(fail_count > 0 時のみ、初回起動では表示しない)。
  • TCP 7701 が起動時にランダムで listen していない問題を修正(電源 OFF→ON で復旧していた症状)。
    • WiFiServer::begin() は socket/bind/listen 失敗時に silent に return し _listening = false のまま戻るが、tcpServerStart() は結果をチェックせず常に true を返していたため、checkWifiServices の retry ロジックが効かなかった。operator bool() で listen 状態を検証して失敗時 false を返すように修正。
    • begin() 直前に s_server.end() を defensive に呼び、過去の半端な socket fd の leak を解消。
    • tcpServerUpdate() に listen socket dropped watchdog を追加(runtime に socket が剥がれたら tcpServerStop() 経由でクリーンに停止し、main の retry loop で自動再 bind)。watchdog 発火時に s_client.stop() も呼ぶことで orphan client が次回 accept をブロックする問題を回避。
    • tcpServerStop()Update.abort() を追加(OTA 進行中に Wi-Fi 切断 / watchdog 発火で停止した場合、staging partition の lock を解放して次回 OTA を成功させる)。
    • main.cpp::checkWifiServices()s_tcp_startedtcpServerIsRunning() と同期するように修正(watchdog 検出後の再 bind を可能にする)。
  • Wi-Fi 接続成功 / 切断 / 再接続失敗 / プロファイル切替の OLED メッセージで SSID をフル表示するように変更(IP アドレス削除、ssidShort ヘルパ撤去)。OLED の wrap で 2 行目まで使い、長い SSID も識別しやすくなる。
    • 旧: WiFi OK <ssid5> <ip> / WiFi LOST <ssid5> / WiFi FAIL <ssid5> retry Ns / WiFi -> <ssid5> ...
    • 新: WiFi OK <ssid> / WiFi LOST <ssid> / WiFi FAIL <ssid> retry Ns / WiFi -> <ssid>
  • list_wifi_profiles レスポンスから pass(平文パスワード)フィールドを削除。代わりに has_pass(boolean)のみ返す write-only 設計に変更。TCP 7701 は認証なしで LAN に開いているため、平文パスワードを返すことで同一 Wi-Fi 上の任意のデバイスからパスワードが取得可能だった(TCP / Serial 両経路で対応)。
  • 配布物を 2 ファイル化(firmware_app_ota.bin / firmware_full_serial.bin
  • GitHub Actions firmware release workflow + manifest 生成スクリプト
  • cmdScanWifi 追加、NVS 保護 split flash、TCP 再試行リファクタ
  • Initial release