CHANGE: multiple entites
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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<MQTTEntity> = [];
|
||||
public _selected_entity: MQTTEntity | null = null;
|
||||
public created_enteties: Set<MQTTEntity> = new Set();
|
||||
// private entities: Map<string, MQTTEntity> = new Map<string, MQTTEntity>();
|
||||
|
||||
@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<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html5>
|
||||
<main class="grid grid-cols-2 gap-4">
|
||||
<form class="grid grid-cols-2 gap-4" (submit)="$event.preventDefault();generatorService.createEntity()" >
|
||||
<div class="property" *ngIf="hasProperty('name')">
|
||||
<p>Name</p>
|
||||
<input required placeholder="entity name" type="text"[ngModel]="entity_name" (ngModelChange)="entity_name = $event"/>
|
||||
<input required placeholder="entity name" type="text" name="entity_name" [ngModel]="entity_name" (ngModelChange)="entity_name = $event"/>
|
||||
</div>
|
||||
<div class="property" *ngIf="hasProperty('uniq_id')">
|
||||
<p>Uniqe ID</p>
|
||||
<div class="flex-row flex gap-2">
|
||||
<input type="text" [ngModel]="entity_uniq_id" (ngModelChange)="entity_uniq_id = $event"/>
|
||||
<input type="text" name="entity_uniq_id" [ngModel]="entity_uniq_id" (ngModelChange)="entity_uniq_id = $event"/>
|
||||
<button class="randomButton" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dice-3" viewBox="0 0 16 16">
|
||||
<path d="M13 1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2zM3 0a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V3a3 3 0 0 0-3-3z"/>
|
||||
@@ -18,43 +18,44 @@
|
||||
</div>
|
||||
<div class="property" *ngIf="hasProperty('cmd_t')">
|
||||
<p>Command Topic</p>
|
||||
<input placeholder="command/topic" type="text" [ngModel]="entity_cmd_t" (ngModelChange)="entity_cmd_t = $event" /> <!-- (input)="lock_auto_topic(); update('entity_cmd_t', $event)"-->
|
||||
<input placeholder="command/topic" type="text" name="entity_cmd_t" [ngModel]="entity_cmd_t" (ngModelChange)="entity_cmd_t = $event" /> <!-- (input)="lock_auto_topic(); update('entity_cmd_t', $event)"-->
|
||||
</div>
|
||||
<div class="property" *ngIf="hasProperty('bri_cmd_t')">
|
||||
<p>Brightness Command Topic</p>
|
||||
<input placeholder="brightness/command/topic" type="text" [ngModel]="entity_bri_cmd_t" (ngModelChange)="entity_bri_cmd_t = $event" /> <!--(ngModelChange)="lock_auto_topic(); update('entity_bri_cmd_t', $event)"-->
|
||||
<input placeholder="brightness/command/topic" type="text" name="entity_bri_cmd_t" [ngModel]="entity_bri_cmd_t" (ngModelChange)="entity_bri_cmd_t = $event" /> <!--(ngModelChange)="lock_auto_topic(); update('entity_bri_cmd_t', $event)"-->
|
||||
</div>
|
||||
<div class="property !flex-row" *ngIf="hasProperty('pl_off') || hasProperty('pl_on')">
|
||||
<div *ngIf="hasProperty('pl_on')">
|
||||
<p>Payload on</p>
|
||||
<input placeholder="1" type="text" [ngModel]="entity_pl_on" (ngModelChange)="entity_pl_on = $event"/>
|
||||
<input placeholder="1" type="text" name="entity_pl_on" [ngModel]="entity_pl_on" (ngModelChange)="entity_pl_on = $event"/>
|
||||
</div>
|
||||
<div *ngIf="hasProperty('pl_off')">
|
||||
<p>Payload off</p>
|
||||
<input placeholder="0" type="text" [ngModel]="entity_pl_off" (ngModelChange)="entity_pl_off = $event"/>
|
||||
<input placeholder="0" type="text" name="entity_pl_off" [ngModel]="entity_pl_off" (ngModelChange)="entity_pl_off = $event"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property" *ngIf="hasProperty('unit_of_meas')">
|
||||
<p>Unit of meassurement</p>
|
||||
<input placeholder="°C" type="text" [ngModel]="entity_unit_of_meas" (ngModelChange)="entity_unit_of_meas = $event"/>
|
||||
<input placeholder="°C" type="text" name="entity_unit_of_meas" [ngModel]="entity_unit_of_meas" (ngModelChange)="entity_unit_of_meas = $event"/>
|
||||
</div>
|
||||
<div class="property" *ngIf="hasProperty('val_tpl')">
|
||||
<p>Value Template</p>
|
||||
<input type="text" [ngModel]="entity_val_tpl" (ngModelChange)="entity_val_tpl = $event"/>
|
||||
<input type="text" name="entity_val_tpl" [ngModel]="entity_val_tpl" (ngModelChange)="entity_val_tpl = $event"/>
|
||||
</div>
|
||||
<div class="property bg-mySecondary" *ngIf="hasProperty('dev_cla')">
|
||||
<div class="property " *ngIf="hasProperty('dev_cla')">
|
||||
<p>Device Class</p>
|
||||
<select [ngModel]="basemodel.getProperty('dev_cla').value" (ngModelChange)="entity_dev_cla =$event">
|
||||
<select name="entity_dev_cla" [ngModel]="entity_dev_cla" (ngModelChange)="entity_dev_cla =$event">
|
||||
<option *ngFor="let choice of basemodel.getProperty('dev_cla').choices" value="{{basemodel.getProperty('dev_cla').choices.indexOf(choice)}}">{{choice}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="property" *ngIf="hasProperty('stat_t')">
|
||||
<p>State Topic</p>
|
||||
<div class="flex-row flex gap-2">
|
||||
<input placeholder="state/topic" type="text" [ngModel]="basemodel.getProperty('stat_t')" (ngModelChange)="basemodel.stat_t= $event" /> <!--(ngModelChange)="lock_auto_topic(); update('stat_t', $event)"-->
|
||||
<input placeholder="state/topic" type="text" name="stat_t" [ngModel]="basemodel.getProperty('stat_t')" (ngModelChange)="basemodel.stat_t= $event" /> <!--(ngModelChange)="lock_auto_topic(); update('stat_t', $event)"-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="property col-span-2" *ngIf="!created">
|
||||
<button class="w-full" (click)="generatorService.createEntity()">Add Entity</button>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</form>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
|
||||
|
||||
</div>
|
||||
<ng-container *ngIf="generatorService.selected_entity == null" >
|
||||
<button (click)="select_type(entity_type)" class="genContainer" id="entityPlaceholder">Create new entity</button>
|
||||
|
||||
</ng-container>
|
||||
<app-entity-data class="genContainer" [basemodel]="generatorService.selected_entity" *ngIf="generatorService.selected_entity != null" ></app-entity-data>
|
||||
<!-- <app-entity class="genContainer" ></app-entity> -->
|
||||
<app-entity-data class="genContainer" *ngFor="let entity of created_entities" [basemodel]="entity" [created]="true" ></app-entity-data>
|
||||
</div>
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user