Skip to content

feat: v0.6.0 — generic telemetry events, default filters, per-frame TUI updates#15

Merged
Oceanswave merged 3 commits intomainfrom
feat/v0.5.0-openclaw-lifecycle
Feb 5, 2026
Merged

feat: v0.6.0 — generic telemetry events, default filters, per-frame TUI updates#15
Oceanswave merged 3 commits intomainfrom
feat/v0.5.0-openclaw-lifecycle

Conversation

@Oceanswave
Copy link
Owner

@Oceanswave Oceanswave commented Feb 5, 2026

Summary

Features

  • Generic telemetry events — all 230+ telemetry fields now produce OpenClaw events via a generic fallback in the emitter; unmapped fields emit as snake_case event types (PackVoltagepack_voltage) with field and value payload
  • Default filter for unconfigured fieldsDualGateFilter applies sensible defaults (any-change, 5s throttle, 2min staleness) to unconfigured fields instead of silently dropping them
  • telemetry.get handler + MCP tool — agents can read the latest value of any telemetry field from the in-memory store
  • Trigger commands in capabilitiesNodeCapabilities advertises telemetry.get, trigger.list, trigger.create, trigger.delete
  • TUI per-frame updates — panel DataTables update immediately as telemetry data arrives instead of polling on a 1-second timer
  • Removed trigger.poll — trigger notifications are delivered exclusively via push callbacks over the OpenClaw WebSocket; the polling endpoint, MCP tool, and pending queue have been removed

Bugfixes & hardening

  • Port-in-use crash_resolve_port() pre-checks availability, auto-selects a free port when the default is occupied, raises clear UsageError for explicit --port; environment-sourced ports treated as explicit
  • SystemExit killing the event loop — uvicorn's sys.exit(1) caught by _safe_uvicorn_serve() and converted to OSError; clean shutdown (code 0) logged at debug
  • Notification serialization hardening — guards narrowed from except Exception to (AttributeError, TypeError, ValueError); per-notification isolation in both push callback and flush loop
  • Pending push queue overflow — logs dropped notification before eviction; flush_pending_push guarded after reconnect
  • system.run unknown method — bumped to warning with both raw and resolved method names
  • contextlib.suppress hiding bugs — replaced with explicit try/except + debug-level logging
  • p.pop("field") mutating MCP params — fixed with p.get() + filtered dict copy
  • _matches()matches() — renamed to public API for cross-module consumers
  • Shared _internal/units.py — replaces 3 duplicate temperature conversion implementations
  • telemetry_get store-unavailable — returns {"error": "telemetry_store_unavailable"} instead of misleading {"pending": true}
  • Empty exception message crash — shows "Unexpected {Type}" + --verbose hint
  • Reconnect/Tailscale warnings — added exc_info=True for traceability

Test plan

  • All 1749 tests pass (pytest --timeout=30)
  • Ruff lint clean (ruff check src/ tests/)
  • New tests/cli/test_serve_port.py — port resolution, conflict handling, SystemExit wrapping (8 tests)
  • Manual: run tescmd serve and confirm TUI panels populate immediately on first telemetry frame
  • Manual: confirm unconfigured telemetry fields appear as events in OpenClaw gateway logs
  • Manual: start tescmd serve when port 8080 is occupied — verify auto-select and log message

🤖 Generated with Claude Code

Oceanswave and others added 3 commits February 4, 2026 23:33
…UI updates

All 230+ telemetry fields now produce OpenClaw events via a generic
fallback emitter (PascalCase → snake_case event types). Unconfigured
fields pass through DualGateFilter with sensible defaults instead of
being silently dropped. Added telemetry.get read handler and MCP tool
for arbitrary field reads. TUI panels now update per-frame instead of
polling on a 1-second timer.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Trigger notifications are delivered exclusively via push callbacks over
the OpenClaw WebSocket. Removed the polling endpoint, MCP trigger_poll
tool, pending notification queue, drain_pending(), and queue_notification()
from TriggerManager. Tests updated to use fire callbacks instead of
drain_pending() assertions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Port-in-use crash: pre-check with _resolve_port(), auto-select free
  port when default is occupied, clear UsageError for explicit --port
- SystemExit from uvicorn caught and converted to OSError; clean
  shutdown (code 0) logged at debug level and passed through
- Environment-sourced --port treated as explicit (not auto-select)
- Notification serialization guards narrowed from except Exception to
  (AttributeError, TypeError, ValueError) in push callback and flush
- Pending push queue overflow logs dropped notification before eviction
- flush_pending_push guarded after reconnect so one bad notification
  cannot break recovery
- system.run unknown method bumped to warning with resolved name
- contextlib.suppress replaced with explicit try/except + debug log
- p.pop("field") mutation fixed with p.get() + filtered dict copy
- _matches() renamed to matches() as public API
- Shared _internal/units.py replaces 3 duplicate temp conversions
- telemetry_get distinguishes store-unavailable from pending
- Empty exception message shows "Unexpected {Type}" + --verbose hint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Oceanswave Oceanswave force-pushed the feat/v0.5.0-openclaw-lifecycle branch from 6108d86 to 2decf37 Compare February 5, 2026 04:34
@Oceanswave Oceanswave merged commit cf47a0e into main Feb 5, 2026
0 of 3 checks passed
@Oceanswave Oceanswave deleted the feat/v0.5.0-openclaw-lifecycle branch February 5, 2026 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant