Files
docker-configs/linkwarden/data/archives/3/15_readability.json

1 line
49 KiB
JSON
Executable File

{"title":"","byline":"jmcollin78","dir":null,"lang":null,"content":"<div id=\"readability-page-1\" class=\"page\"><div data-hpc=\"true\"><article><p dir=\"auto\"><a href=\"https://github.com/jmcollin78/solar_optimizer/releases\"><img data-canonical-src=\"https://img.shields.io/github/release/jmcollin78/solar_optimizer.svg?style=for-the-badge\" alt=\"GitHub Release\" src=\"https://camo.githubusercontent.com/e3468f14ecfa11f9298f60ebc46a4ab44c08691ea0584a20d922e65d4ecf35ec/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6a6d636f6c6c696e37382f736f6c61725f6f7074696d697a65722e7376673f7374796c653d666f722d7468652d6261646765\"></a>\n<a href=\"https://github.com/jmcollin78/solar_optimizer/commits/master\"><img data-canonical-src=\"https://img.shields.io/github/commit-activity/y/jmcollin78/solar_optimizer.svg?style=for-the-badge\" alt=\"GitHub Activity\" src=\"https://camo.githubusercontent.com/377d9568dd2a2c2af2c4be7d90534f35a235ee1eedf5ba110962d0843116894c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f792f6a6d636f6c6c696e37382f736f6c61725f6f7074696d697a65722e7376673f7374796c653d666f722d7468652d6261646765\"></a>\n<a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/LICENSE\"><img data-canonical-src=\"https://img.shields.io/github/license/jmcollin78/solar_optimizer.svg?style=for-the-badge\" alt=\"License\" src=\"https://camo.githubusercontent.com/32e0c68ab0943eb5e282b25b58c383c706aeb6e4cf30dce48972bbf5bd840e92/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6d636f6c6c696e37382f736f6c61725f6f7074696d697a65722e7376673f7374796c653d666f722d7468652d6261646765\"></a>\n<a href=\"https://github.com/custom-components/hacs\"><img data-canonical-src=\"https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge\" alt=\"hacs\" src=\"https://camo.githubusercontent.com/c6cc4252a49311200bc294f28002c1f223bee97ea35e7f93e8a990c64f804198/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f484143532d437573746f6d2d3431424446352e7376673f7374796c653d666f722d7468652d6261646765\"></a>\n<a rel=\"nofollow\" href=\"https://www.buymeacoffee.com/jmcollin78\"><img data-canonical-src=\"https://img.shields.io/badge/Buy%20me%20a%20beer-%245-orange?style=for-the-badge&amp;logo=buy-me-a-beer\" alt=\"BuyMeCoffee\" src=\"https://camo.githubusercontent.com/65ca663c31100e74122c1e4588886df98ceea998dde3b213606e186f31fd5aa4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275792532306d6525323061253230626565722d253234352d6f72616e67653f7374796c653d666f722d7468652d6261646765266c6f676f3d6275792d6d652d612d62656572\"></a></p>\n<p dir=\"auto\"><a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/images/icon.png?raw=true\" rel=\"noopener noreferrer\"><img alt=\"Icon\" src=\"https://github.com/jmcollin78/solar_optimizer/raw/main/images/icon.png?raw=true\"></a></p>\n<blockquote>\n<p dir=\"auto\"><a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/images/tips.png?raw=true\" rel=\"noopener noreferrer\"><img alt=\"Tip\" src=\"https://github.com/jmcollin78/solar_optimizer/raw/main/images/tips.png?raw=true\"></a> This integration allows you to optimize the use of your solar energy. It controls the switching on and off of your equipment, the activation of which is deferred over time depending on production and current electricity consumption.</p>\n</blockquote>\n<ul dir=\"auto\">\n<li><a href=\"#what-is-solar-optimizer\">What is Solar Optimizer?</a></li>\n<li><a href=\"#how-does-it-work\">How does it work?</a>\n<ul dir=\"auto\">\n<li><a href=\"#anti-flickering\">Anti-flickering</a></li>\n<li><a href=\"#usability\">Usability</a></li>\n</ul>\n</li>\n<li><a href=\"#how-do-we-install-it\">How do we install it?</a>\n<ul dir=\"auto\">\n<li><a href=\"#hacs-installation-recommended\">HACS installation (recommended)</a></li>\n<li><a href=\"#manual-install\">Manual Install</a></li>\n</ul>\n</li>\n<li><a href=\"#the-configuration\">The configuration</a>\n<ul dir=\"auto\">\n<li><a href=\"#configure-integration\">Configure integration</a></li>\n<li><a href=\"#configure-equipment\">Configure equipment</a></li>\n</ul>\n</li>\n<li><a href=\"#available-entities\">Available entities</a></li>\n<li><a href=\"#in-addition\">In addition</a></li>\n<li><a href=\"#contributions-are-welcome\">Contributions are welcome!</a></li>\n</ul>\n<blockquote>\n<p dir=\"auto\"><a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/images/new-icon.png?raw=true\" rel=\"noopener noreferrer\"><img alt=\"New\" src=\"https://github.com/jmcollin78/solar_optimizer/raw/main/images/new-icon.png?raw=true\"></a> <em><em>News</em></em></p>\n<ul dir=\"auto\">\n<li><strong>release 1.7.0</strong>:</li>\n</ul>\n<ul dir=\"auto\">\n<li>added battery management. You can specify a percentage type entity that gives the state of charge of the battery (soc). On each device you can specify a <code>battery_soc_threshold</code> parameter: the battery threshold below which the device will not be usable.</li>\n</ul>\n<ul dir=\"auto\">\n<li><strong>release 1.3.0</strong>:\n<ul dir=\"auto\">\n<li>added the parameter <code>duration_stop_min</code> which allows to specify a minimal duration of deactivation to distinguish it from the minimal delay of activation <code>duration_min</code>. If not specified, this parameter takes the value of <code>duration_min</code>.</li>\n<li>restores the state of the <code>enable</code> switches when the integration starts.</li>\n<li>starts a calculation immediately after starting Home Assistant</li>\n</ul>\n</li>\n<li><strong>release 1.0</strong>: first operational version. Control of equipment based on switches, power control (Tesla) and configuration via configuration.yaml.</li>\n</ul>\n</blockquote>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">What is Solar Optimizer?</h2><a href=\"#what-is-solar-optimizer\" aria-label=\"Permalink: What is Solar Optimizer?\" id=\"user-content-what-is-solar-optimizer\"></a></p>\n<p dir=\"auto\">This integration will allow you to maximize the use of your solar production. You delegate to it the control of your equipment whose activation can be deferred over time (water heater, swimming pool pump, electric vehicle charge, dishwasher, washing machine, etc.) and it takes care of launching them when the power produced is sufficient.</p>\n<p dir=\"auto\">It constantly tries to minimize the import and export of energy by starting, stopping and modifying the power allocated to equipment.</p>\n<p dir=\"auto\">2 types of equipment are managed:</p>\n<ol dir=\"auto\">\n<li>equipment controlled by a switch (a service in general) which has a fixed and pre-determined power consumption,</li>\n<li>equipment whose power consumption is adjustable (Tesla, Robotdyn). By adjusting the power allocated to this equipment, Solar Optimizer aligns consumption as closely as possible with production.</li>\n</ol>\n<p dir=\"auto\">The ideal is to have at least one piece of equipment whose power is adjustable in the list of equipment managed by Solar Optimizer.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">How does it work?</h2><a href=\"#how-does-it-work\" aria-label=\"Permalink: How does it work?\" id=\"user-content-how-does-it-work\"></a></p>\n<p dir=\"auto\">The operation is as follows:</p>\n<ol dir=\"auto\">\n<li>at regular intervals (configurable), the algorithm simulates modifications to the states of the equipment (on / off / allocated power) and calculates a cost for this configuration. Overall the cost is the <code>a * imported_power + b * exported_power</code>. The coefficients a and b are calculated according to the cost of electricity at the time of calculation,</li>\n<li>the algorithm keeps the best configuration (the one with a minimum cost) and looks for other solutions, until a minimum is reached.</li>\n<li>the best configuration is then applied.</li>\n</ol>\n<p dir=\"auto\">The algorithm used is a simulated annealing type algorithm, a description of which you will find here: <a rel=\"nofollow\" href=\"https://fr.wikipedia.org/wiki/Recuit_simul%C3%A9\">https://fr.wikipedia.org/wiki/Recuit_simul%C3%A9</a></p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Anti-flickering</h2><a href=\"#anti-flickering\" aria-label=\"Permalink: Anti-flickering\" id=\"user-content-anti-flickering\"></a></p>\n<p dir=\"auto\">To avoid the effects of flickering from one cycle to another, a minimum activation delay can be configured by equipment: <code>duration_min</code>. For example: a water heater must be activated for at least one hour for the ignition to be useful, charging an electric car must last at least two hours, ...\nSimilarly, a minimum stop duration can be specified in the <code>duration_stop_min</code> parameter.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Usability</h2><a href=\"#usability\" aria-label=\"Permalink: Usability\" id=\"user-content-usability\"></a></p>\n<p dir=\"auto\">Each configured device is associated with a switch-type entity that authorizes the algorithm to use the device. If I want to force the heating of the hot water tank, I put its switch to off. The algorithm will therefore not look at it, the water heater switches back to manual, not managed by Solar Optimizer.</p>\n<p dir=\"auto\">In addition, it is possible to define a usability rule for equipment. For example, if the car is charged at more than 90%, the algorithm considers that the equipment which controls the charging of the car must be switched off. This rule is defined in the form of a configurable template which is True if the equipment is usable.</p>\n<p dir=\"auto\">If a battery is specified when configuring the integration and if the threshold <code>battery_soc_threshold</code> is specified, the equipment will only be usable if the soc (percentage of battery charge) is greater than or equal to the threshold.</p>\n<p dir=\"auto\">These 3 rules allow the algorithm to only order what is really useful at a given time. These rules are re-evaluated each cycle.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">How do we install it?</h2><a href=\"#how-do-we-install-it\" aria-label=\"Permalink: How do we install it?\" id=\"user-content-how-do-we-install-it\"></a></p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">HACS installation (recommended)</h2><a href=\"#hacs-installation-recommended\" aria-label=\"Permalink: HACS installation (recommended)\" id=\"user-content-hacs-installation-recommended\"></a></p>\n<ol dir=\"auto\">\n<li>Install <a rel=\"nofollow\" href=\"https://hacs.xyz/\">HACS</a>. This way you get updates automatically.</li>\n<li>Add this Github repo as a custom repo in HACS settings.</li>\n<li>Find and install \"Solar Optimizer\" in HACS and click \"Install\".</li>\n<li>Restart Home Assistant.</li>\n<li>Then you can add the Solar Optimizer integration in the integration page. You can only install one Solar Optimizer integration.</li>\n</ol>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Manual Install</h2><a href=\"#manual-install\" aria-label=\"Permalink: Manual Install\" id=\"user-content-manual-install\"></a></p>\n<p dir=\"auto\">Manual installation is possible. It is not recommended and therefore it will not be described here.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">The configuration</h2><a href=\"#the-configuration\" aria-label=\"Permalink: The configuration\" id=\"user-content-the-configuration\"></a></p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Configure integration</h2><a href=\"#configure-integration\" aria-label=\"Permalink: Configure integration\" id=\"user-content-configure-integration\"></a></p>\n<p dir=\"auto\">When adding the Solar Optimizer integration, the following settings page opens:</p>\n<p dir=\"auto\">You must specify:</p>\n<ol dir=\"auto\">\n<li>the sensor which gives the instantaneous net consumption of the dwelling (it must be negative if production exceeds consumption). This figure is indicated in Watt,</li>\n<li>the sensor which gives the instantaneous photovoltaic production in Watt too,</li>\n<li>a sensor or input_number which gives the cost of the imported kwh,</li>\n<li>a sensor or input_number which gives the price of the exported kwh (depends on your contract),</li>\n<li>a sensor or input_number which gives the applicable tax on the exported kwh (depends on your contract)</li>\n</ol>\n<p dir=\"auto\">These 5 pieces of information are necessary for the algorithm to work, so they are all mandatory. The fact that they are sensors or input_number allows to have values that are re-evaluated at each cycle. Consequently, switching to off-peak hours can modify the calculation and therefore the states of the equipment since the import becomes less expensive. So everything is dynamic and recalculated at each cycle.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Configure equipment</h2><a href=\"#configure-equipment\" aria-label=\"Permalink: Configure equipment\" id=\"user-content-configure-equipment\"></a></p>\n<p dir=\"auto\">Controllable devices are defined in the configuration.yaml file as follows:</p>\n<ul dir=\"auto\">\n<li>\n<p dir=\"auto\">add the following line in your configuration.yaml:</p>\n<p dir=\"auto\"><code>solar_optimizer: !include solar_optimizer.yaml</code></p>\n</li>\n<li>\n<p dir=\"auto\">and create a file at the same level as the configuration.yaml with the following information:</p>\n</li>\n</ul>\n<div><pre><code>algorithm:\n initial_temp: 1000\n min_temp: 0.1\n cooling_factor: 0.95\n max_iteration_number: 1000\ndevices:\n - name: \"&lt;equipment name&gt;\"\n entity_id: \"switch.xxxxx\"\n power_max: &lt;max power consumed&gt;\n check_usable_template: \"{{ &lt;the template which is True if the equipment is usable&gt; }}\"\n duration_min: &lt;the minimum activation duration in minutes&gt;\n duration_stop_min: &lt;minimum stop duration in minutes&gt;\n action_mode: \"service_call\"\n activation_service: \"&lt;service name&gt;\"\n deactivation_service: \"&lt;service name&gt;\"\n battery_soc_threshold: 30\n</code></pre></div>\n<p dir=\"auto\">Note: parameters under <code>algorithm</code> should not be touched unless you know exactly what you are doing.</p>\n<p dir=\"auto\">Under <code>devices</code> you must declare all the equipment that will be controlled by Solar Optimizer as follows:</p>\n<table tabindex=\"0\">\n<thead>\n<tr>\n<th>attribute</th>\n<th>valid for</th>\n<th>meaning</th>\n<th>example</th>\n<th>comment</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>all</td>\n<td>The name of the equipment</td>\n<td>\"VMC basement\"</td>\n<td>-</td>\n</tr>\n<tr>\n<td><code>entity_id</code></td>\n<td>all</td>\n<td>the entity id of the equipment to order</td>\n<td>\"switch.vmc_basement\"</td>\n<td>-</td>\n</tr>\n<tr>\n<td><code>power_max</code></td>\n<td>all</td>\n<td>the maximum power consumed by the equipment</td>\n<td>250</td>\n<td>-</td>\n</tr>\n<tr>\n<td><code>check_usable_template</code></td>\n<td>all</td>\n<td>A template that is True if the equipment can be used by Solar Optimizer</td>\n<td>\"{{ is_state('cover.porte_garage_garage', 'closed') }}\"</td>\n<td>In the example, Sonar Optimizer will not try to control the \"VMC basement\" if the garage door is open</td>\n</tr>\n<tr>\n<td><code>duration_min</code></td>\n<td>all</td>\n<td>The minimum duration in minutes of activation</td>\n<td>60</td>\n<td>The basement VMC will always turn on for at least one hour</td>\n</tr>\n<tr>\n<td><code>duration_stop_min</code></td>\n<td>all</td>\n<td>The minimum duration in minutes of deactivation. Is <code>duration_min</code> if not specified</td>\n<td>15</td>\n<td>The basement VMC will always turn off for at least 15 min</td>\n</tr>\n<tr>\n<td><code>action_mode</code></td>\n<td>all</td>\n<td>the mode of action for turning the equipment on or off. Can be \"service_call\" or \"event\" (*)</td>\n<td>\"service_call\"</td>\n<td>\"service_call\" indicates that the equipment is switched on and off via a service call. See below. \"event\" indicates that an event is sent when the state should change. See (*)</td>\n</tr>\n<tr>\n<td><code>activation_service</code></td>\n<td>only if action_mode=\"service_call\"</td>\n<td>the service to be called to activate the equipment in the form \"domain/service\"</td>\n<td>\"switch/turn_on\"</td>\n<td>activation will trigger the \"switch/turn_on\" service on the entity \"entity_id\"</td>\n</tr>\n<tr>\n<td><code>deactivation_service</code></td>\n<td>only if action_mode=\"service_call\"</td>\n<td>the service to call to deactivate the equipment in the form \"domain/service\"</td>\n<td>\"switch/turn_off\"</td>\n<td>deactivation will trigger the \"switch/turn_off\" service on the entity \"entity_id\"</td>\n</tr>\n<tr>\n<td><code>battery_soc_threshold</code></td>\n<td>tous</td>\n<td>minimal percentage of charge of the solar battery to enable this device</td>\n<td>30</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<p dir=\"auto\">For variable power equipment, the following attributes must be valued:</p>\n<table tabindex=\"0\">\n<thead>\n<tr>\n<th>attribute</th>\n<th>valid for</th>\n<th>meaning</th>\n<th>example</th>\n<th>comment</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>power_entity_id</code></td>\n<td>variable power equipment</td>\n<td>the entity_id of the entity managing the power</td>\n<td><code>number.tesla_charging_amps</code></td>\n<td>The power change will be done by calling the <code>change_power_service</code> service on this entity</td>\n</tr>\n<tr>\n<td><code>power_min</code></td>\n<td>variable power equipment</td>\n<td>The minimum power in watts of the equipment</td>\n<td>100</td>\n<td>When the power setpoint falls below this value, the equipment will be switched off by calling the <code>deactivation_service</code></td>\n</tr>\n<tr>\n<td><code>power_step</code></td>\n<td>variable power equipment</td>\n<td>The power step</td>\n<td>10</td>\n<td>-</td>\n</tr>\n<tr>\n<td><code>change_power_service</code></td>\n<td>variable power equipment</td>\n<td>Service called to change power</td>\n<td><code>\"number/set_value\"</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td><code>convert_power_divide_factor</code></td>\n<td>variable power equipment</td>\n<td>The divisor applied to convert power to value</td>\n<td>50</td>\n<td>In the example, the \"number/set_value\" service will be called with the <code>power setpoint / 50</code> on the entity <code>entity_id</code>. For a Tesla on a three-phase electrical installation this parameter should be set to 660 (220 x 3), to convert power to amperes. For mono-phase installation, set it to 220.</td>\n</tr>\n</tbody>\n</table>\n<p dir=\"auto\">Complete and commented example of the device part:</p>\n<div><pre><code>devices:\n - name: \"Reservoir pump\"\n # The switch that controls the tank pump\n entity_id: \"switch.tank_pump_socket\"\n # the power of this pump\n power_max: 170\n # Always usable\n # check_usable_template: \"{{ True }}\"\n # 15 min minimum activation\n duration_min: 15\n # 5 min deactivation minimum\n duration_stop_min: 5\n # On enable/disable via a service call\n action_mode: \"service_call\"\n # The service enabling the switch\n activation_service: \"switch/turn_on\"\n # The service to deactivate the switch\n deactivation_service: \"switch/turn_off\"\n # We authorize the pump to start if there is 10% battery in the solar installation\n battery_soc_threshold: 10\n\n - name: \"Tesla Recharge\"\n entity_id: \"switch.cloucloute_charger\"\n # The minimum load power is 660 W (i.e. 1 Amp because convert_power_divide_factor=660 too)\n power_min: 660\n # The minimum load power is 3960 W (i.e. 5 Amp (= 3960/600) )\n power_max: 3960\n # the step of 660 or 1 Amp after division by convert_power_divide_factor\n power_step: 660\n # Usable if the charging mode is \"Solar\" and the car is plugged into the charger and it is charged at less than 90% (so it stops by itself at 90%)\n check_usable_template: \"{{ is_state('input_select.charge_mode', 'Solar') and is_state('binary_sensor.tesla_wall_connector_vehicle_connected', 'on') and is_state('binary_sensor.tesla_charger', 'on') and states('sensor.tesla_battery ') | float(100) &lt; states('number.cloucloute_charge_limit') | float(90) }}\"\n # 1 hour minimum charge\n duration_min: 60\n # 15 min minimum stop charge\n duration_stop_min: 15\n # The entity that drives the load amperage\n power_entity_id: \"number.tesla_charging_amps\"\n # 5 min minimum between 2 power changes\n duration_power_min: 5\n # activation is done by a service call\n action_mode: \"service_call\"\n activation_service: \"switch/turn_on\"\n deactivation_service: \"switch/turn_off\"\n # the power change is done by a service call\n change_power_service: \"number/set_value\"\n # the factor used to convert the set power into Amps (number.tesla_charging_amps takes Amps)\n convert_power_divide_factor: 660\n # We do not start a charge if the battery of the solar installation is not at least 50% charged\n battery_soc_threshold: 50\n...\n</code></pre></div>\n<p dir=\"auto\">Any change in the configuration requires a stop / restart of the integration (or of Home Assistant) to be taken into account.</p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Available entities</h2><a href=\"#available-entities\" aria-label=\"Permalink: Available entities\" id=\"user-content-available-entities\"></a></p>\n<p dir=\"auto\">The integration, once properly configured, creates a device that contains several entities:</p>\n<ol dir=\"auto\">\n<li>a sensor named \"total_power\" which is the total of all the powers of the equipment controlled by Solar Optimizer,</li>\n<li>a sensor named \"best_objective\" which is the value of the cost function (see how the algorithm works),</li>\n<li>a switch per equipment named <code>switch.enable_solar_optimizer_&lt;name&gt;</code> declared in the configuration.yaml. If the switch is \"Off\", the algorithm will not consider this equipment for the calculation. This allows you to manually remove equipment from the list without having to modify the list. This switch contains additional attributes which make it possible to follow the internal state of the equipment seen by the algorithm.</li>\n</ol>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">In addition</h2><a href=\"#in-addition\" aria-label=\"Permalink: In addition\" id=\"user-content-in-addition\"></a></p>\n<p dir=\"auto\">In addition, the following Lovelace code is used to control each declared device:</p>\n<div><pre><code># To put at the beginning of the front-end page\ndecluttering_templates:\n managed_device_power:\n default: null\n card:\n type: custom:expander-card\n expanded: false\n title-card-button-overlay: true\n title-card:\n type: custom:mushroom-template-card\n primary: \"{{ state_attr('[[device]]', 'friendly_name') }}\"\n secondary: \"[[secondary_infos]]\"\n icon: \"[[icon]]\"\n badge_icon: &gt;-\n {% if is_state_attr('[[device]]','is_enabled', True) %}mdi:check{%\n else %}mdi:cancel{% endif %}\n badge_color: &gt;-\n {% if is_state_attr('[[device]]', 'is_usable', True) and\n is_state_attr('[[device]]', 'is_enabled', True) %}green {% elif\n is_state_attr('[[device]]', 'is_enabled', False) %}red {% elif\n is_state_attr('[[device]]','is_waiting', True) %}orange {% elif\n is_state_attr('[[device]]', 'is_usable', False) or\n state_attr('[[device]]', 'is_usable') is none %}#A0B0FF{% else\n %}blue{% endif %}\n entity: \"[[device]]\"\n icon_color: &gt;-\n {% if is_state('[[device]]', 'on')%}orange{% else %}lightgray{% endif\n %}\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n double_tap_action:\n action: none\n cards:\n - type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: \"[[enable_entity]]\"\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: name\n - type: markdown\n content: &gt;-\n **Prochaine dispo** : {{ ((as_timestamp(state_attr('[[device]]',\n 'next_date_available')) - as_timestamp(now())) / 60) | int }}\n min&lt;br&gt; **Prochaine dispo puissance**: {{\n ((as_timestamp(state_attr('[[device]]',\n 'next_date_available_power')) - as_timestamp(now())) / 60) | int }}\n min&lt;br&gt; **Utilisable** : {{ state_attr('[[device]]', 'is_usable')\n }}&lt;br&gt; **Est en attente** : {{ state_attr('[[device]]',\n 'is_waiting') }}&lt;br&gt; **Puissance requise** : {{\n state_attr('[[device]]', 'requested_power') }} W&lt;br&gt; **Puissance\n courante** : {{ state_attr('[[device]]', 'current_power') }} W\n title: Infos\n managed_device:\n default: null\n card:\n type: custom:expander-card\n expanded: false\n title-card-button-overlay: true\n title-card:\n type: custom:mushroom-template-card\n primary: \"{{ state_attr('[[device]]', 'friendly_name') }}\"\n secondary: &gt;-\n [[secondary_infos]] (max. {{ state_attr('[[device]]', 'power_max') }}\n W)\n icon: \"[[icon]]\"\n badge_icon: &gt;-\n {% if is_state_attr('[[device]]','is_enabled', True) %}mdi:check{%\n else %}mdi:cancel{% endif %}\n badge_color: &gt;-\n {% if is_state_attr('[[device]]', 'is_usable', True) and\n is_state_attr('[[device]]', 'is_enabled', True) %}green {% elif\n is_state_attr('[[device]]', 'is_enabled', False) %}red {% elif\n is_state_attr('[[device]]','is_waiting', True) %}orange {% elif\n is_state_attr('[[device]]', 'is_usable', False) or\n state_attr('[[device]]', 'is_usable') is none %}#A0B0FF{% else\n %}blue{% endif %}\n entity: \"[[device]]\"\n icon_color: &gt;-\n {% if is_state('[[device]]', 'on')%}orange{% else %}lightgray{% endif\n %}\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n double_tap_action:\n action: none\n cards:\n - type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: \"[[enable_entity]]\"\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: name\n - type: markdown\n content: &gt;-\n **Prochaine dispo** : {{ ((as_timestamp(state_attr('[[device]]',\n 'next_date_available')) - as_timestamp(now())) / 60) | int }}\n min&lt;br&gt; **Utilisable** : {{ state_attr('[[device]]', 'is_usable')\n }}&lt;br&gt; **Est en attente** : {{ state_attr('[[device]]',\n 'is_waiting') }}&lt;br&gt; **Puissance requise** : {{\n state_attr('[[device]]', 'requested_power') }} W&lt;br&gt; **Puissance\n courante** : {{ state_attr('[[device]]', 'current_power') }} W\n enable_template:\n default: null\n card:\n type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: '[[enable_entity]]'\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: none\n</code></pre></div>\n<p dir=\"auto\">then use as follows:</p>\n<div><pre><code> - type: vertical-stack\n cards:\n - type: custom:decluttering-card\n template: managed_device_power\n variables:\n - device: switch.solar_optimizer_recharge_tesla\n - secondary_infos: &gt;-\n {{ states('sensor.total_puissance_instantanee_twc_w') }} W\n ({{ states('number.tesla_charging_amps')}} A)\n - icon: mdi:ev-station\n - enable_entity: switch.enable_solar_optimizer_recharge_tesla\n - type: custom:decluttering-card\n template: managed_device\n variables:\n - device: switch.solar_optimizer_prise_recharge_voiture_garage\n - secondary_infos: '{{ states(''sensor.prise_garage_voiture_power'') }} W'\n - icon: mdi:power-socket-fr\n - enable_entity: &gt;-\n switch.enable_solar_optimizer_prise_recharge_voiture_garage\n</code></pre></div>\n<p dir=\"auto\">You will then get a component to interact with the equipment that looks like this:</p>\n<p dir=\"auto\"><a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/images/lovelace-eqts.png?raw=true\" rel=\"noopener noreferrer\"><img alt=\"Lovelace equipment\" src=\"https://github.com/jmcollin78/solar_optimizer/raw/main/images/lovelace-eqts.png?raw=true\"></a></p>\n<p dir=\"auto\"><h2 dir=\"auto\" tabindex=\"-1\">Contributions are welcome!</h2><a href=\"#contributions-are-welcome\" aria-label=\"Permalink: Contributions are welcome!\" id=\"user-content-contributions-are-welcome\"></a></p>\n<p dir=\"auto\">If you would like to contribute, please read the <a href=\"https://github.com/jmcollin78/solar_optimizer/blob/main/CONTRIBUTING.md\">contribution guidelines</a></p>\n<hr>\n</article></div></div>","textContent":"\n\n\n\n\n\n\n This integration allows you to optimize the use of your solar energy. It controls the switching on and off of your equipment, the activation of which is deferred over time depending on production and current electricity consumption.\n\n\nWhat is Solar Optimizer?\nHow does it work?\n\nAnti-flickering\nUsability\n\n\nHow do we install it?\n\nHACS installation (recommended)\nManual Install\n\n\nThe configuration\n\nConfigure integration\nConfigure equipment\n\n\nAvailable entities\nIn addition\nContributions are welcome!\n\n\n News\n\nrelease 1.7.0:\n\n\nadded battery management. You can specify a percentage type entity that gives the state of charge of the battery (soc). On each device you can specify a battery_soc_threshold parameter: the battery threshold below which the device will not be usable.\n\n\nrelease 1.3.0:\n\nadded the parameter duration_stop_min which allows to specify a minimal duration of deactivation to distinguish it from the minimal delay of activation duration_min. If not specified, this parameter takes the value of duration_min.\nrestores the state of the enable switches when the integration starts.\nstarts a calculation immediately after starting Home Assistant\n\n\nrelease 1.0: first operational version. Control of equipment based on switches, power control (Tesla) and configuration via configuration.yaml.\n\n\nWhat is Solar Optimizer?\nThis integration will allow you to maximize the use of your solar production. You delegate to it the control of your equipment whose activation can be deferred over time (water heater, swimming pool pump, electric vehicle charge, dishwasher, washing machine, etc.) and it takes care of launching them when the power produced is sufficient.\nIt constantly tries to minimize the import and export of energy by starting, stopping and modifying the power allocated to equipment.\n2 types of equipment are managed:\n\nequipment controlled by a switch (a service in general) which has a fixed and pre-determined power consumption,\nequipment whose power consumption is adjustable (Tesla, Robotdyn). By adjusting the power allocated to this equipment, Solar Optimizer aligns consumption as closely as possible with production.\n\nThe ideal is to have at least one piece of equipment whose power is adjustable in the list of equipment managed by Solar Optimizer.\nHow does it work?\nThe operation is as follows:\n\nat regular intervals (configurable), the algorithm simulates modifications to the states of the equipment (on / off / allocated power) and calculates a cost for this configuration. Overall the cost is the a * imported_power + b * exported_power. The coefficients a and b are calculated according to the cost of electricity at the time of calculation,\nthe algorithm keeps the best configuration (the one with a minimum cost) and looks for other solutions, until a minimum is reached.\nthe best configuration is then applied.\n\nThe algorithm used is a simulated annealing type algorithm, a description of which you will find here: https://fr.wikipedia.org/wiki/Recuit_simul%C3%A9\nAnti-flickering\nTo avoid the effects of flickering from one cycle to another, a minimum activation delay can be configured by equipment: duration_min. For example: a water heater must be activated for at least one hour for the ignition to be useful, charging an electric car must last at least two hours, ...\nSimilarly, a minimum stop duration can be specified in the duration_stop_min parameter.\nUsability\nEach configured device is associated with a switch-type entity that authorizes the algorithm to use the device. If I want to force the heating of the hot water tank, I put its switch to off. The algorithm will therefore not look at it, the water heater switches back to manual, not managed by Solar Optimizer.\nIn addition, it is possible to define a usability rule for equipment. For example, if the car is charged at more than 90%, the algorithm considers that the equipment which controls the charging of the car must be switched off. This rule is defined in the form of a configurable template which is True if the equipment is usable.\nIf a battery is specified when configuring the integration and if the threshold battery_soc_threshold is specified, the equipment will only be usable if the soc (percentage of battery charge) is greater than or equal to the threshold.\nThese 3 rules allow the algorithm to only order what is really useful at a given time. These rules are re-evaluated each cycle.\nHow do we install it?\nHACS installation (recommended)\n\nInstall HACS. This way you get updates automatically.\nAdd this Github repo as a custom repo in HACS settings.\nFind and install \"Solar Optimizer\" in HACS and click \"Install\".\nRestart Home Assistant.\nThen you can add the Solar Optimizer integration in the integration page. You can only install one Solar Optimizer integration.\n\nManual Install\nManual installation is possible. It is not recommended and therefore it will not be described here.\nThe configuration\nConfigure integration\nWhen adding the Solar Optimizer integration, the following settings page opens:\nYou must specify:\n\nthe sensor which gives the instantaneous net consumption of the dwelling (it must be negative if production exceeds consumption). This figure is indicated in Watt,\nthe sensor which gives the instantaneous photovoltaic production in Watt too,\na sensor or input_number which gives the cost of the imported kwh,\na sensor or input_number which gives the price of the exported kwh (depends on your contract),\na sensor or input_number which gives the applicable tax on the exported kwh (depends on your contract)\n\nThese 5 pieces of information are necessary for the algorithm to work, so they are all mandatory. The fact that they are sensors or input_number allows to have values that are re-evaluated at each cycle. Consequently, switching to off-peak hours can modify the calculation and therefore the states of the equipment since the import becomes less expensive. So everything is dynamic and recalculated at each cycle.\nConfigure equipment\nControllable devices are defined in the configuration.yaml file as follows:\n\n\nadd the following line in your configuration.yaml:\nsolar_optimizer: !include solar_optimizer.yaml\n\n\nand create a file at the same level as the configuration.yaml with the following information:\n\n\nalgorithm:\n initial_temp: 1000\n min_temp: 0.1\n cooling_factor: 0.95\n max_iteration_number: 1000\ndevices:\n - name: \"<equipment name>\"\n entity_id: \"switch.xxxxx\"\n power_max: <max power consumed>\n check_usable_template: \"{{ <the template which is True if the equipment is usable> }}\"\n duration_min: <the minimum activation duration in minutes>\n duration_stop_min: <minimum stop duration in minutes>\n action_mode: \"service_call\"\n activation_service: \"<service name>\"\n deactivation_service: \"<service name>\"\n battery_soc_threshold: 30\n\nNote: parameters under algorithm should not be touched unless you know exactly what you are doing.\nUnder devices you must declare all the equipment that will be controlled by Solar Optimizer as follows:\n\n\n\nattribute\nvalid for\nmeaning\nexample\ncomment\n\n\n\n\nname\nall\nThe name of the equipment\n\"VMC basement\"\n-\n\n\nentity_id\nall\nthe entity id of the equipment to order\n\"switch.vmc_basement\"\n-\n\n\npower_max\nall\nthe maximum power consumed by the equipment\n250\n-\n\n\ncheck_usable_template\nall\nA template that is True if the equipment can be used by Solar Optimizer\n\"{{ is_state('cover.porte_garage_garage', 'closed') }}\"\nIn the example, Sonar Optimizer will not try to control the \"VMC basement\" if the garage door is open\n\n\nduration_min\nall\nThe minimum duration in minutes of activation\n60\nThe basement VMC will always turn on for at least one hour\n\n\nduration_stop_min\nall\nThe minimum duration in minutes of deactivation. Is duration_min if not specified\n15\nThe basement VMC will always turn off for at least 15 min\n\n\naction_mode\nall\nthe mode of action for turning the equipment on or off. Can be \"service_call\" or \"event\" (*)\n\"service_call\"\n\"service_call\" indicates that the equipment is switched on and off via a service call. See below. \"event\" indicates that an event is sent when the state should change. See (*)\n\n\nactivation_service\nonly if action_mode=\"service_call\"\nthe service to be called to activate the equipment in the form \"domain/service\"\n\"switch/turn_on\"\nactivation will trigger the \"switch/turn_on\" service on the entity \"entity_id\"\n\n\ndeactivation_service\nonly if action_mode=\"service_call\"\nthe service to call to deactivate the equipment in the form \"domain/service\"\n\"switch/turn_off\"\ndeactivation will trigger the \"switch/turn_off\" service on the entity \"entity_id\"\n\n\nbattery_soc_threshold\ntous\nminimal percentage of charge of the solar battery to enable this device\n30\n\n\n\n\nFor variable power equipment, the following attributes must be valued:\n\n\n\nattribute\nvalid for\nmeaning\nexample\ncomment\n\n\n\n\npower_entity_id\nvariable power equipment\nthe entity_id of the entity managing the power\nnumber.tesla_charging_amps\nThe power change will be done by calling the change_power_service service on this entity\n\n\npower_min\nvariable power equipment\nThe minimum power in watts of the equipment\n100\nWhen the power setpoint falls below this value, the equipment will be switched off by calling the deactivation_service\n\n\npower_step\nvariable power equipment\nThe power step\n10\n-\n\n\nchange_power_service\nvariable power equipment\nService called to change power\n\"number/set_value\"\n-\n\n\nconvert_power_divide_factor\nvariable power equipment\nThe divisor applied to convert power to value\n50\nIn the example, the \"number/set_value\" service will be called with the power setpoint / 50 on the entity entity_id. For a Tesla on a three-phase electrical installation this parameter should be set to 660 (220 x 3), to convert power to amperes. For mono-phase installation, set it to 220.\n\n\n\nComplete and commented example of the device part:\ndevices:\n - name: \"Reservoir pump\"\n # The switch that controls the tank pump\n entity_id: \"switch.tank_pump_socket\"\n # the power of this pump\n power_max: 170\n # Always usable\n # check_usable_template: \"{{ True }}\"\n # 15 min minimum activation\n duration_min: 15\n # 5 min deactivation minimum\n duration_stop_min: 5\n # On enable/disable via a service call\n action_mode: \"service_call\"\n # The service enabling the switch\n activation_service: \"switch/turn_on\"\n # The service to deactivate the switch\n deactivation_service: \"switch/turn_off\"\n # We authorize the pump to start if there is 10% battery in the solar installation\n battery_soc_threshold: 10\n\n - name: \"Tesla Recharge\"\n entity_id: \"switch.cloucloute_charger\"\n # The minimum load power is 660 W (i.e. 1 Amp because convert_power_divide_factor=660 too)\n power_min: 660\n # The minimum load power is 3960 W (i.e. 5 Amp (= 3960/600) )\n power_max: 3960\n # the step of 660 or 1 Amp after division by convert_power_divide_factor\n power_step: 660\n # Usable if the charging mode is \"Solar\" and the car is plugged into the charger and it is charged at less than 90% (so it stops by itself at 90%)\n check_usable_template: \"{{ is_state('input_select.charge_mode', 'Solar') and is_state('binary_sensor.tesla_wall_connector_vehicle_connected', 'on') and is_state('binary_sensor.tesla_charger', 'on') and states('sensor.tesla_battery ') | float(100) < states('number.cloucloute_charge_limit') | float(90) }}\"\n # 1 hour minimum charge\n duration_min: 60\n # 15 min minimum stop charge\n duration_stop_min: 15\n # The entity that drives the load amperage\n power_entity_id: \"number.tesla_charging_amps\"\n # 5 min minimum between 2 power changes\n duration_power_min: 5\n # activation is done by a service call\n action_mode: \"service_call\"\n activation_service: \"switch/turn_on\"\n deactivation_service: \"switch/turn_off\"\n # the power change is done by a service call\n change_power_service: \"number/set_value\"\n # the factor used to convert the set power into Amps (number.tesla_charging_amps takes Amps)\n convert_power_divide_factor: 660\n # We do not start a charge if the battery of the solar installation is not at least 50% charged\n battery_soc_threshold: 50\n...\n\nAny change in the configuration requires a stop / restart of the integration (or of Home Assistant) to be taken into account.\nAvailable entities\nThe integration, once properly configured, creates a device that contains several entities:\n\na sensor named \"total_power\" which is the total of all the powers of the equipment controlled by Solar Optimizer,\na sensor named \"best_objective\" which is the value of the cost function (see how the algorithm works),\na switch per equipment named switch.enable_solar_optimizer_<name> declared in the configuration.yaml. If the switch is \"Off\", the algorithm will not consider this equipment for the calculation. This allows you to manually remove equipment from the list without having to modify the list. This switch contains additional attributes which make it possible to follow the internal state of the equipment seen by the algorithm.\n\nIn addition\nIn addition, the following Lovelace code is used to control each declared device:\n# To put at the beginning of the front-end page\ndecluttering_templates:\n managed_device_power:\n default: null\n card:\n type: custom:expander-card\n expanded: false\n title-card-button-overlay: true\n title-card:\n type: custom:mushroom-template-card\n primary: \"{{ state_attr('[[device]]', 'friendly_name') }}\"\n secondary: \"[[secondary_infos]]\"\n icon: \"[[icon]]\"\n badge_icon: >-\n {% if is_state_attr('[[device]]','is_enabled', True) %}mdi:check{%\n else %}mdi:cancel{% endif %}\n badge_color: >-\n {% if is_state_attr('[[device]]', 'is_usable', True) and\n is_state_attr('[[device]]', 'is_enabled', True) %}green {% elif\n is_state_attr('[[device]]', 'is_enabled', False) %}red {% elif\n is_state_attr('[[device]]','is_waiting', True) %}orange {% elif\n is_state_attr('[[device]]', 'is_usable', False) or\n state_attr('[[device]]', 'is_usable') is none %}#A0B0FF{% else\n %}blue{% endif %}\n entity: \"[[device]]\"\n icon_color: >-\n {% if is_state('[[device]]', 'on')%}orange{% else %}lightgray{% endif\n %}\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n double_tap_action:\n action: none\n cards:\n - type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: \"[[enable_entity]]\"\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: name\n - type: markdown\n content: >-\n **Prochaine dispo** : {{ ((as_timestamp(state_attr('[[device]]',\n 'next_date_available')) - as_timestamp(now())) / 60) | int }}\n min<br> **Prochaine dispo puissance**: {{\n ((as_timestamp(state_attr('[[device]]',\n 'next_date_available_power')) - as_timestamp(now())) / 60) | int }}\n min<br> **Utilisable** : {{ state_attr('[[device]]', 'is_usable')\n }}<br> **Est en attente** : {{ state_attr('[[device]]',\n 'is_waiting') }}<br> **Puissance requise** : {{\n state_attr('[[device]]', 'requested_power') }} W<br> **Puissance\n courante** : {{ state_attr('[[device]]', 'current_power') }} W\n title: Infos\n managed_device:\n default: null\n card:\n type: custom:expander-card\n expanded: false\n title-card-button-overlay: true\n title-card:\n type: custom:mushroom-template-card\n primary: \"{{ state_attr('[[device]]', 'friendly_name') }}\"\n secondary: >-\n [[secondary_infos]] (max. {{ state_attr('[[device]]', 'power_max') }}\n W)\n icon: \"[[icon]]\"\n badge_icon: >-\n {% if is_state_attr('[[device]]','is_enabled', True) %}mdi:check{%\n else %}mdi:cancel{% endif %}\n badge_color: >-\n {% if is_state_attr('[[device]]', 'is_usable', True) and\n is_state_attr('[[device]]', 'is_enabled', True) %}green {% elif\n is_state_attr('[[device]]', 'is_enabled', False) %}red {% elif\n is_state_attr('[[device]]','is_waiting', True) %}orange {% elif\n is_state_attr('[[device]]', 'is_usable', False) or\n state_attr('[[device]]', 'is_usable') is none %}#A0B0FF{% else\n %}blue{% endif %}\n entity: \"[[device]]\"\n icon_color: >-\n {% if is_state('[[device]]', 'on')%}orange{% else %}lightgray{% endif\n %}\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n double_tap_action:\n action: none\n cards:\n - type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: \"[[enable_entity]]\"\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: name\n - type: markdown\n content: >-\n **Prochaine dispo** : {{ ((as_timestamp(state_attr('[[device]]',\n 'next_date_available')) - as_timestamp(now())) / 60) | int }}\n min<br> **Utilisable** : {{ state_attr('[[device]]', 'is_usable')\n }}<br> **Est en attente** : {{ state_attr('[[device]]',\n 'is_waiting') }}<br> **Puissance requise** : {{\n state_attr('[[device]]', 'requested_power') }} W<br> **Puissance\n courante** : {{ state_attr('[[device]]', 'current_power') }} W\n enable_template:\n default: null\n card:\n type: custom:mushroom-chips-card\n chips:\n - type: entity\n entity: '[[enable_entity]]'\n double_tap_action:\n action: more-info\n tap_action:\n action: toggle\n hold_action:\n action: more-info\n icon_color: green\n content_info: none\n\nthen use as follows:\n - type: vertical-stack\n cards:\n - type: custom:decluttering-card\n template: managed_device_power\n variables:\n - device: switch.solar_optimizer_recharge_tesla\n - secondary_infos: >-\n {{ states('sensor.total_puissance_instantanee_twc_w') }} W\n ({{ states('number.tesla_charging_amps')}} A)\n - icon: mdi:ev-station\n - enable_entity: switch.enable_solar_optimizer_recharge_tesla\n - type: custom:decluttering-card\n template: managed_device\n variables:\n - device: switch.solar_optimizer_prise_recharge_voiture_garage\n - secondary_infos: '{{ states(''sensor.prise_garage_voiture_power'') }} W'\n - icon: mdi:power-socket-fr\n - enable_entity: >-\n switch.enable_solar_optimizer_prise_recharge_voiture_garage\n\nYou will then get a component to interact with the equipment that looks like this:\n\nContributions are welcome!\nIf you would like to contribute, please read the contribution guidelines\n\n","length":19536,"excerpt":"","siteName":null}