Skip to content

feat: add support for /time and /settime endpoints - #714

Merged
firstof9 merged 2 commits into
mainfrom
feat/time-support
Sep 25, 2026
Merged

firstof9 merged 2 commits into
mainfrom
feat/time-support

Conversation

@firstof9

Copy link
Copy Markdown
Owner

Description

Adds support for OpenEVSE /time and /settime endpoints and associated properties:

  • Added property accessors: timezone, time_offset, sntp_enabled, and sntp_hostname.
  • Added command methods:
    • get_time(): Retrieves RTC / NTP / timezone status from GET /time on 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 ($S1 RTC time set).
    • sync_time(): Triggers immediate NTP synchronization via POST /time (sync_now: True) on gateway firmware v4.0.0+.
  • Updated API matrix documentation in README.md and developer skills (endpoints_matrix.md, SKILL.md).
  • Added comprehensive unit tests for all properties and command variations across firmware versions.

Type of change

  • New feature (non-breaking change which adds functionality)
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 89419d6b-6e66-4065-8115-09fc9d5f53f0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the feature New Features label Sep 25, 2026

@secondof9 secondof9 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 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 /time on v4.0.0+ firmware, falls back to synthesized data from _status/_config on legacy firmware.
    • Returns dict with time, offset, and local_time keys — consistent structure across firmware versions.
    • Validates response type and raises CommandFailedError on invalid response — good defensive practice.
  • _format_time_str() static method (lines 968–982)

    • Handles datetime, ISO-8601 string, and None inputs cleanly.
    • Converts timezone-aware datetimes to UTC ISO-8601 format — correct for API consumption.
    • Raises descriptive TypeError for unsupported types.
  • _set_time_v4() (lines 984–1019)

    • Validates sntp (bool) and timezone_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=False and target_time=None — sensible default.
    • Updates local _config cache on success — maintains consistency for property accessors.
  • _set_time_v3() (lines 1021–1045)

    • Uses legacy /settime endpoint for v3.x firmware.
    • Same validation and auto-UTC logic as v4 path.
    • Only includes provided parameters in payload — avoids overwriting unset fields.
  • _set_time_v2() (lines 1047–1074)

    • Falls back to RAPI $S1 command for v2.x (ESP8266) firmware.
    • Parses ISO-8601 strings with Z → +00:00 replacement for datetime.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.
  • 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, or None for target_time — flexible API.
  • sync_time() (lines 1098–1117)

    • Requires v4.0.0+ firmware — raises UnsupportedFeature on older versions with clear message.
    • Sends {"sync_now": true} payload — matches documented v4 API.
    • Same response validation pattern as other commands.
openevsehttp/properties.py — Time Property Accessors
  • timezone (lines 618–620) — Returns time_zone from _config (e.g., America/Phoenix|MST7).
  • time_offset (lines 622–625) — Returns offset from _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) — Returns sntp_hostname from _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 — Verifies UnsupportedFeature raised 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: /time now ✅, added /settime row 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 /time and /settime to "✅ 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:

  1. Correctly handles multi-generation firmware with appropriate version checks and fallbacks.
  2. Follows existing code patterns — error handling, logging, response validation match the codebase style.
  3. Provides defensive validation — type checks on inputs, response type verification, clear error messages.
  4. Maintains async safety — no blocking I/O in properties or commands, proper await usage.
  5. Has comprehensive test coverage — all paths, error conditions, and firmware versions tested.
  6. Updates documentation — README, SKILL.md, and endpoints matrix all synchronized.
  7. All CI checks pass — including Python 3.13 and 3.14 builds.

No blocking issues found. Approved.

@firstof9
firstof9 merged commit 6102b73 into main Sep 25, 2026
13 checks passed
@firstof9
firstof9 deleted the feat/time-support branch September 25, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants