qolsys-controller 0.0.44__py3-none-any.whl → 0.0.87__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qolsys-controller might be problematic. Click here for more details.
- qolsys_controller/adc_device.py +202 -0
- qolsys_controller/adc_service.py +139 -0
- qolsys_controller/adc_service_garagedoor.py +35 -0
- qolsys_controller/controller.py +1040 -20
- qolsys_controller/database/db.py +108 -29
- qolsys_controller/database/table.py +90 -60
- qolsys_controller/database/table_alarmedsensor.py +2 -2
- qolsys_controller/database/table_automation.py +0 -1
- qolsys_controller/database/table_country_locale.py +0 -1
- qolsys_controller/database/table_dashboard_msgs.py +1 -2
- qolsys_controller/database/table_dimmerlight.py +0 -1
- qolsys_controller/database/table_doorlock.py +0 -1
- qolsys_controller/database/table_eu_event.py +1 -2
- qolsys_controller/database/table_heat_map.py +0 -2
- qolsys_controller/database/table_history.py +4 -1
- qolsys_controller/database/table_iqremotesettings.py +0 -2
- qolsys_controller/database/table_iqrouter_network_config.py +0 -1
- qolsys_controller/database/table_iqrouter_user_device.py +0 -2
- qolsys_controller/database/table_master_slave.py +0 -1
- qolsys_controller/database/table_nest_device.py +0 -1
- qolsys_controller/database/table_output_rules.py +0 -1
- qolsys_controller/database/table_partition.py +0 -1
- qolsys_controller/database/table_pgm_outputs.py +0 -2
- qolsys_controller/database/table_powerg_device.py +0 -2
- qolsys_controller/database/table_qolsyssettings.py +0 -2
- qolsys_controller/database/table_scene.py +0 -2
- qolsys_controller/database/table_sensor.py +2 -2
- qolsys_controller/database/table_sensor_group.py +23 -0
- qolsys_controller/database/table_shades.py +0 -2
- qolsys_controller/database/table_smartsocket.py +12 -3
- qolsys_controller/database/table_state.py +0 -1
- qolsys_controller/database/table_tcc.py +0 -1
- qolsys_controller/database/table_thermostat.py +3 -1
- qolsys_controller/database/table_trouble_conditions.py +0 -2
- qolsys_controller/database/table_user.py +0 -2
- qolsys_controller/database/table_virtual_device.py +13 -3
- qolsys_controller/database/table_weather.py +0 -2
- qolsys_controller/database/table_zigbee_device.py +0 -1
- qolsys_controller/database/table_zwave_association_group.py +0 -1
- qolsys_controller/database/table_zwave_history.py +0 -1
- qolsys_controller/database/table_zwave_node.py +3 -1
- qolsys_controller/database/table_zwave_other.py +0 -1
- qolsys_controller/enum.py +42 -13
- qolsys_controller/enum_adc.py +28 -0
- qolsys_controller/enum_zwave.py +210 -36
- qolsys_controller/errors.py +14 -12
- qolsys_controller/mdns.py +7 -4
- qolsys_controller/mqtt_command.py +125 -0
- qolsys_controller/mqtt_command_queue.py +5 -4
- qolsys_controller/observable.py +2 -2
- qolsys_controller/panel.py +304 -156
- qolsys_controller/partition.py +149 -127
- qolsys_controller/pki.py +69 -97
- qolsys_controller/scene.py +30 -28
- qolsys_controller/settings.py +96 -50
- qolsys_controller/state.py +221 -34
- qolsys_controller/task_manager.py +11 -14
- qolsys_controller/users.py +25 -0
- qolsys_controller/utils_mqtt.py +8 -16
- qolsys_controller/weather.py +71 -0
- qolsys_controller/zone.py +243 -214
- qolsys_controller/zwave_device.py +234 -93
- qolsys_controller/zwave_dimmer.py +55 -49
- qolsys_controller/zwave_energy_clamp.py +15 -0
- qolsys_controller/zwave_garagedoor.py +3 -1
- qolsys_controller/zwave_generic.py +5 -3
- qolsys_controller/zwave_lock.py +51 -44
- qolsys_controller/zwave_outlet.py +3 -1
- qolsys_controller/zwave_service_meter.py +192 -0
- qolsys_controller/zwave_service_multilevelsensor.py +119 -0
- qolsys_controller/zwave_thermometer.py +21 -0
- qolsys_controller/zwave_thermostat.py +249 -143
- qolsys_controller-0.0.87.dist-info/METADATA +89 -0
- qolsys_controller-0.0.87.dist-info/RECORD +77 -0
- {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.87.dist-info}/WHEEL +1 -1
- qolsys_controller/plugin.py +0 -34
- qolsys_controller/plugin_c4.py +0 -17
- qolsys_controller/plugin_remote.py +0 -1298
- qolsys_controller-0.0.44.dist-info/METADATA +0 -93
- qolsys_controller-0.0.44.dist-info/RECORD +0 -68
- {qolsys_controller-0.0.44.dist-info → qolsys_controller-0.0.87.dist-info}/licenses/LICENSE +0 -0
qolsys_controller/zwave_lock.py
CHANGED
|
@@ -6,29 +6,31 @@ LOGGER = logging.getLogger(__name__)
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class QolsysLock(QolsysZWaveDevice):
|
|
9
|
-
|
|
10
9
|
LOCK_STATUS_ARRAY = ["Locked"] # noqa: RUF012
|
|
11
10
|
|
|
12
|
-
def __init__(self, lock_dict: dict, zwave_dict: dict) -> None:
|
|
13
|
-
|
|
11
|
+
def __init__(self, lock_dict: dict[str, str], zwave_dict: dict[str, str]) -> None:
|
|
14
12
|
super().__init__(zwave_dict)
|
|
15
13
|
|
|
16
|
-
self._lock_id = lock_dict.get("_id")
|
|
17
|
-
self._lock_version = lock_dict.get("version", "")
|
|
18
|
-
self._lock_opr = lock_dict.get("opr", "")
|
|
19
|
-
self._lock_partition_id = lock_dict.get("partition_id", "")
|
|
20
|
-
self._lock_name = lock_dict.get("doorlock_name", "")
|
|
21
|
-
self._lock_status = lock_dict.get("status", "")
|
|
22
|
-
self._lock_node_id = lock_dict.get("node_id", "")
|
|
23
|
-
self._lock_created_by = lock_dict.get("created_by", "")
|
|
24
|
-
self._lock_created_date = lock_dict.get("created_date", "")
|
|
25
|
-
self._lock_updated_by = lock_dict.get("updated_by", "")
|
|
26
|
-
self._lock_last_updated_date = lock_dict.get("last_updated_date", "")
|
|
27
|
-
self._lock_remote_arming = lock_dict.get("remote_arming", "")
|
|
28
|
-
self._lock_keyfob_arming = lock_dict.get("keyfob_arming", "")
|
|
29
|
-
self._lock_panel_arming = lock_dict.get("panel_arming", "")
|
|
30
|
-
self._lock_endpoint = lock_dict.get("endpoint", "")
|
|
31
|
-
self._lock_paired_status = lock_dict.get("paired_status", "")
|
|
14
|
+
self._lock_id: str = lock_dict.get("_id", "")
|
|
15
|
+
self._lock_version: str = lock_dict.get("version", "")
|
|
16
|
+
self._lock_opr: str = lock_dict.get("opr", "")
|
|
17
|
+
self._lock_partition_id: str = lock_dict.get("partition_id", "")
|
|
18
|
+
self._lock_name: str = lock_dict.get("doorlock_name", "")
|
|
19
|
+
self._lock_status: str = lock_dict.get("status", "")
|
|
20
|
+
self._lock_node_id: str = lock_dict.get("node_id", "")
|
|
21
|
+
self._lock_created_by: str = lock_dict.get("created_by", "")
|
|
22
|
+
self._lock_created_date: str = lock_dict.get("created_date", "")
|
|
23
|
+
self._lock_updated_by: str = lock_dict.get("updated_by", "")
|
|
24
|
+
self._lock_last_updated_date: str = lock_dict.get("last_updated_date", "")
|
|
25
|
+
self._lock_remote_arming: str = lock_dict.get("remote_arming", "")
|
|
26
|
+
self._lock_keyfob_arming: str = lock_dict.get("keyfob_arming", "")
|
|
27
|
+
self._lock_panel_arming: str = lock_dict.get("panel_arming", "")
|
|
28
|
+
self._lock_endpoint: str = lock_dict.get("endpoint", "")
|
|
29
|
+
self._lock_paired_status: str = lock_dict.get("paired_status", "")
|
|
30
|
+
|
|
31
|
+
# -----------------------------
|
|
32
|
+
# properties + setters
|
|
33
|
+
# -----------------------------
|
|
32
34
|
|
|
33
35
|
@property
|
|
34
36
|
def lock_node_id(self) -> str:
|
|
@@ -38,14 +40,6 @@ class QolsysLock(QolsysZWaveDevice):
|
|
|
38
40
|
def lock_status(self) -> str:
|
|
39
41
|
return self._lock_status
|
|
40
42
|
|
|
41
|
-
@property
|
|
42
|
-
def lock_name(self) -> str:
|
|
43
|
-
return self._lock_name
|
|
44
|
-
|
|
45
|
-
@property
|
|
46
|
-
def paired_status(self) -> str:
|
|
47
|
-
return self._paired_status
|
|
48
|
-
|
|
49
43
|
@lock_status.setter
|
|
50
44
|
def lock_status(self, value: str) -> None:
|
|
51
45
|
if self._lock_status != value:
|
|
@@ -53,6 +47,10 @@ class QolsysLock(QolsysZWaveDevice):
|
|
|
53
47
|
self._lock_status = value
|
|
54
48
|
self.notify()
|
|
55
49
|
|
|
50
|
+
@property
|
|
51
|
+
def lock_name(self) -> str:
|
|
52
|
+
return self._lock_name
|
|
53
|
+
|
|
56
54
|
@lock_name.setter
|
|
57
55
|
def lock_name(self, value: str) -> None:
|
|
58
56
|
if self._lock_name != value:
|
|
@@ -60,6 +58,10 @@ class QolsysLock(QolsysZWaveDevice):
|
|
|
60
58
|
self._lock_name = value
|
|
61
59
|
self.notify()
|
|
62
60
|
|
|
61
|
+
@property
|
|
62
|
+
def paired_status(self) -> str:
|
|
63
|
+
return self._paired_status
|
|
64
|
+
|
|
63
65
|
@paired_status.setter
|
|
64
66
|
def paired_status(self, value: str) -> None:
|
|
65
67
|
if self._paired_status != value:
|
|
@@ -67,54 +69,59 @@ class QolsysLock(QolsysZWaveDevice):
|
|
|
67
69
|
self._lock_paired_status = value
|
|
68
70
|
self.notify()
|
|
69
71
|
|
|
70
|
-
def
|
|
72
|
+
def update_raw(self, payload: bytes) -> None:
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
def update_lock(self, data: dict[str, str]) -> None: # noqa: PLR0912
|
|
71
76
|
# Check if we are updating same zoneid
|
|
72
77
|
node_id_update = data.get("node_id", "")
|
|
73
78
|
if node_id_update != self.lock_node_id:
|
|
74
79
|
LOGGER.error(
|
|
75
|
-
"Updating Lock %s (%s) with Lock '%s' (different id)", self.lock_node_id, self.lock_name, node_id_update
|
|
80
|
+
"Updating Lock %s (%s) with Lock '%s' (different id)", self.lock_node_id, self.lock_name, node_id_update
|
|
81
|
+
)
|
|
76
82
|
return
|
|
77
83
|
|
|
78
84
|
self.start_batch_update()
|
|
79
85
|
|
|
80
86
|
if "version" in data:
|
|
81
|
-
self._lock_version = data.get("version")
|
|
87
|
+
self._lock_version = data.get("version", "")
|
|
82
88
|
if "opr" in data:
|
|
83
|
-
self._lock_opr = data.get("opr")
|
|
89
|
+
self._lock_opr = data.get("opr", "")
|
|
84
90
|
if "partition_id" in data:
|
|
85
|
-
self._lock_partition_id = data.get("partition_id")
|
|
91
|
+
self._lock_partition_id = data.get("partition_id", "")
|
|
86
92
|
if "lock_name" in data:
|
|
87
|
-
self.lock_name = data.get("lock_name")
|
|
93
|
+
self.lock_name = data.get("lock_name", "")
|
|
88
94
|
if "status" in data:
|
|
89
|
-
self.lock_status = data.get("status")
|
|
95
|
+
self.lock_status = data.get("status", "")
|
|
90
96
|
if "created_by" in data:
|
|
91
|
-
self._lock_created_by = data.get("created_by")
|
|
97
|
+
self._lock_created_by = data.get("created_by", "")
|
|
92
98
|
if "created_date" in data:
|
|
93
|
-
self._lock_created_date = data.get("created_date")
|
|
99
|
+
self._lock_created_date = data.get("created_date", "")
|
|
94
100
|
if "updated_by" in data:
|
|
95
|
-
self._lock_updated_by = data.get("updated_by")
|
|
101
|
+
self._lock_updated_by = data.get("updated_by", "")
|
|
96
102
|
if "last_updated_date" in data:
|
|
97
|
-
self._lock_last_updated_date = data.get("last_updated_date")
|
|
103
|
+
self._lock_last_updated_date = data.get("last_updated_date", "")
|
|
98
104
|
if "remote_arming" in data:
|
|
99
|
-
self._lock_remote_arming = data.get("remote_arming")
|
|
105
|
+
self._lock_remote_arming = data.get("remote_arming", "")
|
|
100
106
|
if "keyfob_arming" in data:
|
|
101
|
-
self._lock_keyfob_arming = data.get("keyfob_arming")
|
|
107
|
+
self._lock_keyfob_arming = data.get("keyfob_arming", "")
|
|
102
108
|
if "panel_arming" in data:
|
|
103
|
-
self._lock_panel_arming = data.get("panel_arming")
|
|
109
|
+
self._lock_panel_arming = data.get("panel_arming", "")
|
|
104
110
|
if "endpoint" in data:
|
|
105
|
-
self._lock_endpoint = data.get("endpoint")
|
|
111
|
+
self._lock_endpoint = data.get("endpoint", "")
|
|
106
112
|
if "paired_status" in data:
|
|
107
|
-
self._lock_paired_status = data.get("paired_status")
|
|
113
|
+
self._lock_paired_status = data.get("paired_status", "")
|
|
108
114
|
|
|
109
115
|
self.end_batch_update()
|
|
110
116
|
|
|
111
|
-
def to_dict_lock(self) -> dict:
|
|
117
|
+
def to_dict_lock(self) -> dict[str, str]:
|
|
112
118
|
return {
|
|
113
119
|
"_id": self._lock_id,
|
|
114
120
|
"version": self._lock_version,
|
|
115
121
|
"opr": self._lock_opr,
|
|
116
122
|
"partition_id": self._lock_partition_id,
|
|
117
123
|
"doorlock_name": self.lock_name,
|
|
124
|
+
"node_id": self.lock_node_id,
|
|
118
125
|
"status": self.lock_status,
|
|
119
126
|
"created_by": self._lock_created_by,
|
|
120
127
|
"created_date": self._lock_created_date,
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
__all__ = ["QolsysZwaveMeterSensor"]
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from enum import IntEnum
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Type
|
|
7
|
+
|
|
8
|
+
from qolsys_controller.enum_zwave import (
|
|
9
|
+
MeterRateType,
|
|
10
|
+
MeterType,
|
|
11
|
+
ZWaveElectricMeterScale,
|
|
12
|
+
ZWaveUnknownMeterScale,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .zwave_device import QolsysZWaveDevice
|
|
17
|
+
|
|
18
|
+
LOGGER = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_enum_by_name(enum: type[IntEnum], name: str) -> IntEnum | None:
|
|
22
|
+
for val in enum:
|
|
23
|
+
if val.name.upper() == name.upper():
|
|
24
|
+
return val
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class QolsysZwaveMeterSensor:
|
|
29
|
+
def __init__(self, parent_device: "QolsysZWaveDevice", parent_meter: "QolsysZwaveServiceMeter", scale: IntEnum) -> None:
|
|
30
|
+
self._parent_device: QolsysZWaveDevice = parent_device
|
|
31
|
+
self._parent_meter: QolsysZwaveServiceMeter = parent_meter
|
|
32
|
+
self._scale: IntEnum = scale
|
|
33
|
+
self._value: float | None = None
|
|
34
|
+
self._delta_time: int | None = None
|
|
35
|
+
self._previous_value: float | None = None
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def value(self) -> float | None:
|
|
39
|
+
return self._value
|
|
40
|
+
|
|
41
|
+
@value.setter
|
|
42
|
+
def value(self, new_value: float | None) -> None:
|
|
43
|
+
if self._value != new_value:
|
|
44
|
+
self._value = new_value
|
|
45
|
+
LOGGER.debug(
|
|
46
|
+
"ZWaveMeter%s-%s (%s) - %s - value: %s (%s)",
|
|
47
|
+
self._parent_device.node_id,
|
|
48
|
+
self._parent_meter.endpoint,
|
|
49
|
+
self._parent_device.node_name,
|
|
50
|
+
self._parent_meter._meter_type.name,
|
|
51
|
+
new_value,
|
|
52
|
+
self._scale.name,
|
|
53
|
+
)
|
|
54
|
+
self._parent_device.notify()
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def scale(self) -> IntEnum:
|
|
58
|
+
return self._scale
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class QolsysZwaveServiceMeter:
|
|
62
|
+
def __init__(self, parent_device: "QolsysZWaveDevice", endpoint: str, meter_dict: dict[str, Any]) -> None:
|
|
63
|
+
self._parent_device: QolsysZWaveDevice = parent_device
|
|
64
|
+
self._endpoint: str = endpoint
|
|
65
|
+
self._meter_type: MeterType = MeterType.UNKNOWN
|
|
66
|
+
self._rate_type: MeterRateType = MeterRateType.UNSPECIFIED
|
|
67
|
+
self._scale_type: Type[IntEnum] = ZWaveUnknownMeterScale
|
|
68
|
+
self._supported_scale: list[IntEnum] = []
|
|
69
|
+
self._sensors: list[QolsysZwaveMeterSensor] = []
|
|
70
|
+
self._master_reset_flag: bool = False
|
|
71
|
+
|
|
72
|
+
# Set Meter_Type
|
|
73
|
+
type: str | int = meter_dict.get("meter_type", "")
|
|
74
|
+
if type == "ENERGY_METER" or type == MeterType.ELECTRIC_METER.value:
|
|
75
|
+
self._meter_type = MeterType.ELECTRIC_METER
|
|
76
|
+
self._scale_type = ZWaveElectricMeterScale
|
|
77
|
+
else:
|
|
78
|
+
LOGGER.warning("Zave Meter Service - Unknown Meter Type: %s", type)
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
# Set Rate Type
|
|
82
|
+
rate_type: int = meter_dict.get("meter_ratetype_supported", -1)
|
|
83
|
+
try:
|
|
84
|
+
self._rate_type = MeterRateType(rate_type)
|
|
85
|
+
except ValueError:
|
|
86
|
+
LOGGER.error("Zave Meter Service - Unknown MeterRateType, Setting to UNSPECIFIED")
|
|
87
|
+
self._rate_type = MeterRateType.UNSPECIFIED
|
|
88
|
+
|
|
89
|
+
# Set Master Reset Flag
|
|
90
|
+
self._master_reset_flag = bool(meter_dict.get("meter_master_reset_flag", False))
|
|
91
|
+
|
|
92
|
+
# Set Supported Scales
|
|
93
|
+
self.supported_scale = meter_dict.get("meter_scale_supported", "[]")
|
|
94
|
+
|
|
95
|
+
# Create Sensors for Supported Scales
|
|
96
|
+
for scale in self._supported_scale:
|
|
97
|
+
qolsys_meter_sensor = QolsysZwaveMeterSensor(self._parent_device, self, scale)
|
|
98
|
+
self.add_sensor(qolsys_meter_sensor)
|
|
99
|
+
|
|
100
|
+
# Update sensor values
|
|
101
|
+
self.update_iq2medi(meter_dict)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def sensors(self) -> list[QolsysZwaveMeterSensor]:
|
|
105
|
+
return self._sensors
|
|
106
|
+
|
|
107
|
+
def add_sensor(self, new_sensor: QolsysZwaveMeterSensor) -> None:
|
|
108
|
+
for sensor in self._sensors:
|
|
109
|
+
if sensor._scale == new_sensor._scale:
|
|
110
|
+
LOGGER.error("Error Adding Sensor, scale allready present")
|
|
111
|
+
return
|
|
112
|
+
self._sensors.append(new_sensor)
|
|
113
|
+
self._parent_device.notify()
|
|
114
|
+
|
|
115
|
+
def get_sensor(self, scale: IntEnum) -> QolsysZwaveMeterSensor | None:
|
|
116
|
+
for sensor in self._sensors:
|
|
117
|
+
if sensor._scale == scale:
|
|
118
|
+
return sensor
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def endpoint(self) -> str:
|
|
123
|
+
return self._endpoint
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def rate_type(self) -> MeterRateType:
|
|
127
|
+
return self._rate_type
|
|
128
|
+
|
|
129
|
+
@rate_type.setter
|
|
130
|
+
def rate_type(self, value: MeterRateType) -> None:
|
|
131
|
+
if self._rate_type != value:
|
|
132
|
+
self._rate_type = value
|
|
133
|
+
# LOGGER.debug("Zave Meter Service - rate_type: %s", value.name)
|
|
134
|
+
self._parent_device.notify()
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def supported_scale(self) -> list[IntEnum]:
|
|
138
|
+
return self._supported_scale
|
|
139
|
+
|
|
140
|
+
@supported_scale.setter
|
|
141
|
+
def supported_scale(self, value: str) -> None:
|
|
142
|
+
try:
|
|
143
|
+
scales = json.loads(value)
|
|
144
|
+
cleaned = [s.strip() for s in scales]
|
|
145
|
+
|
|
146
|
+
except json.JSONDecodeError:
|
|
147
|
+
self._supported_scale = []
|
|
148
|
+
LOGGER.error("Zave Meter Service - Error parsing meter_scale_supported, Setting to empty list")
|
|
149
|
+
|
|
150
|
+
for key in cleaned:
|
|
151
|
+
for scale in self._scale_type:
|
|
152
|
+
if key.lower() == scale.name.lower():
|
|
153
|
+
if scale not in self._supported_scale:
|
|
154
|
+
self._supported_scale.append(scale)
|
|
155
|
+
|
|
156
|
+
def update_iq2medi(self, data: dict[str, Any]) -> None:
|
|
157
|
+
# Update Z-Wave Meter Service
|
|
158
|
+
|
|
159
|
+
# Cannot change meter type once created
|
|
160
|
+
type: str | int = data.get("meter_type", "")
|
|
161
|
+
if type == "ENERGY_METER" or type == MeterType.ELECTRIC_METER:
|
|
162
|
+
if self._meter_type is not MeterType.ELECTRIC_METER:
|
|
163
|
+
LOGGER.error("Zave Meter Service - Cannot change Meter Type once created")
|
|
164
|
+
return
|
|
165
|
+
|
|
166
|
+
self._parent_device.start_batch_update()
|
|
167
|
+
|
|
168
|
+
# Upate Rate Type
|
|
169
|
+
if "meter_ratetype_supported" in data:
|
|
170
|
+
rate_type: int = data.get("meter_ratetype_supported", -1)
|
|
171
|
+
try:
|
|
172
|
+
self.rate_type = MeterRateType(rate_type)
|
|
173
|
+
except ValueError:
|
|
174
|
+
LOGGER.error("Zave Meter Service - Unknown MeterRateType, Setting to UNSPECIFIED")
|
|
175
|
+
self.rate_type = MeterRateType.UNSPECIFIED
|
|
176
|
+
|
|
177
|
+
# Update Master Reset Flag
|
|
178
|
+
if "meter_master_reset_flag" in data:
|
|
179
|
+
self._master_reset_flag = bool(data.get("meter_master_reset_flag", False))
|
|
180
|
+
|
|
181
|
+
# Update Meter Values
|
|
182
|
+
if "meter_scale_reading_values" in data:
|
|
183
|
+
scale_values: dict[str, Any] = data.get("meter_scale_reading_values", {})
|
|
184
|
+
|
|
185
|
+
for key, value in scale_values.items():
|
|
186
|
+
temp = get_enum_by_name(self._scale_type, key.strip())
|
|
187
|
+
if temp in self._supported_scale:
|
|
188
|
+
sensor = self.get_sensor(temp)
|
|
189
|
+
if sensor is not None:
|
|
190
|
+
sensor.value = float(value)
|
|
191
|
+
|
|
192
|
+
self._parent_device.end_batch_update()
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
__all__ = ["QolsysZwaveMultilevelSensor"]
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from enum import IntEnum
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from qolsys_controller.enum_zwave import ZWaveMultilevelSensorScale
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .zwave_device import QolsysZWaveDevice
|
|
11
|
+
|
|
12
|
+
LOGGER = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_enum_by_name(enum: type[IntEnum], name: str) -> IntEnum | None:
|
|
16
|
+
for val in enum:
|
|
17
|
+
if val.name.upper() == name.upper():
|
|
18
|
+
return val
|
|
19
|
+
return None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class QolsysZwaveMultilevelSensor:
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
parent_device: "QolsysZWaveDevice",
|
|
26
|
+
parent_sensor: "QolsysZwaveServiceMultilevelSensor",
|
|
27
|
+
unit: ZWaveMultilevelSensorScale,
|
|
28
|
+
) -> None:
|
|
29
|
+
self._parent_device: QolsysZWaveDevice = parent_device
|
|
30
|
+
self._parent_meter: QolsysZwaveServiceMultilevelSensor = parent_sensor
|
|
31
|
+
self._value: float | None = None
|
|
32
|
+
self._unit: ZWaveMultilevelSensorScale = unit
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def unit(self) -> ZWaveMultilevelSensorScale:
|
|
36
|
+
return self._unit
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def value(self) -> float | None:
|
|
40
|
+
return self._value
|
|
41
|
+
|
|
42
|
+
@value.setter
|
|
43
|
+
def value(self, new_value: float | None) -> None:
|
|
44
|
+
if self._value != new_value:
|
|
45
|
+
self._value = new_value
|
|
46
|
+
LOGGER.debug(
|
|
47
|
+
"ZWaveMultilevelSensor%s-%s (%s) - value: %s (%s)",
|
|
48
|
+
self._parent_device.node_id,
|
|
49
|
+
self._parent_meter.endpoint,
|
|
50
|
+
self._parent_device.node_name,
|
|
51
|
+
new_value,
|
|
52
|
+
self._unit.name,
|
|
53
|
+
)
|
|
54
|
+
self._parent_device.notify()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class QolsysZwaveServiceMultilevelSensor:
|
|
58
|
+
def __init__(self, parent_device: "QolsysZWaveDevice", endpoint: str, sensor_dict: dict[str, Any]) -> None:
|
|
59
|
+
self._parent_device: QolsysZWaveDevice = parent_device
|
|
60
|
+
self._endpoint: str = endpoint
|
|
61
|
+
self._sensors: list[QolsysZwaveMultilevelSensor] = []
|
|
62
|
+
|
|
63
|
+
# Update sensor values
|
|
64
|
+
self.update_iq2medi(sensor_dict)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def sensors(self) -> list[QolsysZwaveMultilevelSensor]:
|
|
68
|
+
return self._sensors
|
|
69
|
+
|
|
70
|
+
def add_sensor(self, new_sensor: QolsysZwaveMultilevelSensor) -> None:
|
|
71
|
+
for sensor in self._sensors:
|
|
72
|
+
if sensor._unit == new_sensor._unit:
|
|
73
|
+
LOGGER.error("Error Adding Sensor, unit allready present")
|
|
74
|
+
return
|
|
75
|
+
self._sensors.append(new_sensor)
|
|
76
|
+
self._parent_device.notify()
|
|
77
|
+
|
|
78
|
+
def get_sensor(self, unit: ZWaveMultilevelSensorScale) -> QolsysZwaveMultilevelSensor | None:
|
|
79
|
+
for sensor in self._sensors:
|
|
80
|
+
if sensor.unit == unit:
|
|
81
|
+
return sensor
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def endpoint(self) -> str:
|
|
86
|
+
return self._endpoint
|
|
87
|
+
|
|
88
|
+
def update_iq2medi(self, data: dict[str, Any]) -> None:
|
|
89
|
+
# Update Z-Wave Multilevelsensor Service
|
|
90
|
+
|
|
91
|
+
self._parent_device.start_batch_update()
|
|
92
|
+
|
|
93
|
+
# Update Sensors Values
|
|
94
|
+
for key, value in data.items():
|
|
95
|
+
if key == "AIR TEMPERATURE":
|
|
96
|
+
temperature: float | None = value.get("Fahrenheit (F)", None)
|
|
97
|
+
sensor = self.get_sensor(ZWaveMultilevelSensorScale.TEMPERATURE_FAHRENHEIT)
|
|
98
|
+
if sensor:
|
|
99
|
+
sensor.value = temperature
|
|
100
|
+
else:
|
|
101
|
+
sensor = QolsysZwaveMultilevelSensor(
|
|
102
|
+
self._parent_device, self, ZWaveMultilevelSensorScale.TEMPERATURE_FAHRENHEIT
|
|
103
|
+
)
|
|
104
|
+
self.add_sensor(sensor)
|
|
105
|
+
sensor.value = temperature
|
|
106
|
+
|
|
107
|
+
if key == "HUMIDITY":
|
|
108
|
+
humidity: float | None = value.get("Percentage value (%)", None)
|
|
109
|
+
sensor = self.get_sensor(ZWaveMultilevelSensorScale.RELATIVE_HUMIDITY)
|
|
110
|
+
if sensor:
|
|
111
|
+
sensor.value = humidity
|
|
112
|
+
else:
|
|
113
|
+
sensor = QolsysZwaveMultilevelSensor(
|
|
114
|
+
self._parent_device, self, ZWaveMultilevelSensorScale.RELATIVE_HUMIDITY
|
|
115
|
+
)
|
|
116
|
+
self.add_sensor(sensor)
|
|
117
|
+
sensor.value = humidity
|
|
118
|
+
|
|
119
|
+
self._parent_device.end_batch_update()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from .zwave_device import QolsysZWaveDevice
|
|
4
|
+
|
|
5
|
+
LOGGER = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class QolsysThermometer(QolsysZWaveDevice):
|
|
9
|
+
def __init__(self, zwave_dict: dict[str, str]) -> None:
|
|
10
|
+
super().__init__(zwave_dict)
|
|
11
|
+
self._temprature_value = ""
|
|
12
|
+
self._humidity_value = ""
|
|
13
|
+
|
|
14
|
+
def update_raw(self, payload: bytes) -> None:
|
|
15
|
+
LOGGER.debug("Raw Update (node%s) - payload: %s", self.node_id, payload.hex())
|
|
16
|
+
|
|
17
|
+
def to_dict_thermometer(self) -> dict[str, str]:
|
|
18
|
+
return {
|
|
19
|
+
"temperature_value": self._temprature_value,
|
|
20
|
+
"humidity_value": self._humidity_value,
|
|
21
|
+
}
|