Skip to content

Commit 5aab073

Browse files
authored
Merge pull request #182 from plugwise/typed-dict
Implement TypedDict for the various Plugwise data items
2 parents a00d6a5 + 0163aa0 commit 5aab073

File tree

12 files changed

+5634
-923
lines changed

12 files changed

+5634
-923
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
# v0.18.0: Smile: add generation of cooling-schedules
4+
- Further improve typing hints: e.g. all collected measurements are now typed via TypedDicts
5+
- Implement correct generation of schedules for both heating and cooling (needs testing)
6+
37
# v0.17.8: Smile: Bugfix, improve testing
48
- Fix https://github.com/plugwise/plugwise-beta/issues/277
59
- Improve incorrect test-case validation

plugwise/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Plugwise module."""
22

3-
__version__ = "0.17.8"
3+
__version__ = "0.18.0"
44

55
from plugwise.smile import Smile
66
from plugwise.stick import Stick

plugwise/constants.py

Lines changed: 170 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from __future__ import annotations
33

44
import logging
5-
from typing import Any, Final
5+
from typing import Final, TypedDict
66

77
LOGGER = logging.getLogger(__name__)
88

@@ -406,15 +406,12 @@
406406
# P1 related measurements:
407407
HOME_MEASUREMENTS: Final[dict[str, dict[str, str]]] = {
408408
"electricity_consumed": {
409-
ATTR_TYPE: "power",
410409
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
411410
},
412411
"electricity_produced": {
413-
ATTR_TYPE: "power",
414412
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
415413
},
416414
"gas_consumed": {
417-
ATTR_TYPE: "gas",
418415
ATTR_UNIT_OF_MEASUREMENT: VOLUME_CUBIC_METERS,
419416
},
420417
}
@@ -423,7 +420,7 @@
423420
# Excluded:
424421
# zone_thermosstat: 'temperature_offset'
425422
# radiator_valve: 'uncorrected_temperature', 'temperature_offset'
426-
DEVICE_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = {
423+
DEVICE_MEASUREMENTS: Final[dict[str, dict[str, str]]] = {
427424
# HA Core thermostat current_temperature
428425
"temperature": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
429426
# HA Core thermostat setpoint
@@ -444,24 +441,24 @@
444441
# Specific for a Plug
445442
"electricity_consumed": {ATTR_UNIT_OF_MEASUREMENT: POWER_WATT},
446443
"electricity_produced": {ATTR_UNIT_OF_MEASUREMENT: POWER_WATT},
447-
"relay": {ATTR_UNIT_OF_MEASUREMENT: None},
444+
"relay": {ATTR_UNIT_OF_MEASUREMENT: NONE},
448445
# Added measurements from actuator_functionalities/thermostat_functionality
449446
"lower_bound": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
450447
"upper_bound": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
451448
"resolution": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
452-
"regulation_mode": {ATTR_UNIT_OF_MEASUREMENT: None},
453-
"maximum_boiler_temperature": {ATTR_UNIT_OF_MEASUREMENT: None},
449+
"regulation_mode": {ATTR_UNIT_OF_MEASUREMENT: NONE},
450+
"maximum_boiler_temperature": {ATTR_UNIT_OF_MEASUREMENT: NONE},
454451
}
455452

456453
# Heater Central related measurements
457-
HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = {
454+
HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, dict[str, str]]] = {
458455
"boiler_temperature": {
459456
ATTR_NAME: "water_temperature",
460457
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
461458
},
462459
"domestic_hot_water_comfort_mode": {
463460
ATTR_NAME: "dhw_cm_switch",
464-
ATTR_UNIT_OF_MEASUREMENT: None,
461+
ATTR_UNIT_OF_MEASUREMENT: NONE,
465462
},
466463
"domestic_hot_water_state": {
467464
ATTR_NAME: "dhw_state",
@@ -472,35 +469,35 @@
472469
}, # Non-zero when heating, zero when dhw-heating
473470
"central_heating_state": {
474471
ATTR_NAME: "c_heating_state",
475-
ATTR_UNIT_OF_MEASUREMENT: None,
472+
ATTR_UNIT_OF_MEASUREMENT: NONE,
476473
}, # For Elga (heatpump) use this instead of intended_central_heating_state
477474
"intended_central_heating_state": {
478475
ATTR_NAME: "heating_state",
479-
ATTR_UNIT_OF_MEASUREMENT: None,
476+
ATTR_UNIT_OF_MEASUREMENT: NONE,
480477
}, # This key shows in general the heating-behavior better than c-h_state. except when connected to a heatpump
481478
"modulation_level": {ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE},
482479
"return_water_temperature": {
483480
ATTR_NAME: "return_temperature",
484481
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
485482
},
486483
# Used with the Elga heatpump - marcelveldt
487-
"compressor_state": {ATTR_UNIT_OF_MEASUREMENT: None},
488-
"cooling_state": {ATTR_UNIT_OF_MEASUREMENT: None},
484+
"compressor_state": {ATTR_UNIT_OF_MEASUREMENT: NONE},
485+
"cooling_state": {ATTR_UNIT_OF_MEASUREMENT: NONE},
489486
# Next 2 keys are used to show the state of the gas-heater used next to the Elga heatpump - marcelveldt
490-
"slave_boiler_state": {ATTR_UNIT_OF_MEASUREMENT: None},
487+
"slave_boiler_state": {ATTR_UNIT_OF_MEASUREMENT: NONE},
491488
"flame_state": {
492-
ATTR_UNIT_OF_MEASUREMENT: None
489+
ATTR_UNIT_OF_MEASUREMENT: NONE
493490
}, # Also present when there is a single gas-heater
494491
"central_heater_water_pressure": {
495492
ATTR_NAME: "water_pressure",
496493
ATTR_UNIT_OF_MEASUREMENT: PRESSURE_BAR,
497494
},
498495
# Legacy Anna: similar to flame-state on Anna/Adam
499-
"boiler_state": {ATTR_NAME: "flame_state", ATTR_UNIT_OF_MEASUREMENT: None},
496+
"boiler_state": {ATTR_NAME: "flame_state", ATTR_UNIT_OF_MEASUREMENT: NONE},
500497
# Legacy Anna: shows when heating is active, we don't show dhw_state, cannot be determined reliably
501498
"intended_boiler_state": {
502499
ATTR_NAME: "heating_state",
503-
ATTR_UNIT_OF_MEASUREMENT: None,
500+
ATTR_UNIT_OF_MEASUREMENT: NONE,
504501
},
505502
# Outdoor temperature from APPLIANCES - present for a heatpump
506503
"outdoor_temperature": {
@@ -510,7 +507,7 @@
510507
}
511508

512509
# Known types of Smiles and Stretches
513-
SMILES: Final[dict[str, dict[str, Any]]] = {
510+
SMILES: Final[dict[str, dict[str, str]]] = {
514511
"smile_open_therm_v3": {
515512
"type": "thermostat",
516513
"friendly_name": "Adam",
@@ -530,7 +527,7 @@
530527
"smile_thermo_v1": {
531528
"type": "thermostat",
532529
"friendly_name": "Anna",
533-
"legacy": True,
530+
"legacy": "true",
534531
},
535532
"smile_v4": {
536533
"type": "power",
@@ -543,10 +540,10 @@
543540
"smile_v2": {
544541
"type": "power",
545542
"friendly_name": "P1",
546-
"legacy": True,
543+
"legacy": "true",
547544
},
548-
"stretch_v3": {"type": "stretch", "friendly_name": "Stretch", "legacy": True},
549-
"stretch_v2": {"type": "stretch", "friendly_name": "Stretch", "legacy": True},
545+
"stretch_v3": {"type": "stretch", "friendly_name": "Stretch", "legacy": "true"},
546+
"stretch_v2": {"type": "stretch", "friendly_name": "Stretch", "legacy": "true"},
550547
}
551548

552549

@@ -608,3 +605,153 @@
608605
"lock",
609606
"relay",
610607
]
608+
609+
610+
class ApplianceData(TypedDict, total=False):
611+
"""The Appliance Data class."""
612+
613+
dev_class: str
614+
firmware: str | None
615+
hardware: str
616+
location: str
617+
mac_address: str | None
618+
members: list[str]
619+
model: str
620+
name: str
621+
vendor: str
622+
zigbee_mac_address: str | None
623+
624+
625+
class GatewayData(TypedDict, total=False):
626+
"""The Gateway Data class."""
627+
628+
smile_name: str
629+
gateway_id: str
630+
heater_id: str | None
631+
cooling_present: bool
632+
notifications: dict[str, str]
633+
634+
635+
class ModelData(TypedDict):
636+
"""The ModelData class."""
637+
638+
contents: bool
639+
vendor_name: str | None
640+
vendor_model: str | None
641+
hardware_version: str | None
642+
firmware_version: str | None
643+
zigbee_mac_address: str | None
644+
645+
646+
class SmileBinarySensors(TypedDict, total=False):
647+
"""Smile Binary Sensors class."""
648+
649+
compressor_state: bool
650+
cooling_state: bool
651+
dhw_state: bool
652+
flame_state: bool
653+
heating_state: bool
654+
plugwise_notification: bool
655+
slave_boiler_state: bool
656+
657+
658+
class SmileSensors(TypedDict, total=False):
659+
"""Smile Sensors class."""
660+
661+
battery: float
662+
cooling_activation_outdoor_temperature: float
663+
cooling_deactivation_threshold: float
664+
temperature: float
665+
electricity_consumed: float
666+
electricity_consumed_interval: float
667+
electricity_consumed_off_peak_cumulative: float
668+
electricity_consumed_off_peak_interval: int
669+
electricity_consumed_off_peak_point: int
670+
electricity_consumed_peak_cumulative: float
671+
electricity_consumed_peak_interval: int
672+
electricity_consumed_peak_point: int
673+
electricity_consumed_point: float
674+
electricity_produced: float
675+
electricity_produced_interval: float
676+
electricity_produced_off_peak_cumulative: float
677+
electricity_produced_off_peak_interval: int
678+
electricity_produced_off_peak_point: int
679+
electricity_produced_peak_cumulative: float
680+
electricity_produced_peak_interval: int
681+
electricity_produced_peak_point: int
682+
electricity_produced_point: float
683+
gas_consumed_cumulative: float
684+
gas_consumed_interval: float
685+
humidity: float
686+
illuminance: float
687+
intended_boiler_temperature: float
688+
modulation_level: float
689+
net_electricity_cumulative: float
690+
net_electricity_point: int
691+
outdoor_air_temperature: float
692+
outdoor_temperature: float
693+
return_temperature: float
694+
setpoint: float
695+
temperature_difference: float
696+
valve_position: float
697+
water_pressure: float
698+
water_temperature: float
699+
700+
701+
class SmileSwitches(TypedDict, total=False):
702+
"""Smile Switches class."""
703+
704+
dhw_cm_switch: bool
705+
lock: bool
706+
relay: bool
707+
708+
709+
class ThermoLoc(TypedDict, total=False):
710+
"""Thermo Location class."""
711+
712+
name: str
713+
master: str | None
714+
master_prio: int
715+
slaves: set[str]
716+
717+
718+
class DeviceDataPoints(
719+
SmileBinarySensors, SmileSensors, SmileSwitches, TypedDict, total=False
720+
):
721+
"""The class covering all possible collected data points."""
722+
723+
# Gateway
724+
regulation_mode: str
725+
regulation_modes: list[str]
726+
727+
# Heater Central
728+
maximum_boiler_temperature: float
729+
730+
# Master Thermostats
731+
lower_bound: float
732+
upper_bound: float
733+
resolution: float
734+
735+
preset_modes: list[str] | None
736+
active_preset: str | None
737+
738+
available_schedules: list[str]
739+
selected_schedule: str
740+
last_used: str | None
741+
schedule_temperature: float | None
742+
743+
mode: str
744+
745+
# Extra for Adam Master Thermostats
746+
control_state: str | bool
747+
748+
# For temporary use
749+
c_heating_state: str
750+
751+
752+
class DeviceData(ApplianceData, DeviceDataPoints, TypedDict, total=False):
753+
"""The Device Data class, covering the collected and ordere output-data per device."""
754+
755+
binary_sensors: SmileBinarySensors
756+
sensors: SmileSensors
757+
switches: SmileSwitches

0 commit comments

Comments
 (0)