Skip to content

Commit

Permalink
fix(select): Save changes made in HA
Browse files Browse the repository at this point in the history
Fixes #1100

fix(number): Save changes made in HA

fix(text): Save changes made in HA

fix(time-entity): Save changes made in HA
  • Loading branch information
zachowj committed Oct 6, 2023
1 parent 45351a0 commit 9975266
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 142 deletions.
26 changes: 11 additions & 15 deletions src/common/integration/BidirectionalEntityIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HaEvent } from '../../homeAssistant/index';
import { SubscriptionUnsubscribe } from '../../types/home-assistant';
import State from '../State';
import { createHaConfig } from './helpers';
import { IntegrationEvent, MessageType } from './Integration';
import { MessageType } from './Integration';
import UnidirectionalEntityIntegration, {
EntityMessage,
} from './UnidirectionalEntityIntegration';
Expand All @@ -24,11 +24,16 @@ interface StateChangeEvent {
state: boolean;
}

interface ValueChangedEvent {
export interface ValueChangedEvent {
type: HaEvent.ValueChange;
value: number;
value: number | string;
}

export type HaEventMessage =
| StateChangeEvent
| TriggerEvent
| ValueChangedEvent;

export interface StateChangePayload {
state: boolean;
changed: boolean;
Expand Down Expand Up @@ -101,25 +106,16 @@ export default class BidirectionalIntegration extends UnidirectionalEntityIntegr
}
}

protected onHaEventMessage(
evt: StateChangeEvent | TriggerEvent | ValueChangedEvent
) {
protected onHaEventMessage(evt: HaEventMessage) {
evt.type ??= HaEvent.StateChanged; // no type prior to 0.20.0
switch (evt.type) {
case HaEvent.AutomationTriggered:
this.entityConfigNode.emit(
HaEvent.AutomationTriggered,
evt.data
);
break;
case HaEvent.ValueChange:
this.entityConfigNode.emit(
IntegrationEvent.ValueChange,
evt.value
);
break;
case HaEvent.StateChanged:
default: {
// no type prior to 0.20.0
case HaEvent.StateChanged: {
const previousState = this.state.isEnabled();
this.state.setEnabled(evt.state);
this.entityConfigNode.emit(HaEvent.StateChanged, {
Expand Down
32 changes: 30 additions & 2 deletions src/common/integration/ValueEntityIntegration.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import { HaEvent } from '../../homeAssistant';
import State from '../State';
import BidirectionalIntegration from './BidirectionalEntityIntegration';
import BidirectionalEntityIntegration, {
HaEventMessage,
} from './BidirectionalEntityIntegration';
import { IntegrationEvent } from './Integration';
import { EntityMessage } from './UnidirectionalEntityIntegration';

export default class ValueEntityIntegration extends BidirectionalIntegration {
export default class ValueEntityIntegration extends BidirectionalEntityIntegration {
protected onHaEventMessage(evt: HaEventMessage) {
super.onHaEventMessage(evt);

if (evt.type === HaEvent.ValueChange) {
const value = evt.value;
const previousValue = this.state.getLastPayload()?.state;

this.updateValue(value);
this.entityConfigNode.emit(
IntegrationEvent.ValueChange,
value,
previousValue
);
}
}

protected getStateData(state?: State): Partial<EntityMessage> {
const lastPayload = state?.getLastPayload();
if (!lastPayload) {
Expand All @@ -11,4 +31,12 @@ export default class ValueEntityIntegration extends BidirectionalIntegration {

return lastPayload;
}

public async updateValue(value: string | number) {
await this.state.setLastPayload({
state: value,
attributes: {},
});
await this.updateHomeAssistant(value);
}
}
52 changes: 22 additions & 30 deletions src/nodes/number/NumberController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,28 @@ export default class NumberController extends InputOutputController<
}

value = this.#getValidatedValue(value);

// get previous value before updating
const previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as number | undefined;
await this.#prepareSend(message, value);
await this.integration?.updateValue(value);

// send value change to all number nodes
this.#entityConfigNode?.emit(
IntegrationEvent.ValueChange,
value,
previousValue
);

await this.setCustomOutputs(
this.node.config.outputProperties,
message,
{
config: this.node.config,
value,
previousValue,
}
);
this.status.setSuccess(value.toString());
send(message);
done();
}
Expand All @@ -118,8 +128,17 @@ export default class NumberController extends InputOutputController<
if (isNaN(value)) return;

const message: NodeMessage = {};
await this.#prepareSend(message, value, previousValue);

await this.setCustomOutputs(
this.node.config.outputProperties,
message,
{
config: this.node.config,
value,
previousValue,
}
);
this.status.setSuccess(value.toString());
this.node.send(message);
}

Expand All @@ -140,31 +159,4 @@ export default class NumberController extends InputOutputController<

return value;
}

// Take care of repetative code in onInput and #onValueChange
async #prepareSend(
message: NodeMessage,
value: number,
previousValue?: number
): Promise<void> {
await this.integration?.updateHomeAssistant(value);
if (!previousValue) {
previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as number | undefined;
}
await this.setCustomOutputs(
this.node.config.outputProperties,
message,
{
config: this.node.config,
value,
previousValue,
}
);
this.#entityConfigNode?.state?.setLastPayload({
state: value,
attributes: {},
});
this.status.setSuccess(value.toString());
}
}
50 changes: 22 additions & 28 deletions src/nodes/select/SelectController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,35 @@ export default class SelectController extends InputOutputController<
}
);

