node-red-contrib-power-saver 3.2.0 → 3.3.0

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 (60) hide show
  1. package/docs/.vuepress/config.js +5 -0
  2. package/docs/.vuepress/dist/.nojekyll +0 -0
  3. package/docs/.vuepress/dist/404.html +2 -2
  4. package/docs/.vuepress/dist/assets/js/{app.eae70176.js → app.49ad6d54.js} +1 -1
  5. package/docs/.vuepress/dist/assets/js/runtime~app.547d0f4e.js +1 -0
  6. package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.3b37457f.js +1 -0
  7. package/docs/.vuepress/dist/assets/js/{v-1e2b191e.50b8fa18.js → v-1e2b191e.98cc227b.js} +1 -1
  8. package/docs/.vuepress/dist/assets/js/v-4637f9e4.b320f5e8.js +1 -0
  9. package/docs/.vuepress/dist/assets/js/v-510ed0d4.3c7e0056.js +1 -0
  10. package/docs/.vuepress/dist/changelog/index.html +3 -3
  11. package/docs/.vuepress/dist/contribute/index.html +2 -2
  12. package/docs/.vuepress/dist/examples/example-next-schedule-entity.html +2 -2
  13. package/docs/.vuepress/dist/examples/example-nordpool-current-state.html +2 -2
  14. package/docs/.vuepress/dist/examples/example-nordpool-events-state.html +2 -2
  15. package/docs/.vuepress/dist/examples/example-tibber-mqtt.html +2 -2
  16. package/docs/.vuepress/dist/examples/index.html +2 -2
  17. package/docs/.vuepress/dist/faq/index.html +2 -2
  18. package/docs/.vuepress/dist/guide/index.html +2 -2
  19. package/docs/.vuepress/dist/index.html +2 -2
  20. package/docs/.vuepress/dist/nodes/index.html +2 -2
  21. package/docs/.vuepress/dist/nodes/old-power-saver-doc.html +2 -2
  22. package/docs/.vuepress/dist/nodes/power-saver.html +2 -2
  23. package/docs/.vuepress/dist/nodes/ps-elvia-add-tariff.html +2 -2
  24. package/docs/.vuepress/dist/nodes/ps-general-add-tariff.html +3 -3
  25. package/docs/.vuepress/dist/nodes/ps-receive-price.html +2 -2
  26. package/docs/.vuepress/dist/nodes/ps-strategy-best-save.html +4 -4
  27. package/docs/.vuepress/dist/nodes/ps-strategy-lowest-price.html +4 -4
  28. package/docs/.vuepress/dist/nodes/strategy-input.html +2 -2
  29. package/docs/changelog/README.md +22 -0
  30. package/docs/examples/example-nordpool-current-state.md +0 -1
  31. package/docs/examples/example-tibber-mqtt.md +0 -1
  32. package/docs/faq/README.md +5 -1
  33. package/docs/images/best-save-config.png +0 -0
  34. package/docs/nodes/ps-strategy-best-save.md +77 -8
  35. package/docs/nodes/ps-strategy-lowest-price.md +43 -0
  36. package/package.json +1 -1
  37. package/src/general-add-tariff-functions.js +0 -1
  38. package/src/general-add-tariff.js +2 -4
  39. package/src/handle-input.js +32 -13
  40. package/src/strategy-best-save.html +0 -21
  41. package/src/strategy-best-save.js +8 -11
  42. package/test/commands-input.test.js +47 -0
  43. package/test/data/best-save-result.json +1 -2
  44. package/test/data/current-undefined-prices.json +197 -0
  45. package/test/data/current-undefined-result.json +208 -0
  46. package/test/data/lowest-price-result-missing-end.json +2 -1
  47. package/test/data/reconfigResult.js +56 -294
  48. package/test/data/reconfigResult_old2.js +75 -0
  49. package/test/data/tibber-result-end-0-24h.json +1 -0
  50. package/test/data/tibber-result-end-0.json +1 -0
  51. package/test/send-config-input.test.js +3 -37
  52. package/test/strategy-best-save-test-utils.js +2 -1
  53. package/test/test-utils.js +1 -7
  54. package/test/utils.test.js +0 -33
  55. package/docs/.vuepress/dist/assets/js/runtime~app.3384c251.js +0 -1
  56. package/docs/.vuepress/dist/assets/js/v-0b5e3c8c.d62b30f7.js +0 -1
  57. package/docs/.vuepress/dist/assets/js/v-4637f9e4.b67738ed.js +0 -1
  58. package/docs/.vuepress/dist/assets/js/v-510ed0d4.528dd6f3.js +0 -1
  59. package/test/data/adjustedResult.js +0 -302
  60. package/test/data/adjustedResult_old.js +0 -154
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta name="generator" content="VuePress 2.0.0-beta.27">
7
7
  <link rel="icon" href="/euro.png"><title>ps-general-add-tariff | Power Saver</title><meta name="description" content="A Node-RED note to save money on hourly changing power prices">
8
- <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.eae70176.js" as="script">
8
+ <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" as="script">
9
9
  <link rel="stylesheet" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css">
10
10
  </head>
11
11
  <body>
