tliu93
8d4f496ff4
DSMR hardening: restart-free config + decouple from telegram id
...
Config hot-reload (no restart):
- MqttManager.unsubscribe(); apply_dsmr_subscription(settings) re-applies the
DSMR subscription (subscribe/unsubscribe/topic-change, fresh snapshot so the
sample interval also takes effect).
- Called from lifespan AND PUT /api/config, so toggling DSMR ingest in the UI
takes effect immediately without restarting the app.
Decouple ingest from the DSMR telegram id (overflows / resets to zero):
- Migration 20260624_12: drop UNIQUE(source_id), make recorded_at UNIQUE.
- Idempotency now keys on recorded_at (telegram timestamp); the table's own
autoincrement PK is the stable identity. source_id kept only as a reference.
- Regression test: colliding telegram ids no longer drop new data.
2026-06-24 11:02:32 +02:00
tliu93
c61fc2d4ba
M6-T08: add energy_cost expose provider + post-billing state publish
...
- expose.py: _energy_cost_provider yields buy/sell_price_now + import_cost_total
/export_revenue_total (total_increasing, monetary), value_getters read from
energy_cost_period; 2-element identifiers so the existing HA Discovery builder
(which indexes identifiers[1]) works. Other providers/mechanism untouched.
- main.py: energy-cost job calls publish_states after computing periods (no-op
when MQTT/Discovery off). Tests added.
Note: energy-cost sensors lack an availability heartbeat (ha_discovery mechanism
limitation, out of scope here).
2026-06-23 22:44:41 +02:00
tliu93
ef48032adb
M6-T06: extend MqttManager with subscribe + DSMR ingest
...
- mqtt.py: subscription registry, on_message dispatch (swallows handler
errors), re-subscribe on (re)connect; publish/connect/disconnect/reconnect
unchanged.
- app/services/dsmr_ingest.py: handle_message stores the full telegram frame
(no allowlist; gas/phases/null preserved), 10s downsample by timestamp.second,
source_id idempotency (select + IntegrityError rollback). Net-thread safe.
- main.py registers the DSMR subscription only when dsmr_ingest_enabled.
2026-06-23 21:52:57 +02:00
tliu93
7e266a21eb
M6-T05: add Tibber GraphQL client + price refresh service + schedule
...
- app/integrations/tibber/client.py: fetch_price_range/fetch_current_price
(priceInfoRange QUARTER_HOURLY, startsAt->UTC, no fixed node count assumption),
TibberError/TibberAuthError; token never logged or put in exception text.
- app/services/tibber_prices.py: refresh_prices upserts by starts_at (idempotent),
no-op unless an active kind=tibber contract + token exist.
- main.py: hourly tibber-refresh job (existing jobs/MQTT untouched). Tests added.
2026-06-23 21:35:29 +02:00
tliu93
bedea196c3
M6-T03: add pricing profile framework + strategy registry
...
- app/integrations/pricing: profiles.py (pydantic ManualProfile/TibberProfile,
load_profile/list_profiles/validate_values), manual.yaml + tibber.yaml
(structure-only, no price values), strategies.py (register/get_strategy,
manual dual-tariff + tibber strategies, all Decimal).
- tibber strategy matches nearest tibber_price with starts_at <= t0.
- tests for profiles + strategies (hand-checked dual-tariff & tibber math).
2026-06-23 20:58:34 +02:00
tliu93
35b95f5c88
M5-T11: add HA discovery and state publishing wired to polling
2026-06-22 15:32:43 +02:00
tliu93
9d05f5ea62
M5-T10: add paho MQTT client with lifespan connect/reconnect and mqtt/test endpoint
2026-06-22 15:06:30 +02:00
tliu93
360cddc05b
M5-T09: add exposed_entities table and ExposableEntity provider framework
2026-06-22 14:50:40 +02:00
tliu93
c89cea4953
M5-T03: add Modbus TCP driver, YAML profile framework, sdm120, modbus_cli
2026-06-22 13:03:50 +02:00
tliu93
fe0409dafe
Refine runtime config and redirect settings
2026-04-20 17:36:05 +02:00
tliu93
982af62f4f
Migrate TickTick OAuth and action tasks
2026-04-20 17:06:03 +02:00
tliu93
151ad46275
Add Home Assistant outbound adapter
2026-04-20 10:11:02 +02:00
tliu93
31390882ef
Bootstrap Python rewrite skeleton
2026-04-19 20:19:58 +02:00