juham-automation 0.0.10__tar.gz → 0.0.12__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.
Files changed (143) hide show
  1. {juham_automation-0.0.10 → juham_automation-0.0.12}/PKG-INFO +4 -5
  2. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/hotwateroptimizer.py +9 -15
  3. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/spothintafi.py +18 -12
  4. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation.egg-info/PKG-INFO +4 -5
  5. juham_automation-0.0.12/juham_automation.egg-info/SOURCES.txt +42 -0
  6. juham_automation-0.0.12/juham_automation.egg-info/requires.txt +9 -0
  7. {juham_automation-0.0.10 → juham_automation-0.0.12}/pyproject.toml +4 -5
  8. juham_automation-0.0.12/tests/automation/test_hotwateroptimizer.py +109 -0
  9. juham_automation-0.0.12/tests/automation/test_spothintafi.py +67 -0
  10. juham_automation-0.0.10/docs/build/html/.buildinfo +0 -4
  11. juham_automation-0.0.10/docs/build/html/.buildinfo.bak +0 -4
  12. juham_automation-0.0.10/docs/build/html/.nojekyll +0 -0
  13. juham_automation-0.0.10/docs/build/html/_images/juham.png +0 -0
  14. juham_automation-0.0.10/docs/build/html/_modules/index.html +0 -148
  15. juham_automation-0.0.10/docs/build/html/_modules/juham_core/juham.html +0 -478
  16. juham_automation-0.0.10/docs/build/html/_modules/juham_core/juham_ts.html +0 -272
  17. juham_automation-0.0.10/docs/build/html/_modules/masterpiece/application.html +0 -474
  18. juham_automation-0.0.10/docs/build/html/_modules/masterpiece/composite.html +0 -334
  19. juham_automation-0.0.10/docs/build/html/_modules/masterpiece/masterpiece.html +0 -643
  20. juham_automation-0.0.10/docs/build/html/_sources/index.rst.txt +0 -57
  21. juham_automation-0.0.10/docs/build/html/_sources/juham_automation/index.rst.txt +0 -9
  22. juham_automation-0.0.10/docs/build/html/_static/basic.css +0 -906
  23. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap-responsive.css +0 -1109
  24. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css +0 -9
  25. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap.css +0 -6167
  26. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap.min.css +0 -9
  27. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png +0 -0
  28. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/img/glyphicons-halflings.png +0 -0
  29. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/js/bootstrap.js +0 -2287
  30. juham_automation-0.0.10/docs/build/html/_static/bootstrap-2.3.2/js/bootstrap.min.js +0 -6
  31. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.css +0 -587
  32. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.css.map +0 -1
  33. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css +0 -6
  34. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css.map +0 -1
  35. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.css +0 -6834
  36. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.css.map +0 -1
  37. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.min.css +0 -6
  38. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.min.css.map +0 -1
  39. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot +0 -0
  40. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg +0 -288
  41. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf +0 -0
  42. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff +0 -0
  43. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 +0 -0
  44. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/js/bootstrap.js +0 -2580
  45. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/js/bootstrap.min.js +0 -6
  46. juham_automation-0.0.10/docs/build/html/_static/bootstrap-3.4.1/js/npm.js +0 -13
  47. juham_automation-0.0.10/docs/build/html/_static/bootstrap-sphinx.css +0 -221
  48. juham_automation-0.0.10/docs/build/html/_static/bootstrap-sphinx.js +0 -175
  49. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/amelia/bootstrap.min.css +0 -9
  50. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/cerulean/bootstrap.min.css +0 -9
  51. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/cosmo/bootstrap.min.css +0 -9
  52. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/cyborg/bootstrap.min.css +0 -9
  53. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/flatly/bootstrap.min.css +0 -9
  54. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png +0 -0
  55. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/img/glyphicons-halflings.png +0 -0
  56. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/journal/bootstrap.min.css +0 -9
  57. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/readable/bootstrap.min.css +0 -9
  58. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/simplex/bootstrap.min.css +0 -9
  59. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/slate/bootstrap.min.css +0 -9
  60. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/spacelab/bootstrap.min.css +0 -9
  61. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/spruce/bootstrap.min.css +0 -9
  62. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/superhero/bootstrap.min.css +0 -9
  63. juham_automation-0.0.10/docs/build/html/_static/bootswatch-2.3.2/united/bootstrap.min.css +0 -9
  64. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/cerulean/bootstrap.min.css +0 -11
  65. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/cosmo/bootstrap.min.css +0 -11
  66. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/cyborg/bootstrap.min.css +0 -11
  67. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/darkly/bootstrap.min.css +0 -11
  68. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/flatly/bootstrap.min.css +0 -11
  69. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.eot +0 -0
  70. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.svg +0 -288
  71. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.ttf +0 -0
  72. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff +0 -0
  73. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff2 +0 -0
  74. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/journal/bootstrap.min.css +0 -11
  75. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/lumen/bootstrap.min.css +0 -11
  76. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/paper/bootstrap.min.css +0 -11
  77. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/readable/bootstrap.min.css +0 -11
  78. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/sandstone/bootstrap.min.css +0 -11
  79. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/simplex/bootstrap.min.css +0 -11
  80. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/slate/bootstrap.min.css +0 -11
  81. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/spacelab/bootstrap.min.css +0 -11
  82. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/superhero/bootstrap.min.css +0 -11
  83. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/united/bootstrap.min.css +0 -11
  84. juham_automation-0.0.10/docs/build/html/_static/bootswatch-3.4.1/yeti/bootstrap.min.css +0 -11
  85. juham_automation-0.0.10/docs/build/html/_static/doctools.js +0 -149
  86. juham_automation-0.0.10/docs/build/html/_static/documentation_options.js +0 -13
  87. juham_automation-0.0.10/docs/build/html/_static/file.png +0 -0
  88. juham_automation-0.0.10/docs/build/html/_static/graphviz.css +0 -12
  89. juham_automation-0.0.10/docs/build/html/_static/js/jquery-1.12.4.min.js +0 -5
  90. juham_automation-0.0.10/docs/build/html/_static/js/jquery-fix.js +0 -2
  91. juham_automation-0.0.10/docs/build/html/_static/juham.css +0 -64
  92. juham_automation-0.0.10/docs/build/html/_static/juham.png +0 -0
  93. juham_automation-0.0.10/docs/build/html/_static/language_data.js +0 -192
  94. juham_automation-0.0.10/docs/build/html/_static/minus.png +0 -0
  95. juham_automation-0.0.10/docs/build/html/_static/plus.png +0 -0
  96. juham_automation-0.0.10/docs/build/html/_static/pygments.css +0 -75
  97. juham_automation-0.0.10/docs/build/html/_static/searchtools.js +0 -635
  98. juham_automation-0.0.10/docs/build/html/_static/sphinx_highlight.js +0 -154
  99. juham_automation-0.0.10/docs/build/html/genindex.html +0 -140
  100. juham_automation-0.0.10/docs/build/html/index.html +0 -408
  101. juham_automation-0.0.10/docs/build/html/juham_automation/index.html +0 -161
  102. juham_automation-0.0.10/docs/build/html/objects.inv +0 -0
  103. juham_automation-0.0.10/docs/build/html/py-modindex.html +0 -158
  104. juham_automation-0.0.10/docs/build/html/search.html +0 -155
  105. juham_automation-0.0.10/docs/build/html/searchindex.js +0 -1
  106. juham_automation-0.0.10/juham_automation.egg-info/SOURCES.txt +0 -137
  107. juham_automation-0.0.10/juham_automation.egg-info/requires.txt +0 -10
  108. juham_automation-0.0.10/tests/automation/test_hotwateroptimizer.py +0 -20
  109. {juham_automation-0.0.10 → juham_automation-0.0.12}/LICENSE.rst +0 -0
  110. {juham_automation-0.0.10 → juham_automation-0.0.12}/MANIFEST.in +0 -0
  111. {juham_automation-0.0.10 → juham_automation-0.0.12}/README.rst +0 -0
  112. {juham_automation-0.0.10 → juham_automation-0.0.12}/examples/myapp.py +0 -0
  113. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/__init__.py +0 -0
  114. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/__init__.py +0 -0
  115. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/energycostcalculator.py +0 -0
  116. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/powermeter_simulator.py +0 -0
  117. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/automation/watercirculator.py +0 -0
  118. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/japp.py +0 -0
  119. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/py.typed +0 -0
  120. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/__init__.py +0 -0
  121. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/electricityprice_ts.py +0 -0
  122. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/energycostcalculator_ts.py +0 -0
  123. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/forecast_ts.py +0 -0
  124. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/log_ts.py +0 -0
  125. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/power_ts.py +0 -0
  126. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/powermeter_ts.py +0 -0
  127. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation/ts/powerplan_ts.py +0 -0
  128. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation.egg-info/dependency_links.txt +0 -0
  129. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation.egg-info/entry_points.txt +0 -0
  130. {juham_automation-0.0.10 → juham_automation-0.0.12}/juham_automation.egg-info/top_level.txt +0 -0
  131. {juham_automation-0.0.10 → juham_automation-0.0.12}/setup.cfg +0 -0
  132. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/__init__.py +0 -0
  133. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/automation/__init__.py +0 -0
  134. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/automation/test_energycostcalculator.py +0 -0
  135. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/automation/test_juham.py +0 -0
  136. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/test_japp.py +0 -0
  137. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/__init__.py +0 -0
  138. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/test_energycostcalculator_ts.py +0 -0
  139. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/test_forecast_ts.py +0 -0
  140. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/test_log_ts.py +0 -0
  141. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/test_power_ts.py +0 -0
  142. {juham_automation-0.0.10 → juham_automation-0.0.12}/tests/ts/test_powermeter_ts.py +0 -0
  143. {juham_automation-0.0.10 → juham_automation-0.0.12}/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.10
