juham-automation 0.0.2__tar.gz → 0.0.4__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 (177) hide show
  1. {juham_automation-0.0.2 → juham_automation-0.0.4}/PKG-INFO +1 -1
  2. juham_automation-0.0.4/examples/myapp.log +252 -0
  3. juham_automation-0.0.4/examples/myapp.py +37 -0
  4. juham_automation-0.0.4/juham_automation/__init__.py +38 -0
  5. juham_automation-0.0.4/juham_automation/automation/__init__.py +21 -0
  6. juham_automation-0.0.4/juham_automation/automation/energycostcalculator.py +266 -0
  7. juham_automation-0.0.4/juham_automation/automation/hotwateroptimizer.py +527 -0
  8. juham_automation-0.0.4/juham_automation/automation/powermeter_simulator.py +139 -0
  9. juham_automation-0.0.4/juham_automation/automation/spothintafi.py +123 -0
  10. juham_automation-0.0.4/juham_automation/automation/watercirculator.py +159 -0
  11. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation/japp.py +9 -15
  12. juham_automation-0.0.4/juham_automation/ts/__init__.py +25 -0
  13. juham_automation-0.0.4/juham_automation/ts/electricityprice_ts.py +47 -0
  14. juham_automation-0.0.4/juham_automation/ts/energycostcalculator_ts.py +43 -0
  15. juham_automation-0.0.4/juham_automation/ts/forecast_ts.py +97 -0
  16. juham_automation-0.0.4/juham_automation/ts/log_ts.py +57 -0
  17. juham_automation-0.0.4/juham_automation/ts/power_ts.py +49 -0
  18. juham_automation-0.0.4/juham_automation/ts/powermeter_ts.py +70 -0
  19. juham_automation-0.0.4/juham_automation/ts/powerplan_ts.py +45 -0
  20. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/PKG-INFO +1 -1
  21. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/SOURCES.txt +16 -1
  22. {juham_automation-0.0.2 → juham_automation-0.0.4}/pyproject.toml +4 -4
  23. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/__pycache__/test_japp.cpython-312.pyc +0 -0
  24. juham_automation-0.0.4/tests/automation/__pycache__/__init__.cpython-312.pyc +0 -0
  25. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/__pycache__/test_energycostcalculator.cpython-312.pyc +0 -0
  26. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/__pycache__/test_hotwateroptimizer.cpython-312.pyc +0 -0
  27. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/__pycache__/test_juham.cpython-312.pyc +0 -0
  28. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/test_japp.py +1 -1
  29. juham_automation-0.0.4/tests/ts/__pycache__/__init__.cpython-312.pyc +0 -0
  30. juham_automation-0.0.4/tests/ts/__pycache__/test_energycostcalculator_ts.cpython-312.pyc +0 -0
  31. juham_automation-0.0.4/tests/ts/__pycache__/test_forecast_ts.cpython-312.pyc +0 -0
  32. juham_automation-0.0.4/tests/ts/__pycache__/test_log_ts.cpython-312.pyc +0 -0
  33. juham_automation-0.0.4/tests/ts/__pycache__/test_power_ts.cpython-312.pyc +0 -0
  34. juham_automation-0.0.4/tests/ts/__pycache__/test_powermeter_ts.cpython-312.pyc +0 -0
  35. juham_automation-0.0.4/tests/ts/__pycache__/test_powerplan_ts.cpython-312.pyc +0 -0
  36. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_energycostcalculator_ts.py +1 -1
  37. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_forecast_ts.py +1 -1
  38. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_log_ts.py +1 -1
  39. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_power_ts.py +1 -1
  40. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_powermeter_ts.py +1 -1
  41. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/test_powerplan_ts.py +1 -1
  42. juham_automation-0.0.2/examples/myhome.py +0 -47
  43. juham_automation-0.0.2/juham_automation/__init__.py +0 -37
  44. juham_automation-0.0.2/tests/automation/__pycache__/__init__.cpython-312.pyc +0 -0
  45. juham_automation-0.0.2/tests/ts/__pycache__/__init__.cpython-312.pyc +0 -0
  46. juham_automation-0.0.2/tests/ts/__pycache__/test_energycostcalculator_ts.cpython-312.pyc +0 -0
  47. juham_automation-0.0.2/tests/ts/__pycache__/test_forecast_ts.cpython-312.pyc +0 -0
  48. juham_automation-0.0.2/tests/ts/__pycache__/test_log_ts.cpython-312.pyc +0 -0
  49. juham_automation-0.0.2/tests/ts/__pycache__/test_power_ts.cpython-312.pyc +0 -0
  50. juham_automation-0.0.2/tests/ts/__pycache__/test_powermeter_ts.cpython-312.pyc +0 -0
  51. juham_automation-0.0.2/tests/ts/__pycache__/test_powerplan_ts.cpython-312.pyc +0 -0
  52. {juham_automation-0.0.2 → juham_automation-0.0.4}/LICENSE.rst +0 -0
  53. {juham_automation-0.0.2 → juham_automation-0.0.4}/MANIFEST.in +0 -0
  54. {juham_automation-0.0.2 → juham_automation-0.0.4}/README.rst +0 -0
  55. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/.buildinfo +0 -0
  56. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/.nojekyll +0 -0
  57. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_images/inheritance-0c6ef089a7a7f411f3d0290bc4290f5c273d8ef6.svg +0 -0
  58. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_images/juham.png +0 -0
  59. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/index.html +0 -0
  60. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/automation/energycostcalculator.html +0 -0
  61. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/automation/hotwateroptimizer.html +0 -0
  62. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/automation/powermeter_simulator.html +0 -0
  63. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/automation/spothintafi.html +0 -0
  64. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/automation/watercirculator.html +0 -0
  65. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/japp.html +0 -0
  66. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/electricityprice_ts.html +0 -0
  67. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/energycostcalculator_ts.html +0 -0
  68. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/forecast_ts.html +0 -0
  69. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/log_ts.html +0 -0
  70. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/power_ts.html +0 -0
  71. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/powermeter_ts.html +0 -0
  72. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_automation/ts/powerplan_ts.html +0 -0
  73. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_core/juham.html +0 -0
  74. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_core/juham_thread.html +0 -0
  75. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/juham_core/juham_ts.html +0 -0
  76. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/masterpiece/application.html +0 -0
  77. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/masterpiece/composite.html +0 -0
  78. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_modules/masterpiece/masterpiece.html +0 -0
  79. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_sources/index.rst.txt +0 -0
  80. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_sources/juham_automation/index.rst.txt +0 -0
  81. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/basic.css +0 -0
  82. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap-responsive.css +0 -0
  83. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css +0 -0
  84. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap.css +0 -0
  85. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/css/bootstrap.min.css +0 -0
  86. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png +0 -0
  87. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/img/glyphicons-halflings.png +0 -0
  88. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/js/bootstrap.js +0 -0
  89. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-2.3.2/js/bootstrap.min.js +0 -0
  90. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.css +0 -0
  91. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.css.map +0 -0
  92. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css +0 -0
  93. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css.map +0 -0
  94. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.css +0 -0
  95. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.css.map +0 -0
  96. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.min.css +0 -0
  97. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/css/bootstrap.min.css.map +0 -0
  98. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot +0 -0
  99. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg +0 -0
  100. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf +0 -0
  101. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff +0 -0
  102. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 +0 -0
  103. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/js/bootstrap.js +0 -0
  104. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/js/bootstrap.min.js +0 -0
  105. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-3.4.1/js/npm.js +0 -0
  106. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-sphinx.css +0 -0
  107. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootstrap-sphinx.js +0 -0
  108. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/amelia/bootstrap.min.css +0 -0
  109. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/cerulean/bootstrap.min.css +0 -0
  110. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/cosmo/bootstrap.min.css +0 -0
  111. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/cyborg/bootstrap.min.css +0 -0
  112. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/flatly/bootstrap.min.css +0 -0
  113. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png +0 -0
  114. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/img/glyphicons-halflings.png +0 -0
  115. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/journal/bootstrap.min.css +0 -0
  116. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/readable/bootstrap.min.css +0 -0
  117. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/simplex/bootstrap.min.css +0 -0
  118. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/slate/bootstrap.min.css +0 -0
  119. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/spacelab/bootstrap.min.css +0 -0
  120. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/spruce/bootstrap.min.css +0 -0
  121. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/superhero/bootstrap.min.css +0 -0
  122. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-2.3.2/united/bootstrap.min.css +0 -0
  123. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/cerulean/bootstrap.min.css +0 -0
  124. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/cosmo/bootstrap.min.css +0 -0
  125. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/cyborg/bootstrap.min.css +0 -0
  126. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/darkly/bootstrap.min.css +0 -0
  127. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/flatly/bootstrap.min.css +0 -0
  128. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.eot +0 -0
  129. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.svg +0 -0
  130. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.ttf +0 -0
  131. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff +0 -0
  132. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff2 +0 -0
  133. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/journal/bootstrap.min.css +0 -0
  134. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/lumen/bootstrap.min.css +0 -0
  135. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/paper/bootstrap.min.css +0 -0
  136. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/readable/bootstrap.min.css +0 -0
  137. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/sandstone/bootstrap.min.css +0 -0
  138. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/simplex/bootstrap.min.css +0 -0
  139. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/slate/bootstrap.min.css +0 -0
  140. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/spacelab/bootstrap.min.css +0 -0
  141. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/superhero/bootstrap.min.css +0 -0
  142. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/united/bootstrap.min.css +0 -0
  143. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/bootswatch-3.4.1/yeti/bootstrap.min.css +0 -0
  144. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/doctools.js +0 -0
  145. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/documentation_options.js +0 -0
  146. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/file.png +0 -0
  147. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/graphviz.css +0 -0
  148. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/js/jquery-1.12.4.min.js +0 -0
  149. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/js/jquery-fix.js +0 -0
  150. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/juham.css +0 -0
  151. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/juham.png +0 -0
  152. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/language_data.js +0 -0
  153. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/minus.png +0 -0
  154. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/plus.png +0 -0
  155. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/pygments.css +0 -0
  156. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/searchtools.js +0 -0
  157. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/_static/sphinx_highlight.js +0 -0
  158. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/genindex.html +0 -0
  159. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/index.html +0 -0
  160. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/juham_automation/index.html +0 -0
  161. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/objects.inv +0 -0
  162. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/py-modindex.html +0 -0
  163. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/search.html +0 -0
  164. {juham_automation-0.0.2 → juham_automation-0.0.4}/docs/build/html/searchindex.js +0 -0
  165. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation/py.typed +0 -0
  166. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/dependency_links.txt +0 -0
  167. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/entry_points.txt +0 -0
  168. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/requires.txt +0 -0
  169. {juham_automation-0.0.2 → juham_automation-0.0.4}/juham_automation.egg-info/top_level.txt +0 -0
  170. {juham_automation-0.0.2 → juham_automation-0.0.4}/setup.cfg +0 -0
  171. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/__init__.py +0 -0
  172. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/__init__.py +0 -0
  173. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/__pycache__/test_powermeter_simulator.cpython-312.pyc +0 -0
  174. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/test_energycostcalculator.py +0 -0
  175. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/test_hotwateroptimizer.py +0 -0
  176. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/automation/test_juham.py +0 -0
  177. {juham_automation-0.0.2 → juham_automation-0.0.4}/tests/ts/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: juham-automation
