juham-automation 0.0.11__tar.gz → 0.0.13__tar.gz
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-0.0.11/juham_automation.egg-info → juham_automation-0.0.13}/PKG-INFO +2 -7
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/spothintafi.py +18 -12
- {juham_automation-0.0.11 → juham_automation-0.0.13/juham_automation.egg-info}/PKG-INFO +2 -7
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/SOURCES.txt +1 -0
- juham_automation-0.0.13/juham_automation.egg-info/requires.txt +5 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/pyproject.toml +2 -7
- juham_automation-0.0.13/tests/automation/test_hotwateroptimizer.py +109 -0
- juham_automation-0.0.13/tests/automation/test_spothintafi.py +67 -0
- juham_automation-0.0.11/juham_automation.egg-info/requires.txt +0 -10
- juham_automation-0.0.11/tests/automation/test_hotwateroptimizer.py +0 -20
- {juham_automation-0.0.11 → juham_automation-0.0.13}/LICENSE.rst +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/MANIFEST.in +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/README.rst +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/examples/myapp.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/energycostcalculator.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/hotwateroptimizer.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/powermeter_simulator.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/watercirculator.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/japp.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/py.typed +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/electricityprice_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/energycostcalculator_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/forecast_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/log_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/power_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/powermeter_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/powerplan_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/dependency_links.txt +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/entry_points.txt +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/top_level.txt +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/setup.cfg +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/automation/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/automation/test_energycostcalculator.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/automation/test_juham.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/test_japp.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/__init__.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_energycostcalculator_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_forecast_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_log_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_power_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_powermeter_ts.py +0 -0
- {juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_powerplan_ts.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: juham-automation
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
4
4
|
Summary: Juha's Ultimate Home Automation Masterpiece
|
5
5
|
Author-email: J Meskanen <juham.api@gmail.com>
|
6
6
|
Maintainer-email: "J. Meskanen" <juham.api@gmail.com>
|
@@ -44,12 +44,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
44
44
|
Requires-Python: >=3.8
|
45
45
|
Description-Content-Type: text/markdown
|
46
46
|
License-File: LICENSE.rst
|
47
|
-
Requires-Dist:
|
48
|
-
Requires-Dist: masterpiece_influx>=0.1.9
|
49
|
-
Requires-Dist: masterpiece_pahomqtt>=0.1.5
|
50
|
-
Requires-Dist: juham_core>=0.1.0
|
51
|
-
Requires-Dist: requests>=2.31
|
52
|
-
Requires-Dist: pytz>=2024.1
|
47
|
+
Requires-Dist: juham_core>=0.1.2
|
53
48
|
Provides-Extra: dev
|
54
49
|
Requires-Dist: check-manifest; extra == "dev"
|
55
50
|
Requires-Dist: types-pyz; extra == "dev"
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/spothintafi.py
RENAMED
@@ -12,7 +12,7 @@ class SpotHintaFiThread(JuhamCloudThread):
|
|
12
12
|
"""Thread running SpotHinta.fi.
|
13
13
|
|
14
14
|
Periodically fetches the spot electricity prices and publishes them
|
15
|
-
to
|
15
|
+
to 'spot' topic.
|
16
16
|
"""
|
17
17
|
|
18
18
|
_spot_topic: str = ""
|
@@ -52,25 +52,30 @@ class SpotHintaFiThread(JuhamCloudThread):
|
|
52
52
|
|
53
53
|
spot = []
|
54
54
|
for e in data:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
dt = datetime.fromisoformat(e["DateTime"]) # Correct timezone handling
|
56
|
+
ts = int(dt.timestamp()) # Ensure integer timestamps like in the test
|
57
|
+
|
58
|
+
hour = dt.strftime("%H") # Correctly extract hour
|
59
|
+
|
60
|
+
if 6 <= int(hour) < 22:
|
60
61
|
grid_cost = self.grid_cost_day
|
61
62
|
else:
|
62
63
|
grid_cost = self.grid_cost_night
|
63
|
-
|
64
|
+
|
65
|
+
total_price = round(e["PriceWithTax"] + grid_cost + self.grid_cost_tax, 6)
|
66
|
+
grid_cost_total = round(grid_cost + self.grid_cost_tax, 6)
|
67
|
+
|
64
68
|
h = {
|
65
69
|
"Timestamp": ts,
|
66
70
|
"hour": hour,
|
67
71
|
"Rank": e["Rank"],
|
68
72
|
"PriceWithTax": total_price,
|
69
|
-
"GridCost":
|
73
|
+
"GridCost": grid_cost_total,
|
70
74
|
}
|
71
75
|
spot.append(h)
|
76
|
+
|
72
77
|
self.publish(self._spot_topic, json.dumps(spot), 1, True)
|
73
|
-
self.info(f"Spot electricity prices published for the next {len(spot)} days")
|
78
|
+
# self.info(f"Spot electricity prices published for the next {len(spot)} days")
|
74
79
|
|
75
80
|
|
76
81
|
class SpotHintaFi(JuhamThread):
|
@@ -78,6 +83,7 @@ class SpotHintaFi(JuhamThread):
|
|
78
83
|
https://api.spot-hinta.fi site.
|
79
84
|
"""
|
80
85
|
|
86
|
+
_SPOTHINTAFI: str = "_spothintafi"
|
81
87
|
worker_thread_id = SpotHintaFiThread.get_class_id()
|
82
88
|
url = "https://api.spot-hinta.fi/TodayAndDayForward"
|
83
89
|
update_interval = 12 * 3600
|
@@ -119,7 +125,7 @@ class SpotHintaFi(JuhamThread):
|
|
119
125
|
@override
|
120
126
|
def to_dict(self) -> Dict[str, Any]:
|
121
127
|
data: Dict[str, Any] = super().to_dict()
|
122
|
-
data[
|
128
|
+
data[self._SPOTHINTAFI] = {
|
123
129
|
"topic": self.spot_topic,
|
124
130
|
"url": self.url,
|
125
131
|
"interval": self.update_interval,
|
@@ -129,6 +135,6 @@ class SpotHintaFi(JuhamThread):
|
|
129
135
|
@override
|
130
136
|
def from_dict(self, data: Dict[str, Any]) -> None:
|
131
137
|
super().from_dict(data)
|
132
|
-
if
|
133
|
-
for key, value in data[
|
138
|
+
if self._SPOTHINTAFI in data:
|
139
|
+
for key, value in data[self._SPOTHINTAFI].items():
|
134
140
|
setattr(self, key, value)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: juham-automation
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
4
4
|
Summary: Juha's Ultimate Home Automation Masterpiece
|
5
5
|
Author-email: J Meskanen <juham.api@gmail.com>
|
6
6
|
Maintainer-email: "J. Meskanen" <juham.api@gmail.com>
|
@@ -44,12 +44,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
44
44
|
Requires-Python: >=3.8
|
45
45
|
Description-Content-Type: text/markdown
|
46
46
|
License-File: LICENSE.rst
|
47
|
-
Requires-Dist:
|
48
|
-
Requires-Dist: masterpiece_influx>=0.1.9
|
49
|
-
Requires-Dist: masterpiece_pahomqtt>=0.1.5
|
50
|
-
Requires-Dist: juham_core>=0.1.0
|
51
|
-
Requires-Dist: requests>=2.31
|
52
|
-
Requires-Dist: pytz>=2024.1
|
47
|
+
Requires-Dist: juham_core>=0.1.2
|
53
48
|
Provides-Extra: dev
|
54
49
|
Requires-Dist: check-manifest; extra == "dev"
|
55
50
|
Requires-Dist: types-pyz; extra == "dev"
|
@@ -32,6 +32,7 @@ tests/automation/__init__.py
|
|
32
32
|
tests/automation/test_energycostcalculator.py
|
33
33
|
tests/automation/test_hotwateroptimizer.py
|
34
34
|
tests/automation/test_juham.py
|
35
|
+
tests/automation/test_spothintafi.py
|
35
36
|
tests/ts/__init__.py
|
36
37
|
tests/ts/test_energycostcalculator_ts.py
|
37
38
|
tests/ts/test_forecast_ts.py
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
5
5
|
|
6
6
|
[project]
|
7
7
|
name = "juham-automation"
|
8
|
-
version = "0.0.
|
8
|
+
version = "0.0.13"
|
9
9
|
description = "Juha's Ultimate Home Automation Masterpiece"
|
10
10
|
readme = {file = "README.rst", content-type = "text/markdown"}
|
11
11
|
requires-python = ">=3.8"
|
@@ -27,12 +27,7 @@ classifiers = [
|
|
27
27
|
]
|
28
28
|
|
29
29
|
dependencies = [
|
30
|
-
"
|
31
|
-
"masterpiece_influx >= 0.1.9",
|
32
|
-
"masterpiece_pahomqtt >= 0.1.5",
|
33
|
-
"juham_core >= 0.1.0",
|
34
|
-
"requests >= 2.31",
|
35
|
-
"pytz >= 2024.1",
|
30
|
+
"juham_core >= 0.1.2",
|
36
31
|
]
|
37
32
|
|
38
33
|
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import unittest
|
2
|
+
from typing import Any
|
3
|
+
from masterpiece import MqttMsg
|
4
|
+
from unittest.mock import MagicMock, patch
|
5
|
+
from masterpiece.mqtt import MqttMsg
|
6
|
+
from juham_automation.automation.hotwateroptimizer import HotWaterOptimizer
|
7
|
+
|
8
|
+
|
9
|
+
class SimpleMqttMsg(MqttMsg):
|
10
|
+
def __init__(self, topic: str, payload: Any):
|
11
|
+
self._topic = topic
|
12
|
+
self._payload = payload
|
13
|
+
|
14
|
+
@property
|
15
|
+
def payload(self) -> Any:
|
16
|
+
return self._payload
|
17
|
+
|
18
|
+
@payload.setter
|
19
|
+
def payload(self, value: Any) -> None:
|
20
|
+
self._payload = value
|
21
|
+
|
22
|
+
@property
|
23
|
+
def topic(self) -> str:
|
24
|
+
return self._topic
|
25
|
+
|
26
|
+
@topic.setter
|
27
|
+
def topic(self, value: str) -> None:
|
28
|
+
self._topic = value
|
29
|
+
|
30
|
+
|
31
|
+
class TestHotWaterOptimizer(unittest.TestCase):
|
32
|
+
def setUp(self) -> None:
|
33
|
+
self.optimizer = HotWaterOptimizer(
|
34
|
+
name="test_optimizer",
|
35
|
+
temperature_sensor="temp_sensor",
|
36
|
+
start_hour=5,
|
37
|
+
num_hours=3,
|
38
|
+
spot_limit=0.25,
|
39
|
+
)
|
40
|
+
|
41
|
+
# Use patch.object to mock instance methods dynamically
|
42
|
+
self.patcher_subscribe = patch.object(
|
43
|
+
self.optimizer, "subscribe", autospec=True
|
44
|
+
)
|
45
|
+
self.patcher_debug = patch.object(self.optimizer, "debug", autospec=True)
|
46
|
+
self.patcher_info = patch.object(self.optimizer, "info", autospec=True)
|
47
|
+
self.patcher_error = patch.object(self.optimizer, "error", autospec=True)
|
48
|
+
self.patcher_warning = patch.object(self.optimizer, "warning", autospec=True)
|
49
|
+
|
50
|
+
# Start the patches
|
51
|
+
self.mock_subscribe = self.patcher_subscribe.start()
|
52
|
+
self.mock_debug = self.patcher_debug.start()
|
53
|
+
self.mock_info = self.patcher_info.start()
|
54
|
+
self.mock_error = self.patcher_error.start()
|
55
|
+
self.mock_warning = self.patcher_warning.start()
|
56
|
+
|
57
|
+
def tearDown(self) -> None:
|
58
|
+
# Stop the patches to clean up
|
59
|
+
self.patcher_subscribe.stop()
|
60
|
+
self.patcher_debug.stop()
|
61
|
+
self.patcher_info.stop()
|
62
|
+
self.patcher_error.stop()
|
63
|
+
self.patcher_warning.stop()
|
64
|
+
|
65
|
+
def test_initialization(self) -> None:
|
66
|
+
self.assertEqual(self.optimizer.heating_hours_per_day, 3)
|
67
|
+
self.assertEqual(self.optimizer.start_hour, 5)
|
68
|
+
self.assertEqual(self.optimizer.spot_limit, 0.25)
|
69
|
+
self.assertEqual(self.optimizer.current_temperature, 100)
|
70
|
+
self.assertFalse(self.optimizer.relay)
|
71
|
+
|
72
|
+
def test_on_connect(self) -> None:
|
73
|
+
self.optimizer.on_connect(None, None, 0, 0)
|
74
|
+
self.mock_subscribe.assert_any_call(self.optimizer.topic_spot)
|
75
|
+
self.mock_subscribe.assert_any_call(self.optimizer.topic_forecast)
|
76
|
+
self.mock_subscribe.assert_any_call(self.optimizer.topic_temperature)
|
77
|
+
self.mock_subscribe.assert_any_call(self.optimizer.topic_in_powerconsumption)
|
78
|
+
self.mock_subscribe.assert_any_call(self.optimizer.topic_in_net_energy_balance)
|
79
|
+
|
80
|
+
def test_sort_by_rank(self) -> None:
|
81
|
+
test_data = [
|
82
|
+
{"Rank": 2, "Timestamp": 2000},
|
83
|
+
{"Rank": 1, "Timestamp": 3000},
|
84
|
+
{"Rank": 3, "Timestamp": 1000},
|
85
|
+
]
|
86
|
+
sorted_data = self.optimizer.sort_by_rank(test_data, 1500)
|
87
|
+
self.assertEqual(sorted_data[0]["Rank"], 1)
|
88
|
+
self.assertEqual(sorted_data[1]["Rank"], 2)
|
89
|
+
|
90
|
+
def test_sort_by_power(self) -> None:
|
91
|
+
test_data = [
|
92
|
+
{"solarenergy": 50, "ts": 2000},
|
93
|
+
{"solarenergy": 100, "ts": 3000},
|
94
|
+
{"solarenergy": 10, "ts": 1000},
|
95
|
+
]
|
96
|
+
sorted_data = self.optimizer.sort_by_power(test_data, 1500)
|
97
|
+
self.assertEqual(sorted_data[0]["solarenergy"], 100)
|
98
|
+
self.assertEqual(sorted_data[1]["solarenergy"], 50)
|
99
|
+
|
100
|
+
def test_on_message_temperature_update(self) -> None:
|
101
|
+
mock_msg = SimpleMqttMsg(
|
102
|
+
topic=self.optimizer.topic_temperature, payload=b'{"temperature": 55}'
|
103
|
+
)
|
104
|
+
self.optimizer.on_message(None, None, mock_msg)
|
105
|
+
self.assertEqual(self.optimizer.current_temperature, 55)
|
106
|
+
|
107
|
+
|
108
|
+
if __name__ == "__main__":
|
109
|
+
unittest.main()
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import unittest
|
2
|
+
from unittest import TestCase, mock
|
3
|
+
from unittest.mock import MagicMock, patch
|
4
|
+
import json
|
5
|
+
from typing import Dict, Any
|
6
|
+
from juham_core import JuhamCloudThread
|
7
|
+
|
8
|
+
from juham_automation.automation.spothintafi import (
|
9
|
+
SpotHintaFiThread,
|
10
|
+
SpotHintaFi,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
class TestSpotHintaFiThread(TestCase):
|
15
|
+
|
16
|
+
@patch("juham_automation.automation.spothintafi.Mqtt")
|
17
|
+
def test_make_weburl(self, mock_mqtt) -> None:
|
18
|
+
|
19
|
+
thread = SpotHintaFiThread(mock_mqtt)
|
20
|
+
thread.init("test/topic", "http://test.url", 60)
|
21
|
+
|
22
|
+
# Test make_weburl method
|
23
|
+
self.assertEqual(thread.make_weburl(), "http://test.url")
|
24
|
+
|
25
|
+
|
26
|
+
class TestSpotHintaFi(unittest.TestCase):
|
27
|
+
|
28
|
+
def test_to_dict(self) -> None:
|
29
|
+
spot_hinta = SpotHintaFi("spot")
|
30
|
+
spot_hinta.url = "http://test.url"
|
31
|
+
expected_dict = {
|
32
|
+
"_class": "SpotHintaFi",
|
33
|
+
"_version": 0,
|
34
|
+
"_object": {"name": "spot", "payload": None},
|
35
|
+
"_base": {},
|
36
|
+
"_spothintafi": {
|
37
|
+
"topic": "/spot",
|
38
|
+
"url": "http://test.url",
|
39
|
+
"interval": 43200,
|
40
|
+
},
|
41
|
+
}
|
42
|
+
|
43
|
+
actual_dict: Dict[str, Any] = spot_hinta.to_dict()
|
44
|
+
self.assertEqual(actual_dict, expected_dict)
|
45
|
+
|
46
|
+
def test_from_dict(self) -> None:
|
47
|
+
spot_hinta = SpotHintaFi()
|
48
|
+
data = {
|
49
|
+
"_class": "SpotHintaFi",
|
50
|
+
"_object": {"name": "rspothintafi"},
|
51
|
+
"_base": {},
|
52
|
+
"_spothintafi": {
|
53
|
+
"topic": "spot/topic",
|
54
|
+
"url": "http://test.url",
|
55
|
+
"interval": 60,
|
56
|
+
},
|
57
|
+
}
|
58
|
+
|
59
|
+
spot_hinta.from_dict(data)
|
60
|
+
|
61
|
+
self.assertEqual(spot_hinta.spot_topic, "/spot")
|
62
|
+
self.assertEqual(spot_hinta.url, "http://test.url")
|
63
|
+
self.assertEqual(spot_hinta.update_interval, 43200)
|
64
|
+
|
65
|
+
|
66
|
+
if __name__ == "__main__":
|
67
|
+
unittest.main()
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
from masterpiece import MqttMsg
|
3
|
-
from juham_automation.automation.hotwateroptimizer import HotWaterOptimizer
|
4
|
-
|
5
|
-
|
6
|
-
class TestHotWaterOptimizer(unittest.TestCase):
|
7
|
-
|
8
|
-
def test_constructor(self) -> None:
|
9
|
-
obj = HotWaterOptimizer(
|
10
|
-
name="test_optimizer",
|
11
|
-
temperature_sensor="test_sensor",
|
12
|
-
start_hour=0,
|
13
|
-
num_hours=4,
|
14
|
-
spot_limit=0.1,
|
15
|
-
)
|
16
|
-
self.assertIsNotNone(obj)
|
17
|
-
|
18
|
-
|
19
|
-
if __name__ == "__main__":
|
20
|
-
unittest.main()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/hotwateroptimizer.py
RENAMED
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/automation/watercirculator.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/electricityprice_ts.py
RENAMED
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation/ts/energycostcalculator_ts.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/dependency_links.txt
RENAMED
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/juham_automation.egg-info/entry_points.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/tests/automation/test_energycostcalculator.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{juham_automation-0.0.11 → juham_automation-0.0.13}/tests/ts/test_energycostcalculator_ts.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|