Skip to content

Commit 2b3cd41

Browse files
authored
Merge pull request #41 from plugwise/move-formatting
Move formatting performed in beta into plugwise
2 parents c60a8ce + 6163396 commit 2b3cd41

File tree

5 files changed

+163
-65
lines changed

5 files changed

+163
-65
lines changed

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.8.2a3"
3+
__version__ = "0.8.2a4"
44

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

plugwise/constants.py

Lines changed: 103 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
""" Plugwise Stick and Smile constants."""
22

3+
# Copied homeassistant.consts
4+
ATTR_NAME = "name"
5+
ATTR_UNIT_OF_MEASUREMENT = "unit_of_measurement"
6+
DEGREE = "°"
7+
ENERGY_KILO_WATT_HOUR = "kWh"
8+
ENERGY_WATT_HOUR = "Wh"
9+
PERCENTAGE = "%"
10+
POWER_WATT = "W"
11+
PRESSURE_BAR = "bar"
12+
SIGNAL_STRENGTH_DECIBELS_MILLIWATT = "dBm"
13+
TEMP_CELSIUS = "°C"
14+
TIME_MILLISECONDS = "ms"
15+
VOLUME_CUBIC_METERS = "m³"
16+
VOLUME_CUBIC_METERS_PER_HOUR = "m³/h"
17+
318
### Stick constants ###
419

520
UTF8_DECODE = "utf-8"
@@ -145,13 +160,6 @@
145160
CB_NEW_NODE = "NEW_NODE"
146161
CB_JOIN_REQUEST = "JOIN_REQUEST"
147162

148-
# Unit of measurement
149-
TIME_MILLISECONDS = "ms"
150-
POWER_WATT = "W"
151-
ENERGY_KILO_WATT_HOUR = "kWh"
152-
ENERGY_WATT_HOUR = "Wh"
153-
CELSIUS = "°C"
154-
155163
# Sensors
156164
SENSOR_AVAILABLE = {
157165
"id": "available",
@@ -235,7 +243,7 @@
235243
"id": "temperature",
236244
"name": "Temperature",
237245
"state": "get_temperature",
238-
"unit": CELSIUS,
246+
"unit": TEMP_CELSIUS,
239247
}
240248

241249
# TODO: Need to validate RSSI sensors
@@ -283,49 +291,109 @@
283291
SWITCH_GROUP_TYPES = ["switching", "report"]
284292

285293
HOME_MEASUREMENTS = {
286-
"electricity_consumed": "power",
287-
"electricity_produced": "power",
288-
"gas_consumed": "gas",
289-
"outdoor_temperature": "temperature",
294+
"electricity_consumed": {
295+
ATTR_NAME: "power",
296+
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
297+
},
298+
"electricity_produced": {
299+
ATTR_NAME: "power",
300+
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
301+
},
302+
"gas_consumed": {
303+
ATTR_NAME: "gas",
304+
ATTR_UNIT_OF_MEASUREMENT: VOLUME_CUBIC_METERS,
305+
},
306+
"outdoor_temperature": {
307+
ATTR_NAME: "temperature",
308+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
309+
},
290310
}
291311

