juham-automation 0.0.13__py3-none-any.whl → 0.0.15__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.
- juham_automation/__init__.py +38 -38
- juham_automation/automation/__init__.py +21 -21
- juham_automation/automation/energycostcalculator.py +266 -266
- juham_automation/automation/hotwateroptimizer.py +568 -567
- juham_automation/automation/powermeter_simulator.py +139 -139
- juham_automation/automation/spothintafi.py +140 -140
- juham_automation/automation/watercirculator.py +159 -159
- juham_automation/japp.py +49 -49
- juham_automation/ts/__init__.py +25 -25
- juham_automation/ts/electricityprice_ts.py +51 -51
- juham_automation/ts/energycostcalculator_ts.py +43 -43
- juham_automation/ts/forecast_ts.py +97 -97
- juham_automation/ts/log_ts.py +57 -57
- juham_automation/ts/power_ts.py +49 -49
- juham_automation/ts/powermeter_ts.py +70 -70
- juham_automation/ts/powerplan_ts.py +45 -45
- {juham_automation-0.0.13.dist-info → juham_automation-0.0.15.dist-info}/METADATA +106 -105
- juham_automation-0.0.15.dist-info/RECORD +23 -0
- {juham_automation-0.0.13.dist-info → juham_automation-0.0.15.dist-info}/WHEEL +1 -1
- {juham_automation-0.0.13.dist-info → juham_automation-0.0.15.dist-info/licenses}/LICENSE.rst +25 -25
- juham_automation-0.0.13.dist-info/RECORD +0 -23
- {juham_automation-0.0.13.dist-info → juham_automation-0.0.15.dist-info}/entry_points.txt +0 -0
- {juham_automation-0.0.13.dist-info → juham_automation-0.0.15.dist-info}/top_level.txt +0 -0
@@ -1,97 +1,97 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any
|
3
|
-
from typing_extensions import override
|
4
|
-
|
5
|
-
from masterpiece.mqtt import MqttMsg
|
6
|
-
from juham_core import JuhamTs
|
7
|
-
from juham_core.timeutils import epoc2utc
|
8
|
-
|
9
|
-
|
10
|
-
class ForecastTs(JuhamTs):
|
11
|
-
"""Forecast database record.
|
12
|
-
|
13
|
-
This class listens the forecast topic and writes to the time series
|
14
|
-
database.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def __init__(self, name: str = "forecast_ts") -> None:
|
18
|
-
"""Construct forecast record object with the given name."""
|
19
|
-
super().__init__(name)
|
20
|
-
self.forecast_topic = self.make_topic_name("forecast")
|
21
|
-
|
22
|
-
@override
|
23
|
-
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
24
|
-
"""Standard mqtt connect notification.
|
25
|
-
|
26
|
-
This method is called when the client connection with the MQTT
|
27
|
-
broker is established.
|
28
|
-
"""
|
29
|
-
super().on_connect(client, userdata, flags, rc)
|
30
|
-
self.subscribe(self.forecast_topic)
|
31
|
-
self.debug(f"Subscribed to {self.forecast_topic}")
|
32
|
-
|
33
|
-
@override
|
34
|
-
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
35
|
-
"""Standard mqtt message notification method.
|
36
|
-
|
37
|
-
This method is called upon new arrived message.
|
38
|
-
"""
|
39
|
-
if msg.topic == self.forecast_topic:
|
40
|
-
m = json.loads(msg.payload.decode())
|
41
|
-
self.on_forecast(m)
|
42
|
-
else:
|
43
|
-
super().on_message(client, userdata, msg)
|
44
|
-
|
45
|
-
def on_forecast(self, em: dict[Any, Any]) -> None:
|
46
|
-
"""Handle weather forecast data. Writes the received hourly forecast
|
47
|
-
data to timeseries database.
|
48
|
-
|
49
|
-
Args:
|
50
|
-
em (dict): forecast
|
51
|
-
"""
|
52
|
-
|
53
|
-
# List of fields you want to add
|
54
|
-
fields = [
|
55
|
-
"ts",
|
56
|
-
"day",
|
57
|
-
"solarradiation",
|
58
|
-
"solarenergy",
|
59
|
-
"cloudcover",
|
60
|
-
"snowdepth",
|
61
|
-
"uvindex",
|
62
|
-
"pressure",
|
63
|
-
"humidity",
|
64
|
-
"windspeed",
|
65
|
-
"winddir",
|
66
|
-
"temp",
|
67
|
-
"feels",
|
68
|
-
]
|
69
|
-
days: int = 0
|
70
|
-
for m in em:
|
71
|
-
senderid: str = "unknown"
|
72
|
-
if "id" in m:
|
73
|
-
senderid = m["id"]
|
74
|
-
if not "hour" in m:
|
75
|
-
self.error(
|
76
|
-
f"No hour key in forecast record from {senderid}, skipped", str(m)
|
77
|
-
)
|
78
|
-
else:
|
79
|
-
point = (
|
80
|
-
self.measurement("forecast")
|
81
|
-
.tag("hour", m.get("hour"))
|
82
|
-
.tag("source", senderid)
|
83
|
-
.field("hr", str(m["hour"]))
|
84
|
-
)
|
85
|
-
# Conditionally add each field
|
86
|
-
for field in fields:
|
87
|
-
if field in m:
|
88
|
-
if field == "day" or field == "ts":
|
89
|
-
point = point.field(field, m[field])
|
90
|
-
else:
|
91
|
-
point = point.field(field, float(m[field]))
|
92
|
-
point = point.time(epoc2utc(m["ts"]))
|
93
|
-
self.write(point)
|
94
|
-
days = days + 1
|
95
|
-
self.info(
|
96
|
-
f"Forecast from {senderid} for the next {days} days written to time series database"
|
97
|
-
)
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
from typing_extensions import override
|
4
|
+
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
from juham_core import JuhamTs
|
7
|
+
from juham_core.timeutils import epoc2utc
|
8
|
+
|
9
|
+
|
10
|
+
class ForecastTs(JuhamTs):
|
11
|
+
"""Forecast database record.
|
12
|
+
|
13
|
+
This class listens the forecast topic and writes to the time series
|
14
|
+
database.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, name: str = "forecast_ts") -> None:
|
18
|
+
"""Construct forecast record object with the given name."""
|
19
|
+
super().__init__(name)
|
20
|
+
self.forecast_topic = self.make_topic_name("forecast")
|
21
|
+
|
22
|
+
@override
|
23
|
+
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
24
|
+
"""Standard mqtt connect notification.
|
25
|
+
|
26
|
+
This method is called when the client connection with the MQTT
|
27
|
+
broker is established.
|
28
|
+
"""
|
29
|
+
super().on_connect(client, userdata, flags, rc)
|
30
|
+
self.subscribe(self.forecast_topic)
|
31
|
+
self.debug(f"Subscribed to {self.forecast_topic}")
|
32
|
+
|
33
|
+
@override
|
34
|
+
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
35
|
+
"""Standard mqtt message notification method.
|
36
|
+
|
37
|
+
This method is called upon new arrived message.
|
38
|
+
"""
|
39
|
+
if msg.topic == self.forecast_topic:
|
40
|
+
m = json.loads(msg.payload.decode())
|
41
|
+
self.on_forecast(m)
|
42
|
+
else:
|
43
|
+
super().on_message(client, userdata, msg)
|
44
|
+
|
45
|
+
def on_forecast(self, em: dict[Any, Any]) -> None:
|
46
|
+
"""Handle weather forecast data. Writes the received hourly forecast
|
47
|
+
data to timeseries database.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
em (dict): forecast
|
51
|
+
"""
|
52
|
+
|
53
|
+
# List of fields you want to add
|
54
|
+
fields = [
|
55
|
+
"ts",
|
56
|
+
"day",
|
57
|
+
"solarradiation",
|
58
|
+
"solarenergy",
|
59
|
+
"cloudcover",
|
60
|
+
"snowdepth",
|
61
|
+
"uvindex",
|
62
|
+
"pressure",
|
63
|
+
"humidity",
|
64
|
+
"windspeed",
|
65
|
+
"winddir",
|
66
|
+
"temp",
|
67
|
+
"feels",
|
68
|
+
]
|
69
|
+
days: int = 0
|
70
|
+
for m in em:
|
71
|
+
senderid: str = "unknown"
|
72
|
+
if "id" in m:
|
73
|
+
senderid = m["id"]
|
74
|
+
if not "hour" in m:
|
75
|
+
self.error(
|
76
|
+
f"No hour key in forecast record from {senderid}, skipped", str(m)
|
77
|
+
)
|
78
|
+
else:
|
79
|
+
point = (
|
80
|
+
self.measurement("forecast")
|
81
|
+
.tag("hour", m.get("hour"))
|
82
|
+
.tag("source", senderid)
|
83
|
+
.field("hr", str(m["hour"]))
|
84
|
+
)
|
85
|
+
# Conditionally add each field
|
86
|
+
for field in fields:
|
87
|
+
if field in m:
|
88
|
+
if field == "day" or field == "ts":
|
89
|
+
point = point.field(field, m[field])
|
90
|
+
else:
|
91
|
+
point = point.field(field, float(m[field]))
|
92
|
+
point = point.time(epoc2utc(m["ts"]))
|
93
|
+
self.write(point)
|
94
|
+
days = days + 1
|
95
|
+
self.info(
|
96
|
+
f"Forecast from {senderid} for the next {days} days written to time series database"
|
97
|
+
)
|
juham_automation/ts/log_ts.py
CHANGED
@@ -1,57 +1,57 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any
|
3
|
-
from typing_extensions import override
|
4
|
-
|
5
|
-
from masterpiece.mqtt import MqttMsg
|
6
|
-
from juham_core import JuhamTs
|
7
|
-
from juham_core.timeutils import epoc2utc
|
8
|
-
|
9
|
-
|
10
|
-
class LogTs(JuhamTs):
|
11
|
-
"""Class recording application events, such as warnings and errors,
|
12
|
-
to time series database."""
|
13
|
-
|
14
|
-
def __init__(self, name: str = "log_ts") -> None:
|
15
|
-
"""Creates mqtt client for recording log events to time series
|
16
|
-
database.
|
17
|
-
|
18
|
-
Args:
|
19
|
-
name (str): name for the client
|
20
|
-
"""
|
21
|
-
super().__init__(name)
|
22
|
-
self.topic_name = self.make_topic_name("log")
|
23
|
-
|
24
|
-
@override
|
25
|
-
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
26
|
-
"""Connects the client to mqtt broker.
|
27
|
-
|
28
|
-
Args:
|
29
|
-
client (obj): client to be connected
|
30
|
-
userdata (any): caller specific data
|
31
|
-
flags (int): implementation specific shit
|
32
|
-
|
33
|
-
Returns:
|
34
|
-
rc (bool): True if successful
|
35
|
-
"""
|
36
|
-
super().on_connect(client, userdata, flags, rc)
|
37
|
-
if rc == 0:
|
38
|
-
self.subscribe(self.topic_name)
|
39
|
-
|
40
|
-
@override
|
41
|
-
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
42
|
-
m = json.loads(msg.payload.decode())
|
43
|
-
ts = epoc2utc(m["Timestamp"])
|
44
|
-
|
45
|
-
point = (
|
46
|
-
self.measurement("log")
|
47
|
-
.tag("class", m["Class"])
|
48
|
-
.field("source", m["Source"])
|
49
|
-
.field("msg", m["Msg"])
|
50
|
-
.field("details", m["Details"])
|
51
|
-
.field("Timestamp", m["Timestamp"])
|
52
|
-
.time(ts)
|
53
|
-
)
|
54
|
-
try:
|
55
|
-
self.write(point)
|
56
|
-
except Exception as e:
|
57
|
-
self.log_message("Error", f"Cannot write log event {m['Msg']}", str(e))
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
from typing_extensions import override
|
4
|
+
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
from juham_core import JuhamTs
|
7
|
+
from juham_core.timeutils import epoc2utc
|
8
|
+
|
9
|
+
|
10
|
+
class LogTs(JuhamTs):
|
11
|
+
"""Class recording application events, such as warnings and errors,
|
12
|
+
to time series database."""
|
13
|
+
|
14
|
+
def __init__(self, name: str = "log_ts") -> None:
|
15
|
+
"""Creates mqtt client for recording log events to time series
|
16
|
+
database.
|
17
|
+
|
18
|
+
Args:
|
19
|
+
name (str): name for the client
|
20
|
+
"""
|
21
|
+
super().__init__(name)
|
22
|
+
self.topic_name = self.make_topic_name("log")
|
23
|
+
|
24
|
+
@override
|
25
|
+
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
26
|
+
"""Connects the client to mqtt broker.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
client (obj): client to be connected
|
30
|
+
userdata (any): caller specific data
|
31
|
+
flags (int): implementation specific shit
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
rc (bool): True if successful
|
35
|
+
"""
|
36
|
+
super().on_connect(client, userdata, flags, rc)
|
37
|
+
if rc == 0:
|
38
|
+
self.subscribe(self.topic_name)
|
39
|
+
|
40
|
+
@override
|
41
|
+
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
42
|
+
m = json.loads(msg.payload.decode())
|
43
|
+
ts = epoc2utc(m["Timestamp"])
|
44
|
+
|
45
|
+
point = (
|
46
|
+
self.measurement("log")
|
47
|
+
.tag("class", m["Class"])
|
48
|
+
.field("source", m["Source"])
|
49
|
+
.field("msg", m["Msg"])
|
50
|
+
.field("details", m["Details"])
|
51
|
+
.field("Timestamp", m["Timestamp"])
|
52
|
+
.time(ts)
|
53
|
+
)
|
54
|
+
try:
|
55
|
+
self.write(point)
|
56
|
+
except Exception as e:
|
57
|
+
self.log_message("Error", f"Cannot write log event {m['Msg']}", str(e))
|
juham_automation/ts/power_ts.py
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any
|
3
|
-
from typing_extensions import override
|
4
|
-
|
5
|
-
from masterpiece.mqtt import MqttMsg
|
6
|
-
|
7
|
-
from juham_core import JuhamTs
|
8
|
-
from juham_core.timeutils import epoc2utc
|
9
|
-
|
10
|
-
|
11
|
-
class PowerTs(JuhamTs):
|
12
|
-
"""Power utilization record.
|
13
|
-
|
14
|
-
This class listens the power utilization message and writes the
|
15
|
-
state to time series database.
|
16
|
-
"""
|
17
|
-
|
18
|
-
def __init__(self, name: str = "power_ts") -> None:
|
19
|
-
"""Construct power record object with the given name."""
|
20
|
-
|
21
|
-
super().__init__(name)
|
22
|
-
self.topic_name = self.make_topic_name("power")
|
23
|
-
|
24
|
-
@override
|
25
|
-
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
26
|
-
super().on_connect(client, userdata, flags, rc)
|
27
|
-
self.subscribe(self.topic_name)
|
28
|
-
self.debug(f"Subscribed to {self.topic_name}")
|
29
|
-
|
30
|
-
@override
|
31
|
-
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
32
|
-
"""Standard mqtt message notification method.
|
33
|
-
|
34
|
-
This method is called upon new arrived message.
|
35
|
-
"""
|
36
|
-
|
37
|
-
m = json.loads(msg.payload.decode())
|
38
|
-
if not "Unit" in m:
|
39
|
-
return
|
40
|
-
unit = m["Unit"]
|
41
|
-
ts = m["Timestamp"]
|
42
|
-
state = m["State"]
|
43
|
-
point = (
|
44
|
-
self.measurement("power")
|
45
|
-
.tag("unit", unit)
|
46
|
-
.field("state", state)
|
47
|
-
.time(epoc2utc(ts))
|
48
|
-
)
|
49
|
-
self.write(point)
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
from typing_extensions import override
|
4
|
+
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
|
7
|
+
from juham_core import JuhamTs
|
8
|
+
from juham_core.timeutils import epoc2utc
|
9
|
+
|
10
|
+
|
11
|
+
class PowerTs(JuhamTs):
|
12
|
+
"""Power utilization record.
|
13
|
+
|
14
|
+
This class listens the power utilization message and writes the
|
15
|
+
state to time series database.
|
16
|
+
"""
|
17
|
+
|
18
|
+
def __init__(self, name: str = "power_ts") -> None:
|
19
|
+
"""Construct power record object with the given name."""
|
20
|
+
|
21
|
+
super().__init__(name)
|
22
|
+
self.topic_name = self.make_topic_name("power")
|
23
|
+
|
24
|
+
@override
|
25
|
+
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
26
|
+
super().on_connect(client, userdata, flags, rc)
|
27
|
+
self.subscribe(self.topic_name)
|
28
|
+
self.debug(f"Subscribed to {self.topic_name}")
|
29
|
+
|
30
|
+
@override
|
31
|
+
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
32
|
+
"""Standard mqtt message notification method.
|
33
|
+
|
34
|
+
This method is called upon new arrived message.
|
35
|
+
"""
|
36
|
+
|
37
|
+
m = json.loads(msg.payload.decode())
|
38
|
+
if not "Unit" in m:
|
39
|
+
return
|
40
|
+
unit = m["Unit"]
|
41
|
+
ts = m["Timestamp"]
|
42
|
+
state = m["State"]
|
43
|
+
point = (
|
44
|
+
self.measurement("power")
|
45
|
+
.tag("unit", unit)
|
46
|
+
.field("state", state)
|
47
|
+
.time(epoc2utc(ts))
|
48
|
+
)
|
49
|
+
self.write(point)
|
@@ -1,70 +1,70 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any, Dict
|
3
|
-
from typing_extensions import override
|
4
|
-
|
5
|
-
from masterpiece.mqtt import MqttMsg
|
6
|
-
from juham_core import JuhamTs
|
7
|
-
from juham_core.timeutils import epoc2utc
|
8
|
-
|
9
|
-
|
10
|
-
class PowerMeterTs(JuhamTs):
|
11
|
-
"""Power meter recorder.
|
12
|
-
|
13
|
-
Listens 'powerconsumption' topic and records the corresponding
|
14
|
-
time series.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def __init__(self, name: str = "powermeter_record") -> None:
|
18
|
-
super().__init__(name)
|
19
|
-
self.power_topic = self.make_topic_name("powerconsumption") # topic to listen
|
20
|
-
|
21
|
-
@override
|
22
|
-
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
23
|
-
super().on_connect(client, userdata, flags, rc)
|
24
|
-
if rc == 0:
|
25
|
-
self.subscribe(self.power_topic)
|
26
|
-
|
27
|
-
@override
|
28
|
-
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
29
|
-
super().on_message(client, userdata, msg)
|
30
|
-
if msg.topic == self.power_topic:
|
31
|
-
m = json.loads(msg.payload.decode())
|
32
|
-
self.record_power(m)
|
33
|
-
|
34
|
-
def record_power(self, em: dict[str, Any]) -> None:
|
35
|
-
"""Write from the power (energy) meter to the time
|
36
|
-
series database accordingly.
|
37
|
-
|
38
|
-
Args:
|
39
|
-
ts (float): utc time
|
40
|
-
em (dict): energy meter message
|
41
|
-
"""
|
42
|
-
point = (
|
43
|
-
self.measurement("powermeter")
|
44
|
-
.tag("sensor", "em0")
|
45
|
-
.field("real_A", em["real_a"])
|
46
|
-
.field("real_B", em["real_b"])
|
47
|
-
.field("real_C", em["real_c"])
|
48
|
-
.field("total_real_power", em["real_total"])
|
49
|
-
.time(epoc2utc(em["timestamp"]))
|
50
|
-
)
|
51
|
-
try:
|
52
|
-
self.write(point)
|
53
|
-
# self.debug(
|
54
|
-
# f"PowerMeter event recorded {epoc2utc(em['timestamp'])} - {em['real_a']} {em['real_b']} {em['real_c']}"
|
55
|
-
# )
|
56
|
-
except Exception as e:
|
57
|
-
self.error(f"Writing to influx failed {str(e)}")
|
58
|
-
|
59
|
-
def to_dict(self) -> Dict[str, Any]:
|
60
|
-
data: Dict[str, Any] = super().to_dict()
|
61
|
-
data["_powermeter_record"] = {
|
62
|
-
"power_topic": self.power_topic,
|
63
|
-
}
|
64
|
-
return data
|
65
|
-
|
66
|
-
def from_dict(self, data: Dict[str, Any]) -> None:
|
67
|
-
super().from_dict(data)
|
68
|
-
if "_powermeter_record" in data:
|
69
|
-
for key, value in data["_powermeter_record"].items():
|
70
|
-
setattr(self, key, value)
|
1
|
+
import json
|
2
|
+
from typing import Any, Dict
|
3
|
+
from typing_extensions import override
|
4
|
+
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
from juham_core import JuhamTs
|
7
|
+
from juham_core.timeutils import epoc2utc
|
8
|
+
|
9
|
+
|
10
|
+
class PowerMeterTs(JuhamTs):
|
11
|
+
"""Power meter recorder.
|
12
|
+
|
13
|
+
Listens 'powerconsumption' topic and records the corresponding
|
14
|
+
time series.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, name: str = "powermeter_record") -> None:
|
18
|
+
super().__init__(name)
|
19
|
+
self.power_topic = self.make_topic_name("powerconsumption") # topic to listen
|
20
|
+
|
21
|
+
@override
|
22
|
+
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
23
|
+
super().on_connect(client, userdata, flags, rc)
|
24
|
+
if rc == 0:
|
25
|
+
self.subscribe(self.power_topic)
|
26
|
+
|
27
|
+
@override
|
28
|
+
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
29
|
+
super().on_message(client, userdata, msg)
|
30
|
+
if msg.topic == self.power_topic:
|
31
|
+
m = json.loads(msg.payload.decode())
|
32
|
+
self.record_power(m)
|
33
|
+
|
34
|
+
def record_power(self, em: dict[str, Any]) -> None:
|
35
|
+
"""Write from the power (energy) meter to the time
|
36
|
+
series database accordingly.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
ts (float): utc time
|
40
|
+
em (dict): energy meter message
|
41
|
+
"""
|
42
|
+
point = (
|
43
|
+
self.measurement("powermeter")
|
44
|
+
.tag("sensor", "em0")
|
45
|
+
.field("real_A", em["real_a"])
|
46
|
+
.field("real_B", em["real_b"])
|
47
|
+
.field("real_C", em["real_c"])
|
48
|
+
.field("total_real_power", em["real_total"])
|
49
|
+
.time(epoc2utc(em["timestamp"]))
|
50
|
+
)
|
51
|
+
try:
|
52
|
+
self.write(point)
|
53
|
+
# self.debug(
|
54
|
+
# f"PowerMeter event recorded {epoc2utc(em['timestamp'])} - {em['real_a']} {em['real_b']} {em['real_c']}"
|
55
|
+
# )
|
56
|
+
except Exception as e:
|
57
|
+
self.error(f"Writing to influx failed {str(e)}")
|
58
|
+
|
59
|
+
def to_dict(self) -> Dict[str, Any]:
|
60
|
+
data: Dict[str, Any] = super().to_dict()
|
61
|
+
data["_powermeter_record"] = {
|
62
|
+
"power_topic": self.power_topic,
|
63
|
+
}
|
64
|
+
return data
|
65
|
+
|
66
|
+
def from_dict(self, data: Dict[str, Any]) -> None:
|
67
|
+
super().from_dict(data)
|
68
|
+
if "_powermeter_record" in data:
|
69
|
+
for key, value in data["_powermeter_record"].items():
|
70
|
+
setattr(self, key, value)
|
@@ -1,45 +1,45 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any
|
3
|
-
from typing_extensions import override
|
4
|
-
|
5
|
-
from masterpiece.mqtt import MqttMsg
|
6
|
-
from juham_core import JuhamTs
|
7
|
-
from juham_core.timeutils import epoc2utc
|
8
|
-
|
9
|
-
|
10
|
-
class PowerPlanTs(JuhamTs):
|
11
|
-
"""Power plan time series record.
|
12
|
-
|
13
|
-
Listens powerplan topic and updates time series database
|
14
|
-
accordingly.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def __init__(self, name: str = "powerplan_ts") -> None:
|
18
|
-
super().__init__(name)
|
19
|
-
self.powerplan_topic = self.make_topic_name("powerplan")
|
20
|
-
|
21
|
-
@override
|
22
|
-
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
23
|
-
super().on_connect(client, userdata, flags, rc)
|
24
|
-
self.subscribe(self.powerplan_topic)
|
25
|
-
|
26
|
-
@override
|
27
|
-
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
28
|
-
super().on_message(client, userdata, msg)
|
29
|
-
m = json.loads(msg.payload.decode())
|
30
|
-
schedule = m["Schedule"]
|
31
|
-
uoi = m["UOI"]
|
32
|
-
ts = m["Timestamp"]
|
33
|
-
|
34
|
-
point = (
|
35
|
-
self.measurement("powerplan")
|
36
|
-
.tag("unit", m["Unit"])
|
37
|
-
.field("state", m["State"]) # 1 on, 0 off
|
38
|
-
.field("name", m["Unit"]) # e.g main_boiler
|
39
|
-
.field("type", "C") # C=consumption, S = supply
|
40
|
-
.field("power", 16.0) # kW
|
41
|
-
.field("Schedule", schedule) # figures of merit
|
42
|
-
.field("UOI", float(uoi)) # Utilitzation Optimizing Index
|
43
|
-
.time(epoc2utc(ts))
|
44
|
-
)
|
45
|
-
self.write(point)
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
from typing_extensions import override
|
4
|
+
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
from juham_core import JuhamTs
|
7
|
+
from juham_core.timeutils import epoc2utc
|
8
|
+
|
9
|
+
|
10
|
+
class PowerPlanTs(JuhamTs):
|
11
|
+
"""Power plan time series record.
|
12
|
+
|
13
|
+
Listens powerplan topic and updates time series database
|
14
|
+
accordingly.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, name: str = "powerplan_ts") -> None:
|
18
|
+
super().__init__(name)
|
19
|
+
self.powerplan_topic = self.make_topic_name("powerplan")
|
20
|
+
|
21
|
+
@override
|
22
|
+
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
|
23
|
+
super().on_connect(client, userdata, flags, rc)
|
24
|
+
self.subscribe(self.powerplan_topic)
|
25
|
+
|
26
|
+
@override
|
27
|
+
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
|
28
|
+
super().on_message(client, userdata, msg)
|
29
|
+
m = json.loads(msg.payload.decode())
|
30
|
+
schedule = m["Schedule"]
|
31
|
+
uoi = m["UOI"]
|
32
|
+
ts = m["Timestamp"]
|
33
|
+
|
34
|
+
point = (
|
35
|
+
self.measurement("powerplan")
|
36
|
+
.tag("unit", m["Unit"])
|
37
|
+
.field("state", m["State"]) # 1 on, 0 off
|
38
|
+
.field("name", m["Unit"]) # e.g main_boiler
|
39
|
+
.field("type", "C") # C=consumption, S = supply
|
40
|
+
.field("power", 16.0) # kW
|
41
|
+
.field("Schedule", schedule) # figures of merit
|
42
|
+
.field("UOI", float(uoi)) # Utilitzation Optimizing Index
|
43
|
+
.time(epoc2utc(ts))
|
44
|
+
)
|
45
|
+
self.write(point)
|