Skip to content

Commit

Permalink
Add knx-group-address-selector component
Browse files Browse the repository at this point in the history
  • Loading branch information
farmio committed Dec 27, 2023
1 parent a2fba7a commit cbf432a
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 41 deletions.
56 changes: 19 additions & 37 deletions src/components/knx-configure-switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "@ha/components/ha-settings-row";
import { fireEvent } from "@ha/common/dom/fire_event";
import { HomeAssistant } from "@ha/types";

import "./knx-group-address-selector";
import "./knx-sync-state-selector-row";
import { renderConfigureEntityCard } from "./knx-configure-entity-card";
import { KNXLogger } from "../tools/knx-logger";
Expand All @@ -19,13 +20,6 @@ import { platformConstants } from "../utils/common";

const logger = new KNXLogger("knx-configure-switch");

declare global {
// for fire event
interface HASSDomEvents {
"knx-entity-configuration-changed": CreateEntityData;
}
}

@customElement("knx-configure-switch")
export class KNXConfigureSwitch extends LitElement {
@property({ type: Object }) public hass!: HomeAssistant;
Expand All @@ -38,14 +32,6 @@ export class KNXConfigureSwitch extends LitElement {
@property({ type: Object }) public schemaOptions: SchemaOptions = {};

protected render(): TemplateResult | void {
const dpt1gas = Object.values(this.knx.project!.knxproject.group_addresses).filter(
(groupAddress) => groupAddress.dpt?.main === 1,
);
const addressOptions = dpt1gas.map((groupAddress) => ({
value: groupAddress.address,
label: `${groupAddress.address} - ${groupAddress.name}`,
}));

return html`
<div class="header">
<h1><ha-svg-icon .path=${platformConstants.switch.iconPath}></ha-svg-icon>Switch</h1>
Expand All @@ -56,31 +42,20 @@ export class KNXConfigureSwitch extends LitElement {
<ha-settings-row narrow>
<div slot="heading">Switching</div>
<div slot="description">DPT 1 group addresses controlling the switch function.</div>
<ha-selector
<knx-group-address-selector
.hass=${this.hass}
.label=${"Address"}
.selector=${{
select: { multiple: true, custom_value: true, options: addressOptions },
.knx=${this.knx}
.key=${"ga_switch"}
.config=${this.config.ga_switch ?? {}}
.options=${{
send: { required: true },
read: { required: false },
passive: true,
validDPTs: [{ main: 1, sub: null }],
}}
.key=${"switch_address"}
.value=${this.config.switch_address}
@value-changed=${this._updateConfig}
></ha-selector>
<div class="spacer"></div>
<ha-selector
.hass=${this.hass}
.label=${"State address"}
.selector=${{
select: {
multiple: true,
custom_value: true,
options: addressOptions,
},
}}
.key=${"switch_state_address"}
.value=${this.config.switch_state_address}
@value-changed=${this._updateConfig}
></ha-selector>
></knx-group-address-selector>
</ha-settings-row>
<ha-selector
.hass=${this.hass}
.label=${"Invert"}
Expand Down Expand Up @@ -212,3 +187,10 @@ declare global {
"knx-configure-switch": KNXConfigureSwitch;
}
}

declare global {
// for fire event
interface HASSDomEvents {
"knx-entity-configuration-changed": CreateEntityData;
}
}
122 changes: 122 additions & 0 deletions src/components/knx-group-address-selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { LitElement, html, css, nothing } from "lit";
import { customElement, property } from "lit/decorators";

import "@ha/components/ha-selector/ha-selector";
import { fireEvent } from "@ha/common/dom/fire_event";
import { HomeAssistant } from "@ha/types";

import { KNX } from "../types/knx";
import { DPT, KNXProject, GroupAddress } from "../types/websocket";
import { GASchema } from "../types/entity_data";

interface GroupAddressSelectorOptions {
read?: { required: boolean };
send?: { required: boolean };
passive?: boolean;
validDPTs: DPT[];
}

const isValidGroupAddress = (gaDPT: DPT, validDPT: DPT): boolean =>
gaDPT.main === validDPT.main && validDPT.sub ? gaDPT.sub === validDPT.sub : true;

const validGroupAddresses = (knxproject: KNXProject, validDPTs: DPT[]): GroupAddress[] =>
Object.values(knxproject.group_addresses).filter((groupAddress) =>
groupAddress.dpt
? validDPTs.some((testDPT) => isValidGroupAddress(groupAddress.dpt!, testDPT))
: false,
);

@customElement("knx-group-address-selector")
export class GroupAddressSelector extends LitElement {
@property({ type: Object }) public hass!: HomeAssistant;

@property({ type: Object }) public knx!: KNX;

@property({ type: Object }) public config: GASchema = {};

@property({ type: Object }) public options!: GroupAddressSelectorOptions;

private addressOptions() {
if (!this.knx.project) {
return [];
}
return validGroupAddresses(this.knx.project.knxproject, this.options.validDPTs).map(
(groupAddress) => ({
value: groupAddress.address,
label: `${groupAddress.address} - ${groupAddress.name}`,
}),
);
}

render() {
const addressOptions = this.addressOptions();
return html`
${this.options.send
? html`<ha-selector
.hass=${this.hass}
.label=${"Send address"}
.required=${this.options.send.required}
.selector=${{
select: { multiple: false, custom_value: true, options: addressOptions },
}}
.key=${"send"}
.value=${this.config.send}
@value-changed=${this._updateConfig}
></ha-selector
>${this.options.read || this.options.passive
? html`<div class="spacer"></div>`
: nothing}`
: nothing}
${this.options.read
? html`<ha-selector
.hass=${this.hass}
.label=${"Read address"}
.required=${this.options.read.required}
.selector=${{
select: { multiple: false, custom_value: true, options: addressOptions },
}}
.key=${"read"}
.value=${this.config.read}
@value-changed=${this._updateConfig}
></ha-selector
>${this.options.passive ? html`<div class="spacer"></div>` : nothing}`
: nothing}
${this.options.passive
? html`<ha-selector
.hass=${this.hass}
.label=${"Passive addresses"}
.selector=${{
select: { multiple: true, custom_value: true, options: addressOptions },
}}
.key=${"passive"}
.value=${this.config.passive}
@value-changed=${this._updateConfig}
></ha-selector>`
: nothing}
`;
}

private _updateConfig(ev: CustomEvent) {
ev.stopPropagation();
const target = ev.target as any;
const value = ev.detail.value;
this.config = { ...this.config, [target.key]: value };
if (true) {

Check warning on line 104 in src/components/knx-group-address-selector.ts

View workflow job for this annotation

GitHub Actions / Lint

Unexpected constant condition
// validate
fireEvent(this, "value-changed", { value: this.config });
}
this.requestUpdate();
}

static styles = css`
.spacer {
height: 16px;
}
`;
}

declare global {
interface HTMLElementTagNameMap {
"knx-group-address-selector": GroupAddressSelector;
}
}
9 changes: 6 additions & 3 deletions src/types/entity_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ export type entityCategory = "config" | "diagnostic";

export type supportedPlatform = "switch";

type groupAddresses = string | string[];
export interface GASchema {
send?: string;
read?: string;
passive?: string[];
}

export interface BaseEntityData {
device_info: string | null;
Expand All @@ -14,8 +18,7 @@ export interface SwitchEntityData {
entity: BaseEntityData;
invert: boolean;
respond_to_read: boolean;
switch_address: groupAddresses;
switch_state_address: groupAddresses | null;
ga_switch: GASchema;
sync_state: string | boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion src/views/entities_create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class KNXCreateEntity extends LitElement {
}
createEntity(this.hass, this._config)
.then((entityId) => {
logger.debug("created entity!");
logger.debug("created entity", entityId);
navigate("/knx/entities", { replace: true });
if (!entityId) {
logger.error("entity_id not found after creation.");
Expand Down

0 comments on commit cbf432a

Please sign in to comment.