Skip to content

Commit

Permalink
Merge pull request #77 from alinbalutoiu/main
Browse files Browse the repository at this point in the history
Feat: Add dynamic limits based on entities
  • Loading branch information
lozzd authored Apr 5, 2024
2 parents e8c401a + 0425af9 commit d6ec28a
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Here's a breakdown of all the available configuration items:
| 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 |
| 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. |
| limitEntity | Y | N/A | Name of the sensor tracking the unit rate to be used to calculate limits. e.g. average rate for the last 12 hours If this is set, MediumLimit and HighLimit are ignored|
Expand All @@ -108,6 +108,7 @@ Here's a breakdown of all the available configuration items:
| multiplier | Y | 100 | multiple rate values for pence (100) or pounds (1) |
| rateListLimit | Y | N/A | Limit number of rates to display, useful if you only want to only show next 4 rates |
| cardRefreshIntervalSeconds | Y | 60 | How often the card should refresh to avoid using lots of CPU, defaults to once a minute |
| additionalDynamicLimits | Y | N/A | List of additional limits to be displayed in the card. This is very similar to `targetTimesEntities` but it supports entities that have a single value state (for example an input number or a sensor). The color specified here takes precedence compared to the one in `targetTimesEntities`. |

#### A note on colouring

Expand All @@ -120,6 +121,28 @@ Here's a breakdown of all the available configuration items:
* Cheapest rate is coloured in light green (above 0) / light blue (below 0)
* If targetTimesEntities is included in the config, the target hours will be highlighted in Navy by default (can be changed via the config)

#### A note on `lowlimit` and `mediumlimit` and `highlimit` options

You can either set these to a fixed value, or you can specify the entity which contains the value you want to use for these limits.

An example of how the fixed values look in the config:

```yaml
lowlimit: 15
mediumlimit: 20
highlimit: 30
```
And here's an example of how to use entities for the limits:
```yaml
lowlimit: sensor.average_rate_last_12_hours
mediumlimit: input_number.medium_rate_limit
highlimit: 30
```
Note that it is possible for you to mix and match fixed values and entities as you see fit.
#### Screenshots
![screenshot_1](assets/import.png)
![screenshot_2](assets/export.png)
Expand Down Expand Up @@ -147,7 +170,7 @@ multiplier: 100
```
![screenshot_3](assets/import_with_target.png)
Here is an example on how you can make use of the `targetTimesEntities` property to highlight the target hours in the card.
Here is an example on how you can make use of the `targetTimesEntities` property to highlight the target hours in the card. It also contains an example for `additionalDynamicLimits` property to highlight when a specific threshold is reached.
```
type: custom:octopus-energy-rates-card
pastEntity: event.octopus_energy_electricity_22l4132637_1900026354329_previous_day_rates
Expand All @@ -165,6 +188,10 @@ hour12: true
cheapest: false
multiplier: 100
exportrates: false
additionalDynamicLimits:
input_number.threshold_turn_on_air_conditioning:
backgroundColour: DarkOliveGreen
prefix: 💰
targetTimesEntities:
binary_sensor.octopus_energy_target_intermittent_best_2h_rates:
backgroundColour: orange
Expand Down
48 changes: 47 additions & 1 deletion octopus-energy-rates-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,22 @@ class OctopusEnergyRatesCard extends HTMLElement {
}
}

const lowlimit = config.lowlimit;
var lowlimit = config.lowlimit;
var mediumlimit = config.mediumlimit;
var highlimit = config.highlimit;

// Check if we've received a number, if not, assume they are entities
// and read them from the state
if (isNaN(lowlimit)) {
lowlimit = parseFloat(hass.states[lowlimit].state)
}
if (isNaN(mediumlimit)) {
mediumlimit = parseFloat(hass.states[mediumlimit].state)
}
if (isNaN(highlimit)) {
highlimit = parseFloat(hass.states[highlimit].state)
}

const unitstr = config.unitstr;
const roundUnits = config.roundUnits;
const showpast = config.showpast;
Expand All @@ -194,6 +207,27 @@ class OctopusEnergyRatesCard extends HTMLElement {
const limitHighMult = config.highLimitMultiplier;
const limitMedMult = config.mediumLimitMultiplier;

// Create an empty array to store the parsed attributes
var additionalDynamicLimits = [];
const additionalDynamicLimitsEntities = config.additionalDynamicLimits && Object.keys(config.additionalDynamicLimits) || [];
// Iterate through each entity in additionalDynamicLimitsEntities
for (const entityId of additionalDynamicLimitsEntities) {
const limitExtraData = config.additionalDynamicLimits[entityId] || [];
const backgroundColour = limitExtraData.backgroundColour || "";
const timePrefix = limitExtraData.prefix || "";

const limit = parseFloat(hass.states[entityId].state);
if (!isNaN(limit)) {
additionalDynamicLimits.push({
limit: limit,
color: backgroundColour,
timePrefix: timePrefix,
})
} else {
console.warn("Couldn't parse entity state ${entityId} as a float")
}
}

if (!(limitEntity == null)) {
const limitAve = parseFloat(limitEntityState.state);
mediumlimit = limitAve * limitMedMult;
Expand Down Expand Up @@ -317,6 +351,15 @@ class OctopusEnergyRatesCard extends HTMLElement {
targetTimePrefix = targetTime.timePrefix ? targetTimePrefix + targetTime.timePrefix : targetTimePrefix;
}
});
// Check if we've got any variable limits defined which will take precedence
additionalDynamicLimits.forEach(function (targetLimit) {
if (key.value_inc_vat <= targetLimit.limit) {
isTargetTime = true;
targetTimeBackgroundColor = "' style='background-color: " + targetLimit.color + ";";
targetTimePrefix = targetLimit.timePrefix ? targetTimePrefix + targetLimit.timePrefix : targetTimePrefix;
}
});

// Add the extra space at the end of the prefix if it's not empty
targetTimePrefix = targetTimePrefix ? targetTimePrefix + " " : targetTimePrefix;
var isCurrentTime = false;
Expand Down Expand Up @@ -388,6 +431,9 @@ class OctopusEnergyRatesCard extends HTMLElement {

const defaultConfig = {
targetTimesEntities: null,
// Additional limits specified in a similar format as targetTimesEntities
// but they take input_numbers as input
additionalDynamicLimits: null,
// Controls how many columns the rates split in to
cols: 1,
// Show rates that already happened in the card
Expand Down

0 comments on commit d6ec28a

Please sign in to comment.