Skip to content

Commit

Permalink
Merge pull request #39 from alfwro13/main
Browse files Browse the repository at this point in the history
Added support to display Target Rate entity and support for lowlimit option
  • Loading branch information
lozzd authored Dec 1, 2023
2 parents 3d49e83 + 181dcb4 commit 8b4605d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 25 deletions.
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

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

##### Advanced Configurations

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

0 comments on commit 8b4605d

Please sign in to comment.