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.
__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).