Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support to display Target Rate entity and support for lowlimit option #39

Merged
merged 9 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 69 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,44 @@ The easiest way to find that entity name is by opening the Search within Home As

(The format is, for example: `event.octopus_energy_electricity_{METER_SERIAL_NUMBER}}_{{MPAN_NUMBER}}_current_day_rates`)

Here's an example yaml configuration - obviously replacing `<your_id_here>` with your data from above.
Here's an example yaml configuration - obviously replacing `<your_id_here>` with your data from above.

```
currentEntity: event.octopus_energy_electricity_<your_id_here>_current_day_rates
pastEntity: event.octopus_energy_electricity_<your_id_here>_previous_day_rates
futureEntity: event.octopus_energy_electricity_<your_id_here>_next_day_rates
type: custom:octopus-energy-rates-card
currentEntity: event.octopus_energy_electricity_<your_id_here>_current_day_rates
cols: 2
hour12: false
showday: true
showpast: false
title: Octopus Import
unitstr: p
lowlimit: 15
mediumlimit: 20
highlimit: 30
roundUnits: 2
cheapest: true
multiplier: 100

```
and here is one for export rates:
```
type: custom:octopus-energy-rates-card
pastEntity: event.octopus_energy_electricity_<your_id_here>_export_previous_day_rates
currentEntity: event.octopus_energy_electricity_<your_id_here>_export_current_day_rates
futureEntity: event.octopus_energy_electricity_22l4132637_<your_id_here>_export_next_day_rates
cols: 3
hour12: false
showday: false
showpast: false
title: Octopus Export
unitstr: p
lowlimit: null
mediumlimit: 10
highlimit: 19
roundUnits: 2
cheapest: true
multiplier: 100
exportrates: true
```

