From 9596eebe336cf12798386da1a3bdeebb457cf567 Mon Sep 17 00:00:00 2001 From: ulic75 Date: Mon, 9 May 2022 16:47:16 -0600 Subject: [PATCH] feat: support watts and kilowats (#18) * baseline all values in watts * support configuration and display of watts --- README.md | 17 +++++---- src/power-flow-card-config.ts | 1 + src/power-flow-card.ts | 66 ++++++++++++++++++----------------- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index d3b28f47..cc6f2b23 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,18 @@ I recommend looking at the [Example usage section](#example-usage) to understand #### Card options -| Name | Type | Default | Description | -| ------------- | -------- | :----------: | --------------------------------------------------------------------------------------------------------------------------------------- | -| type | `string` | **required** | `custom:power-flow-card`. | -| entities | `object` | **required** | One or more sensor entities, see [entities object](#entities-object) for additional entity options. | -| min_flow_rate | `number` | .75 | Represents the fastest amount of time in seconds for a flow dot to travel from one end to the other, see [flow formula](#flow-formula). | -| max_flow_rate | `number` | 6 | Represents the slowest amount of time in seconds for a flow dot to travel from one end to the other, see [flow formula](#flow-formula). | +| Name | Type | Default | Description | +| -------------- | -------- | :----------: | --------------------------------------------------------------------------------------------------------------------------------------- | +| type | `string` | **required** | `custom:power-flow-card`. | +| entities | `object` | **required** | One or more sensor entities, see [entities object](#entities-object) for additional entity options. | +| min_flow_rate | `number` | .75 | Represents the fastest amount of time in seconds for a flow dot to travel from one end to the other, see [flow formula](#flow-formula). | +| max_flow_rate | `number` | 6 | Represents the slowest amount of time in seconds for a flow dot to travel from one end to the other, see [flow formula](#flow-formula). | +| watt_threshold | `number` | 0 | The number of watts to display before converting to and displaying kilowatts. Setting of 0 will always display in kilowatts. | #### Entities object +All entites (except _battery_charge_) should have a `unit_of_measurement` attribute of W(watts) or kW(kilowatts). + | Name | Type | Default | Description | | -------------- | :------------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | grid | `string` / `object` | **required** | Entity ID of a sensor supporting a single state with negative values for production and positive values for consumption or an object for [split entites](#split-entities). Examples of both can be found below. | @@ -66,7 +69,7 @@ I recommend looking at the [Example usage section](#example-usage) to understand #### Split entities -Can be use with either Grid or Battery configuration +Can be use with either Grid or Battery configuration. The same `unit_of_measurement` rule as above applies. | Name | Type | Default | Description | | ----------- | -------- | --------------------- | ------------------------------------------------------------------------------------------------- | diff --git a/src/power-flow-card-config.ts b/src/power-flow-card-config.ts index cb4cb7bb..0caad2a2 100644 --- a/src/power-flow-card-config.ts +++ b/src/power-flow-card-config.ts @@ -19,4 +19,5 @@ export interface PowerFlowCardConfig extends LovelaceCardConfig { }; min_flow_rate: number; max_flow_rate: number; + watt_threshold: number; } diff --git a/src/power-flow-card.ts b/src/power-flow-card.ts index 697d231c..eff63e93 100644 --- a/src/power-flow-card.ts +++ b/src/power-flow-card.ts @@ -40,6 +40,7 @@ export class PowerFlowCard extends LitElement { ...config, min_flow_rate: config.min_flow_rate ?? MIN_FLOW_RATE, max_flow_rate: config.max_flow_rate ?? MAX_FLOW_RATE, + watt_threshold: config.watt_threshold ?? 0, }; } @@ -60,6 +61,19 @@ export class PowerFlowCard extends LitElement { return coerceNumber(this.hass.states[entity].state); }; + private getEntityStateWatts = (entity: string | undefined): number => { + if (!entity) return 0; + const stateObj = this.hass.states[entity]; + const value = coerceNumber(stateObj.state); + if (stateObj.attributes.unit_of_measurement === "W") return value; + return value * 1000; + }; + + private displayValue = (value: number) => + value >= coerceNumber(this._config?.watt_threshold, 0) + ? `${roundValue(value / 1000, 1)} kW` + : `${value} W`; + protected render(): TemplateResult { if (!this._config || !this.hass) { return html``; @@ -75,40 +89,30 @@ export class PowerFlowCard extends LitElement { const batteryChargeState = entities.battery_charge?.length ? this.getEntityState(entities.battery_charge) : null; - const solarState = this.getEntityState(entities.solar); + const solarState = this.getEntityStateWatts(entities.solar); const solarToGrid = hasReturnToGrid - ? roundValue( - typeof entities.grid === "string" - ? Math.abs(Math.min(this.getEntityState(entities.grid), 0)) - : this.getEntityState(entities.grid.production), - 1 - ) + ? typeof entities.grid === "string" + ? Math.abs(Math.min(this.getEntityStateWatts(entities.grid), 0)) + : this.getEntityStateWatts(entities.grid.production) : 0; - const batteryToHome = roundValue( + const batteryToHome = typeof entities.battery === "string" - ? Math.max(this.getEntityState(entities.battery), 0) - : this.getEntityState(entities.battery?.consumption), - 1 - ); + ? Math.max(this.getEntityStateWatts(entities.battery), 0) + : this.getEntityStateWatts(entities.battery?.consumption); - const gridToHome = roundValue( + const gridToHome = typeof entities.grid === "string" - ? Math.max(this.getEntityState(entities.grid), 0) - : this.getEntityState(entities.grid.consumption), - 1 - ); + ? Math.max(this.getEntityStateWatts(entities.grid), 0) + : this.getEntityStateWatts(entities.grid.consumption); - const solarToBattery = roundValue( + const solarToBattery = typeof entities.battery === "string" - ? Math.abs(Math.min(this.getEntityState(entities.battery), 0)) - : this.getEntityState(entities.battery?.production), - 1 - ); + ? Math.abs(Math.min(this.getEntityStateWatts(entities.battery), 0)) + : this.getEntityStateWatts(entities.battery?.production); - const solarToHome = - roundValue(solarState, 1) - solarToGrid - solarToBattery; + const solarToHome = solarState - solarToGrid - solarToBattery; const homeConsumption = batteryToHome + gridToHome + solarToHome; const totalConsumption = homeConsumption + solarToBattery + solarToGrid; @@ -180,9 +184,7 @@ export class PowerFlowCard extends LitElement { >
- - ${roundValue(solarState ?? 0, 1)} kW + ${this.displayValue(solarState)}
` : html``} @@ -196,7 +198,7 @@ export class PowerFlowCard extends LitElement { class="small" .path=${mdiArrowLeft} >${roundValue(solarToGrid, 1)} kW + >${this.displayValue(solarToGrid)} ` : null} @@ -204,7 +206,7 @@ export class PowerFlowCard extends LitElement { class="small" .path=${mdiArrowRight} >${roundValue(gridToHome, 1)} kW + >${this.displayValue(gridToHome)} - ${roundValue(homeConsumption, 1)} kW + ${this.displayValue(homeConsumption)} ${homeSolarCircumference !== undefined ? html` ${homeSolarCircumference !== undefined @@ -300,14 +302,14 @@ export class PowerFlowCard extends LitElement { class="small" .path=${mdiArrowDown} >${roundValue(solarToBattery, 1)} kW${this.displayValue(solarToBattery)} ${roundValue(batteryToHome, 1)} kW${this.displayValue(batteryToHome)}