Skip to content

Commit

Permalink
Merge pull request #44 from dala318/documentation
Browse files Browse the repository at this point in the history
Update documentation to match version 2 integration
  • Loading branch information
dala318 authored Sep 25, 2024
2 parents 97c1c63 + 28ddcc6 commit dd75489
Showing 1 changed file with 42 additions and 95 deletions.
137 changes: 42 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,158 +23,105 @@ Apart from potentially saving some money, this kind of temporal shifting of cons

1. Install and configure https://github.com/custom-components/nordpool first.
2. Copy the `nordpool_planner` folder to HA `<config_dir>/custom_components/nordpool_planner/`
3. Restart HA. (Skipping restarting before modifying configuration would give "Integration 'nordpool_diff' not found"
error message from the configuration.)
3. Restart Home Assistant

### Configuration

> **IMPORTANT NOTE**: With version 2 configuration via `configuration.yaml` is no longer possible. Converting that configuration via "import config" is still not implemented. You wil have to remove the old now broken manual configuration and create a new via the GUI.
During setup some preconditions and selections are needed:

<!-- 1. Add the following to your file:
* Give a name to the service
* Select type "Moving" or "Static", more about these below (only moving is properly implemented)
* Select Nordpool prices entity from list to base states on
* Select which optional features you want activated, more about these below as well
* Submit and set your configuration parameters

```yaml
binary_sensor:
- platform: nordpool_planner
nordpool_entity: sensor.nordpool_kwh_fi_eur_3_095_024
entity_id: activate_heating
moving:
search_length: 8
<or>
static:
end_hour: 7
```
Exclusively either of `moving` or `static` shall be specified, determines the behavior of the sensor. See further down about usage.
Modify the `nordpool_entity` value according to your exact nordpool entity ID, give the entity a describing name and select one of two planner types `moving` or `static`.
`moving` planner searches in a constant window in the future
`static` planner searches for an ammount of cheap hours until a set time (work in progress!)
2. Restart HA again to load the configuration. Now you should see `nordpool_planner_2_10_0_0_0_0` binary_sensor, where
the `2_10_0_0_0_0` part corresponds to default values of optional parameters, explained below. -->

## Optional parameters

<!-- There are some optional parameters that could be provided to the sensor, they can be grouped in some categories.
Generic optional: `duration` (2), `var_duration_entity` (""), `accept_cost` (0.0) and `accept_rate` (0.0). Default values in parenthesis.
`duration` can be in the range of 1 to 5 and specifies how large window of censecutive hours to slide forward in search for a minimum average price.
### Moving

`var_duration_entity` an entity that provides a numerical value in hours.
Two non-optional configuration entities will be created and you need to set these to a value that matches your consumption profile.

The integration will use `var_duration_entity` if supplied and can be interpreted as int, otherwise `duration` or the default value.
* `search_length` specifies how many hours ahead to search for lowest price.
* `duration` specifies how large window to average when searching for lowest price

A simple way to get you a slider to manually select an input entity value is by an `input_number` as below
The service will then take `duration` number of consecutive prices from the nordpool sensor starting from `now` and average them, then shift start one hour and repeat, until reaching `search_length` from now.
If no optional features activated the `duration` window in the current range of prices within `search_length` with lowest average is selected as cheapest and the `low_cost` entity will turn on if `now` is within those hours.

```yaml
input_number:
np_time:
name: Time to Nordpool Planner
initial: 2
min: 0
max: 24
step: 1
``` -->
In general you should set `search_length` to a value how long you could wait to activate high-consumption device and `duration` to how long it have to be kept active. But you have to test different settings to find your optimal configuration.

`accept_cost` specifies a price level in the currency of your `nordpool_entity`, that if an "average over a duration" is below this value, it is accepted and used. Even if not the lowest in the range specified.
What should be said is that since the `search_length` window is continuously moving forward for every hour that passes the lowest cost `duration` may change as new prices comes inside range of search. There is also no guarantee that it will keep active for `duration` once activated.

`accept_rate` specifies a price rate, that if an "average over a duration" divided by nordpool average (`nordpool_entity.attributes.average`) is below this rate, it is accepted and used. Even if not the lowest in the range specified. E.g. if set to 1 an "average over a duration" <= "nordpool average" is accepted. If 0.5 it has to be half the price of "nordpool average". The idea is to not be as sensitive to offsets I price levels but just a generic rule to accept low section, not just the lowest.
### Static

The planner types has some additional configuration variables
> **WORK IN PROGRESS**: This version of entity is still not fully tested, may need some more work to work properly.
### Moving
`end_hour` can be in the range of 0 to 23 and specifies at what time within 24 hours the amount of active hours shall be selected.

<!-- Optional parameter `var_search_length_entity` (""). Default value in parenthesis.
The integration will use `var_end_hour_entity` if supplied and can be interpreted as int, otherwise `end_hour` or the default value.

```yaml
binary_sensor:
- platform: nordpool_planner
nordpool_entity: sensor.nordpool_kwh_fi_eur_3_095_024
entity_id: "heat_house_when_cheap"
duration: 2
var_duration_entity: input_number.needed_ammount_of_hours
accept_cost: 0.0
accept_rate: 0.0
moving:
search_length: 10
var_search_length_entity: input_number.look_this_far_ahead
``` -->
> **NOT IMPLEMENTED**: No support implemented to use this setting
`split_hours` tell if allowed to find low-cost hours that are not consecutive

`search_length` can be in the range of 2 to 24 and specifies how many hours ahead to serach for lowest price.
## Optional features

`var_search_length_entity` an entity that provides a numerical value in hours.
### Accept cost