292312
# Excluded:
293313
# zone_thermosstat 'temperature_offset'
294314
# radiator_valve 'uncorrected_temperature', 'temperature_offset'
295315
DEVICE_MEASUREMENTS = {
296316
# HA Core current_temperature
297-
"temperature": "temperature",
317+
"temperature": {ATTR_NAME: "temperature", ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
298318
# HA Core setpoint
299-
"thermostat": "setpoint",
319+
"thermostat": {ATTR_NAME: "setpoint", ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
300320
# Anna/Adam
301-
"boiler_temperature": "water_temperature",
302-
"domestic_hot_water_state": "dhw_state",
303-
"intended_boiler_temperature": "intended_boiler_temperature", # non-zero when heating, zero when dhw-heating
304-
"intended_central_heating_state": "heating_state", # use intended_c_h_state, this key shows the heating-behavior better than c-h_state
305-
"modulation_level": "modulation_level",
306-
"return_water_temperature": "return_temperature",
321+
"boiler_temperature": {
322+
ATTR_NAME: "water_temperature",
323+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
324+
},
325+
"domestic_hot_water_state": {
326+
ATTR_NAME: "dhw_state",
327+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
328+
},
329+
"intended_boiler_temperature": {
330+
ATTR_NAME: "intended_boiler_temperature",
331+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
332+
}, # non-zero when heating, zero when dhw-heating
333+
"intended_central_heating_state": {
334+
ATTR_NAME: "heating_state",
335+
ATTR_UNIT_OF_MEASUREMENT: None,
336+
}, # use intended_c_h_state, this key shows the heating-behavior better than c-h_state
337+
"modulation_level": {
338+
ATTR_NAME: "modulation_level",
339+
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
340+
},
341+
"return_water_temperature": {
342+
ATTR_NAME: "return_temperature",
343+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
344+
},
307345
# Used with the Elga heatpump - marcelveldt
308-
"compressor_state": "compressor_state",
309-
"cooling_state": "cooling_state",
346+
"compressor_state": {ATTR_NAME: "compressor_state", ATTR_UNIT_OF_MEASUREMENT: None},
347+
"cooling_state": {ATTR_NAME: "cooling_state", ATTR_UNIT_OF_MEASUREMENT: None},
310348
# Next 2 keys are used to show the state of the gas-heater used next to the Elga heatpump - marcelveldt
311-
"slave_boiler_state": "slave_boiler_state",
312-
"flame_state": "flame_state", # also present when there is a single gas-heater
349+
"slave_boiler_state": {
350+
ATTR_NAME: "slave_boiler_state",
351+
ATTR_UNIT_OF_MEASUREMENT: None,
352+
},
353+
"flame_state": {
354+
ATTR_NAME: "flame_state",
355+
ATTR_UNIT_OF_MEASUREMENT: None,
356+
}, # also present when there is a single gas-heater
313357
# Anna only
314-
"central_heater_water_pressure": "water_pressure",
315-
"outdoor_temperature": "outdoor_temperature", # Outdoor temp as reported on the Anna, in the App
316-
"schedule_temperature": "schedule_temperature", # Only present on legacy Anna and Anna_v3
358+
"central_heater_water_pressure": {
359+
ATTR_NAME: "water_pressure",
360+
ATTR_UNIT_OF_MEASUREMENT: PRESSURE_BAR,
361+
},
362+
"outdoor_temperature": {
363+
ATTR_NAME: "outdoor_temperature",
364+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
365+
}, # Outdoor temp as reported on the Anna, in the App
366+
"schedule_temperature": {
367+
ATTR_NAME: "schedule_temperature",
368+
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
369+
}, # Only present on legacy Anna and Anna_v3
317370
# Legacy Anna: similar to flame-state on Anna/Adam
318-
"boiler_state": "boiler_state",
371+
"boiler_state": {ATTR_NAME: "boiler_state", ATTR_UNIT_OF_MEASUREMENT: None},
319372
# Legacy Anna: shows when heating is active, don't show dhw_state, cannot be determined reliably
320-
"intended_boiler_state": "intended_boiler_state",
373+
"intended_boiler_state": {
374+
ATTR_NAME: "intended_boiler_state",
375+
ATTR_UNIT_OF_MEASUREMENT: None,
376+
},
321377
# Lisa and Tom
322-
"battery": "battery",
323-
"temperature_difference": "temperature_difference",
324-
"valve_position": "valve_position",
378+
"battery": {ATTR_NAME: "battery", ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE},
379+
"temperature_difference": {
380+
ATTR_NAME: "temperature_difference",
381+
ATTR_UNIT_OF_MEASUREMENT: DEGREE,
382+
},
383+
"valve_position": {
384+
ATTR_NAME: "valve_position",
385+
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
386+
},
325387
# Plug
326-
"electricity_consumed": "electricity_consumed",
327-
"electricity_produced": "electricity_produced",
328-
"relay": "relay",
388+
"electricity_consumed": {
389+
ATTR_NAME: "electricity_consumed",
390+
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
391+
},
392+
"electricity_produced": {
393+
ATTR_NAME: "electricity_produced",
394+
ATTR_UNIT_OF_MEASUREMENT: POWER_WATT,
395+
},
396+
"relay": {ATTR_NAME: "relay", ATTR_UNIT_OF_MEASUREMENT: None},
329397
}
330398

331399
SMILES = {

plugwise/smile.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717

1818
from plugwise.constants import (
1919
APPLIANCES,
20+
ATTR_NAME,
21+
ATTR_UNIT_OF_MEASUREMENT,
2022
DEFAULT_PORT,
2123
DEFAULT_TIMEOUT,
2224
DEFAULT_USERNAME,
2325
DEVICE_MEASUREMENTS,
2426
DOMAIN_OBJECTS,
27+
ENERGY_KILO_WATT_HOUR,
28+
ENERGY_WATT_HOUR,
2529
HOME_MEASUREMENTS,
2630
LOCATIONS,
2731
NOTIFICATIONS,
@@ -328,18 +332,18 @@ async def full_update_device(self):
328332
def _types_finder(data):
329333
"""Detect types within locations from logs."""
330334
types = set()
331-
for measure, measure_type in HOME_MEASUREMENTS.items():
335+
for measure, attrs in HOME_MEASUREMENTS.items():
332336
locator = f".//logs/point_log[type='{measure}']"
333337
if data.find(locator) is not None:
334338
log = data.find(locator)
335339

336340
if measure == "outdoor_temperature":
337-
types.add(measure_type)
341+
types.add(attrs[ATTR_NAME])
338342

339343
p_locator = ".//electricity_point_meter"
340344
if log.find(p_locator) is not None:
341345
if log.find(p_locator).get("id"):
342-
types.add(measure_type)
346+
types.add(attrs[ATTR_NAME])
343347

344348
return types
345349

@@ -775,7 +779,7 @@ def get_appliance_data(self, dev_id):
775779
appliances = search.findall(f'.//appliance[@id="{dev_id}"]')
776780

777781
for appliance in appliances:
778-
for measurement, name in DEVICE_MEASUREMENTS.items():
782+
for measurement, attrs in DEVICE_MEASUREMENTS.items():
779783

780784
p_locator = (
781785
f'.//logs/point_log[type="{measurement}"]/period/measurement'
@@ -797,25 +801,27 @@ def get_appliance_data(self, dev_id):
797801
if measurement in ["compressor_state", "flame_state"]:
798802
self.active_device_present = True
799803

800-
data[name] = format_measure(measure)
804+
data[attrs[ATTR_NAME]] = format_measure(
805+
measure, attrs[ATTR_UNIT_OF_MEASUREMENT]
806+
)
801807

802808
i_locator = (
803809
f'.//logs/interval_log[type="{measurement}"]/period/measurement'
804810
)
805811
if appliance.find(i_locator) is not None:
806-
name = f"{name}_interval"
812+
name = f"{attrs[ATTR_NAME]}_interval"
807813
measure = appliance.find(i_locator).text
808814

809-
data[name] = format_measure(measure)
815+
data[name] = format_measure(measure, ENERGY_WATT_HOUR)
810816

811817
c_locator = (
812818
f'.//logs/cumulative_log[type="{measurement}"]/period/measurement'
813819
)
814820
if appliance.find(c_locator) is not None:
815-
name = f"{name}_cumulative"
821+
name = f"{attrs[ATTR_NAME]}_cumulative"
816822
measure = appliance.find(c_locator).text
817823

818-
data[name] = format_measure(measure)
824+
data[name] = format_measure(measure, ENERGY_KILO_WATT_HOUR)
819825

820826
return data
821827

@@ -836,7 +842,7 @@ def get_power_data_from_location(self, loc_id):
836842
peak_list = ["nl_peak", "nl_offpeak"]
837843

838844
# meter_string = ".//{}[type='{}']/"
839-
for measurement in HOME_MEASUREMENTS:
845+
for measurement, attrs in HOME_MEASUREMENTS.items():
840846
for log_type in log_list:
841847
for peak_select in peak_list:
842848
locator = (
@@ -863,7 +869,12 @@ def get_power_data_from_location(self, loc_id):
863869
key_string = f"{measurement}_{peak}_{log_found}"
864870
net_string = f"net_electricity_{log_found}"
865871
val = loc_logs.find(locator).text
866-
f_val = format_measure(val)
872+
if all(
873+
item in key_string for item in ["electricity", "cumulative"]
874+
):
875+
f_val = format_measure(val, ENERGY_KILO_WATT_HOUR)
876+
else:
877+
f_val = format_measure(val, attrs[ATTR_UNIT_OF_MEASUREMENT])
867878
if "gas" in measurement:
868879
key_string = f"{measurement}_{log_found}"
869880
f_val = float(f"{round(float(val), 3):.3f}")
@@ -1082,7 +1093,7 @@ def get_object_value(self, obj_type, obj_id, measurement):
10821093
f'[type="{measurement}"]/period/measurement'
10831094
)
10841095
if search.find(locator) is not None:
1085-
val = format_measure(search.find(locator).text)
1096+
val = format_measure(search.find(locator).text, None)
10861097
return val
10871098

10881099
return None

plugwise/util.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@
1010

1111
import crcmod
1212

13-
from .constants import LOGADDR_OFFSET, PLUGWISE_EPOCH, UTF8_DECODE
13+
from plugwise.constants import (
14+
ENERGY_KILO_WATT_HOUR,
15+
LOGADDR_OFFSET,
16+
PERCENTAGE,
17+
PLUGWISE_EPOCH,
18+
UTF8_DECODE,
19+
)
1420

1521
crc_fun = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0x0000, xorOut=0x0000)
1622

@@ -65,8 +71,12 @@ def escape_illegal_xml_characters(xmldata):
6571
return re.sub(r"&([^a-zA-Z#])", r"&\1", xmldata)
6672

6773

68-
def format_measure(measure):
74+
def format_measure(measure, unit):
6975
"""Format measure to correct type."""
76+
if unit == PERCENTAGE and float(measure) > 0:
77+
measure = int(float(measure) * 100)
78+
if unit == ENERGY_KILO_WATT_HOUR:
79+
measure = float(measure) / 1000
7080
try:
7181
measure = int(measure)
7282
except ValueError:

0 commit comments

Comments
 (0)