access-controller-reliability
Run full reliability, load, OTA, AP recovery, and UI uptime validation for the Access Controller ESP32.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Run full reliability, load, OTA, AP recovery, and UI uptime validation for the Access Controller ESP32.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | access-controller-reliability |
| description | Run full reliability, load, OTA, AP recovery, and UI uptime validation for the Access Controller ESP32. |
Use this skill before considering controller firmware/UI changes stable. It assumes the repo root is ~/projects/access-controller and the live controller is reachable at DEVICE_URL or AP fallback http://192.168.4.1.
cd ~/projects/access-controller/code/controller
source ~/esp/esp-idf/export.sh
idf.py build
curl -sf "$DEVICE_URL/api/state" | jq '{version:.system.firmware.projectVersion, ota:.system.firmware.otaState, network:.device.network, uptime:.system.uptimeSeconds}'
ls -l /dev/ttyUSB* /dev/ttyACM*
For new boards, network changes, OTA work, UI changes, or install handoff, use
the full runbook in docs/CONTROLLER_DEPLOY_AND_TEST.md. Do not stop at a
local build or a direct-controller curl when the user asked for end-to-end
proof.
Minimum sequence:
http://192.168.4.1/.Echo42 and
HelloWorld; switch both directions and confirm the active SSID, IP, link
quality/RSSI, gateway, AP BSSID, channel, and security update in /api/state
and the Settings UI.ac_<uuid-suffix> appears, 192.168.4.1 responds, and
recovery returns to station mode when a valid saved network is restored.curl -sS -i -X POST https://open-automation.org/devices \
-H 'Content-Type: application/json' \
-d '{"id":"route-smoke","name":"Route Smoke","type":"access_controller"}'
curl -sS -i https://open-automation.org/devices/ | sed -n '1,12p'
Expected: POST /devices returns 200, while browser GET /devices/
returns 401 Basic realm="Device Manager" without credentials.curl -sf http://192.168.1.40:8102/api/health
curl -sf 'http://192.168.1.40:8102/api/devices/<device-manager-id>/access-controller/state' \
| jq '{uuid:.state.device.uuid, ssid:.state.wifi.active_ssid, ip:.state.device.network.wifi_sta_ip, quality:.state.device.network.wifi_sta_quality, ota:.state.system.firmware.otaState}'
If Device Manager hangs while health is stale or partial, restart it on
Sonic: ssh sonic 'docker restart device-manager'.curl -sS --max-time 180 -X POST \
"http://192.168.1.40:8102/api/devices/<device-manager-id>/access-controller/ota" \
-H 'Content-Type: application/octet-stream' \
-H 'X-Firmware-Filename: controller.bin' \
--data-binary @/home/andy/projects/access-controller/code/controller/build/controller.bin
Confirm the running partition flips and otaState becomes valid.cd ~/projects/access-controller/code/controller/tests
DEVICE_URL=http://<controller-ip> npm test
Normal successful testing must be quiet. Keep controller quiet-test mode enabled for synthetic load/config traffic; beep only for unexpected failures or reboot alerts.
Run the full load test with browser refreshes, settings churn, API traffic, uptime tick checks, and repeated OTA uploads:
cd ~/projects/access-controller/code/controller/tests
DEVICE_URL=http://192.168.1.131 \
SOAK_DURATION_MS=3600000 \
SOAK_STATE_WORKERS=2 \
SOAK_SETTINGS_WORKERS=1 \
SOAK_BROWSER_WORKERS=1 \
SOAK_BROWSER_REFRESH_MS=3000 \
SOAK_OTA_REPEATS=4 \
SOAK_AUDIBLE_ALERT=1 \
SOAK_PROGRESS_MS=60000 \
npm run test:soak
Expected evidence:
GET /api/state, /api/signals, logs, Wi-Fi, Wiegand, RF, and discovery stay responsive.alert:false.code/controller/tests/artifacts/.The 4 state / 2 settings / 2 browser worker profile is a destructive stress profile for the current ESP32 build. Use it only when intentionally investigating overload behavior; it can wedge Wi-Fi/HTTP without a firmware panic. The acceptance soak is the 2/1/1 profile above, which still exercises continuous API traffic, browser refreshes, settings churn, uptime ticks, and OTA.
cd ~/projects/access-controller/code/controller/tests
DEVICE_URL=http://192.168.1.131 npm run test:quick
DEVICE_URL=http://192.168.1.131 SOAK_DURATION_MS=120000 SOAK_OTA_REPEATS=0 SOAK_AUDIBLE_ALERT=1 npm run test:soak
DEVICE_URL=http://192.168.1.131 npm run test:ui
Use this when validating app-slot stability:
cd ~/projects/access-controller/code/controller
for i in 1 2 3 4 5; do
python3 tools/ota_client.py --host http://192.168.1.131 --binary build/controller.bin --yes
sleep 12
curl -sf http://192.168.1.131/api/state | jq '{version:.system.firmware.projectVersion, ota:.system.firmware.otaState, running:.system.firmware.runningPartition.label, uptime:.system.uptimeSeconds}'
done
/devicesThe production path is:
https://open-automation.org/devices.sonic controls and OTAs the controller over LAN at the controller STA IP.CONFIG_ACCESS_CONTROLLER_ENABLE_TUNNEL=n; do not re-enable it for normal testing because it consumes heap/socket capacity and the current implementation is not suitable for full OTA-sized bodies.Verify the public punch path without exposing the full UI:
curl -sf -X POST https://open-automation.org/devices \
-H 'Content-Type: application/json' \
-d '{"uuid":"smoke-test","name":"codex-smoke","type":"access_controller"}'
curl -sS -i https://open-automation.org/devices/ | sed -n '1,12p'
Expected: the POST returns 200, and unauthenticated browser GET returns
401 Basic realm="Device Manager". Remove any temporary punch record after the
test from sonic:/home/andy/projects/device-manager/data/discovery/punched.json
using the Device Manager data-volume owner.
Verify Device Manager LAN-backed state:
ssh sonic 'curl -sf http://127.0.0.1:8102/api/devices/<device-manager-id>/access-controller/state \
| jq "{ok, device_id, uuid:.state.device.uuid, ip:.state.device.network.wifi_sta_ip, running:.state.system.firmware.runningPartition.label, ota:.state.system.firmware.otaState}"'
Verify Device Manager OTA:
scp ~/projects/access-controller/code/controller/build/controller.bin sonic:/tmp/access-controller-candidate.bin
ssh sonic 'curl -sf --max-time 180 -X POST \
http://127.0.0.1:8102/api/devices/<device-manager-id>/access-controller/ota \
-H "Content-Type: application/octet-stream" \
-H "X-Firmware-Filename: controller.bin" \
--data-binary @/tmp/access-controller-candidate.bin | jq .'
After Device Manager OTA, confirm both direct LAN and Device Manager state return otaState: valid.
This is destructive to saved settings. Preserve the known Wi-Fi credentials first.
Build the app:
cd ~/projects/access-controller/code/controller
source ~/esp/esp-idf/export.sh
idf.py build
Erase and flash over serial:
ESP_PORT=/dev/ttyUSB0 idf.py -p /dev/ttyUSB0 erase-flash
./flash_now.sh
Verify AP mode:
http://192.168.4.1/api/state.device.network.wifi_ap_ip is 192.168.4.1 and STA IP is empty.device.uuid is stable for this board across full-chip erases.Restore Wi-Fi from AP mode:
curl -sf -X POST http://192.168.4.1/api/wifi/add \
-H 'Content-Type: application/json' \
-d '{"ssid":"HelloWorld","password":"qscwdvpk"}'
Wait for STA mode:
for i in $(seq 1 90); do
curl -sf http://192.168.1.131/api/state && break
sleep 2
done
Confirm server policy and tunnel target:
curl -sf http://192.168.1.131/api/state | jq '{server:.server, network:.device.network, firmware:.system.firmware}'
To test fallback without erasing flash:
http://192.168.4.1:
cd ~/projects/access-controller/code/controller/tests
DEVICE_URL=http://192.168.4.1 SOAK_DURATION_MS=300000 SOAK_OTA_REPEATS=0 SOAK_AUDIBLE_ALERT=1 npm run test:soak
valid.sonic; public POST /devices accepts punch-in, and public browser GET /devices/ is authenticated.