3
- Version: 0.0.2
3
+ Version: 0.0.4
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>
@@ -0,0 +1,252 @@
1
+ 2025-02-16 07:51:17,702 [INFO ] MyApp : Configuration files in ~/.myapp/config
2
+ 2025-02-16 07:51:20,734 [INFO ] Influx : Class Influx initialized
3
+ 2025-02-16 07:51:20,736 [INFO ] PlugMaster : myapp : Plugin Influx loaded
4
+ 2025-02-16 07:51:20,929 [INFO ] PahoMqtt : Class PahoMqtt initialized
5
+ 2025-02-16 07:51:20,931 [INFO ] PlugMaster : myapp : Plugin PahoMqtt loaded
6
+ 2025-02-16 07:51:20,997 [INFO ] OpenWeatherMapThread : Class OpenWeatherMapThread initialized
7
+ 2025-02-16 07:51:20,999 [INFO ] OpenWeatherMap : Class OpenWeatherMap initialized
8
+ 2025-02-16 07:51:21,002 [INFO ] PlugMaster : myapp : Plugin OpenWeatherMap loaded
9
+ 2025-02-16 07:51:21,024 [INFO ] VisualCrossingThread : Class VisualCrossingThread initialized
10
+ 2025-02-16 07:51:21,026 [INFO ] VisualCrossing : Class VisualCrossing initialized
11
+ 2025-02-16 07:51:21,031 [INFO ] PlugMaster : myapp : Plugin VisualCrossing loaded
12
+ 2025-02-16 07:51:21,035 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
13
+ 2025-02-16 07:51:21,038 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
14
+ 2025-02-16 07:51:21,041 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
15
+ 2025-02-16 07:51:21,046 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
16
+ 2025-02-16 07:51:21,050 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
17
+ 2025-02-16 07:51:21,053 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
18
+ 2025-02-16 07:51:21,057 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
19
+ 2025-02-16 07:51:21,061 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
20
+ 2025-02-16 07:51:21,065 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
21
+ 2025-02-16 07:51:21,068 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
22
+ 2025-02-16 07:51:21,071 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
23
+ 2025-02-16 07:51:21,075 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
24
+ 2025-02-16 07:51:21,078 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
25
+ 2025-02-16 07:51:21,082 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
26
+ 2025-02-16 07:51:21,085 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
27
+ 2025-02-16 07:51:21,090 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
28
+ 2025-02-16 07:51:21,093 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
29
+ 2025-02-16 07:51:21,097 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
30
+ 2025-02-16 07:51:21,106 [INFO ] HomeWizardWaterMeterThread : Class HomeWizardWaterMeterThread initialized
31
+ 2025-02-16 07:51:21,107 [INFO ] HomeWizardWaterMeter : Class HomeWizardWaterMeter initialized
32
+ 2025-02-16 07:51:21,110 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: module 'juham_homewizard' has no attribute 'HomewizardWaterMeter'
33
+ 2025-02-16 07:56:17,335 [INFO ] MyApp : --init requested, creating class configuration files
34
+ 2025-02-16 07:56:17,336 [INFO ] MyApp : Configuration files in ~/.myapp/config
35
+ 2025-02-16 07:56:17,338 [INFO ] MyApp : --init specified, class configuration files will be created upon exit
36
+ 2025-02-16 07:56:17,826 [INFO ] Influx : Class Influx initialized
37
+ 2025-02-16 07:56:17,828 [INFO ] PlugMaster : myapp : Plugin Influx loaded
38
+ 2025-02-16 07:56:17,918 [INFO ] PahoMqtt : Class PahoMqtt initialized
39
+ 2025-02-16 07:56:17,920 [INFO ] PlugMaster : myapp : Plugin PahoMqtt loaded
40
+ 2025-02-16 07:56:17,966 [INFO ] OpenWeatherMapThread : Class OpenWeatherMapThread initialized
41
+ 2025-02-16 07:56:17,968 [INFO ] OpenWeatherMap : Class OpenWeatherMap initialized
42
+ 2025-02-16 07:56:17,971 [INFO ] PlugMaster : myapp : Plugin OpenWeatherMap loaded
43
+ 2025-02-16 07:56:17,975 [INFO ] VisualCrossingThread : Class VisualCrossingThread initialized
44
+ 2025-02-16 07:56:17,977 [INFO ] VisualCrossing : Class VisualCrossing initialized
45
+ 2025-02-16 07:56:17,978 [INFO ] PlugMaster : myapp : Plugin VisualCrossing loaded
46
+ 2025-02-16 07:56:17,984 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
47
+ 2025-02-16 07:56:17,988 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
48
+ 2025-02-16 07:56:17,991 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
49
+ 2025-02-16 07:56:17,994 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
50
+ 2025-02-16 07:56:17,998 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
51
+ 2025-02-16 07:56:18,002 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
52
+ 2025-02-16 07:56:18,006 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
53
+ 2025-02-16 07:56:18,009 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
54
+ 2025-02-16 07:56:18,012 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
55
+ 2025-02-16 07:56:18,016 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
56
+ 2025-02-16 07:56:18,020 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
57
+ 2025-02-16 07:56:18,023 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
58
+ 2025-02-16 07:56:18,026 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
59
+ 2025-02-16 07:56:18,030 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
60
+ 2025-02-16 07:56:18,034 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
61
+ 2025-02-16 07:56:18,037 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
62
+ 2025-02-16 07:56:18,042 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
63
+ 2025-02-16 07:56:18,045 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
64
+ 2025-02-16 07:56:18,050 [INFO ] HomeWizardWaterMeterThread : Class HomeWizardWaterMeterThread initialized
65
+ 2025-02-16 07:56:18,051 [INFO ] HomeWizardWaterMeter : Class HomeWizardWaterMeter initialized
66
+ 2025-02-16 07:56:18,053 [INFO ] PlugMaster : myapp : Plugin HomeWizardWaterMeter loaded
67
+ 2025-02-16 07:56:26,368 [ERROR] PlugMaster : myapp : Failed to load plugin <class 'importlib.metadata.EntryPoint'>: No module named 'juham'
68
+ 2025-02-16 07:56:26,383 [INFO ] Shelly : Class Shelly initialized
69
+ 2025-02-16 07:56:26,384 [INFO ] ShellyMotionSimulatorThread : Class ShellyMotionSimulatorThread initialized
70
+ 2025-02-16 07:56:26,385 [INFO ] ShellyMotionSimulator : Class ShellyMotionSimulator initialized
71
+ 2025-02-16 07:56:26,390 [INFO ] ShellyPlusAddOnSimulatorThread : Class ShellyPlusAddOnSimulatorThread initialized
72
+ 2025-02-16 07:56:26,391 [INFO ] ShellyPlusAddOnSimulator : Class ShellyPlusAddOnSimulator initialized
73
+ 2025-02-16 07:56:26,397 [INFO ] ShellyMotion : Class ShellyMotion initialized
74
+ 2025-02-16 07:56:26,402 [INFO ] ShellyDS18B20 : Class ShellyDS18B20 initialized
75
+ 2025-02-16 07:56:26,406 [INFO ] Shelly1G3 : Class Shelly1G3 initialized
76
+ 2025-02-16 07:56:26,410 [INFO ] ShellyPlus1 : Class ShellyPlus1 initialized
77
+ 2025-02-16 07:56:26,414 [INFO ] ShellyPro3EM : Class ShellyPro3EM initialized
78
+ 2025-02-16 07:56:26,419 [INFO ] ShellyPro3 : Class ShellyPro3 initialized
79
+ 2025-02-16 07:56:26,422 [INFO ] ShellyDHT22 : Class ShellyDHT22 initialized
80
+ 2025-02-16 07:56:26,423 [INFO ] PlugMaster : myapp : Plugin Shelly loaded
81
+ 2025-02-16 07:56:26,426 [INFO ] PlugMaster : myapp : Plugin Shelly1G3 loaded
82
+ 2025-02-16 07:56:26,428 [INFO ] PlugMaster : myapp : Plugin ShellyDHT22 loaded
83
+ 2025-02-16 07:56:26,429 [INFO ] PlugMaster : myapp : Plugin ShellyDS18B20 loaded
84
+ 2025-02-16 07:56:26,430 [INFO ] PlugMaster : myapp : Plugin ShellyMotion loaded
85
+ 2025-02-16 07:56:26,431 [INFO ] PlugMaster : myapp : Plugin ShellyPlus1 loaded
86
+ 2025-02-16 07:56:26,433 [INFO ] PlugMaster : myapp : Plugin ShellyPro3 loaded
87
+ 2025-02-16 07:56:26,434 [INFO ] PlugMaster : myapp : Plugin ShellyPro3EM loaded
88
+ 2025-02-16 07:56:26,435 [INFO ] PlugMaster : myapp : Plugin SystemStatus loaded
89
+ 2025-02-16 07:56:26,874 [INFO ] WebCameraThread : Class WebCameraThread initialized
90
+ 2025-02-16 07:56:26,876 [INFO ] WebCamera : Class WebCamera initialized
91
+ 2025-02-16 07:56:26,974 [INFO ] WaterMeterThreadOCR : Class WaterMeterThreadOCR initialized
92
+ 2025-02-16 07:56:26,976 [INFO ] WaterMeterOCR : Class WaterMeterOCR initialized
93
+ 2025-02-16 07:56:26,985 [INFO ] WaterMeterThreadImgDiff : Class WaterMeterThreadImgDiff initialized
94
+ 2025-02-16 07:56:26,986 [INFO ] WaterMeterImgDiff : Class WaterMeterImgDiff initialized
95
+ 2025-02-16 07:56:26,990 [INFO ] WaterMeterTs : Class WaterMeterTs initialized
96
+ 2025-02-16 07:56:26,993 [INFO ] LeakDetector : Class LeakDetector initialized
97
+ 2025-02-16 07:56:26,996 [INFO ] PlugMaster : myapp : Plugin WaterMeterImgDiff loaded
98
+ 2025-02-16 07:56:26,997 [INFO ] PlugMaster : myapp : Plugin LeakDetector loaded
99
+ 2025-02-16 07:56:27,001 [INFO ] PlugMaster : myapp : Plugin WaterMeterOCR loaded
100
+ 2025-02-16 07:56:27,002 [INFO ] PlugMaster : myapp : Plugin WaterMeterTs loaded
101
+ 2025-02-16 07:56:27,003 [INFO ] PlugMaster : myapp : Plugin WebCamera loaded
102
+ 2025-02-16 07:56:27,045 [INFO ] PlugMaster : myapp : Class SystemStatus imported into myapp
103
+ 2025-02-16 07:56:27,047 [DEBUG] SystemStatus : systemstatus : System status with name systemstatus created
104
+ 2025-02-16 07:56:27,050 [INFO ] PlugMaster : myapp : Class VisualCrossing imported into myapp
105
+ 2025-02-16 07:56:27,052 [DEBUG] VisualCrossing : visualcrossing : VisualCrossing with name visualcrossing created
106
+ 2025-02-16 07:56:27,053 [INFO ] PlugMaster : myapp : Class OpenWeatherMap imported into myapp
107
+ 2025-02-16 07:56:27,090 [INFO ] MyApp : Saving configuration
108
+ 2025-02-16 07:56:27,095 [ERROR] MyApp : Error in saving MasterPiece:C:\Users\juham\.myapp\config\MasterPiece.json Object of type property is not JSON serializable
109
+ 2025-02-16 07:56:27,097 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Composite.json saved
110
+ 2025-02-16 07:56:27,100 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PlugMaster.json saved
111
+ 2025-02-16 07:56:27,102 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Application.json saved
112
+ 2025-02-16 07:56:27,106 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\JsonFormat.json saved
113
+ 2025-02-16 07:56:27,108 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\MasterPieceThread.json saved
114
+ 2025-02-16 07:56:27,110 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\TimeSeries.json saved
115
+ 2025-02-16 07:56:27,111 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Juham.json saved
116
+ 2025-02-16 07:56:27,113 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\JuhamTs.json saved
117
+ 2025-02-16 07:56:27,114 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\JuhamThread.json saved
118
+ 2025-02-16 07:56:27,117 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\JuhamCloudThread.json saved
119
+ 2025-02-16 07:56:27,121 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\EnergyCostCalculator.json saved
120
+ 2025-02-16 07:56:27,123 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\SpotHintaFiThread.json saved
121
+ 2025-02-16 07:56:27,126 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\SpotHintaFi.json saved
122
+ 2025-02-16 07:56:27,127 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterCirculator.json saved
123
+ 2025-02-16 07:56:27,129 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\HotWaterOptimizer.json saved
124
+ 2025-02-16 07:56:27,130 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PowerMeterSimulatorThread.json saved
125
+ 2025-02-16 07:56:27,133 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PowerMeterSimulator.json saved
126
+ 2025-02-16 07:56:27,135 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\EnergyCostCalculatorTs.json saved
127
+ 2025-02-16 07:56:27,137 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ForecastTs.json saved
128
+ 2025-02-16 07:56:27,140 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\LogTs.json saved
129
+ 2025-02-16 07:56:27,141 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PowerTs.json saved
130
+ 2025-02-16 07:56:27,143 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PowerPlanTs.json saved
131
+ 2025-02-16 07:56:27,144 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\PowerMeterTs.json saved
132
+ 2025-02-16 07:56:27,146 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ElectricityPriceTs.json saved
133
+ 2025-02-16 07:56:27,147 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\SystemStatusThread.json saved
134
+ 2025-02-16 07:56:27,150 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\SystemStatus.json saved
135
+ 2025-02-16 07:56:27,152 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Influx.json saved
136
+ 2025-02-16 07:56:27,156 [ERROR] MyApp : Error in saving PahoMqtt:C:\Users\juham\.myapp\config\PahoMqtt.json Object of type property is not JSON serializable
137
+ 2025-02-16 07:56:27,157 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\OpenWeatherMapThread.json saved
138
+ 2025-02-16 07:56:27,158 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\OpenWeatherMap.json saved
139
+ 2025-02-16 07:56:27,159 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\VisualCrossingThread.json saved
140
+ 2025-02-16 07:56:27,161 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\VisualCrossing.json saved
141
+ 2025-02-16 07:56:27,162 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\HomeWizardWaterMeterThread.json saved
142
+ 2025-02-16 07:56:27,164 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\HomeWizardWaterMeter.json saved
143
+ 2025-02-16 07:56:27,166 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Shelly.json saved
144
+ 2025-02-16 07:56:27,168 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyMotionSimulatorThread.json saved
145
+ 2025-02-16 07:56:27,172 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyMotionSimulator.json saved
146
+ 2025-02-16 07:56:27,173 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyPlusAddOnSimulatorThread.json saved
147
+ 2025-02-16 07:56:27,175 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyPlusAddOnSimulator.json saved
148
+ 2025-02-16 07:56:27,177 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyMotion.json saved
149
+ 2025-02-16 07:56:27,178 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyDS18B20.json saved
150
+ 2025-02-16 07:56:27,179 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\Shelly1G3.json saved
151
+ 2025-02-16 07:56:27,180 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyPlus1.json saved
152
+ 2025-02-16 07:56:27,183 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyPro3EM.json saved
153
+ 2025-02-16 07:56:27,186 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyPro3.json saved
154
+ 2025-02-16 07:56:27,189 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\ShellyDHT22.json saved
155
+ 2025-02-16 07:56:27,190 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WebCameraThread.json saved
156
+ 2025-02-16 07:56:27,191 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WebCamera.json saved
157
+ 2025-02-16 07:56:27,193 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterMeterThreadOCR.json saved
158
+ 2025-02-16 07:56:27,195 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterMeterOCR.json saved
159
+ 2025-02-16 07:56:27,196 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterMeterThreadImgDiff.json saved
160
+ 2025-02-16 07:56:27,198 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterMeterImgDiff.json saved
161
+ 2025-02-16 07:56:27,202 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\WaterMeterTs.json saved
162
+ 2025-02-16 07:56:27,204 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\config\LeakDetector.json saved
163
+ 2025-02-16 07:59:14,869 [INFO ] MyApp : --init requested, creating class configuration files
164
+ 2025-02-16 07:59:14,870 [INFO ] MyApp : Configuration files in ~/.myapp/config
165
+ 2025-02-16 07:59:14,871 [INFO ] MyApp : --init specified, class configuration files will be created upon exit
166
+ 2025-02-16 08:27:54,443 [INFO ] MyApp : --init requested, creating class configuration files
167
+ 2025-02-16 08:27:54,445 [INFO ] MyApp : Configuration files in ~/.myapp/foo
168
+ 2025-02-16 08:27:54,445 [INFO ] MyApp : --init specified, class configuration files will be created upon exit
169
+ 2025-02-16 08:27:54,472 [INFO ] MyApp : Saving configuration
170
+ 2025-02-16 08:27:54,474 [ERROR] MyApp : Error in saving MasterPiece:C:\Users\juham\.myapp\foo\MasterPiece.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\MasterPiece.json'
171
+ 2025-02-16 08:27:54,476 [ERROR] MyApp : Error in saving Composite:C:\Users\juham\.myapp\foo\Composite.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Composite.json'
172
+ 2025-02-16 08:27:54,476 [ERROR] MyApp : Error in saving PlugMaster:C:\Users\juham\.myapp\foo\PlugMaster.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PlugMaster.json'
173
+ 2025-02-16 08:27:54,478 [ERROR] MyApp : Error in saving Application:C:\Users\juham\.myapp\foo\Application.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Application.json'
174
+ 2025-02-16 08:27:54,479 [ERROR] MyApp : Error in saving JsonFormat:C:\Users\juham\.myapp\foo\JsonFormat.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JsonFormat.json'
175
+ 2025-02-16 08:27:54,481 [ERROR] MyApp : Error in saving MasterPieceThread:C:\Users\juham\.myapp\foo\MasterPieceThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\MasterPieceThread.json'
176
+ 2025-02-16 08:27:54,483 [ERROR] MyApp : Error in saving TimeSeries:C:\Users\juham\.myapp\foo\TimeSeries.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\TimeSeries.json'
177
+ 2025-02-16 08:27:54,486 [ERROR] MyApp : Error in saving Juham:C:\Users\juham\.myapp\foo\Juham.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Juham.json'
178
+ 2025-02-16 08:27:54,487 [ERROR] MyApp : Error in saving JuhamTs:C:\Users\juham\.myapp\foo\JuhamTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamTs.json'
179
+ 2025-02-16 08:27:54,489 [ERROR] MyApp : Error in saving JuhamThread:C:\Users\juham\.myapp\foo\JuhamThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamThread.json'
180
+ 2025-02-16 08:27:54,491 [ERROR] MyApp : Error in saving JuhamCloudThread:C:\Users\juham\.myapp\foo\JuhamCloudThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamCloudThread.json'
181
+ 2025-02-16 08:27:54,492 [ERROR] MyApp : Error in saving EnergyCostCalculator:C:\Users\juham\.myapp\foo\EnergyCostCalculator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\EnergyCostCalculator.json'
182
+ 2025-02-16 08:27:54,493 [ERROR] MyApp : Error in saving SpotHintaFiThread:C:\Users\juham\.myapp\foo\SpotHintaFiThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\SpotHintaFiThread.json'
183
+ 2025-02-16 08:27:54,494 [ERROR] MyApp : Error in saving SpotHintaFi:C:\Users\juham\.myapp\foo\SpotHintaFi.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\SpotHintaFi.json'
184
+ 2025-02-16 08:27:54,495 [ERROR] MyApp : Error in saving WaterCirculator:C:\Users\juham\.myapp\foo\WaterCirculator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\WaterCirculator.json'
185
+ 2025-02-16 08:27:54,498 [ERROR] MyApp : Error in saving HotWaterOptimizer:C:\Users\juham\.myapp\foo\HotWaterOptimizer.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\HotWaterOptimizer.json'
186
+ 2025-02-16 08:27:54,502 [ERROR] MyApp : Error in saving PowerMeterSimulatorThread:C:\Users\juham\.myapp\foo\PowerMeterSimulatorThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterSimulatorThread.json'
187
+ 2025-02-16 08:27:54,503 [ERROR] MyApp : Error in saving PowerMeterSimulator:C:\Users\juham\.myapp\foo\PowerMeterSimulator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterSimulator.json'
188
+ 2025-02-16 08:27:54,504 [ERROR] MyApp : Error in saving EnergyCostCalculatorTs:C:\Users\juham\.myapp\foo\EnergyCostCalculatorTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\EnergyCostCalculatorTs.json'
189
+ 2025-02-16 08:27:54,506 [ERROR] MyApp : Error in saving ForecastTs:C:\Users\juham\.myapp\foo\ForecastTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\ForecastTs.json'
190
+ 2025-02-16 08:27:54,507 [ERROR] MyApp : Error in saving LogTs:C:\Users\juham\.myapp\foo\LogTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\LogTs.json'
191
+ 2025-02-16 08:27:54,509 [ERROR] MyApp : Error in saving PowerTs:C:\Users\juham\.myapp\foo\PowerTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerTs.json'
192
+ 2025-02-16 08:27:54,510 [ERROR] MyApp : Error in saving PowerPlanTs:C:\Users\juham\.myapp\foo\PowerPlanTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerPlanTs.json'
193
+ 2025-02-16 08:27:54,513 [ERROR] MyApp : Error in saving PowerMeterTs:C:\Users\juham\.myapp\foo\PowerMeterTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterTs.json'
194
+ 2025-02-16 08:27:54,513 [ERROR] MyApp : Error in saving ElectricityPriceTs:C:\Users\juham\.myapp\foo\ElectricityPriceTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\ElectricityPriceTs.json'
195
+ 2025-02-16 08:27:58,786 [INFO ] MyApp : --init requested, creating class configuration files
196
+ 2025-02-16 08:27:58,787 [INFO ] MyApp : Configuration files in ~/.myapp/foo
197
+ 2025-02-16 08:27:58,792 [INFO ] MyApp : --init specified, class configuration files will be created upon exit
198
+ 2025-02-16 08:27:58,813 [INFO ] MyApp : Saving configuration
199
+ 2025-02-16 08:27:58,816 [ERROR] MyApp : Error in saving MasterPiece:C:\Users\juham\.myapp\foo\MasterPiece.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\MasterPiece.json'
200
+ 2025-02-16 08:27:58,820 [ERROR] MyApp : Error in saving Composite:C:\Users\juham\.myapp\foo\Composite.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Composite.json'
201
+ 2025-02-16 08:27:58,821 [ERROR] MyApp : Error in saving PlugMaster:C:\Users\juham\.myapp\foo\PlugMaster.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PlugMaster.json'
202
+ 2025-02-16 08:27:58,823 [ERROR] MyApp : Error in saving Application:C:\Users\juham\.myapp\foo\Application.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Application.json'
203
+ 2025-02-16 08:27:58,825 [ERROR] MyApp : Error in saving JsonFormat:C:\Users\juham\.myapp\foo\JsonFormat.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JsonFormat.json'
204
+ 2025-02-16 08:27:58,826 [ERROR] MyApp : Error in saving MasterPieceThread:C:\Users\juham\.myapp\foo\MasterPieceThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\MasterPieceThread.json'
205
+ 2025-02-16 08:27:58,827 [ERROR] MyApp : Error in saving TimeSeries:C:\Users\juham\.myapp\foo\TimeSeries.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\TimeSeries.json'
206
+ 2025-02-16 08:27:58,828 [ERROR] MyApp : Error in saving Juham:C:\Users\juham\.myapp\foo\Juham.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\Juham.json'
207
+ 2025-02-16 08:27:58,829 [ERROR] MyApp : Error in saving JuhamTs:C:\Users\juham\.myapp\foo\JuhamTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamTs.json'
208
+ 2025-02-16 08:27:58,830 [ERROR] MyApp : Error in saving JuhamThread:C:\Users\juham\.myapp\foo\JuhamThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamThread.json'
209
+ 2025-02-16 08:27:58,832 [ERROR] MyApp : Error in saving JuhamCloudThread:C:\Users\juham\.myapp\foo\JuhamCloudThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\JuhamCloudThread.json'
210
+ 2025-02-16 08:27:58,836 [ERROR] MyApp : Error in saving EnergyCostCalculator:C:\Users\juham\.myapp\foo\EnergyCostCalculator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\EnergyCostCalculator.json'
211
+ 2025-02-16 08:27:58,837 [ERROR] MyApp : Error in saving SpotHintaFiThread:C:\Users\juham\.myapp\foo\SpotHintaFiThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\SpotHintaFiThread.json'
212
+ 2025-02-16 08:27:58,839 [ERROR] MyApp : Error in saving SpotHintaFi:C:\Users\juham\.myapp\foo\SpotHintaFi.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\SpotHintaFi.json'
213
+ 2025-02-16 08:27:58,840 [ERROR] MyApp : Error in saving WaterCirculator:C:\Users\juham\.myapp\foo\WaterCirculator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\WaterCirculator.json'
214
+ 2025-02-16 08:27:58,842 [ERROR] MyApp : Error in saving HotWaterOptimizer:C:\Users\juham\.myapp\foo\HotWaterOptimizer.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\HotWaterOptimizer.json'
215
+ 2025-02-16 08:27:58,843 [ERROR] MyApp : Error in saving PowerMeterSimulatorThread:C:\Users\juham\.myapp\foo\PowerMeterSimulatorThread.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterSimulatorThread.json'
216
+ 2025-02-16 08:27:58,844 [ERROR] MyApp : Error in saving PowerMeterSimulator:C:\Users\juham\.myapp\foo\PowerMeterSimulator.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterSimulator.json'
217
+ 2025-02-16 08:27:58,845 [ERROR] MyApp : Error in saving EnergyCostCalculatorTs:C:\Users\juham\.myapp\foo\EnergyCostCalculatorTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\EnergyCostCalculatorTs.json'
218
+ 2025-02-16 08:27:58,848 [ERROR] MyApp : Error in saving ForecastTs:C:\Users\juham\.myapp\foo\ForecastTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\ForecastTs.json'
219
+ 2025-02-16 08:27:58,851 [ERROR] MyApp : Error in saving LogTs:C:\Users\juham\.myapp\foo\LogTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\LogTs.json'
220
+ 2025-02-16 08:27:58,853 [ERROR] MyApp : Error in saving PowerTs:C:\Users\juham\.myapp\foo\PowerTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerTs.json'
221
+ 2025-02-16 08:27:58,854 [ERROR] MyApp : Error in saving PowerPlanTs:C:\Users\juham\.myapp\foo\PowerPlanTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerPlanTs.json'
222
+ 2025-02-16 08:27:58,855 [ERROR] MyApp : Error in saving PowerMeterTs:C:\Users\juham\.myapp\foo\PowerMeterTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\PowerMeterTs.json'
223
+ 2025-02-16 08:27:58,857 [ERROR] MyApp : Error in saving ElectricityPriceTs:C:\Users\juham\.myapp\foo\ElectricityPriceTs.json [Errno 2] No such file or directory: 'C:\\Users\\juham\\.myapp\\foo\\ElectricityPriceTs.json'
224
+ 2025-02-16 08:28:28,658 [INFO ] MyApp : --init requested, creating class configuration files
225
+ 2025-02-16 08:28:28,659 [INFO ] MyApp : Configuration files in ~/.myapp/foo
226
+ 2025-02-16 08:28:28,662 [INFO ] MyApp : --init specified, class configuration files will be created upon exit
227
+ 2025-02-16 08:28:28,684 [INFO ] MyApp : Saving configuration
228
+ 2025-02-16 08:28:28,689 [ERROR] MyApp : Error in saving MasterPiece:C:\Users\juham\.myapp\foo\MasterPiece.json Object of type property is not JSON serializable
229
+ 2025-02-16 08:28:28,692 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\Composite.json saved
230
+ 2025-02-16 08:28:28,695 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PlugMaster.json saved
231
+ 2025-02-16 08:28:28,699 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\Application.json saved
232
+ 2025-02-16 08:28:28,702 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\JsonFormat.json saved
233
+ 2025-02-16 08:28:28,706 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\MasterPieceThread.json saved
234
+ 2025-02-16 08:28:28,708 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\TimeSeries.json saved
235
+ 2025-02-16 08:28:28,709 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\Juham.json saved
236
+ 2025-02-16 08:28:28,711 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\JuhamTs.json saved
237
+ 2025-02-16 08:28:28,712 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\JuhamThread.json saved
238
+ 2025-02-16 08:28:28,714 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\JuhamCloudThread.json saved
239
+ 2025-02-16 08:28:28,715 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\EnergyCostCalculator.json saved
240
+ 2025-02-16 08:28:28,718 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\SpotHintaFiThread.json saved
241
+ 2025-02-16 08:28:28,722 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\SpotHintaFi.json saved
242
+ 2025-02-16 08:28:28,725 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\WaterCirculator.json saved
243
+ 2025-02-16 08:28:28,726 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\HotWaterOptimizer.json saved
244
+ 2025-02-16 08:28:28,728 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PowerMeterSimulatorThread.json saved
245
+ 2025-02-16 08:28:28,733 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PowerMeterSimulator.json saved
246
+ 2025-02-16 08:28:28,734 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\EnergyCostCalculatorTs.json saved
247
+ 2025-02-16 08:28:28,738 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\ForecastTs.json saved
248
+ 2025-02-16 08:28:28,740 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\LogTs.json saved
249
+ 2025-02-16 08:28:28,742 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PowerTs.json saved
250
+ 2025-02-16 08:28:28,743 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PowerPlanTs.json saved
251
+ 2025-02-16 08:28:28,744 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\PowerMeterTs.json saved
252
+ 2025-02-16 08:28:28,745 [INFO ] MyApp : Configuration file C:\Users\juham\.myapp\foo\ElectricityPriceTs.json saved
@@ -0,0 +1,37 @@
1
+ from typing_extensions import override
2
+
3
+ from juham_automation import JApp
4
+ from juham_automation import PowerMeterSimulator
5
+ from juham_automation import HotWaterOptimizer
6
+
7
+
8
+ class MyApp(JApp):
9
+ """Juham home automation example application."""
10
+
11
+ def __init__(self, name: str = "myapp"):
12
+ """Creates home automation application with the given name."""
13
+ super().__init__(name)
14
+ self.instantiate_classes()
15
+
16
+ @override
17
+ def instantiate_classes(self) -> None:
18
+ super().instantiate_classes()
19
+ # generate simulated energy meter readings
20
+ self.add(PowerMeterSimulator("powerconsumption"))
21
+
22
+ # Heating plan for the main boiler, with shelly's temperature sensor
23
+ self.add(HotWaterOptimizer("boiler", "temperature/102", 0, 3, 0.15))
24
+
25
+ # print the instance hierarchy
26
+ self.print()
27
+
28
+
29
+ def main() -> None:
30
+ id: str = "myapp"
31
+ MyApp.init_app_id(id)
32
+ app: MyApp = MyApp(id)
33
+ app.run_forever()
34
+
35
+
36
+ if __name__ == "__main__":
37
+ main()
@@ -0,0 +1,38 @@
1
+ """
2
+ Description
3
+ ===========
4
+
5
+ Juham - Juha's Ultimate Home Automation Masterpiece
6
+
7
+ """
8
+
9
+ from .automation import EnergyCostCalculator
10
+ from .automation import PowerMeterSimulator
11
+ from .automation import SpotHintaFi
12
+ from .automation import WaterCirculator
13
+ from .automation import HotWaterOptimizer
14
+ from .ts import EnergyCostCalculatorTs
15
+ from .ts import ForecastTs
16
+ from .ts import LogTs
17
+ from .ts import PowerTs
18
+ from .ts import PowerPlanTs
19
+ from .ts import PowerMeterTs
20
+ from .ts import ElectricityPriceTs
21
+ from .japp import JApp
22
+
23
+
24
+ __all__ = [
25
+ "EnergyCostCalculator",
26
+ "EnergyCostCalculatorTs",
27
+ "ForecastTs",
28
+ "HotWaterOptimizer",
29
+ "LogTs",
30
+ "PowerTs",
31
+ "PowerPlanTs",
32
+ "PowerMeterTs",
33
+ "SpotHintaFi",
34
+ "WaterCirculator",
35
+ "JApp",
36
+ "PowerMeterSimulator",
37
+ "ElectricityPriceTs",
38
+ ]
@@ -0,0 +1,21 @@
1
+ """
2
+ Description
3
+ ===========
4
+
5
+ Juham - Juha's Ultimate Home Automation classes
6
+
7
+ """
8
+
9
+ from .energycostcalculator import EnergyCostCalculator
10
+ from .spothintafi import SpotHintaFi
11
+ from .watercirculator import WaterCirculator
12
+ from .hotwateroptimizer import HotWaterOptimizer
13
+ from .powermeter_simulator import PowerMeterSimulator
14
+
15
+ __all__ = [
16
+ "EnergyCostCalculator",
17
+ "HotWaterOptimizer",
18
+ "SpotHintaFi",
19
+ "WaterCirculator",
20
+ "PowerMeterSimulator",
21
+ ]
@@ -0,0 +1,266 @@
1
+ from typing import Any
2
+ from typing_extensions import override
3
+ import json
4
+ from masterpiece.mqtt import MqttMsg
5
+ from juham_core import Juham
6
+ from juham_core.timeutils import (
7
+ elapsed_seconds_in_day,
8
+ elapsed_seconds_in_hour,
9
+ quantize,
10
+ timestamp,
11
+ )
12
+
13
+
14
+ class EnergyCostCalculator(Juham):
15
+ """The EnergyCostCalculator class calculates the net energy balance between produced
16
+ and consumed energy for Time-Based Settlement (TBS). It performs the following functions:
17
+
18
+ * Subscribes to 'spot' and 'power' MQTT topics.
19
+ * Calculates the net energy and the rate of change of the net energy per hour and per day (24h)
20
+ * Publishes the calculated values to the MQTT net energy balance topic.
21
+ * Stores the data in a time series database.
22
+
23
+ This information helps other home automation components optimize energy usage and
24
+ minimize electricity bills.
25
+ """
26
+
27
+ _kwh_to_joule_coeff: float = 1000.0 * 3600
28
+ _joule_to_kwh_coeff: float = 1.0 / _kwh_to_joule_coeff
29
+
30
+ energy_balancing_interval: float = 3600
31
+
32
+ def __init__(self, name: str = "ecc") -> None:
33
+ super().__init__(name)
34
+ self.current_ts: float = 0
35
+ self.total_balance_hour: float = 0
36
+ self.total_balance_day: float = 0
37
+ self.net_energy_balance_cost_hour: float = 0
38
+ self.net_energy_balance_cost_day: float = 0
39
+ self.net_energy_balance_start_hour = elapsed_seconds_in_hour(timestamp())
40
+ self.net_energy_balance_start_day = elapsed_seconds_in_day(timestamp())
41
+ self.spots: list[dict[str, float]] = []
42
+ self.init_topics()
43
+
44
+ def init_topics(self) -> None:
45
+ self.topic_in_spot = self.make_topic_name("spot")
46
+ self.topic_in_powerconsumption = self.make_topic_name("powerconsumption")
47
+ self.topic_out_net_energy_balance = self.make_topic_name("net_energy_balance")
48
+ self.topic_out_energy_cost = self.make_topic_name("net_energy_cost")
49
+
50
+ @override
51
+ def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
52
+ super().on_connect(client, userdata, flags, rc)
53
+ if rc == 0:
54
+ self.subscribe(self.topic_in_spot)
55
+ self.subscribe(self.topic_in_powerconsumption)
56
+
57
+ @override
58
+ def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
59
+ ts_now = timestamp()
60
+
61
+ m = json.loads(msg.payload.decode())
62
+ if msg.topic == self.topic_in_spot:
63
+ self.on_spot(m)
64
+ elif msg.topic == self.topic_in_powerconsumption:
65
+ self.on_powerconsumption(ts_now, m)
66
+ else:
67
+ self.error(f"Unknown event {msg.topic}")
68
+
69
+ def on_spot(self, spot: dict[Any, Any]) -> None:
70
+ """Stores the received per hour electricity prices to spots list.
71
+
72
+ Args:
73
+ spot (list): list of hourly spot prices
74
+ """
75
+
76
+ for s in spot:
77
+ self.spots.append(
78
+ {"Timestamp": s["Timestamp"], "PriceWithTax": s["PriceWithTax"]}
79
+ )
80
+
81
+ def map_kwh_prices_to_joules(self, price: float) -> float:
82
+ """Convert the given electricity price in kWh to Watt seconds (J)
83
+ Args:
84
+ price (float): electricity price given as kWh
85
+ Returns:
86
+ Electricity price per watt second (J)
87
+ """
88
+ return price * self._joule_to_kwh_coeff
89
+
90
+ def get_prices(self, ts_prev: float, ts_now: float) -> tuple[float, float]:
91
+ """Fetch the electricity prices for the given two subsequent time
92
+ stamps.
93
+
94
+ Args:
95
+ ts_prev (float): previous time
96
+ ts_now (float): current time
97
+ Returns:
98
+ Electricity prices for the given interval
99
+ """
100
+ prev_price = None
101
+ current_price = None
102
+
103
+ for i in range(0, len(self.spots) - 1):
104
+ r0 = self.spots[i]
105
+ r1 = self.spots[i + 1]
106
+ ts0 = r0["Timestamp"]
107
+ ts1 = r1["Timestamp"]
108
+ if ts_prev >= ts0 and ts_prev <= ts1:
109
+ prev_price = r0["PriceWithTax"]
110
+ if ts_now >= ts0 and ts_now <= ts1:
111
+ current_price = r0["PriceWithTax"]
112
+ if prev_price is not None and current_price is not None:
113
+ return prev_price, current_price
114
+ self.error("PANIC: run out of spot prices")
115
+ return 0.0, 0.0
116
+
117
+ def calculate_net_energy_cost(
118
+ self, ts_prev: float, ts_now: float, energy: float
119
+ ) -> float:
120
+ """Given time interval as start and stop Calculate the cost over the
121
+ given time period. Positive values indicate revenue, negative cost.
122
+
123
+ Args:
124
+ ts_prev (timestamp): beginning time stamp of the interval
125
+ ts_now (timestamp): end of the interval
126
+ energy (float): energy consumed during the time interval
127
+ Returns:
128
+ Cost or revenue
129
+ """
130
+ cost: float = 0
131
+ prev = ts_prev
132
+ while prev < ts_now:
133
+ elapsed_seconds: float = ts_now - prev
134
+ if elapsed_seconds > self.energy_balancing_interval:
135
+ elapsed_seconds = self.energy_balancing_interval
136
+ now = prev + elapsed_seconds
137
+ start_per_kwh, stop_per_kwh = self.get_prices(prev, now)
138
+ start_price = self.map_kwh_prices_to_joules(start_per_kwh)
139
+ stop_price = self.map_kwh_prices_to_joules(stop_per_kwh)
140
+ if abs(stop_price - start_price) < 1e-24:
141
+ cost = cost + energy * elapsed_seconds * start_price
142
+ else:
143
+ # interpolate cost over energy balancing interval boundary
144
+ elapsed = now - prev
145
+ if elapsed < 0.00001:
146
+ return 0.0
147
+ ts_0 = quantize(self.energy_balancing_interval, now)
148
+ t1 = (ts_0 - prev) / elapsed
149
+ t2 = (now - ts_0) / elapsed
150
+ cost = (
151
+ cost
152
+ + energy
153
+ * ((1.0 - t1) * start_price + t2 * stop_price)
154
+ * elapsed_seconds
155
+ )
156
+
157
+ prev = prev + elapsed_seconds
158
+ return cost
159
+
160
+ def on_powerconsumption(self, ts_now: float, m: dict[Any, Any]) -> None:
161
+ """Calculate net energy cost and update the hourly consumption attribute
162
+ accordingly.
163
+
164
+ Args:
165
+ ts_now (float): time stamp of the energy consumed
166
+ m (dict): Juham MQTT message holding energy reading
167
+ """
168
+ power = m["real_total"]
169
+ if not self.spots:
170
+ self.info("Waiting for electricity prices...")
171
+ elif self.current_ts == 0:
172
+ self.net_energy_balance_cost_hour = 0.0
173
+ self.net_energy_balance_cost_day = 0.0
174
+ self.current_ts = ts_now
175
+ self.net_energy_balance_start_hour = quantize(
176
+ self.energy_balancing_interval, ts_now
177
+ )
178
+ else:
179
+ # calculate cost of energy consumed/produced
180
+ dp: float = self.calculate_net_energy_cost(self.current_ts, ts_now, power)
181
+ self.net_energy_balance_cost_hour = self.net_energy_balance_cost_hour + dp
182
+ self.net_energy_balance_cost_day = self.net_energy_balance_cost_day + dp
183
+
184
+ # calculate and publish energy balance
185
+ dt = ts_now - self.current_ts # time elapsed since previous call
186
+ balance = dt * power # energy consumed/produced in this slot in Joules
187
+ self.total_balance_hour = (
188
+ self.total_balance_hour + balance * self._joule_to_kwh_coeff
189
+ )
190
+ self.total_balance_day = (
191
+ self.total_balance_day + balance * self._joule_to_kwh_coeff
192
+ )
193
+ self.publish_net_energy_balance(ts_now, self.name, balance, power)
194
+ self.publish_energy_cost(
195
+ ts_now,
196
+ self.name,
197
+ self.net_energy_balance_cost_hour,
198
+ self.net_energy_balance_cost_day,
199
+ )
200
+
201
+ # Check if the current energy balancing interval has ended
202
+ # If so, reset the net_energy_balance attribute for the next interval
203
+ if (
204
+ ts_now - self.net_energy_balance_start_hour
205
+ > self.energy_balancing_interval
206
+ ):
207
+ # publish average energy cost per hour
208
+ if abs(self.total_balance_hour) > 0:
209
+ msg = {
210
+ "name": self.name,
211
+ "average_hour": self.net_energy_balance_cost_hour
212
+ / self.total_balance_hour,
213
+ "ts": ts_now,
214
+ }
215
+ self.publish(self.topic_out_energy_cost, json.dumps(msg), 0, False)
216
+
217
+ # reset for the next hour
218
+ self.total_balance_hour = 0
219
+ self.net_energy_balance_cost_hour = 0.0
220
+ self.net_energy_balance_start_hour = ts_now
221
+
222
+ if ts_now - self.net_energy_balance_start_day > 24 * 3600:
223
+ if abs(self.total_balance_day) > 0:
224
+ msg = {
225
+ "name": self.name,
226
+ "average_day": self.net_energy_balance_cost_day
227
+ / self.total_balance_day,
228
+ "ts": ts_now,
229
+ }
230
+ self.publish(self.topic_out_energy_cost, json.dumps(msg), 0, False)
231
+ # reset for the next day
232
+ self.total_balance_day = 0
233
+ self.net_energy_balance_cost_day = 0.0
234
+ self.net_energy_balance_start_day = ts_now
235
+
236
+ self.current_ts = ts_now
237
+
238
+ def publish_net_energy_balance(
239
+ self, ts_now: float, site: str, energy: float, power: float
240
+ ) -> None:
241
+ """Publish the net energy balance for the current energy balancing interval, as well as
242
+ the real-time power at which energy is currently being produced or consumed (the
243
+ rate of change of net energy).
244
+
245
+ Args:
246
+ ts_now (float): timestamp
247
+ site (str): site
248
+ energy (float): cost or revenue.
249
+ power (float) : momentary power (rage of change of energy)
250
+ """
251
+ msg = {"site": site, "power": power, "energy": energy, "ts": ts_now}
252
+ self.publish(self.topic_out_net_energy_balance, json.dumps(msg), 1, True)
253
+
254
+ def publish_energy_cost(
255
+ self, ts_now: float, site: str, cost_hour: float, cost_day: float
256
+ ) -> None:
257
+ """Publish daily and hourly energy cost/revenue
258
+
259
+ Args:
260
+ ts_now (float): timestamp
261
+ site (str): site
262
+ cost_hour (float): cost or revenue per hour.
263
+ cost_day (float) : cost or revenue per day
264
+ """
265
+ msg = {"name": site, "cost_hour": cost_hour, "cost_day": cost_day, "ts": ts_now}
266
+ self.publish(self.topic_out_energy_cost, json.dumps(msg), 1, True)