3
+ Version: 0.0.12
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,10 +44,9 @@ 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: masterpiece>=0.1.21
48
- Requires-Dist: masterpiece_influx>=0.0.2
49
- Requires-Dist: masterpiece_pahomqtt>=0.0.3
50
- Requires-Dist: juham_core>=0.0.7
47
+ Requires-Dist: masterpiece_influx>=0.1.9
48
+ Requires-Dist: masterpiece_pahomqtt>=0.1.5
49
+ Requires-Dist: juham_core>=0.1.1
51
50
  Requires-Dist: requests>=2.31
52
51
  Requires-Dist: pytz>=2024.1
53
52
  Provides-Extra: dev
@@ -19,30 +19,24 @@ class HotWaterOptimizer(Juham):
19
19
  water radiators. Reads spot prices, electricity forecast and temperatures to minimize electricity bill.
20
20
  Additional control over heating is provided by the following attributes
21
21
 
22
- Attributes:
23
- schedule_start_hour (float): hour heating can start, in local time
24
- schedule_stop_hour (float): hour heating is forced to stop
25
- start_hour (float): start_hour (int): ordinal of the first allowed electricity price slot to be consumed
26
- num_hours (int): the number of hour slots allowed
27
-
28
22
  Computes UOI - optimization utilization index for each hour, based on the spot price and the solar power forecast.
