From 8988e3bdfefaad5c6d006bd51e73f3f828c72078 Mon Sep 17 00:00:00 2001 From: Codegnosis Date: Wed, 24 Jan 2024 13:10:15 +0000 Subject: [PATCH] improvement - clean up and cetagorise/section the visual editor --- package.json | 2 +- src/editor.ts | 257 ++++++++----------------------------------------- src/schemas.ts | 218 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+), 218 deletions(-) create mode 100644 src/schemas.ts diff --git a/package.json b/package.json index 0149c80..79aa242 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "givtcp-battery-card", - "version": "0.2.1", + "version": "0.2.2", "description": "Lovelace card to display GivTCP battery info", "private": true, "type": "module", diff --git a/src/editor.ts b/src/editor.ts index c624353..fc58dd9 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -2,231 +2,48 @@ import {fireEvent, HomeAssistant, LovelaceCardConfig, LovelaceCardEditor, Lovela import {customElement, property, state} from "lit/decorators.js"; import {css, CSSResultGroup, html, LitElement, TemplateResult} from "lit"; import {ConfigUtils} from "./config-utils"; +import {DISPLAY_SCHEMA, DOD_SCHEMA, GENERAL_SCHEMA, SOC_SCHEMA} from "./schemas"; @customElement('givtcp-battery-card-editor') export class GivTCPBatteryCardEditor extends LitElement implements LovelaceCardEditor { @property() hass!: HomeAssistant; lovelace?: LovelaceConfig | undefined; @state() private _config!: LovelaceCardConfig; + @state() private _currentTab?: number; public setConfig(config: LovelaceCardConfig): void { this._config = ConfigUtils.migrateConfig(config, true); } - get _getInvertorList(): string[] { + private get _getInvertorList(): string[] { return this.hass ? Object.keys(this.hass.states).filter((eid) => eid.includes('invertor_serial_number')) : []; } - get _schema(): object[] { + private get _schema(): object[] { const defaults = ConfigUtils.getDefaultConfig(); - return [ - { - name: 'name', - label: 'Name', - default: defaults.name, - selector: { - text: {} - } - }, - { - name: 'entity', - label: 'Invertor', - selector: { - entity: { - multiple: false, - include_entities: this._getInvertorList - } - }, - }, - { - name: 'soc_threshold_very_high', - label: 'SOC Threshold Very High', - default: defaults.soc_threshold_very_high, - selector: { - number: { - min: 0, - max: 100, - unit_of_measurement: "%", - } - } - }, - { - name: 'soc_threshold_very_high_colour', - label: 'SOC Very High Colour', - default: defaults.soc_threshold_very_high_colour, - selector: { - color_rgb: {} - } - }, - { - name: 'soc_threshold_high', - label: 'SOC Threshold High', - default: defaults.soc_threshold_high, - selector: { - number: { - min: 0, - max: 100, - unit_of_measurement: "%", - } - } - }, - { - name: 'soc_threshold_high_colour', - label: 'SOC High Colour', - default: defaults.soc_threshold_high_colour, - selector: { - color_rgb: {} - } - }, - { - name: 'soc_threshold_medium', - label: 'SOC Threshold Medium', - default: defaults.soc_threshold_medium, - selector: { - number: { - min: 0, - max: 100, - unit_of_measurement: "%", - } - } - }, - { - name: 'soc_threshold_medium_colour', - label: 'SOC Medium Colour', - default: defaults.soc_threshold_medium_colour, - selector: { - color_rgb: {} - } - }, - { - name: 'soc_threshold_low', - label: 'SOC Threshold Low', - default: defaults.soc_threshold_low, - selector: { - number: { - min: 0, - max: 100, - unit_of_measurement: "%", - } - } - }, - { - name: 'soc_threshold_low_colour', - label: 'SOC Loc Colour', - default: defaults.soc_threshold_low_colour, - selector: { - color_rgb: {} - } - }, - { - name: 'soc_threshold_very_low_colour', - label: 'SOC Very Low Colour', - default: defaults.soc_threshold_very_low_colour, - selector: { - color_rgb: {} - } - }, - { - name: 'display_abs_power', - label: 'Display power usage as absolute value', - default: defaults.display_abs_power, - selector: { - boolean: {} - } - }, - { - name: 'display_type', - label: 'Display type (0: Wh/W | 1: kWh/kW | 2: Dynamic)', - default: defaults.display_type, - selector: { - number: { - min: 0, - max: 2 - } - } - }, - { - name: 'display_dp', - label: 'Display number decimal places', - default: defaults.display_dp, - selector: { - number: { - min: 1, - max: 3 - } - } - }, - { - name: 'icon_status_charging', - label: 'Status Icon: Charging', - default: defaults.icon_status_charging, - selector: { - icon:{}, - } - }, - { - name: 'icon_status_discharging', - label: 'Status Icon: Discharging', - default: defaults.icon_status_discharging, - selector: { - icon:{}, - } - }, - { - name: 'icon_status_idle', - label: 'Status Icon: Idle', - default: defaults.icon_status_idle, - selector: { - icon:{}, - } - }, - { - name: 'display_battery_rates', - label: 'Display data about battery charge/discharge rates', - default: defaults.display_battery_rates, - selector: { - boolean: {} - } - }, - { - name: 'use_custom_dod', - label: 'Use custom DoD to override GivTCP battery capacity value.', - default: defaults.use_custom_dod, - selector: { - boolean: {} - } - }, - { - name: 'display_custom_dod_stats', - label: 'Display the custom DOD stats', - default: defaults.display_custom_dod_stats, - selector: { - boolean: {} - } - }, - { - name: 'custom_dod', - label: 'Custom DoD as percentage to override GivTCP battery capacity value.', - default: defaults.custom_dod, - selector: { - number: { - min: 0, - max: 100, - step: "any", - unit_of_measurement: "%", - } - } - }, - { - name: 'calculate_reserve_from_dod', - label: 'Use custom DoD to calculate the battery reserve value', - default: defaults.calculate_reserve_from_dod, - selector: { - boolean: {} - } - }, - ]; + switch (this._currentTab) { + case 0: + default: + return GENERAL_SCHEMA(this._getInvertorList, defaults); + case 1: + return SOC_SCHEMA(defaults, this._config); + case 2: + return DISPLAY_SCHEMA(defaults); + case 3: + return DOD_SCHEMA(defaults, this._config); + } + } + + private _handleTabChanged(ev: CustomEvent): void { + ev.preventDefault(); + const tab = ev.detail.selected as number; + this._currentTab = tab; + } + + constructor() { + super(); + this._currentTab = 0; } protected render(): TemplateResult | void { @@ -240,14 +57,20 @@ export class GivTCPBatteryCardEditor extends LitElement implements LovelaceCardE } return html` - - `; + + General + SOC + Display + DOD + + + `; } private _valueChanged(ev: CustomEvent): void { diff --git a/src/schemas.ts b/src/schemas.ts new file mode 100644 index 0000000..f863a1f --- /dev/null +++ b/src/schemas.ts @@ -0,0 +1,218 @@ +import {LovelaceCardConfig} from "custom-card-helpers"; +import {DISPLAY_TYPE_OPTIONS} from "./constants"; + +export const GENERAL_SCHEMA = (invertorList: string[], defaults: LovelaceCardConfig) => { + + return [ + { + name: 'name', + label: 'Name', + default: defaults.name, + selector: { + text: {} + } + }, + { + name: 'entity', + label: 'Invertor', + selector: { + entity: { + multiple: false, + include_entities: invertorList + } + }, + }, + ]; +} + +const HEADING_SCHEMA = (label: string) => { + return { + selector: { + constant: { + label: label, + }, + }, + } +} + +const THRESHOLD_SCHEMA = (name: string, defaultThreshold: number, defaultColour: number[]) => { + return { + type: 'grid', + schema: [ + { + name: `soc_threshold_${name}`, + label: 'Threshold', + default: defaultThreshold, + selector: { + number: { + mode: 'box', + min: 0, + max: 100, + unit_of_measurement: "%", + } + } + }, + { + name: `soc_threshold_${name}_colour`, + label: 'Colour', + default: defaultColour, + selector: { + color_rgb: {} + } + }, + ], + } +} + +export const SOC_SCHEMA = (defaults: LovelaceCardConfig, config: LovelaceCardConfig) => { + + return [ + HEADING_SCHEMA('SOC Thresholds & Colours for Battery Icon'), + HEADING_SCHEMA('Very High'), + THRESHOLD_SCHEMA('very_high', defaults.soc_threshold_very_high, defaults.soc_threshold_very_high_colour), + HEADING_SCHEMA('High'), + THRESHOLD_SCHEMA('high', defaults.soc_threshold_high, defaults.soc_threshold_high_colour), + HEADING_SCHEMA('Medium'), + THRESHOLD_SCHEMA('medium', defaults.soc_threshold_medium, defaults.soc_threshold_medium_colour), + HEADING_SCHEMA('Low'), + THRESHOLD_SCHEMA('low', defaults.soc_threshold_low, defaults.soc_threshold_low_colour), + HEADING_SCHEMA(`Very Low (< ${config.soc_threshold_low || defaults.soc_threshold_low}%)`), + { + name: 'soc_threshold_very_low_colour', + label: 'Colour', + default: defaults.soc_threshold_very_low_colour, + selector: { + color_rgb: {} + } + }, + ]; +} + +export const DISPLAY_SCHEMA = (defaults: LovelaceCardConfig) => { + + return [ + HEADING_SCHEMA('Power/Capacity'), + { + type: 'grid', + schema: [ + { + name: 'display_type', + label: 'Display type', + default: defaults.display_type, + selector: { + select: { + options: [ + { value: DISPLAY_TYPE_OPTIONS.WH, label: 'Wh/W' }, + { value: DISPLAY_TYPE_OPTIONS.KWH, label: 'kWh/kW' }, + { value: DISPLAY_TYPE_OPTIONS.DYNAMIC, label: 'Dynamic' }, + ], + }, + } + }, + { + name: 'display_dp', + label: 'Decimal places', + default: defaults.display_dp, + selector: { + number: { + mode: 'box', + min: 1, + max: 3 + } + } + }, + ], + }, + { + name: 'display_abs_power', + label: 'Display power usage as absolute value', + default: defaults.display_abs_power, + selector: { + boolean: {} + } + }, + { + name: 'display_battery_rates', + label: 'Display data about battery charge/discharge rates', + default: defaults.display_battery_rates, + selector: { + boolean: {} + } + }, + HEADING_SCHEMA('Icons'), + { + name: 'icon_status_charging', + label: 'Status Icon: Charging', + default: defaults.icon_status_charging, + selector: { + icon:{}, + } + }, + { + name: 'icon_status_discharging', + label: 'Status Icon: Discharging', + default: defaults.icon_status_discharging, + selector: { + icon:{}, + } + }, + { + name: 'icon_status_idle', + label: 'Status Icon: Idle', + default: defaults.icon_status_idle, + selector: { + icon:{}, + } + }, + ]; +} + +export const DOD_SCHEMA = (defaults: LovelaceCardConfig, config: LovelaceCardConfig) => { + + let settings: object[] = [ + HEADING_SCHEMA('Custom DoD to override GivTCP values'), + { + name: 'use_custom_dod', + label: 'Use custom DoD', + default: defaults.use_custom_dod, + selector: { + boolean: {} + } + }, + ]; + if (config.use_custom_dod) { + settings = [ + ...settings, + { + name: 'custom_dod', + label: 'DoD Percent', + default: defaults.custom_dod, + selector: { + number: { + min: 0, + max: 100, + step: "any", + unit_of_measurement: "%", + } + } + }, + { + name: 'display_custom_dod_stats', + label: 'Display DOD stats', + default: defaults.display_custom_dod_stats, + selector: { + boolean: {} + } + }, + { + name: 'calculate_reserve_from_dod', + label: 'Use custom DoD to calculate battery reserve', + default: defaults.calculate_reserve_from_dod, + selector: { + boolean: {} + } + }, + ]; + } + return settings; +}