The integration will use minimum of `var_search_length_entity` (if supplied and can be interpreted as int) and `duration` (or the default value).
Creates a configuration number entity slider that accepts the first price that has an average price below this value, regardless if there are lower prices further ahead.
<!-- `accept_cost` specifies a price level in the currency of your `nordpool_entity`, that if an "average over a duration" is below this value, it is accepted and used. Even if not the lowest in the range specified. -->

### Static
### Accept rate

> **WORK IN PROGRESS**: This version of entity is still not fully tested, may need some more work to work properly.
Creates a configuration number entity slider that accepts the first price that has an average price-rate to Nordpool average below this value, regardless if there are lower prices further ahead.
<!-- `accept_rate` specifies a price rate, that if an "average over a duration" divided by nordpool average (`nordpool_entity.attributes.average`) is below this rate, it is accepted and used. Even if not the lowest in the range specified. E.g. if set to 1 an "average over a duration" <= "nordpool average" is accepted. If 0.5 it has to be half the price of "nordpool average". The idea is to not be as sensitive to offsets I price levels but just a generic rule to accept low section, not just the lowest. -->

This is more dynamic in the sense that it adapts to overall price level, but there are some consideration you need to think of (and extra logic may have to be implemented).

<!-- Optional parameters `var_end_hour_entity` ("") and `split_hours` (false). Default values in parenthesis.
* If Nordpool average happens to be Zero it will not work (duration-average / nordpool-average)
* If any of nordpool-average or duration-average is negative the rate will be negative. If both negative the rate will be positive.

```yaml
binary_sensor:
- platform: nordpool_planner
nordpool_entity: sensor.nordpool_kwh_fi_eur_3_095_024
entity_id: "heat house when cheap"
duration: 2
var_duration_entity: input_number.needed_ammount_of_hours
accept_cost: 0.0
accept_rate: 0.0
static:
end_hour: 7
var_end_hour_entity: input_number.need_fully_charged_car_at
split_hours: false
``` -->
### High cost

`end_hour` can be in the range of 0 to 23 and specifies at what time within 24 hours the ammount of active hours shall be selected.
This was requested as an extra feature and creates a binary sensor which tell in the current `duration` has the highest cost in the `search_length`. It's to large extent the inverse of the standard `low_cost` entity but without the extra options for `accept_cost` or `accept_rate`.

`var_end_hour_entity` an entity that provides a numerical value in hours.
### Starts at

The integration will use `var_end_hour_entity` if supplied and can be interpreted as int, otherwise `end_hour` or the default value.
No extra logic, just creates extra sensor entities that tell in plain values when each of the binary sensors will activate. Same value that is in the extra_attributes of the binary sensor.

> **NOT IMPLEMENTED**: No support implemented to use this setting
`split_hours` tell if allowed to find low-cost hours that are not censecutive

The planner types has some additional configuration variables

## Attributes
## Binary sensor attributes

Apart from the true/false if now is the time to turn on electricity usage the sensor provides some attributes.

`starts_at` tell when the next low-point starts

`cost_at` tell what the average cost is at the lowest point identified

`now_cost_rate` tell a comparison current price / best average. Is just a comparison to how much more expensive the electricity is right now compared to the found slot. E.g. 2 means you could half the cost by waiting for the found slot.
`now_cost_rate` tell a comparison current price / best average. Is just a comparison to how much more expensive the electricity is right now compared to the found slot. E.g. 2 means you could half the cost by waiting for the found slot. It will turn UNAVAILABLE if best average is zero

## Usage

Some words should be said about the usage and how it behaves.

The search length variable should be set to to a value within which you could accept no high electricity usage, and the ratio window/search should somewhat correspond to the active/passive time of your main user of electricity. Still, the search window for the optimal spot to electricity is moving along in front of corrent time, so there might be a longer duration of passive usage than the search length. Therefor keeping the search length low (3-5h) should likely be optimal, unless you have a large storage capacity of electricity/heat that can wait for a longer duration and when cheap electricity draw as much as possible.
The search length variable should be set to to a value within which you could accept no high electricity usage, and the ratio window/search should somewhat correspond to the active/passive time of your main user of electricity. Still, the search window for the optimal spot to electricity is moving along in front of current time, so there might be a longer duration of passive usage than the search length. Therefor keeping the search length low (3-5h) should likely be optimal, unless you have a large storage capacity of electricity/heat that can wait for a longer duration and when cheap electricity draw as much as possible.

If to explain by an image, first orange is now, second orange is `search_length` ahead in time, width of green is `duration` and placed where it has found the cheapest average price within the orange.

![image](planning_example.png)

Try it and feedback how it works or if there are any improvment to be done!
Try it and feedback how it works or if there are any improvement to be done!

### Tuning your settings

I found it usefull to setup a simple history graph chart comparing the values from `nordpool`, `nordpool_diff` and `nordpool_planner` like this.
I found it useful to setup a simple history graph chart comparing the values from `nordpool`, `nordpool_diff` and `nordpool_planner` like this.

![image](planner_evaluation_chart.png)

Where from top to bottom my named entities are:

* nordpool_diff: duration 3 in search_length 10, accept_cost 2.0
* nordpool_diff: duration 2 in search_lenth 5, accept_cost 2.0 and accept_rate 0.7
* nordpool_diff: duration 2 in search_length 5, accept_cost 2.0 and accept_rate 0.7
* nordpool average: just a template sensor extracting the nordpool attribute average to an entity for easier tracking and comparisons "{{ state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'average') | float }}"
* nordpool
* nordpool_diff:

0 comments on commit dd75489

Please sign in to comment.