import { EventEmitter, Injectable } from '@angular/core'; @Injectable() export class MQTTEntity implements iMQTTEntityBase { protected _name: string = ''; protected _stat_t: string = 'state/topic'; protected _uniq_id: string = ''; private _size: number = 0; attrs = new Set(['name', 'stat_t', 'uniq_id']); topic_updates = new EventEmitter(); readonly ent_type: string = 'base'; get name() { return this._name; } set name(name: string) { this._name = name; if (name == '') return; this._uniq_id = name + '_' + hash(name); this.topic_updates.next('stat_t'); } get stat_t() { return this._stat_t; } set stat_t(stat: string) { this._stat_t = stat; } get uniq_id() { return this._uniq_id; } set uniq_id(uniq_id: string) { this._uniq_id = uniq_id; this.topic_updates.next('stat_t'); } get display_name() { if (this._uniq_id != '') { return this._uniq_id; } return this._name; } publish_topics(index: number = 1): string[] { return [`String stat_topic_${index} = "${this.stat_t}";`]; } toJSON(): { [key: string]: string | {} } { let jsonObject: { [key: string]: string | {} } = {}; for (let prop_name of this.attrs.values()) { let property = this[prop_name as keyof this]; if (property == '') continue; jsonObject[prop_name] = String(property); } return jsonObject; } get size(): number { this._size = JSON.stringify(this.toJSON()).length; return this._size; } getProperty(name: string): any { if (!this.attrs.has(name)) return ''; return this[name as keyof this]; } setProperty(name: string, value: any) { if (!this.attrs.has(name)) return; this[name as keyof this] = value; } } export class DeviceClass { value: number = 0; choices: string[] = ['None']; constructor(choices: string[]) { this.choices = choices; } toString(): string { return this.choices[this.value]; } } export interface iMQTTEntityBase { name: string; stat_t: string; uniq_id: string; display_name: string; attrs: Set; readonly ent_type: string; topic_updates: EventEmitter; publish_topics: (index: number) => string[]; toJSON: () => { [key: string]: string | {} }; } export function hash(str: string, digits: number = 5): string { let seed = cyrb128(str); let rand = sfc32(seed[0], seed[1], seed[2], seed[3]); let rand_num = Math.floor(rand() * 10 ** digits).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; }; }