12
- <div id="app"><!--[--><div class="theme-container"><!--[--><header class="navbar"><div class="toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a href="/node-red-contrib-power-saver/" class=""><!----><span class="site-name">Power Saver</span></a></span><div class="navbar-links-wrapper" style=""><!--[--><!--]--><nav class="navbar-links can-hide"><!--[--><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/guide/" class="nav-link" aria-label="Guide"><!--[--><!--]--> Guide <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/nodes/" class="nav-link router-link-active" aria-label="Nodes"><!--[--><!--]--> Nodes <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/examples/" class="nav-link" aria-label="Examples"><!--[--><!--]--> Examples <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/contribute/" class="nav-link" aria-label="Contribute"><!--[--><!--]--> Contribute <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/changelog/" class="nav-link" aria-label="Changes"><!--[--><!--]--> Changes <!--[--><!--]--></a></div><div class="navbar-links-item"><a class="nav-link external" href="https://github.com/ottopaulsen/node-red-contrib-power-saver" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button class="toggle-dark-button" title="toggle dark mode"><svg style="" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg style="display:none;" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><!----></div></header><!--]--><div class="sidebar-mask"></div><!--[--><aside class="sidebar"><nav class="navbar-links"><!--[--><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/guide/" class="nav-link" aria-label="Guide"><!--[--><!--]--> Guide <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/nodes/" class="nav-link router-link-active" aria-label="Nodes"><!--[--><!--]--> Nodes <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/examples/" class="nav-link" aria-label="Examples"><!--[--><!--]--> Examples <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/contribute/" class="nav-link" aria-label="Contribute"><!--[--><!--]--> Contribute <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/changelog/" class="nav-link" aria-label="Changes"><!--[--><!--]--> Changes <!--[--><!--]--></a></div><div class="navbar-links-item"><a class="nav-link external" href="https://github.com/ottopaulsen/node-red-contrib-power-saver" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="sidebar-links"><!--[--><!--[--><p class="sidebar-heading sidebar-item active">Nodes</p><ul class=""><li><!--[--><a href="/node-red-contrib-power-saver/nodes/power-saver.md" class="nav-link sidebar-item" aria-label="Power Saver"><!--[--><!--]--> Power Saver <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><p class="sidebar-item">Strategy nodes</p><ul class="sidebar-sub-items"><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-strategy-best-save.html" class="nav-link sidebar-item" aria-label="ps-strategy-best-save"><!--[--><!--]--> ps-strategy-best-save <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-strategy-lowest-price.html" class="nav-link sidebar-item" aria-label="ps-strategy-lowest-price"><!--[--><!--]--> ps-strategy-lowest-price <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><p class="sidebar-item">Utility nodes</p><ul class="sidebar-sub-items"><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-receive-price.html" class="nav-link sidebar-item" aria-label="ps-receive-price"><!--[--><!--]--> ps-receive-price <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><p class="sidebar-item active">Grid tariff nodes</p><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html" class="router-link-active router-link-exact-active nav-link router-link-active sidebar-item active" aria-label="ps-general-add-tariff"><!--[--><!--]--> ps-general-add-tariff <!--[--><!--]--></a><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#description" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Description"><!--[--><!--]--> Description <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#configuration" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Configuration"><!--[--><!--]--> Configuration <!--[--><!--]--></a><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#add-and-delete-periods" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Add and delete periods"><!--[--><!--]--> Add and delete periods <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#from-time-and-value" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="From time and Value"><!--[--><!--]--> From time and Value <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#valid-from-date" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Valid from date"><!--[--><!--]--> Valid from date <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#valid-to-date" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Valid to date"><!--[--><!--]--> Valid to date <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#input" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Input"><!--[--><!--]--> Input <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#output" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Output"><!--[--><!--]--> Output <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-elvia-add-tariff.html" class="nav-link sidebar-item" aria-label="ps-elvia-add-tariff"><!--[--><!--]--> ps-elvia-add-tariff <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li></ul><!--]--><!--[--><p class="sidebar-heading sidebar-item">Data format</p><ul class=""><li><!--[--><a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="nav-link sidebar-item" aria-label="Strategy input format"><!--[--><!--]--> Strategy input format <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="page"><!--[--><!--]--><div class="theme-default-content"><!--[--><h1 id="ps-general-add-tariff" tabindex="-1"><a class="header-anchor" href="#ps-general-add-tariff" aria-hidden="true">#</a> ps-general-add-tariff</h1><p><img src="/node-red-contrib-power-saver/assets/img/node-ps-general-add-tariff.a3cf6f06.png" alt="ps-general-add-tariff"></p><p>Node to add a value, for example a variable grid tariff, to the price before it is used to calculate savings in the strategy nodes.</p><h2 id="description" tabindex="-1"><a class="header-anchor" href="#description" aria-hidden="true">#</a> Description</h2><p>This node is useful if there is an addition to the electricity price that varies over the day, as it might be for the grid tariff.</p><p>If there is one price for example from 22:00 to 06:00 every day, and another price from 06:00 to 22:00, this is the right node to use. It can be used for more than two periods, as long as the time it changes is the same every day.</p><p>Here is how this node is normally used:</p><p><img src="/node-red-contrib-power-saver/assets/img/add-tariff-flow.eb700d4f.png" alt="general flow"></p><div class="custom-container tip"><p class="custom-container-title">Changes during the year</p><p>If there is one price now, and another price from a specific date, you can use two nodes after each other. Set the <code>Valid to date</code> of the node with the current prices to the last date the current prices are valid. Set the <code>Valid from date</code> of the node with the upcoming prices to the first date those prices are valid.</p></div><h2 id="configuration" tabindex="-1"><a class="header-anchor" href="#configuration" aria-hidden="true">#</a> Configuration</h2><h3 id="add-and-delete-periods" tabindex="-1"><a class="header-anchor" href="#add-and-delete-periods" aria-hidden="true">#</a> Add and delete periods</h3><p>You can have from 1 to 24 periods during the day, with different values to add for each hour. Click the <code>Add period</code> button to add more periods. Click the <code>X</code> button to delete a period.</p><h3 id="from-time-and-value" tabindex="-1"><a class="header-anchor" href="#from-time-and-value" aria-hidden="true">#</a> From time and Value</h3><p>For each period, select the time of the day the value is valid from, and enter the value.</p><h3 id="valid-from-date" tabindex="-1"><a class="header-anchor" href="#valid-from-date" aria-hidden="true">#</a> Valid from date</h3><p>Fill in the first date the config is valid.</p><p>If this is empty, the config is valid from the dawn of time.</p><h3 id="valid-to-date" tabindex="-1"><a class="header-anchor" href="#valid-to-date" aria-hidden="true">#</a> Valid to date</h3><p>Fill in the last date the config is valid.</p><p>If this is empty, the config is valid until forever.</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>The output is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/5/2022, 7:42:13 PM</span></div><!----></footer><nav class="page-nav"><p class="inner"><!----><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-elvia-add-tariff.html" class="nav-link" aria-label="ps-elvia-add-tariff"><!--[--><!--]--> ps-elvia-add-tariff <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
13
- <script src="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.eae70176.js" defer></script>
12
+ <div id="app"><!--[--><div class="theme-container"><!--[--><header class="navbar"><div class="toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a href="/node-red-contrib-power-saver/" class=""><!----><span class="site-name">Power Saver</span></a></span><div class="navbar-links-wrapper" style=""><!--[--><!--]--><nav class="navbar-links can-hide"><!--[--><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/guide/" class="nav-link" aria-label="Guide"><!--[--><!--]--> Guide <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/nodes/" class="nav-link router-link-active" aria-label="Nodes"><!--[--><!--]--> Nodes <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/examples/" class="nav-link" aria-label="Examples"><!--[--><!--]--> Examples <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/contribute/" class="nav-link" aria-label="Contribute"><!--[--><!--]--> Contribute <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/changelog/" class="nav-link" aria-label="Changes"><!--[--><!--]--> Changes <!--[--><!--]--></a></div><div class="navbar-links-item"><a class="nav-link external" href="https://github.com/ottopaulsen/node-red-contrib-power-saver" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button class="toggle-dark-button" title="toggle dark mode"><svg style="" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg style="display:none;" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><!----></div></header><!--]--><div class="sidebar-mask"></div><!--[--><aside class="sidebar"><nav class="navbar-links"><!--[--><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/guide/" class="nav-link" aria-label="Guide"><!--[--><!--]--> Guide <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/nodes/" class="nav-link router-link-active" aria-label="Nodes"><!--[--><!--]--> Nodes <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/examples/" class="nav-link" aria-label="Examples"><!--[--><!--]--> Examples <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/contribute/" class="nav-link" aria-label="Contribute"><!--[--><!--]--> Contribute <!--[--><!--]--></a></div><div class="navbar-links-item"><a href="/node-red-contrib-power-saver/changelog/" class="nav-link" aria-label="Changes"><!--[--><!--]--> Changes <!--[--><!--]--></a></div><div class="navbar-links-item"><a class="nav-link external" href="https://github.com/ottopaulsen/node-red-contrib-power-saver" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="sidebar-links"><!--[--><!--[--><p class="sidebar-heading sidebar-item active">Nodes</p><ul class=""><li><!--[--><a href="/node-red-contrib-power-saver/nodes/power-saver.md" class="nav-link sidebar-item" aria-label="Power Saver"><!--[--><!--]--> Power Saver <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><p class="sidebar-item">Strategy nodes</p><ul class="sidebar-sub-items"><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-strategy-best-save.html" class="nav-link sidebar-item" aria-label="ps-strategy-best-save"><!--[--><!--]--> ps-strategy-best-save <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-strategy-lowest-price.html" class="nav-link sidebar-item" aria-label="ps-strategy-lowest-price"><!--[--><!--]--> ps-strategy-lowest-price <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><p class="sidebar-item">Utility nodes</p><ul class="sidebar-sub-items"><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-receive-price.html" class="nav-link sidebar-item" aria-label="ps-receive-price"><!--[--><!--]--> ps-receive-price <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><p class="sidebar-item active">Grid tariff nodes</p><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html" class="router-link-active router-link-exact-active nav-link router-link-active sidebar-item active" aria-label="ps-general-add-tariff"><!--[--><!--]--> ps-general-add-tariff <!--[--><!--]--></a><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#description" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Description"><!--[--><!--]--> Description <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#configuration" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Configuration"><!--[--><!--]--> Configuration <!--[--><!--]--></a><ul class="sidebar-sub-items"><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#add-and-delete-periods" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Add and delete periods"><!--[--><!--]--> Add and delete periods <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#from-time-and-value" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="From time and Value"><!--[--><!--]--> From time and Value <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#valid-from-date" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Valid from date"><!--[--><!--]--> Valid from date <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#valid-to-date" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Valid to date"><!--[--><!--]--> Valid to date <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#input" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Input"><!--[--><!--]--> Input <!--[--><!--]--></a><!----><!--]--></li><li><!--[--><a aria-current="page" href="/node-red-contrib-power-saver/nodes/ps-general-add-tariff.html#output" class="router-link-active router-link-exact-active nav-link sidebar-item" aria-label="Output"><!--[--><!--]--> Output <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li><li><!--[--><a href="/node-red-contrib-power-saver/nodes/ps-elvia-add-tariff.html" class="nav-link sidebar-item" aria-label="ps-elvia-add-tariff"><!--[--><!--]--> ps-elvia-add-tariff <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--></li></ul><!--]--><!--[--><p class="sidebar-heading sidebar-item">Data format</p><ul class=""><li><!--[--><a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="nav-link sidebar-item" aria-label="Strategy input format"><!--[--><!--]--> Strategy input format <!--[--><!--]--></a><!----><!--]--></li></ul><!--]--><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="page"><!--[--><!--]--><div class="theme-default-content"><!--[--><h1 id="ps-general-add-tariff" tabindex="-1"><a class="header-anchor" href="#ps-general-add-tariff" aria-hidden="true">#</a> ps-general-add-tariff</h1><p><img src="/node-red-contrib-power-saver/assets/img/node-ps-general-add-tariff.a3cf6f06.png" alt="ps-general-add-tariff"></p><p>Node to add a value, for example a variable grid tariff, to the price before it is used to calculate savings in the strategy nodes.</p><h2 id="description" tabindex="-1"><a class="header-anchor" href="#description" aria-hidden="true">#</a> Description</h2><p>This node is useful if there is an addition to the electricity price that varies over the day, as it might be for the grid tariff.</p><p>If there is one price for example from 22:00 to 06:00 every day, and another price from 06:00 to 22:00, this is the right node to use. It can be used for more than two periods, as long as the time it changes is the same every day.</p><p>Here is how this node is normally used:</p><p><img src="/node-red-contrib-power-saver/assets/img/add-tariff-flow.eb700d4f.png" alt="general flow"></p><div class="custom-container tip"><p class="custom-container-title">Changes during the year</p><p>If there is one price now, and another price from a specific date, you can use two nodes after each other. Set the <code>Valid to date</code> of the node with the current prices to the last date the current prices are valid. Set the <code>Valid from date</code> of the node with the upcoming prices to the first date those prices are valid.</p></div><h2 id="configuration" tabindex="-1"><a class="header-anchor" href="#configuration" aria-hidden="true">#</a> Configuration</h2><h3 id="add-and-delete-periods" tabindex="-1"><a class="header-anchor" href="#add-and-delete-periods" aria-hidden="true">#</a> Add and delete periods</h3><p>You can have from 1 to 24 periods during the day, with different values to add for each hour. Click the <code>Add period</code> button to add more periods. Click the <code>X</code> button to delete a period.</p><h3 id="from-time-and-value" tabindex="-1"><a class="header-anchor" href="#from-time-and-value" aria-hidden="true">#</a> From time and Value</h3><p>For each period, select the time of the day the value is valid from, and enter the value.</p><h3 id="valid-from-date" tabindex="-1"><a class="header-anchor" href="#valid-from-date" aria-hidden="true">#</a> Valid from date</h3><p>Fill in the first date the config is valid.</p><p>If this is empty, the config is valid from the dawn of time.</p><h3 id="valid-to-date" tabindex="-1"><a class="header-anchor" href="#valid-to-date" aria-hidden="true">#</a> Valid to date</h3><p>Fill in the last date the config is valid.</p><p>If this is empty, the config is valid until forever.</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>The output is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><p>If there is a config property in the input payload, it is passed on to the output payload.</p><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/7/2022, 9:09:31 PM</span></div><!----></footer><nav class="page-nav"><p class="inner"><!----><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-elvia-add-tariff.html" class="nav-link" aria-label="ps-elvia-add-tariff"><!--[--><!--]--> ps-elvia-add-tariff <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
13
+ <script src="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" defer></script>
14
14
  </body>
15
15
  </html>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta name="generator" content="VuePress 2.0.0-beta.27">
7
7
  <link rel="icon" href="/euro.png"><title>ps-receive-price | Power Saver</title><meta name="description" content="A Node-RED note to save money on hourly changing power prices">
8
- <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.eae70176.js" as="script">
8
+ <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" as="script">
9
9
  <link rel="stylesheet" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css">
10
10
  </head>
11
11
  <body>
@@ -75,6 +75,6 @@
75
75
  <span class="token punctuation">]</span>
76
76
  <span class="token punctuation">}</span>
77
77
  </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>The output is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a>, so it can be sent directly to the strategy nodes, or via any <code>ps-xxx-add-tariff</code> node.</p><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">12/20/2021, 10:10:18 PM</span></div><!----></footer><nav class="page-nav"><p class="inner"><span class="prev"> ← <a href="/node-red-contrib-power-saver/nodes/ps-strategy-lowest-price.html" class="nav-link" aria-label="ps-strategy-lowest-price"><!--[--><!--]--> ps-strategy-lowest-price <!--[--><!--]--></a></span><!----></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
78
- <script src="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.eae70176.js" defer></script>
78
+ <script src="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" defer></script>
79
79
  </body>
80
80
  </html>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta name="generator" content="VuePress 2.0.0-beta.27">
7
7
  <link rel="icon" href="/euro.png"><title>ps-strategy-best-save | Power Saver</title><meta name="description" content="A Node-RED note to save money on hourly changing power prices">
8
- <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.eae70176.js" as="script">
8
+ <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" as="script">
9
9
  <link rel="stylesheet" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css">
10
10
  </head>
11
11
  <body>
@@ -19,7 +19,7 @@
19
19
  <span class="token property">&quot;scheduleOnlyFromCurrentTime&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span>
20
20
  <span class="token punctuation">}</span>
21
21
  <span class="token punctuation">}</span>
22
- </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>All the variables in the config object are optional. You can send only those you want to change.</p><p>The config sent like this will be valid until a new config is sent the same way, or until the flow is restarted. On a restart, the original config set up in the node will be used.</p><p>When a config is sent like this, the schedule will be replanned based on the last previously received price data. If no price data has been received, no scheduling is done.</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>There are three outputs. You use only those you need for your purpose.</p><h3 id="output-1" tabindex="-1"><a class="header-anchor" href="#output-1" aria-hidden="true">#</a> Output 1</h3><p>A payload with the word <code>true</code> is sent to output 1 whenever the power / switch shall be turned on.</p><h3 id="output-2" tabindex="-1"><a class="header-anchor" href="#output-2" aria-hidden="true">#</a> Output 2</h3><p>A payload with the word <code>false</code> is sent to output 2 whenever the power / switch shall be turned off.</p><h3 id="output-3" tabindex="-1"><a class="header-anchor" href="#output-3" aria-hidden="true">#</a> Output 3</h3><p>When a valid input is received, and the schedule is recalculated, the resulting schedule, as well as some other information, is sent to output 3. You can use this to see the plan and verify that it meets your expectations. You can also use it to display the schedule in any way you like.</p><p>Example of output:</p><div class="language-json ext-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
22
+ </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>All the variables in the config object are optional. You can send only those you want to change.</p><p>The config sent like this will be valid until a new config is sent the same way, or until the flow is restarted. On a restart, the original config set up in the node will be used.</p><p>When a config is sent like this, and without price data, the schedule will be replanned based on the last previously received price data. If no price data has been received, no scheduling is done.</p><p>However, you can send config and price data in the same message. Then both will be used .</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>There are three outputs. You use only those you need for your purpose.</p><h3 id="output-1" tabindex="-1"><a class="header-anchor" href="#output-1" aria-hidden="true">#</a> Output 1</h3><p>A payload with the word <code>true</code> is sent to output 1 whenever the power / switch shall be turned on.</p><h3 id="output-2" tabindex="-1"><a class="header-anchor" href="#output-2" aria-hidden="true">#</a> Output 2</h3><p>A payload with the word <code>false</code> is sent to output 2 whenever the power / switch shall be turned off.</p><h3 id="output-3" tabindex="-1"><a class="header-anchor" href="#output-3" aria-hidden="true">#</a> Output 3</h3><p>When a valid input is received, and the schedule is recalculated, the resulting schedule, as well as some other information, is sent to output 3. You can use this to see the plan and verify that it meets your expectations. You can also use it to display the schedule in any way you like.</p><p>Example of output:</p><div class="language-json ext-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
23
23
  <span class="token property">&quot;schedule&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
24
24
  <span class="token punctuation">{</span>
25
25
  <span class="token property">&quot;time&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2021-09-30T00:00:00.000+02:00&quot;</span><span class="token punctuation">,</span>
@@ -61,7 +61,7 @@
61
61
  <span class="token property">&quot;time&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2021-09-30T23:45:12.123+02:00&quot;</span><span class="token punctuation">,</span>
62
62
  <span class="token property">&quot;version&quot;</span><span class="token operator">:</span> <span class="token string">&quot;3.1.2&quot;</span>
63
63
  <span class="token punctuation">}</span>
64
- </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br></div></div><p>The <code>schedule</code> array shows every time the switch is turned on or off. The <code>hours</code> array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.</p><h2 id="algorithm" tabindex="-1"><a class="header-anchor" href="#algorithm" aria-hidden="true">#</a> Algorithm</h2><p>The calculation that decides what hours to turn off works as follows:</p><ol><li>A matrix (x * y) is created where x is the number of hours we have price information for, and y is the configured maximum number of hours to turn off in a sequence.</li><li>The matrix is filled with how much you save by turning off hour x for y hours.</li><li>The matrix is processed calculating all possibilities for turning off a number of hours in a sequence and by that saving money. In this process all non-saving sequences are discarded. Also, if the average saving per hour is less than what you have configured as minimum amount to save per kWh, the sequence is discarded.</li><li>The remaining sequences are sorted by how much that is saved, in descending order.</li><li>Next, a table with one value per hour is created, with all hours in state &quot;on&quot;.</li><li>Then the saving sequences is applied one by one, turning off the hours in each sequence, discarding sequences that lead to any violation of the rules set by the config.</li><li>When all sequences are processed, the resulting table shows a pretty good savings plan, that in most cases would be the optimal plan.</li></ol><p>I say &quot;in most cases&quot;, because there is a chance that a group of two or more sequences combined can give a better plan than a single sequence preceeding those two, but where the selection of the one sequence causes the group to be discarded. If anyone encounters this situation, I would be happy to receive the price data set, and try to improve the algorithm even further.</p><h2 id="integration-with-magicmirror" tabindex="-1"><a class="header-anchor" href="#integration-with-magicmirror" aria-hidden="true">#</a> Integration with MagicMirror</h2><p>Are you using <a href="https://magicmirror.builders/" target="_blank" rel="noopener noreferrer">MagicMirror<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>? Are you also using <a href="https://tibber.com/" target="_blank" rel="noopener noreferrer">Tibber<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>? If so, there is a module for MM called <a href="https://github.com/ottopaulsen/MMM-Tibber" target="_blank" rel="noopener noreferrer">MMM-Tibber<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>, that easily can be used to show savings from this node.</p><p><img src="https://github.com/ottopaulsen/MMM-Tibber/blob/master/doc/MMM-Tibber-screenshot-savings-graph.png?raw=true" alt="Show savings in MMM-Tibber"></p><p>The purple lines show savings per kWh.</p><p>Read more about this in the <a href="https://github.com/ottopaulsen/MMM-Tibber#show-savings" target="_blank" rel="noopener noreferrer">MMM-Tibber documentation<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>.</p><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/7/2022, 12:00:47 AM</span></div><!----></footer><nav class="page-nav"><p class="inner"><!----><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-strategy-lowest-price.html" class="nav-link" aria-label="ps-strategy-lowest-price"><!--[--><!--]--> ps-strategy-lowest-price <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
65
- <script src="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.eae70176.js" defer></script>
64
+ </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br></div></div><p>The <code>schedule</code> array shows every time the switch is turned on or off. The <code>hours</code> array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.</p><h2 id="algorithm" tabindex="-1"><a class="header-anchor" href="#algorithm" aria-hidden="true">#</a> Algorithm</h2><p>The calculation that decides what hours to turn off works as follows:</p><ol><li>A matrix (x * y) is created where x is the number of hours we have price information for, and y is the configured maximum number of hours to turn off in a sequence.</li><li>The matrix is filled with how much you save by turning off hour x for y hours.</li><li>The matrix is processed calculating all possibilities for turning off a number of hours in a sequence and by that saving money. In this process all non-saving sequences are discarded. Also, if the average saving per hour is less than what you have configured as minimum amount to save per kWh, the sequence is discarded.</li><li>The remaining sequences are sorted by how much that is saved, in descending order.</li><li>Next, a table with one value per hour is created, with all hours in state &quot;on&quot;.</li><li>Then the saving sequences is applied one by one, turning off the hours in each sequence, discarding sequences that lead to any violation of the rules set by the config.</li><li>When all sequences are processed, the resulting table shows a pretty good savings plan, that in most cases would be the optimal plan.</li></ol><p>I say &quot;in most cases&quot;, because there is a chance that a group of two or more sequences combined can give a better plan than a single sequence preceeding those two, but where the selection of the one sequence causes the group to be discarded. If anyone encounters this situation, I would be happy to receive the price data set, and try to improve the algorithm even further.</p><h2 id="integration-with-magicmirror" tabindex="-1"><a class="header-anchor" href="#integration-with-magicmirror" aria-hidden="true">#</a> Integration with MagicMirror</h2><p>Are you using <a href="https://magicmirror.builders/" target="_blank" rel="noopener noreferrer">MagicMirror<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>? Are you also using <a href="https://tibber.com/" target="_blank" rel="noopener noreferrer">Tibber<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>? If so, there is a module for MM called <a href="https://github.com/ottopaulsen/MMM-Tibber" target="_blank" rel="noopener noreferrer">MMM-Tibber<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>, that easily can be used to show savings from this node.</p><p><img src="https://github.com/ottopaulsen/MMM-Tibber/blob/master/doc/MMM-Tibber-screenshot-savings-graph.png?raw=true" alt="Show savings in MMM-Tibber"></p><p>The purple lines show savings per kWh.</p><p>Read more about this in the <a href="https://github.com/ottopaulsen/MMM-Tibber#show-savings" target="_blank" rel="noopener noreferrer">MMM-Tibber documentation<span><svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><!--[--><span class="sr-only">open in new window</span><!--]--></span></a>.</p><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/7/2022, 9:09:31 PM</span></div><!----></footer><nav class="page-nav"><p class="inner"><!----><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-strategy-lowest-price.html" class="nav-link" aria-label="ps-strategy-lowest-price"><!--[--><!--]--> ps-strategy-lowest-price <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
65
+ <script src="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" defer></script>
66
66
  </body>
67
67
  </html>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta name="generator" content="VuePress 2.0.0-beta.27">
7
7
  <link rel="icon" href="/euro.png"><title>ps-strategy-lowest-price | Power Saver</title><meta name="description" content="A Node-RED note to save money on hourly changing power prices">
8
- <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.eae70176.js" as="script">
8
+ <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" as="script">
9
9
  <link rel="stylesheet" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css">
10
10
  </head>
11
11
  <body>
@@ -20,7 +20,7 @@
20
20
  <span class="token property">&quot;outputOutsidePeriod&quot;</span><span class="token operator">:</span> <span class="token boolean">false</span>
21
21
  <span class="token punctuation">}</span>
22
22
  <span class="token punctuation">}</span>
23
- </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>All the variables in the config object are optional. You can send only those you want to change.</p><p>The config sent like this will be valid until a new config is sent the same way, or until the flow is restarted. On a restart, the original config set up in the node will be used.</p><p>When a config is sent like this, the schedule will be replanned based on the last previously received price data. If no price data has been received, no scheduling is done.</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>When a valid input is received, and the schedule is recalculated, the resulting schedule, as well as some other information, is sent to output 3. You can use this to see the plan and verify that it meets your expectations. You can also use it to display the schedule in any way you like.</p><p>Example of output:</p><div class="language-json ext-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
23
+ </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>All the variables in the config object are optional. You can send only those you want to change.</p><p>The config sent like this will be valid until a new config is sent the same way, or until the flow is restarted. On a restart, the original config set up in the node will be used.</p><p>When a config is sent like this, and without price data, the schedule will be replanned based on the last previously received price data. If no price data has been received, no scheduling is done.</p><p>However, you can send config and price data in the same message. Then both will be used .</p><h2 id="input" tabindex="-1"><a class="header-anchor" href="#input" aria-hidden="true">#</a> Input</h2><p>The input is the <a href="/node-red-contrib-power-saver/nodes/strategy-input.html" class="">common strategy input format</a></p><h2 id="output" tabindex="-1"><a class="header-anchor" href="#output" aria-hidden="true">#</a> Output</h2><p>When a valid input is received, and the schedule is recalculated, the resulting schedule, as well as some other information, is sent to output 3. You can use this to see the plan and verify that it meets your expectations. You can also use it to display the schedule in any way you like.</p><p>Example of output:</p><div class="language-json ext-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
24
24
  <span class="token property">&quot;schedule&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
25
25
  <span class="token punctuation">{</span>
26
26
  <span class="token property">&quot;time&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2021-12-10T00:00:00.000+01:00&quot;</span><span class="token punctuation">,</span>
@@ -85,7 +85,7 @@
85
85
  <span class="token property">&quot;time&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2021-09-30T23:45:12.123+02:00&quot;</span><span class="token punctuation">,</span>
86
86
  <span class="token property">&quot;version&quot;</span><span class="token operator">:</span> <span class="token string">&quot;3.1.2&quot;</span>
87
87
  <span class="token punctuation">}</span>
88
- </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br></div></div><p>The <code>schedule</code> array shows every time the switch is turned on or off. The <code>hours</code> array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.</p><h2 id="tips-tricks" tabindex="-1"><a class="header-anchor" href="#tips-tricks" aria-hidden="true">#</a> Tips &amp; tricks</h2><h3 id="multiple-nodes-works-together" tabindex="-1"><a class="header-anchor" href="#multiple-nodes-works-together" aria-hidden="true">#</a> Multiple nodes works together</h3><p>You can use multiple nodes simultanously, for different periods, if you want more hours on one part of the day than another part, or to make sure there are at least some hours on during each period.</p><h3 id="highest-price" tabindex="-1"><a class="header-anchor" href="#highest-price" aria-hidden="true">#</a> Highest price</h3><p>If you want to find the <code>x</code> hours with the highest prices, do as follows:</p><ol><li>Calculate <code>y</code> as the total number of hours in the period. For example, if the period is from <code>08:00</code> to <code>20:00</code>, then <code>y = 12</code>.</li><li>Configure <code>Hours On = y - x</code>, so if <code>x = 4</code>, then <code>Hours On = 12 - 4 = 8</code>.</li><li>Use <strong>Output 2</strong> to get a signal when you have the hours with the highest prices. Just remember that the value sent to output 2 is <code>false</code>, not <code>true</code> as it is on output 1.</li></ol><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/7/2022, 12:00:47 AM</span></div><!----></footer><nav class="page-nav"><p class="inner"><span class="prev"> ← <a href="/node-red-contrib-power-saver/nodes/ps-strategy-best-save.html" class="nav-link" aria-label="ps-strategy-best-save"><!--[--><!--]--> ps-strategy-best-save <!--[--><!--]--></a></span><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-receive-price.html" class="nav-link" aria-label="ps-receive-price"><!--[--><!--]--> ps-receive-price <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
89
- <script src="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.eae70176.js" defer></script>
88
+ </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br></div></div><p>The <code>schedule</code> array shows every time the switch is turned on or off. The <code>hours</code> array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.</p><h2 id="tips-tricks" tabindex="-1"><a class="header-anchor" href="#tips-tricks" aria-hidden="true">#</a> Tips &amp; tricks</h2><h3 id="multiple-nodes-works-together" tabindex="-1"><a class="header-anchor" href="#multiple-nodes-works-together" aria-hidden="true">#</a> Multiple nodes works together</h3><p>You can use multiple nodes simultanously, for different periods, if you want more hours on one part of the day than another part, or to make sure there are at least some hours on during each period.</p><h3 id="highest-price" tabindex="-1"><a class="header-anchor" href="#highest-price" aria-hidden="true">#</a> Highest price</h3><p>If you want to find the <code>x</code> hours with the highest prices, do as follows:</p><ol><li>Calculate <code>y</code> as the total number of hours in the period. For example, if the period is from <code>08:00</code> to <code>20:00</code>, then <code>y = 12</code>.</li><li>Configure <code>Hours On = y - x</code>, so if <code>x = 4</code>, then <code>Hours On = 12 - 4 = 8</code>.</li><li>Use <strong>Output 2</strong> to get a signal when you have the hours with the highest prices. Just remember that the value sent to output 2 is <code>false</code>, not <code>true</code> as it is on output 1.</li></ol><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">1/7/2022, 9:09:31 PM</span></div><!----></footer><nav class="page-nav"><p class="inner"><span class="prev"> ← <a href="/node-red-contrib-power-saver/nodes/ps-strategy-best-save.html" class="nav-link" aria-label="ps-strategy-best-save"><!--[--><!--]--> ps-strategy-best-save <!--[--><!--]--></a></span><span class="next"><a href="/node-red-contrib-power-saver/nodes/ps-receive-price.html" class="nav-link" aria-label="ps-receive-price"><!--[--><!--]--> ps-receive-price <!--[--><!--]--></a> → </span></p></nav><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
89
+ <script src="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" defer></script>
90
90
  </body>
91
91
  </html>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta name="generator" content="VuePress 2.0.0-beta.27">
7
7
  <link rel="icon" href="/euro.png"><title>Strategy input format | Power Saver</title><meta name="description" content="A Node-RED note to save money on hourly changing power prices">
8
- <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.eae70176.js" as="script">
8
+ <link rel="preload" href="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css" as="style"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/812.79dad458.js" as="script"><link rel="preload" href="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" as="script">
9
9
  <link rel="stylesheet" href="/node-red-contrib-power-saver/assets/css/styles.e835bef6.css">
10
10
  </head>
11
11
  <body>
@@ -35,6 +35,6 @@
35
35
  <span class="token punctuation">]</span>
36
36
  <span class="token punctuation">}</span>
37
37
  </code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><p>This format is used for:</p><ul><li>Output of the <code>ps-receive-price</code> node</li><li>Input and output of the <code>ps-xxx-add-tariff</code> nodes</li><li>Input for the strategy nodes (<code>ps-strategy-xxx-xxx</code>)</li></ul><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><span class="meta-item-info">12/20/2021, 10:10:18 PM</span></div><!----></footer><!----><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
38
- <script src="/node-red-contrib-power-saver/assets/js/runtime~app.3384c251.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.eae70176.js" defer></script>
38
+ <script src="/node-red-contrib-power-saver/assets/js/runtime~app.547d0f4e.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/812.79dad458.js" defer></script><script src="/node-red-contrib-power-saver/assets/js/app.49ad6d54.js" defer></script>
39
39
  </body>
40
40
  </html>
@@ -6,6 +6,28 @@ sidebar: "auto"
6
6
 
7
7
  List the most significant changes, starting in version 1.0.9.
8
8
 
9
+ ## 3.3.0
10
+
11
+ - Remove the config option to schedule from the current hour. The feature did not work, and it was not clear how it should work.
12
+ - Added a dynamic command feature to make it possible to dynamically
13
+ 1. Tell the node to send the schedule to output 3.
14
+ 2. Reset saved data making the next schedule to start without historical data.
15
+ - Fix node status so it says "No price data" when there is no price data available.
16
+ - Added an FAQ section to the doc.
17
+
18
+ ## 3.2.3
19
+
20
+ - Remove unused imports
21
+ - Fix doc deployment issue
22
+
23
+ ## 3.2.2
24
+
25
+ - New attempt to solve the problem with multiple outputs at the same time.
26
+
27
+ ## 3.2.1
28
+
29
+ - Fix that may solve the problem with multiple outputs at the same time.
30
+
9
31
  ## 3.2.0
10
32
 
11
33
  - Config can be sent on input to strategy nodes together with price data, in the same message.
@@ -154,7 +154,6 @@ In this example, data is read from the Nord Pool sensor in HA via the `current s
154
154
  "minSaving": "0.03",
155
155
  "sendCurrentValueWhenRescheduling": true,
156
156
  "outputIfNoSchedule": "true",
157
- "scheduleOnlyFromCurrentTime": "false",
158
157
  "x": 630,
159
158
  "y": 380,
160
159
  "wires": [
@@ -120,7 +120,6 @@ In this example, data is read from Tibber and used to turn on/off a switch, sche
120
120
  "minSaving": "0.05",
121
121
  "sendCurrentValueWhenRescheduling": true,
122
122
  "outputIfNoSchedule": "true",
123
- "scheduleOnlyFromCurrentTime": "false",
124
123
  "x": 490,
125
124
  "y": 160,
126
125
  "wires": [["467a5fe.d0bbba", "5e485ff7.db156"], ["9c978d1c.ee76", "467a5fe.d0bbba"], ["42d8b632.402e38"]]
@@ -12,7 +12,7 @@ Why does it not save the most expensive period?
12
12
 
13
13
  If you move the saving-period 4-5 hours earlier, the most expensive hours would have been saved. Why is this not better?
14
14
 
15
- Remember that the power that is not used during the saving-period, will be used immediately after. At least, that is the idea, and the normal behaviour if the power consumer is a water heater or another heater controlled by a thermostat. So, then the power would be used one of the blue hours in stead of the green cheaper hour.
15
+ Remember that the power that is not used during the saving-period, will be used immediately after. At least, that is the idea, and the normal behavior if the power consumer is a water heater or another heater controlled by a thermostat. So, then the power would be used one of the blue hours in stead of the green cheaper hour.
16
16
 
17
17
  Also remember that when saving, you do not save the full price. You only save what is the difference between the price during the saved hours and the price the hour immediately after.
18
18
 
@@ -21,3 +21,7 @@ So the best saving is found where this difference is the largest, and that is no
21
21
  Of course, if you expand the saving period from 5 to 10 hours you would save even more, but that would be a different case, and you can do that if it is ok for you to turn off for that long time.
22
22
 
23
23
  Another alternative is to reduce the minimum saving from 0.05 to 0.001. Then the 3 first red hours would be turned off, but the last red would have to be on, in order to get one hour on until the next 5-hour period off. This would however not save you for much money, since the hour that is on is almost as expensive as the hours you would turn off.
24
+
25
+ ## Can we get Legionella bacteria when turning off the water heater?
26
+
27
+ Many people ask if there is a danger that legionella bacteria will grow and become dangerous when the temperature of the water heater is lowered. As long as the water is heated to at least 65 °C every day, or at least every week, the risk of infection is not considered significant, according to the norwegian [FHI](https://www.fhi.no/nettpub/legionellaveilederen/).
Binary file
@@ -19,7 +19,6 @@ The picture at the bottom of the page, under [Integration with MagicMirror](#int
19
19
  | Max per sequence | Maximum number of hours to turn off in a sequence. |
20
20
  | Min recover | Minimum hours to turn on immediately after a period when turned off the maximum number of hours that is allowed to be turned off |
21
21
  | Min saving | Minimum amount to save per kWh in order to bother turning it off. It is recommended to have some amount here, e.g. 2 cents / 2 øre. No point in saving 0.001, is it? |
22
- | Schedule for | Select to schedule for the whole data set or only from the current hour. |
23
22
  | Send when rescheduling | Check this to make sure on or off output is sent immediately after rescheduling |
24
23
  | If no schedule, send | What to do if there is no valid schedule any more (turn on or off). |
25
24
 
@@ -27,10 +26,6 @@ The picture at the bottom of the page, under [Integration with MagicMirror](#int
27
26
  NB! The `Min recover` only has effect if the previous save-period is of length `Max per sequence`. If the save-period is shorter, the following on-period may be as short as one hour.
28
27
  :::
29
28
 
30
- ::: tip Legionella
31
- Many people ask if there is a danger that legionella bacteria will grow and become dangerous when the temperature of the water heater is lowered. As long as the water is heated to at least 65 °C every day, or at least every week, the risk of infection is not considered significant, according to the norwegian [FHI](https://www.fhi.no/nettpub/legionellaveilederen/).
32
- :::
33
-
34
29
  ### Dynamic config
35
30
 
36
31
  It is possible to change config dynamically by sending a config message to the node. The config messages has a payload with a config object like this example:
@@ -43,7 +38,6 @@ It is possible to change config dynamically by sending a config message to the n
43
38
  "minSaving": 0.02,
44
39
  "sendCurrentValueWhenRescheduling": true,
45
40
  "outputIfNoSchedule": true,
46
- "scheduleOnlyFromCurrentTime": false
47
41
  }
48
42
  }
49
43
  ```
@@ -54,11 +48,58 @@ The config sent like this will be valid until a new config is sent the same way,
54
48
 
55
49
  When a config is sent like this, and without price data, the schedule will be replanned based on the last previously received price data. If no price data has been received, no scheduling is done.
56
50
 
57
- However, you can send config and price data in the same message. Then both will be used .
51
+ However, you can send config and price data in the same message. Then both will be used.
52
+
53
+ ### Dynamic commands
54
+
55
+ You can dynamically send some commands to the node via its input, by using a `commands` object in the payload as described below.
56
+
57
+ Commands can be sent together with config and/or price data, but the exact behavior is not defined.
58
+
59
+ #### sendSchedule
60
+
61
+ You can get the schedule sent to output 3 any time by sending a message like this to the node:
62
+
63
+ ```json
64
+ "payload": {
65
+ "commands": {
66
+ "sendSchedule": true,
67
+ }
68
+ }
69
+ ```
70
+
71
+ When you do this, the current schedule is actually recalculated based on the last received data, and then sent to output 3 the same way as when it was originally planned.
72
+
73
+ #### reset
74
+
75
+ You can reset data the node has saved in context by sending this message:
76
+
77
+ ```json
78
+ "payload": {
79
+ "commands": {
80
+ "reset": true,
81
+ }
82
+ }
83
+ ```
84
+
85
+ When you do this, all historical data the node has saved is deleted, including the current schedule, so the result will be
86
+ that the node shows status "No price data". When new price data is received, a schedule is calculated without considering any history.
87
+
88
+ The nodes config is not deleted, as the node depends on it to work.
89
+
90
+ ::: warning
91
+ This operation cannot be undone.
92
+
93
+ However, it is normally not a big loss, as you can just feed the node with new price data and start from scratch.
94
+ :::
58
95
 
59
96
  ## Input
60
97
 
61
- The input is the [common strategy input format](./strategy-input.md)
98
+ The input is the [common strategy input format](./strategy-input.md).
99
+
100
+ In addition to the prices sent as input,
101
+ the node is using the schedule for the day before it receives data for,
102
+ so that it can calculate the schedule in the beginning of the day according to the configured rules. This requires of course that the node was run the day before.
62
103
 
63
104
  ## Output
64
105
 
@@ -125,6 +166,12 @@ Example of output:
125
166
 
126
167
  The `schedule` array shows every time the switch is turned on or off. The `hours` array shows values per hour containing the price (received as input), whether that hour is on or off, the start time of the hour and the amount per kWh that is saved on hours that are turned off, compared to the next hour that is on.
127
168
 
169
+ ### Data saved in context
170
+
171
+ The node saves some data in the nodes context, so that it can be used on restarts and also taken into consideration when calculating the schedule over midnight.
172
+
173
+ You can see the saved data if you select the node in Node-RED, and view "Context data", and refresh the Node context.
174
+
128
175
  ## Algorithm
129
176
 
130
177
  The calculation that decides what hours to turn off works as follows:
@@ -139,6 +186,28 @@ The calculation that decides what hours to turn off works as follows:
139
186
 
140
187
  I say "in most cases", because there is a chance that a group of two or more sequences combined can give a better plan than a single sequence preceeding those two, but where the selection of the one sequence causes the group to be discarded. If anyone encounters this situation, I would be happy to receive the price data set, and try to improve the algorithm even further.
141
188
 
189
+ ## Data used for calculation
190
+
191
+ Normally data is received for one or two whole days, and all this data is used to do the calculation. In addition, if the node has run before, so there is historical data, the last period on or off before the period data is received for, is considered in the calculation, so that the rules in the configuration are followed also between days.
192
+
193
+ ## Restarts
194
+
195
+ The node saves data in the nodes context, so if Node-RED is configured to save context between restarts, the node will replan with the last received data when it restarts.
196
+
197
+ ::: warning
198
+ In Home Assistant, Node-RED is by default configured to save context between restarts. However, if you run Node-RED another way, this may not be the case by default. If context is only stored in memory, it is lost between restarts, and even between re-deployments. This can be changed in the `settings.js` file for Node-RED like this:
199
+
200
+ ```js
201
+ contextStorage: {
202
+ default: {
203
+ module: "localfilesystem"
204
+ }
205
+ }
206
+ ```
207
+
208
+ Please read the [Node-RED documentation](https://nodered.org/docs/user-guide/context) for more details about this.
209
+ :::
210
+
142
211
  ## Integration with MagicMirror
143
212
 
144
213
  Are you using [MagicMirror](https://magicmirror.builders/)? Are you also using [Tibber](https://tibber.com/)? If so, there is a module for MM called [MMM-Tibber](https://github.com/ottopaulsen/MMM-Tibber), that easily can be used to show savings from this node.
@@ -74,6 +74,49 @@ When a config is sent like this, and without price data, the schedule will be re
74
74
 
75
75
  However, you can send config and price data in the same message. Then both will be used .
76
76
 
77
+ ### Dynamic commands
78
+
79
+ You can dynamically send some commands to the node via its input, by using a `commands` object in the payload as described below.
80
+
81
+ Commands can be sent together with config and/or price data, but the exact behavior is not defined.
82
+
83
+ #### sendSchedule
84
+
85
+ You can get the schedule sent to output 3 any time by sending a message like this to the node:
86
+
87
+ ```json
88
+ "payload": {
89
+ "commands": {
90
+ "sendSchedule": true,
91
+ }
92
+ }
93
+ ```
94
+
95
+ When you do this, the current schedule is actually recalculated based on the last received data, and then sent to output 3 the same way as when it was originally planned.
96
+
97
+ #### reset
98
+
99
+ You can reset data the node has saved in context by sending this message:
100
+
101
+ ```json
102
+ "payload": {
103
+ "commands": {
104
+ "reset": true,
105
+ }
106
+ }
107
+ ```
108
+
109
+ When you do this, all historical data the node has saved is deleted, including the current schedule, so the result will be
110
+ that the node shows status "No price data". When new price data is received, a schedule is calculated without considering any history.
111
+
112
+ The nodes config is not deleted, as the node depends on it to work.
113
+
114
+ ::: warning
115
+ This operation cannot be undone.
116
+
117
+ However, it is normally not a big loss, as you can just feed the node with new price data and start from scratch.
118
+ :::
119
+
77
120
  ## Input
78
121
 
79
122
  The input is the [common strategy input format](./strategy-input.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-power-saver",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "A module for Node-RED that you can use to turn on and off a switch based on power prices",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,6 +1,5 @@
1
1
  const cloneDeep = require("lodash.clonedeep");
2
2
  const { DateTime } = require("luxon");
3
- const { nodes } = require("node-red");
4
3
  const { roundPrice } = require("./utils");
5
4
 
6
5
  function buildAllHours(node, periods) {