Here's a breakdown of all the available configuration items:
Expand All @@ -59,10 +87,12 @@ Here's a breakdown of all the available configuration items:
| currentEntity | N | N/A | Name of the sensor that contains the current rates you want to render, generated from the `HomeAssistant-OctopusEnergy` integration |
| pastEntity | Y | N/A | Name of the sensor that contains the past rates you want to render, generated from the `HomeAssistant-OctopusEnergy` integration |
| futureEntity | Y | N/A | Name of the sensor that contains the future rates you want to render, generated from the `HomeAssistant-OctopusEnergy` integration |
| targetTimesEntity | Y | N/A | Name of the sensor that contains the Target Rate Sensor, generated from the `HomeAssistant-OctopusEnergy` integration. [More here: doc](https://github.com/BottlecapDave/HomeAssistant-OctopusEnergy/blob/develop/_docs/setup_target_rate.md) |
| cols | Y | 1 | How many columns to break the rates in to, pick the one that fits best with how wide your card is |
| showpast | Y | false | Show the rates that have already happened today. Provides a simpler card when there are two days of dates to show |
| showday | Y | false | Shows the (short) day of the week next to the time for each rate. Helpful if it's not clear which day is which if you have a lot of rates to display |
| title | Y | "Agile Rates" | The title of the card in the dashboard |
| lowlimit | Y | 5 (pence) | If the price is above `lowlimit`, the row is marked dark green. (this option is only applicable for import rates |
| mediumlimit | Y | 20 (pence) | If the price is above `mediumlimit`, the row is marked yellow |
| highlimit | Y | 30 (pence) | If the price is above `highlimit`, the row is marked red. |
| roundUnits | Y | 2 | Controls how many decimal places to round the rates to |
Expand All @@ -78,14 +108,42 @@ Here's a breakdown of all the available configuration items:

#### A note on colouring

* The card is hardcoded to display plunge pricing (e.g, below 0p/kWh) as blue
* If the price is above `highlimit`, then the row is in red
* If the price is above `mediumlimit`, then the row is coloured orange/yellow
* Otherwise, the row is coloured is green.
* These are reversed if `exportrates` is set to `true`
* The card is hardcoded to display plunge pricing (e.g, below 0p/kWh) as blue.
* If the price is above `highLimit`, then the row is in red
* If the price is above `mediumLimit`, then the row is coloured orange
* if the price is above `lowLimit`, then the row is coloured dark green
* if the price is below `lowLimit`, then the row is coloured green
* These are reversed if `exportrates` is set to `true` (export rates have only 3 colours, red, orange and green)
* Cheapest rate is coloured in light green (above 0) / light blue (below 0)
* If Target Rate entity is included in the config, the target hours will be highlited in Navy Blue
alfwro13 marked this conversation as resolved.
Show resolved Hide resolved

#### Screenshots
![screenshot_1](assets/import.png)
![screenshot_2](assets/export.png)

##### Advanced Configurations

alfwro13 marked this conversation as resolved.
Show resolved Hide resolved
Import rates with the Target Rates and future rates entities specified:
```
type: custom:octopus-energy-rates-card
currentEntity: event.octopus_energy_electricity_22l4132637_1900026354329_current_day_rates
futureEntity: event.octopus_energy_electricity_22l4132637_1900026354329_next_day_rates
targetTimesEntity: binary_sensor.octopus_energy_target_intermittent_best_charging_rates
cols: 3
hour12: false
showday: false
showpast: false
title: Octopus Import - p/kWh
unitstr: ''
lowlimit: 6
mediumlimit: 15
highlimit: 27
cheapest: true
multiplier: 100
```
![screenshot_3](assets/import_with_target.png)


#### Screenshot
![screenshot_1](assets/screenshot_1.png)

#### Thanks/inspiration
This card was based on and reworked from the code [markgdev/home-assistant_OctopusAgile](https://github.com/markgdev/home-assistant_OctopusAgile/tree/master/custom_cards) which is no longer maintained.
Binary file added assets/export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/import.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/import_with_target.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 50 additions & 14 deletions octopus-energy-rates-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class OctopusEnergyRatesCard extends HTMLElement {
table.main {
padding: 0px;
}
td.time_highlight {
font-weight: bold;
background-color: Navy;
}
thead th {
text-align: left;
padding: 0px;
Expand All @@ -47,6 +51,9 @@ class OctopusEnergyRatesCard extends HTMLElement {
td.time_green{
border-bottom: 1px solid MediumSeaGreen;
}
td.time_lightgreen {
border-bottom: 1px solid ForestGreen;
}
td.time_blue{
border-bottom: 1px solid #391CD9;
}
Expand Down Expand Up @@ -77,6 +84,10 @@ class OctopusEnergyRatesCard extends HTMLElement {
border: 2px solid MediumSeaGreen;
background-color: MediumSeaGreen;
}
td.lightgreen {
border: 2px solid ForestGreen;
background-color: ForestGreen;
}
td.blue {
border: 2px solid #391CD9;
background-color: #391CD9;
Expand All @@ -97,12 +108,17 @@ class OctopusEnergyRatesCard extends HTMLElement {
this.appendChild(card);
}

const colours_import = ['green', 'red', 'orange', 'blue', 'cheapest', 'cheapestblue'];
const colours_export = [ 'red', 'green', 'orange' ];

const colours_import = ['lightgreen', 'green', 'orange', 'red', 'blue', 'cheapest', 'cheapestblue'];
const colours_export = [ 'red', 'green', 'orange', 'green' ];
const currentEntityId = config.currentEntity;
const futureEntityId = config.futureEntity;
const pastEntityId = config.pastEntity;
// Read the targetTimes entity if specified
const targetTimesId = config.targetTimesEntity;
const targetTimesstate = hass.states[targetTimesId];
const targetTimesttributes = targetTimesstate ? this.reverseObject(targetTimesstate.attributes) : {};

const lowlimit = config.lowlimit;
const mediumlimit = config.mediumlimit;
const highlimit = config.highlimit;
const unitstr = config.unitstr;
Expand All @@ -116,6 +132,8 @@ class OctopusEnergyRatesCard extends HTMLElement {
var colours = (config.exportrates ? colours_export : colours_import);
var rates_totalnumber = 0;
var combinedRates = [];
// Check if slotsTargetTimes is available before using forEach
const slotsTargetTimes = targetTimesttributes.target_times || [];

// Grab the rates which are stored as an attribute of the sensor
const paststate = hass.states[pastEntityId];
Expand Down Expand Up @@ -230,16 +248,30 @@ class OctopusEnergyRatesCard extends HTMLElement {
// If the showday config option is set, include the shortened weekday name in the user's Locale
var date_locale = (showday ? date.toLocaleDateString(lang, { weekday: 'short' }) + ' ' : '');

var colour = colours[0];
var colour = colours[1]; // Default to 'green' (index 1) (below low limit above 0)
var isTargetTime = false;
// Check if the current time row corresponds to a target time
slotsTargetTimes.forEach(function (targetTime) {
const startTime = new Date(targetTime.start);
const endTime = new Date(targetTime.end);
if (date >= startTime && date < endTime) {
isTargetTime = true;
}
});


var valueToDisplay = key.value_inc_vat * multiplier;
if (cheapest && (valueToDisplay == cheapest_rate && cheapest_rate > 0)) colour = colours[4];
else if (cheapest && (valueToDisplay == cheapest_rate && cheapest_rate <= 0)) colour = colours[5];
else if (valueToDisplay > highlimit) colour = colours[1];
else if (valueToDisplay > mediumlimit) colour = colours[2];
else if (valueToDisplay <= 0) colour = colours[3];
// Apply bold styling if the current time is a target time
var boldStyle = isTargetTime ? 'time_highlight' : '';
if (cheapest && (valueToDisplay == cheapest_rate && cheapest_rate > 0)) colour = colours[5];
else if (cheapest && (valueToDisplay == cheapest_rate && cheapest_rate <= 0)) colour = colours[6];
else if (valueToDisplay > highlimit) colour = colours[3]; //red (import) / green (export)
else if (valueToDisplay > mediumlimit) colour = colours[2]; // orange (import) / orange (export)
else if (valueToDisplay > lowlimit) colour = colours[0]; // lightgreen (import) / red (export)
else if (valueToDisplay <= 0) colour = colours[4]; // below 0 - blue (import/export)

if(showpast || (date - Date.parse(new Date())>-1800000)) {
table = table.concat("<tr class='rate_row'><td class='time time_"+colour+"'>" + date_locale + time_locale +
table = table.concat("<tr class='rate_row'><td class='time " + boldStyle + " " + "time_"+colour+"'>" + date_locale + time_locale +
"</td><td class='rate "+colour+"'>" + valueToDisplay.toFixed(roundUnits) + unitstr + "</td></tr>");

if (x % rows_per_col == 0) {
Expand Down Expand Up @@ -287,6 +319,8 @@ class OctopusEnergyRatesCard extends HTMLElement {
}

const defaultConfig = {
// Entities to get data from
targetTimesEntity: null,
// Controls how many columns the rates split in to
cols: 1,
// Show rates that already happened in the card
Expand All @@ -299,11 +333,13 @@ class OctopusEnergyRatesCard extends HTMLElement {
title: 'Agile Rates',
// Colour controls:
// If the price is above highlimit, the row is marked red.
// If the price is above mediumlimit, the row is marked yellow.
// If the price is below mediumlimit, the row is marked green.
// If the price is above mediumlimit, the row is marked orange.
// If the price is above lowlimit, the row is marked dark green.
// If the price is below lowlimit, the row is marked green.
// If the price is below 0, the row is marked blue.
mediumlimit: 20,
highlimit: 30,
lowlimit: 0.05,
mediumlimit: 0.10,
highlimit: 0.30,
// Controls the rounding of the units of the rate
roundUnits: 2,
// The unit string to show if units are shown after each rate
Expand Down