All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
code=70132 "Energy flow rule not exists"
response fell into the same silent DEBUG-level handling as a merely
unsupported/404 endpoint. That specific error now logs a clear WARNING
explaining the fix is a portal-side setup step (configuring an
energy-flow rule for the device on solar.siseli.com), not something a
future field mapping can resolve. Reported in #21.load_power's unit, the mains-power sign convention,
and the battery terminal current's charge/discharge direction — had only
been captured at night, reading zero. Four daylight captures across every
AC/PV/charging combination settled all three: load_power and the mains
fields carry their own "unit" tag in the payload (kW and W
respectively, not guessed), and the mains-power sign checks out against
simple load-minus-generation arithmetic in every AC-connected sample.
Thanks to @hidemichixt-creator for the four-state capture set (#7).Europe rather than Europe/Warsaw,
for example) was sent as-is to the portal, which rejected the very first
request with Timeseries error code=20101 message=Illegal argument — with
nothing in the error pointing at time zone as the cause. The field is now
validated locally before any API call, with a clear in-form error instead.
Thanks to @Terrorr for the report (#21).unknown on Siseli HPVINV02 devices ("Inverter Top One" gather
protocol), even though the account, station and other sensors all worked
normally. This firmware reports those three fields under different key
names (pvPower, outputActivePower, batteryCapacity) than the
documented ones — the integration now recognises both. Thanks to
@UnSpritz for root-causing this via live debug logging and submitting the
fix (#13).unknown while the
portal showed live data — the shared cause behind #3, #7, #8, #11, #14 and
#15. Those devices serve live values from
/apis/deviceState/simple/energy/flow/v1 under a different set of field
names, and the integration now falls back to that endpoint and maps them.Populated by the fallback: PV Input Power (per-string pv1Power…pv4Power,
summed), Battery Voltage, Battery State of Charge, Battery Power.
Thanks to @jazuch for a report that included the endpoint, the data path, the field names and sample values, and to @hidemichixt-creator for confirming the fix against real hardware.
voltage x current estimate.generationPower, load_power / loadPower, and the per-phase
aPhaseMainsPower / bPhaseMainsPower / cPhaseMainsPower — every
captured sample was zero (night-time reading), so kW-vs-W is unconfirmed.positiveTerminalBatteryCurrent / negativeTerminalBatteryCurrent — the
magnitude is correct, but which terminal means charge and which means
discharge is unverified, and a swap would invert the two.Load Power and Grid Import Power therefore keep their existing derived
estimates. See ENERGY_FLOW_UNVERIFIED in const.py; tracked in #7.
station_id and
device_id are plain strings, and an ID of any length is accepted. The dialog
text, README, QUICKSTART and bug-report template now say "usually 18 digits".stationId from the portal's API request payload
(DevTools → Network). The number printed on the inverter or WiFi dongle, and
plant/registration codes shown in the portal UI, are different identifiers and
will not work — this is the most common cause of the mix-up above.Hyllesen/solar-of-things-solar-usage). It now points here.conexocasa/ URLs to the canonical Conexo-Casa/
organisation, including the outbound User-Agent.User-Agent version string was pinned at 2.3.0 and no longer matched the
shipped release; it now reports the correct version.unknown or stuck at 0, that is a separate, known issue
tracked in #7 (some inverters/dongles return live data from
/energy/flow/v1 under different field keys) and is not addressed by this
release.__init__.py, api.py, config_flow.py,
const.py, sensor.py, number.py, select.py, switch.py, manifest.json,
strings.json, translations/) — these were leftover copies from before the
v2.4.0 HACS restructure. They confused CodeQL (triggering duplicate alerts on
deleted code), could mislead HACS, and were dead code.permissions hardened — validate.yml and codeql.yml now
declare permissions: contents: read (principle of least privilege). Resolves
CodeQL alert #1 (actions/missing-workflow-permissions)..github/workflows/codeql.yml) — explicit weekly
security scan scoped to custom_components/solar_of_things/ only, with a
documented exclusion for the protocol-mandated MD5 pre-hash..github/codeql-config.yml) — scopes analysis to the
integration source, ignores dist/ and tests/, and documents the
py/weak-sensitive-data-hashing suppression rationale.api.py line ~315) — added
# noqa: S324 and an explanatory comment. The Siseli API rejects plaintext
passwords (returns error code 7); MD5(password) is a protocol requirement of
the upstream service transmitted over HTTPS. This is not password storage and
cannot be changed without breaking authentication.validate.yml fixed — was still pointing at root-level .py files and
manifest.json (which no longer exist). Now correctly validates
custom_components/solar_of_things/. Added integration_type and
homeassistant to the manifest required-key check.release.yml fixed — was building the ZIP from root-level files. Now zips
custom_components/solar_of_things/ correctly.Thread-safety crash (HA warning: "calls hass.config_entries.async_update_entry
from a thread other than the event loop") — the on_token_refreshed callback was
decorated @callback but invoked from a background executor thread during token
refresh. async_update_entry can only be called from the event loop. Fixed by
wrapping the update in a nested @callback and scheduling it with
hass.loop.call_soon_threadsafe(). Resolves crash/data-corruption risk reported
in issue #2.
Token refresh 404 ("token refresh request failed: 404 Not Found for url:
https://solar.siseli.com/login/refresh/access/token") — the refresh endpoint
was missing the /apis/ prefix. Corrected to
/apis/login/refresh/access/token. This caused every token refresh to fail
silently, eventually leading to expired tokens and "Unknown" sensor values.
Resolves the sensor data issue reported in issue #2.
via_device warning ("calls device_registry.async_get_or_create referencing
a non existing via_device … This will stop working in Home Assistant 2025.12.0")
— the station hub device was never explicitly registered in the device registry,
so per-device entities' via_device reference pointed to a non-existent device.
The station device is now registered in async_setup_entry before
async_forward_entry_setups is called. Resolves issue #2 comments from Gaz93
and andreasantorelli12-hue.
custom_components/solar_of_things/ as required by HACS. Installing via HACS
or manual copy now works without any path adjustments.brand/icon.png added so the integration displays an icon
in the HACS store and HA Integrations page.translation_key +
has_entity_name = True, enabling future multi-language support and aligning
with HA quality-scale best practices.number.py called api.set_battery_charge_limit(),
api.set_battery_discharge_limit(), and api.set_grid_charge_limit() which did not
exist in api.py. Interacting with any number slider raised an AttributeError.
All three methods are now implemented.strings.json defined state keys
(self_use, time_of_use, backup, grid_tie, off_grid) that did not match
the actual API option strings (Utility First (USO), Solar First (SUB), etc.).
State translations now match the real API values exactly.(DOMAIN, station_id, device_id)
as the device identifier while switches, selects, and numbers used the same tuple
but in a different evaluation path. All device-level entities now use
(DOMAIN, device_id) and station-level entities use (DOMAIN, station_id),
eliminating duplicate device entries in the device registry.async_step_reauth declared entry_data as
a required argument; HA 2024+ calls it with no argument. Made the parameter
optional (entry_data: dict | None = None).manifest.json: added integration_type: hub (required since HA 2023.6),
set homeassistant: "2023.6.0" minimum version, updated codeowners.hacs.json: updated homeassistant minimum to 2023.6.0, removed legacy
zip_release / filename / domains fields incompatible with the new layout.strings.json / translations/en.json: corrected select state keys; added
full sensor translation entries (previously absent)..gitignore: added graphify-out/ to exclude local knowledge-graph cache.POST /apis/remote/device/configs/cache/get?deviceId=<id>POST /apis/remote/device/config/write?deviceId=<id>select.py — Operating Mode and Battery Priority selects now use real API keys
(outputSourcePrioritySetting, chargerSourcePrioritySetting) with correct
integer value mappings (USO/SUB/SBU, CSO/SNU/OSO).switch.py — all three switches map to correct API setting keys.fetch_settings AttributeError — added class-level alias so both get_device_settings
and fetch_settings work.SolarOfThingsAPI added
(set_operating_mode, set_battery_priority, set_grid_charging,
set_grid_feed_in, set_backup_mode).rBrTRfAPXz targeting https://solar.siseli.com.
Previous release used the test AppID, causing "account error" for all real users.on_token_refreshed callback persists tokens to config entry.hacs.json and manifest.json metadata updates.POST /apis/device/list.device_id in config flow (blank = auto-discover all devices).