-
Notifications
You must be signed in to change notification settings - Fork 4
fix(pixii): retain calibration fault while charge status is unknown #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| """Missing SunSpec status cannot prove that battery calibration finished.""" | ||
|
|
||
| from pathlib import Path | ||
| import subprocess | ||
|
|
||
| import pytest | ||
|
|
||
| ROOT = Path(__file__).resolve().parents[2] | ||
| LUA = ROOT / "lua55" | ||
| pytestmark = pytest.mark.skipif(not LUA.exists(), reason="run make test-driver ID=pixii") | ||
|
|
||
|
|
||
| def run_lua(body: str) -> None: | ||
| script = ''' | ||
| package.path = "drivers/tests/lua_harness/?.lua;" .. package.path | ||
| require("host_mock") | ||
| host.reset() | ||
| host._modbus_registers.holding[40000] = {0x5375, 0x6e53} | ||
| host._modbus_registers.holding[40132] = 50 | ||
| host._modbus_registers.holding[40138] = 0 | ||
| host._modbus_registers.holding[40143] = 3 | ||
| dofile("drivers/lua/pixii.lua") | ||
| driver_init({}) | ||
| local function poll(code) | ||
| host._modbus_registers.holding[40137] = code | ||
| host._metrics = {} | ||
| driver_poll() | ||
| return host._emitted.battery[#host._emitted.battery] | ||
| end | ||
| ''' + body | ||
| result = subprocess.run([str(LUA), "-e", script], cwd=ROOT, text=True, capture_output=True) | ||
| assert result.returncode == 0, result.stdout + result.stderr | ||
|
|
||
|
|
||
| def test_pixii_unsupported_status_is_unknown_and_warns_once() -> None: | ||
| run_lua(''' | ||
| host._modbus_registers.holding[40138] = 0xffff | ||
| host._modbus_registers.holding[40143] = 0xffff | ||
| host._modbus_registers.holding[40144] = 0xffff | ||
| for i = 1, 10 do | ||
| local battery = poll(0xffff) | ||
| assert(battery.charge_status == "unknown", battery.charge_status) | ||
| assert(battery.control_mode == "unknown", battery.control_mode) | ||
| assert(battery.battery_state == "unknown", battery.battery_state) | ||
| assert(battery.battery_vendor_state == nil) | ||
| for _, name in ipairs({"battery_charge_status_code", "battery_control_mode_code", | ||
| "battery_state_code", "battery_vendor_state_code"}) do | ||
| assert(host._metrics[name] == nil, name .. " emitted an unsupported value") | ||
| end | ||
| assert(not host._faulted, "unknown status invented a calibration fault") | ||
| end | ||
| local warnings = 0 | ||
| for _, message in ipairs(host._logs) do | ||
| if message:find("calibration state is unknown", 1, true) then warnings = warnings + 1 end | ||
| end | ||
| assert(warnings == 1, "expected one unknown-status warning, got " .. warnings) | ||
| assert(#host._emitted.meter == 10, "unknown status stopped meter telemetry") | ||
| ''') | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("unknown", ["0xffff", "99", "0"]) | ||
| def test_pixii_unknown_status_does_not_clear_calibration(unknown: str) -> None: | ||
| run_lua(f''' | ||
| poll(7) | ||
| assert(host._faulted, "TESTING did not block dispatch") | ||
| poll({unknown}) | ||
| assert(host._faulted, "unknown status cleared calibration") | ||
| assert(host._fault_reason:find("calibrating", 1, true)) | ||
| poll(4) | ||
| assert(not host._faulted, "valid charge status did not clear calibration") | ||
| ''') | ||
|
|
||
|
|
||
| def test_pixii_failed_status_read_does_not_clear_calibration() -> None: | ||
| run_lua(''' | ||
| poll(7) | ||
| host._modbus_read_fail_addresses[40137] = "timeout" | ||
| local battery = poll(4) | ||
| assert(host._faulted, "failed status read cleared calibration") | ||
| assert(battery.charge_status == "unknown") | ||
| host._modbus_read_fail_addresses[40137] = nil | ||
| poll(3) | ||
| assert(not host._faulted, "valid status did not recover after a transient read failure") | ||
| ''') | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("status", [1, 2, 3, 4, 5, 6]) | ||
| def test_pixii_known_status_can_clear_calibration(status: int) -> None: | ||
| run_lua(f''' | ||
| poll(7) | ||
| poll({status}) | ||
| assert(not host._faulted) | ||
| assert(host._metrics.battery_charge_status_code.value == {status}) | ||
| assert(host._metrics.battery_control_mode_code.value == 0, "remote control code 0 is valid") | ||
| ''') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new sentinel and enum interpretation is explicitly decoded from the SunSpec Device Information Model and model 802, but
manifests/pixii.yamlstill has noupstream_docsentry. As a result, the weekly watcher cannot alert maintainers if either specification changes or disappears; add the durable source URLs already identified for this change to the manifest.AGENTS.md reference: AGENTS.md:L76-L82
Useful? React with 👍 / 👎.