From 06e2d77f08402b71d0bd50d7b7a5e506c6fd3b7b Mon Sep 17 00:00:00 2001 From: tom Date: Tue, 30 Jul 2024 15:30:35 +0200 Subject: [PATCH] CHANGE: multiple entites --- src/app/_models/mqtt-binary.ts | 10 +- src/app/_models/mqtt-switch.ts | 10 +- src/app/_models/mqtt_base.ts | 46 +++++- src/app/_services/generator.service.ts | 131 ++++++++++++++---- .../entity-data/entity-data.component.html | 31 +++-- src/app/entity-data/entity-data.component.ts | 17 ++- src/app/generator/generator.component.html | 6 +- src/app/generator/generator.component.ts | 5 + 8 files changed, 204 insertions(+), 52 deletions(-) diff --git a/src/app/_models/mqtt-binary.ts b/src/app/_models/mqtt-binary.ts index 4707f0c..14a0226 100644 --- a/src/app/_models/mqtt-binary.ts +++ b/src/app/_models/mqtt-binary.ts @@ -11,7 +11,15 @@ export class MqttBinary extends MQTTEntity { 'dev_cla', ]); - dev_cla: DeviceClass = new DeviceClass([ + get dev_cla(): DeviceClass { + return this._dev_cla; + } + + set dev_cla(data: number) { + this._dev_cla.value = data; + } + + _dev_cla: DeviceClass = new DeviceClass([ 'battery', 'battery_charging', 'carbon_monoxide', diff --git a/src/app/_models/mqtt-switch.ts b/src/app/_models/mqtt-switch.ts index 4915ae3..08d288a 100644 --- a/src/app/_models/mqtt-switch.ts +++ b/src/app/_models/mqtt-switch.ts @@ -12,7 +12,15 @@ export class MqttSwitch extends MQTTEntity { 'pl_on', 'pl_off', ]); - dev_cla: DeviceClass = new DeviceClass(['switch', 'outlet']); + get dev_cla(): DeviceClass { + return this._dev_cla; + } + + set dev_cla(data: number) { + this._dev_cla.value = data; + } + + _dev_cla: DeviceClass = new DeviceClass(['switch', 'outlet']); cmd_t: string = 'command/topic'; pl_on: string = '1'; pl_off: string = '0'; diff --git a/src/app/_models/mqtt_base.ts b/src/app/_models/mqtt_base.ts index 9a03d00..42028eb 100644 --- a/src/app/_models/mqtt_base.ts +++ b/src/app/_models/mqtt_base.ts @@ -17,7 +17,8 @@ export class MQTTEntity implements iMQTTEntityBase { set name(name: string) { this._name = name; - this._uniq_id = btoa(this._name).slice(-7).slice(0, 5); + if (name == '') return; + this._uniq_id = hash(name); this.topic_updates.next('stat_t'); } @@ -98,3 +99,46 @@ export interface iMQTTEntityBase { toJSON: () => string; } + +function hash(str: string): string { + let seed = cyrb128(str); + let rand = sfc32(seed[0], seed[1], seed[2], seed[3]); + let rand_num = Math.floor(rand() * 100000).toString(); + return rand_num; +} + +function cyrb128(str: string) { + let h1 = 1779033703, + h2 = 3144134277, + h3 = 1013904242, + h4 = 2773480762; + for (let i = 0, k; i < str.length; i++) { + k = str.charCodeAt(i); + h1 = h2 ^ Math.imul(h1 ^ k, 597399067); + h2 = h3 ^ Math.imul(h2 ^ k, 2869860233); + h3 = h4 ^ Math.imul(h3 ^ k, 951274213); + h4 = h1 ^ Math.imul(h4 ^ k, 2716044179); + } + h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067); + h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233); + h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213); + h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179); + (h1 ^= h2 ^ h3 ^ h4), (h2 ^= h1), (h3 ^= h1), (h4 ^= h1); + return [h1 >>> 0, h2 >>> 0, h3 >>> 0, h4 >>> 0]; +} + +function sfc32(a: number, b: number, c: number, d: number) { + return function () { + a |= 0; + b |= 0; + c |= 0; + d |= 0; + let t = (((a + b) | 0) + d) | 0; + d = (d + 1) | 0; + a = b ^ (b >>> 9); + b = (c + (c << 3)) | 0; + c = (c << 21) | (c >>> 11); + c = (c + t) | 0; + return (t >>> 0) / 4294967296; + }; +} diff --git a/src/app/_services/generator.service.ts b/src/app/_services/generator.service.ts index 6077039..2b3efe1 100644 --- a/src/app/_services/generator.service.ts +++ b/src/app/_services/generator.service.ts @@ -1,51 +1,130 @@ import { EventEmitter, Injectable, Input } from '@angular/core'; -import { MQTTEntity } from '../_models/mqtt_base'; -import { MqttLight } from '../_models/mqtt-light'; -import { MqttSwitch } from '../_models/mqtt-switch'; -import { MqttSensor } from '../_models/mqtt-sensor'; import { MqttBinary } from '../_models/mqtt-binary'; +import { MqttLight } from '../_models/mqtt-light'; +import { MqttSensor } from '../_models/mqtt-sensor'; +import { MqttSwitch } from '../_models/mqtt-switch'; +import { MQTTEntity } from '../_models/mqtt_base'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class GeneratorService { - public selected_entity: MQTTEntity | null = null; - public created_enteties: Array = []; + public _selected_entity: MQTTEntity | null = null; + public created_enteties: Set = new Set(); + // private entities: Map = new Map(); - @Input() device_name: string = ""; - @Input() device_id: string = ""; + @Input() device_name: string = ''; + @Input() device_id: string = ''; @Input() device_standalone: boolean = false; - @Input() upperTopic: string = ""; @Input() auto_topic: number = 2; + + _upperTopic: string = ''; + + get upperTopic(): string { + return this._upperTopic; + } + + set upperTopic(value: string) { + this._upperTopic = value; + for (let entity of [...this.created_enteties, this.selected_entity]) { + entity?.setProperty('stat_t', this.updateTopic(entity, 'stat_t')); + entity?.setProperty('cmd_t', this.updateTopic(entity, 'cmd_t')); + entity?.setProperty('bri_cmd_t', this.updateTopic(entity, 'bri_cmd_tt')); + } + } + updateObserver: EventEmitter = new EventEmitter(); - - constructor() { } - - get_properties() { - return Object.getOwnPropertyNames(this.selected_entity); + set selected_entity(entity: MQTTEntity | null) { + this._selected_entity = entity; + console.log('added'); + entity?.topic_updates.subscribe((topic: string) => { + entity.setProperty(topic, this.updateTopic(entity, topic)); + }); } - update(){ - this.updateObserver.emit(); + get selected_entity(): MQTTEntity | null { + return this._selected_entity; } + updateTopic(entity: MQTTEntity, topic: string) { + return join( + '/', + this.upperTopic, + entity.ent_type, + this.device_name, + entity.display_name, + topic + ).toLowerCase(); + } + + createEntity() { + console.log('Creating entity...'); + if (this._selected_entity) { + this.created_enteties.add(this._selected_entity); + this._selected_entity = null; + } + } + + // get_properties() { + // return Object.getOwnPropertyNames(this.selected_entity); + // } + + // update() { + // this.updateObserver.emit(); + // } + has_property(property: string): boolean { - if (this.selected_entity == null) return false; - if (this.selected_entity.hasOwnProperty(property)) return true; - return false + return false; } + // console.log(this.selected_entity); + // if (this.selected_entity == null) return false; + // if (this.selected_entity.attrs.has(property)) return true; + // if (this.selected_entity.hasOwnProperty(property)) return true; + // return false; + // } + // get_entity(key: string): MQTTEntity | undefined { + // return this.entities.get(key); + // if (res === undefined) return new MQTTEntity(); + // return res; + // } + + // add_entity(key: string, data: MQTTEntity) { + // this.entities.set(key, data); + // } + + entity_types: { [id: string]: [string, typeof MQTTEntity] } = { + '0': ['select type', MQTTEntity], + '1': ['light', MqttLight], + '2': ['switch', MqttSwitch], + '3': ['sensor', MqttSensor], + '4': ['binary_sensor', MqttBinary], + }; } export function randomString(length: number): string { - return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1); + return Math.round( + Math.pow(36, length + 1) - Math.random() * Math.pow(36, length) + ) + .toString(36) + .slice(1); } export const entity_types: { [id: string]: [string, typeof MQTTEntity] } = { - '0': ["select type", MQTTEntity], - '1': ["light", MqttLight], - '2': ["switch", MqttSwitch], - '3': ["sensor", MqttSensor], - '4': ["binary_sensor", MqttBinary] + '0': ['select type', MQTTEntity], + '1': ['light', MqttLight], + '2': ['switch', MqttSwitch], + '3': ['sensor', MqttSensor], + '4': ['binary_sensor', MqttBinary], +}; + +function join(seperator = '/', first: string, ...args: string[]): string { + let result = ''; + for (let str of args) { + if (str == '') continue; + result += seperator + str; + } + if (first == '') return result.slice(1); + return first + result; } diff --git a/src/app/entity-data/entity-data.component.html b/src/app/entity-data/entity-data.component.html index ef15b2c..a38d060 100644 --- a/src/app/entity-data/entity-data.component.html +++ b/src/app/entity-data/entity-data.component.html @@ -1,13 +1,13 @@ -
+

Name

- +

Uniqe ID

- +

Command Topic

- +

Brightness Command Topic

- +

Payload on

- +

Payload off

- +

Unit of meassurement

- +

Value Template

- +
-
+

Device Class

-
- -

State Topic

- +
+
+ +
-
\ No newline at end of file + \ No newline at end of file diff --git a/src/app/entity-data/entity-data.component.ts b/src/app/entity-data/entity-data.component.ts index 19d0276..da3042b 100644 --- a/src/app/entity-data/entity-data.component.ts +++ b/src/app/entity-data/entity-data.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from '@angular/core'; -import { MQTTEntity } from '../_models/mqtt_base'; +import { DeviceClass, MQTTEntity } from '../_models/mqtt_base'; import { EntityService } from '../_services/entity.service'; import { GeneratorService } from '../_services/generator.service'; @@ -11,9 +11,10 @@ import { GeneratorService } from '../_services/generator.service'; export class EntityDataComponent { @Input() entity_type: number = 0; @Input() basemodel!: MQTTEntity; + @Input() created: boolean = false; constructor( private entityService: EntityService, - private generatorService: GeneratorService + public generatorService: GeneratorService ) { if (generatorService.selected_entity) { this.basemodel = generatorService.selected_entity; @@ -29,7 +30,7 @@ export class EntityDataComponent { _entity_pl_on: string = ''; _entity_unit_of_meas: string = ''; _entity_val_tpl: string = ''; - _entity_dev_cla: string = ''; + _entity_dev_cla: DeviceClass = new DeviceClass([]); get entity_name() { let base = this.basemodel.getProperty('name'); @@ -137,12 +138,14 @@ export class EntityDataComponent { this.basemodel.setProperty('val_tpl', data); } - get entity_dev_cla() { - return this._entity_dev_cla; + get entity_dev_cla(): number { + this._entity_dev_cla = this.basemodel.getProperty('dev_cla'); + return this._entity_dev_cla.value; } - set entity_dev_cla(data: string) { - this._entity_dev_cla = data; + set entity_dev_cla(data: number) { + data = Number(data); + this._entity_dev_cla.value = data; this.basemodel.setProperty('dev_cla', data); } diff --git a/src/app/generator/generator.component.html b/src/app/generator/generator.component.html index f893625..a413641 100644 --- a/src/app/generator/generator.component.html +++ b/src/app/generator/generator.component.html @@ -30,6 +30,10 @@ + + + + - + \ No newline at end of file diff --git a/src/app/generator/generator.component.ts b/src/app/generator/generator.component.ts index 9ed328a..d8f5353 100644 --- a/src/app/generator/generator.component.ts +++ b/src/app/generator/generator.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import { EntityService } from '../_services/entity.service'; import { GeneratorService, randomString } from '../_services/generator.service'; +import { MQTTEntity } from '../_models/mqtt_base'; @Component({ selector: 'app-home', @@ -25,6 +26,10 @@ export class GeneratorComponent { return String(this.generatorService.auto_topic); } + get created_entities(): MQTTEntity[] { + return Array.from(this.generatorService.created_enteties).reverse(); + } + entity_type: number = 0; select_type(etype: number) {