if (this.#isValidValue(value) === false) {
throw new InputError(
'ha-select.error.invalid_value',
'home-assistant.status.error'
);
}

// get previous value before updating
const previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as string | undefined;
await this.#prepareSend(message, value);
await this.integration?.updateValue(value);

// send value change to all number nodes
this.#entityConfigNode?.emit(
IntegrationEvent.ValueChange,
value,
previousValue
);

await this.setCustomOutputs(
this.node.config.outputProperties,
message,
{
config: this.node.config,
value,
previousValue,
}
);
this.status.setSuccess(value);
send(message);
done();
}
Expand Down Expand Up @@ -112,23 +130,8 @@ export default class SelectController extends InputOutputController<
return options.includes(option);
}

async #prepareSend(
message: NodeMessage,
value: string,
previousValue?: string
) {
if (this.#isValidValue(value) === false) {
throw new InputError(
'ha-select.error.invalid_value',
'home-assistant.status.error'
);
}

await this.integration?.updateHomeAssistant(value);
if (!previousValue) {
previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as string | undefined;
}
public async onValueChange(value: string, previousValue?: string) {
const message: NodeMessage = {};
await this.setCustomOutputs(
this.node.config.outputProperties,
message,
Expand All @@ -138,17 +141,8 @@ export default class SelectController extends InputOutputController<
previousValue,
}
);
this.#entityConfigNode?.state?.setLastPayload({
state: value,
attributes: {},
});
this.status.setSuccess(value);
}

public async onValueChange(value: string, previousValue?: string) {
const message: NodeMessage = {};
await this.#prepareSend(message, value, previousValue);

this.status.setSuccess(value);
this.node.send(message);
}
}
48 changes: 21 additions & 27 deletions src/nodes/text/TextController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,35 @@ export default class TextController extends InputOutputController<
}
);

if (this.#isValidValue(value) === false) {
throw new InputError(
'home-assistant.error.pattern_not_matched',
'home-assistant.status.error'
);
}

// get previous value before updating
const previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as string | undefined;
await this.#prepareSend(message, value);
await this.integration?.updateValue(value);

// send value change to all number nodes
this.#entityConfigNode?.emit(
IntegrationEvent.ValueChange,
value,
previousValue
);

await this.setCustomOutputs(
this.node.config.outputProperties,
message,
{
config: this.node.config,
value,
previousValue,
}
);
this.status.setSuccess(value);
send(message);
done();
}
Expand Down Expand Up @@ -117,23 +135,9 @@ export default class TextController extends InputOutputController<
return true;
}

async #prepareSend(
message: NodeMessage,
value: string,
previousValue?: string
) {
if (this.#isValidValue(value) === false) {
throw new InputError(
'home-assistant.error.pattern_not_matched',
'home-assistant.status.error'
);
}
public async onValueChange(value: string, previousValue?: string) {
const message: NodeMessage = {};

await this.integration?.updateHomeAssistant(value);
if (!previousValue) {
previousValue = this.#entityConfigNode?.state?.getLastPayload()
?.state as string | undefined;
}
await this.setCustomOutputs(
this.node.config.outputProperties,
message,
Expand All @@ -143,17 +147,7 @@ export default class TextController extends InputOutputController<
previousValue,
}
);
this.#entityConfigNode?.state?.setLastPayload({
state: value,
attributes: {},
});
this.status.setSuccess(value);
}

public async onValueChange(value: string, previousValue?: string) {
const message: NodeMessage = {};
await this.#prepareSend(message, value, previousValue);

this.node.send(message);
}
}
Loading

0 comments on commit 9975266

Please sign in to comment.