29
23
  Value of 0 means the hour is expensive, value of 1 means the hour is free. The UOI threshold determines the slots
30
24
  that are allowed to be consumed.
31
25
 
32
26
 
33
27
  """
34
-
35
- maximum_boiler_temperature = 70
36
- minimum_boiler_temperature = 40
28
+ #: Description of the attribute
29
+ maximum_boiler_temperature : float = 70
30
+ minimum_boiler_temperature : float = 40
37
31
  energy_balancing_interval: float = 3600
38
- radiator_power = 3000 # 3 kW
39
- operation_threshold = 5 * 60
40
- heating_hours_per_day = 4 # use the four cheapest hours per day
32
+ radiator_power : float = 3000
33
+ operation_threshold : float = 5 * 60
34
+ heating_hours_per_day : float = 4
41
35
  schedule_start_hour: float = 0
42
36
  schedule_stop_hour: float = 0
43
- timezone = "Europe/Helsinki"
44
- expected_average_price = 0.2 # 20 eur per kWh
45
- uoi_threshold = 0.8
37
+ timezone : str = "Europe/Helsinki"
38
+ expected_average_price : float = 0.2
39
+ uoi_threshold : float = 0.8
46
40
 
47
41
  def __init__(
48
42
  self,
@@ -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 'spot' topic.
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
- ts = time.mktime(time.strptime(e["DateTime"], "%Y-%m-%dT%H:%M:%S%z"))
56
- hour = datetime.utcfromtimestamp(ts).strftime("%H")
57
- total_price: float
58
- grid_cost: float
59
- if int(hour) < 22 and int(hour) >= 6:
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
- total_price = e["PriceWithTax"] + grid_cost + self.grid_cost_tax
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": grid_cost + self.grid_cost_tax,
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["_spothintafi"] = {
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 "_spothintafi" in data:
133
- for key, value in data["_spothintafi"].items():
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.10
3
+ Version: 0.0.12
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,10 +44,9 @@ 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: masterpiece>=0.1.21
48
- Requires-Dist: masterpiece_influx>=0.0.2
49
- Requires-Dist: masterpiece_pahomqtt>=0.0.3
50
- Requires-Dist: juham_core>=0.0.7
47
+ Requires-Dist: masterpiece_influx>=0.1.9
48
+ Requires-Dist: masterpiece_pahomqtt>=0.1.5
49
+ Requires-Dist: juham_core>=0.1.1
51
50
  Requires-Dist: requests>=2.31
52
51
  Requires-Dist: pytz>=2024.1
53
52
  Provides-Extra: dev
@@ -0,0 +1,42 @@
1
+ LICENSE.rst
2
+ MANIFEST.in
3
+ README.rst
4
+ pyproject.toml
5
+ examples/myapp.py
6
+ juham_automation/__init__.py
7
+ juham_automation/japp.py
8
+ juham_automation/py.typed
9
+ juham_automation.egg-info/PKG-INFO
10
+ juham_automation.egg-info/SOURCES.txt
11
+ juham_automation.egg-info/dependency_links.txt
12
+ juham_automation.egg-info/entry_points.txt
13
+ juham_automation.egg-info/requires.txt
14
+ juham_automation.egg-info/top_level.txt
15
+ juham_automation/automation/__init__.py
16
+ juham_automation/automation/energycostcalculator.py
17
+ juham_automation/automation/hotwateroptimizer.py
18
+ juham_automation/automation/powermeter_simulator.py
19
+ juham_automation/automation/spothintafi.py
20
+ juham_automation/automation/watercirculator.py
21
+ juham_automation/ts/__init__.py
22
+ juham_automation/ts/electricityprice_ts.py
23
+ juham_automation/ts/energycostcalculator_ts.py
24
+ juham_automation/ts/forecast_ts.py
25
+ juham_automation/ts/log_ts.py
26
+ juham_automation/ts/power_ts.py
27
+ juham_automation/ts/powermeter_ts.py
28
+ juham_automation/ts/powerplan_ts.py
29
+ tests/__init__.py
30
+ tests/test_japp.py
31
+ tests/automation/__init__.py
32
+ tests/automation/test_energycostcalculator.py
33
+ tests/automation/test_hotwateroptimizer.py
34
+ tests/automation/test_juham.py
35
+ tests/automation/test_spothintafi.py
36
+ tests/ts/__init__.py
37
+ tests/ts/test_energycostcalculator_ts.py
38
+ tests/ts/test_forecast_ts.py
39
+ tests/ts/test_log_ts.py
40
+ tests/ts/test_power_ts.py
41
+ tests/ts/test_powermeter_ts.py
42
+ tests/ts/test_powerplan_ts.py
@@ -0,0 +1,9 @@
1
+ masterpiece_influx>=0.1.9
2
+ masterpiece_pahomqtt>=0.1.5
3
+ juham_core>=0.1.1
4
+ requests>=2.31
5
+ pytz>=2024.1
6
+
7
+ [dev]
8
+ check-manifest
9
+ types-pyz
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "juham-automation"
8
- version = "0.0.10"
8
+ version = "0.0.12"
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,10 +27,9 @@ classifiers = [
27
27
  ]
28
28
 
29
29
  dependencies = [
30
- "masterpiece >= 0.1.21",
31
- "masterpiece_influx >= 0.0.2",
32
- "masterpiece_pahomqtt >= 0.0.3",
33
- "juham_core >= 0.0.7",
30
+ "masterpiece_influx >= 0.1.9",
31
+ "masterpiece_pahomqtt >= 0.1.5",
32
+ "juham_core >= 0.1.1",
34
33
  "requests >= 2.31",
35
34
  "pytz >= 2024.1",
36
35
  ]
@@ -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,4 +0,0 @@
1
- # Sphinx build info version 1
2
- # This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
3
- config: 7048f60e49aacf57039dd4753bf8844f
4
- tags: 645f666f9bcd5a90fca523b33c5a78b7
@@ -1,4 +0,0 @@
1
- # Sphinx build info version 1
2
- # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3
- config: 64f67e183e88374ef9504a7d68e8136b
4
- tags: 645f666f9bcd5a90fca523b33c5a78b7
File without changes
@@ -1,148 +0,0 @@
1
-
2
- <!DOCTYPE html>
3
-
4
- <html lang="en" data-content_root="../">
5
- <head>
6
- <meta charset="utf-8" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
- <title>Overview: module code &#8212; juham documentation</title>
9
- <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
10
- <link rel="stylesheet" type="text/css" href="../_static/bootstrap-sphinx.css?v=4468db6d" />
11
- <link rel="stylesheet" type="text/css" href="../_static/graphviz.css?v=fd3f3429" />
12
- <link rel="stylesheet" type="text/css" href="../_static/juham.css?v=7a3aeb84" />
13
- <script src="../_static/documentation_options.js?v=5929fcd5"></script>
14
- <script src="../_static/doctools.js?v=9a2dae69"></script>
15
- <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
16
- <link rel="index" title="Index" href="../genindex.html" />
17
- <link rel="search" title="Search" href="../search.html" />
18
- <meta charset='utf-8'>
19
- <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
20
- <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
21
- <meta name="apple-mobile-web-app-capable" content="yes">
22
- <script type="text/javascript" src="../_static/js/jquery-1.12.4.min.js"></script>
23
- <script type="text/javascript" src="../_static/js/jquery-fix.js"></script>
24
- <script type="text/javascript" src="../_static/bootstrap-3.4.1/js/bootstrap.min.js"></script>
25
- <script type="text/javascript" src="../_static/bootstrap-sphinx.js"></script>
26
-
27
- </head><body>
28
-
29
- <div id="navbar" class="navbar navbar-default navbar-fixed-top">
30
- <div class="container">
31
- <div class="navbar-header">
32
- <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
33
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
34
- <span class="icon-bar"></span>
35
- <span class="icon-bar"></span>
36
- <span class="icon-bar"></span>
37
- </button>
38
- <a class="navbar-brand" href="../index.html">
39
- juham</a>
40
- <span class="navbar-text navbar-version pull-left"><b></b></span>
41
- </div>
42
-
43
- <div class="collapse navbar-collapse nav-collapse">
44
- <ul class="nav navbar-nav">
45
-
46
-
47
- <li class="dropdown globaltoc-container">
48
- <a role="button"
49
- id="dLabelGlobalToc"
50
- data-toggle="dropdown"
51
- data-target="#"
52
- href="../index.html">Site <b class="caret"></b></a>
53
- <ul class="dropdown-menu globaltoc"
54
- role="menu"
55
- aria-labelledby="dLabelGlobalToc"><p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
56
- <ul>
57
- <li class="toctree-l1"><a class="reference internal" href="../juham_automation/index.html">juham_automation</a></li>
58
- </ul>
59
- </ul>
60
- </li>
61
-
62
- <li class="dropdown">
63
- <a role="button"
64
- id="dLabelLocalToc"
65
- data-toggle="dropdown"
66
- data-target="#"
67
- href="#">Page <b class="caret"></b></a>
68
- <ul class="dropdown-menu localtoc"
69
- role="menu"
70
- aria-labelledby="dLabelLocalToc"></ul>
71
- </li>
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
- <li class="hidden-sm"></li>
83
-
84
- </ul>
85
-
86
-
87
-
88
- <form class="navbar-form navbar-right" action="../search.html" method="get">
89
- <div class="form-group">
90
- <input type="text" name="q" class="form-control" placeholder="Search" />
91
- </div>
92
- <input type="hidden" name="check_keywords" value="yes" />
93
- <input type="hidden" name="area" value="default" />
94
- </form>
95
-
96
- </div>
97
- </div>
98
- </div>
99
-
100
- <div class="container">
101
- <div class="row">
102
- <div class="col-md-3">
103
- <div id="sidebar" class="bs-sidenav" role="complementary">
104
- <form action="../search.html" method="get">
105
- <div class="form-group">
106
- <input type="text" name="q" class="form-control" placeholder="Search" />
107
- </div>
108
- <input type="hidden" name="check_keywords" value="yes" />
109
- <input type="hidden" name="area" value="default" />
110
- </form>
111
- </div>
112
- </div>
113
- <div class="body col-md-9 content" role="main">
114
-
115
- <h1>All modules for which code is available</h1>
116
- <ul><li><a href="juham_automation/automation/energycostcalculator.html">juham_automation.automation.energycostcalculator</a></li>
117
- <li><a href="juham_automation/automation/hotwateroptimizer.html">juham_automation.automation.hotwateroptimizer</a></li>
118
- <li><a href="juham_automation/automation/powermeter_simulator.html">juham_automation.automation.powermeter_simulator</a></li>
119
- <li><a href="juham_automation/automation/spothintafi.html">juham_automation.automation.spothintafi</a></li>
120
- <li><a href="juham_automation/automation/watercirculator.html">juham_automation.automation.watercirculator</a></li>
121
- <li><a href="juham_automation/japp.html">juham_automation.japp</a></li>
122
- <li><a href="juham_automation/ts/electricityprice_ts.html">juham_automation.ts.electricityprice_ts</a></li>
123
- <li><a href="juham_automation/ts/energycostcalculator_ts.html">juham_automation.ts.energycostcalculator_ts</a></li>
124
- <li><a href="juham_automation/ts/forecast_ts.html">juham_automation.ts.forecast_ts</a></li>
125
- <li><a href="juham_automation/ts/log_ts.html">juham_automation.ts.log_ts</a></li>
126
- <li><a href="juham_automation/ts/power_ts.html">juham_automation.ts.power_ts</a></li>
127
- <li><a href="juham_automation/ts/powermeter_ts.html">juham_automation.ts.powermeter_ts</a></li>
128
- <li><a href="juham_automation/ts/powerplan_ts.html">juham_automation.ts.powerplan_ts</a></li>
129
- </ul>
130
-
131
- </div>
132
-
133
- </div>
134
- </div>
135
- <footer class="footer">
136
- <div class="container">
137
- <p class="pull-right">
138
- <a href="#">Back to top</a>
139
-
140
- </p>
141
- <p>
142
- &copy; Copyright 2024, juha meskanen.<br/>
143
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 7.3.7.<br/>
144
- </p>
145
- </div>
146
- </footer>
147
- </body>
148
- </html>