feat: add support for /time and /settime endpoints - #714
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
secondof9
left a comment
There was a problem hiding this comment.
📋 Review Summary
Tip
Review Status: 🟢 APPROVED
Change Type: ⚡ Feature
Review Effort: 🟡 Medium
Core Impact: This PR adds comprehensive support for OpenEVSE time management endpoints (/time and /settime) across all firmware generations (v2.x, v3.x, v4.x+), including property accessors for timezone, offset, SNTP status, and commands for getting/setting time and triggering NTP sync. The implementation correctly handles firmware version detection, provides graceful fallbacks, and includes thorough test coverage.
🚦 CI & Pipeline Health Summary
| Check / Workflow Name | Status | Impact on Review |
|---|---|---|
Analyze (actions) |
✅ PASSED | Static analysis clean |
Analyze (python) |
✅ PASSED | Python linting/type checks clean |
Autolabel PR |
✅ PASSED | Metadata labeling working |
CodeQL |
✅ PASSED | Security analysis clean |
build (3.13) |
✅ PASSED | Python 3.13 build verified |
build (3.14) |
✅ PASSED | Python 3.14 build verified |
codecov/patch |
✅ PASSED | Coverage maintained |
coverage |
✅ PASSED | Full test coverage maintained |
linkChecker |
✅ PASSED | Documentation links valid |
prek |
✅ PASSED | Pre-commit hooks pass |
Note
CI Pipeline Clear: All GitHub Actions workflows completed successfully.
🔍 Architectural Walkthrough
openevsehttp/commands.py — Time Management Commands
-
get_time()(lines 947–966)- Correctly implements version-aware logic: uses
GET /timeon v4.0.0+ firmware, falls back to synthesized data from_status/_configon legacy firmware. - Returns dict with
time,offset, andlocal_timekeys — consistent structure across firmware versions. - Validates response type and raises
CommandFailedErroron invalid response — good defensive practice.
- Correctly implements version-aware logic: uses
-
_format_time_str()static method (lines 968–982)- Handles
datetime, ISO-8601 string, andNoneinputs cleanly. - Converts timezone-aware datetimes to UTC ISO-8601 format — correct for API consumption.
- Raises descriptive
TypeErrorfor unsupported types.
- Handles
-
_set_time_v4()(lines 984–1019)- Validates
sntp(bool) andtimezone_str(str) parameters — prevents silent type coercion bugs. - Defaults SNTP from config when not explicitly provided — preserves existing behavior.
- Auto-generates current UTC time when
sntp=Falseandtarget_time=None— sensible default. - Updates local
_configcache on success — maintains consistency for property accessors.
- Validates
-
_set_time_v3()(lines 1021–1045)- Uses legacy
/settimeendpoint for v3.x firmware. - Same validation and auto-UTC logic as v4 path.
- Only includes provided parameters in payload — avoids overwriting unset fields.
- Uses legacy
-
_set_time_v2()(lines 1047–1074)- Falls back to RAPI
$S1command for v2.x (ESP8266) firmware. - Parses ISO-8601 strings with
Z→+00:00replacement fordatetime.fromisoformat()compatibility. - Extracts year modulo 100 for 2-digit year in RAPI command — matches protocol spec.
- Handles RAPI-specific error responses (
$NK,RAPI_ERRORS) — correct protocol handling.
- Falls back to RAPI
-
set_time()public API (lines 1076–1096)- Clean dispatch based on firmware version: v4.0.0+ → v4 path, v3.0.0+ → v3 path, else → v2 path.
- Uses
_format_time_str()for consistent time formatting across all paths. - Accepts
datetime, ISO-8601 string, orNonefortarget_time— flexible API.
-
sync_time()(lines 1098–1117)- Requires v4.0.0+ firmware — raises
UnsupportedFeatureon older versions with clear message. - Sends
{"sync_now": true}payload — matches documented v4 API. - Same response validation pattern as other commands.
- Requires v4.0.0+ firmware — raises
openevsehttp/properties.py — Time Property Accessors
timezone(lines 618–620) — Returnstime_zonefrom_config(e.g.,America/Phoenix|MST7).time_offset(lines 622–625) — Returnsoffsetfrom_status(e.g.,+0000,-0700).sntp_enabled(lines 627–632) — Returns boolean from_config.get("sntp_enabled", False), handles empty config.sntp_hostname(lines 634–637) — Returnssntp_hostnamefrom_config.
All properties are simple cached accessors — no I/O, no blocking calls — compliant with HA entity property patterns.
Tests — test_commands.py
test_get_time— Tests v4 success, v4 invalid response, v2 legacy fallback. Validates structure and error handling.test_set_time_v4— Tests type validation (sntp, timezone_str, target_time), datetime/string/None inputs, success/failure responses, config cache updates.test_set_time_v3— Tests v3 path with type validation, success cases, failure response.test_set_time_v2— Tests v2 RAPI path: invalid string parsing, type errors, string/datetime/None success, RAPI rejection.test_sync_time_unsupported— VerifiesUnsupportedFeatureraised on v2 firmware.test_sync_time— Tests success and failure on v4+ firmware.
Test coverage is comprehensive across all three firmware generations and error paths.
Documentation Updates
- README.md — Updated endpoint table:
/timenow ✅, added/settimerow with ✅. - .agents/skills/openevse-api-guide/SKILL.md — Added "Time Settings" row to endpoint matrix.
- .agents/skills/openevse-api-guide/references/endpoints_matrix.md — Updated
/timeand/settimeto "✅ Fully Supported".
All documentation changes are accurate and consistent.
🔗 Related / Outside-Diff Context
- No external dependencies or auxiliary files need updates — the PR is self-contained with complete implementation, tests, and documentation.
✅ Final Assessment
This PR is production-ready. The implementation:
- Correctly handles multi-generation firmware with appropriate version checks and fallbacks.
- Follows existing code patterns — error handling, logging, response validation match the codebase style.
- Provides defensive validation — type checks on inputs, response type verification, clear error messages.
- Maintains async safety — no blocking I/O in properties or commands, proper
awaitusage. - Has comprehensive test coverage — all paths, error conditions, and firmware versions tested.
- Updates documentation — README, SKILL.md, and endpoints matrix all synchronized.
- All CI checks pass — including Python 3.13 and 3.14 builds.
No blocking issues found. Approved.
Description
Adds support for OpenEVSE
/timeand/settimeendpoints and associated properties:timezone,time_offset,sntp_enabled, andsntp_hostname.get_time(): Retrieves RTC / NTP / timezone status fromGET /timeon v4.0.0+ gateway firmware, or falls back to synthesizing from status/config data on legacy firmware.set_time(...): Sets charger date/time, timezone, and SNTP enablement. Supports v4.0.0+ (POST /time), v3.x (POST /settime), and v2.x RAPI fallback ($S1RTC time set).sync_time(): Triggers immediate NTP synchronization viaPOST /time(sync_now: True) on gateway firmware v4.0.0+.README.mdand developer skills (endpoints_matrix.md,SKILL.md).Type of change
Checklist