1
0

Rework watch module

This commit is contained in:
2024-01-04 06:26:47 +01:00
parent fe6f6e3d51
commit 37c0057aad
2 changed files with 62 additions and 64 deletions

View File

@@ -32,21 +32,12 @@ class Equipment {
// Initialization of properties // Initialization of properties
this.name = this.equipmentItem.name; this.name = this.equipmentItem.name;
this.watch = new Object();
this.timers = new timer.Timer(); this.timers = new timer.Timer();
// Check if equipment has state item
if (this.hasProperty('State')) {
this.stateItem = items[this.getPropertyItemName('State')];
this.watch['State'] = new watch.Watch(this.stateItem);
} else {
console.info(`Item ${this.equipmentItem.name} has no state item`)
}
// Check if equipment has LowBat item // Check if equipment has LowBat item
if (this.hasProperty('LowBat')) { if (this.hasProperty('LowBat')) {
this.watch['LowBat'] = new watch.Watch(this.getPropertyItemName('LowBat')); watches.add({
this.watch['LowBat'].add({ item: this.getPropertyItemName('LowBat'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.#notifyLowBat(); }, alertFunc: () => { this.#notifyLowBat(); },
alertRepeat: 'PT23H' alertRepeat: 'PT23H'
@@ -55,8 +46,8 @@ class Equipment {
// Check if equipment has Unreach item // Check if equipment has Unreach item
if (this.hasProperty('Unreach')) { if (this.hasProperty('Unreach')) {
this.watch['Unreach'] = new watch.Watch(this.getPropertyItemName('Unreach')); watches.add({
this.watch['Unreach'].add({ item: this.getPropertyItemName('Unreach'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.#notifyUnreach(); }, alertFunc: () => { this.#notifyUnreach(); },
alertDelay: 'PT15M', alertDelay: 'PT15M',
@@ -110,12 +101,7 @@ class Equipment {
} }
gc() { gc() {
console.log('Denitialization of eqipment ' + this.name); console.log('Denitialization of equipment ' + this.name);
// Delete all watchObjects
for (let watchItem of Object.keys(this.watch)) {
this.watch[watchItem].deleteAll();
}
// Cancel all timers // Cancel all timers
this.timers.cancelAll(); this.timers.cancelAll();
@@ -139,12 +125,13 @@ class CCTV extends Equipment {
super(equipmentItem); super(equipmentItem);
// Watch // Watch
this.watch['AP_ResidentsAreHome'] = new watch.Watch('AP_ResidentsAreHome'); watches.add({
this.watch['AP_ResidentsAreHome'].add({ item: 'AP_ResidentsAreHome',
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.setHomeMode('ON'); } alertFunc: () => { this.setHomeMode('ON'); }
}); });
this.watch['AP_ResidentsAreHome'].add({ watches.add({
item: 'AP_ResidentsAreHome',
targetState: 'OFF', targetState: 'OFF',
alertFunc: () => { this.setHomeMode('OFF'); }, alertFunc: () => { this.setHomeMode('OFF'); },
alertDelay: 'PT1M' alertDelay: 'PT1M'
@@ -229,6 +216,7 @@ class Doorbell extends Equipment {
super(equipmentItem); super(equipmentItem);
this.watch['State'].add({ this.watch['State'].add({
item: this.getPropertyItemName('State'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { items.getItem("OF_Alexa_Desk_TTS").sendCommand('Es hat geklingelt'); items.getItem("LR_Alexa_TV_TTS").sendCommand('Es hat geklingelt'); } alertFunc: () => { items.getItem("OF_Alexa_Desk_TTS").sendCommand('Es hat geklingelt'); items.getItem("LR_Alexa_TV_TTS").sendCommand('Es hat geklingelt'); }
}); });
@@ -243,7 +231,8 @@ class Irrigation extends Equipment {
this.valves = new Object(); this.valves = new Object();
// Add on/off watch rule // Add on/off watch rule
this.watch['State'].add({ watches.add({
item: this.getPropertyItemName('State'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.#irrigationOn(); }, alertFunc: () => { this.#irrigationOn(); },
endAlertFunc: () => { this.#irrigationOff(); }, endAlertFunc: () => { this.#irrigationOff(); },
@@ -346,7 +335,8 @@ class IrrigationValve extends Equipment {
constructor(equipmentItem) { constructor(equipmentItem) {
super(equipmentItem); super(equipmentItem);
this.watch['State'].add({ watches.add({
item: this.getPropertyItemName('State'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.stateItem.sendCommand('OFF'); }, alertFunc: () => { this.stateItem.sendCommand('OFF'); },
alertDelay: 'PT30M' alertDelay: 'PT30M'
@@ -376,7 +366,8 @@ class TowelRadiator extends Equipment {
constructor(equipmentItem) { constructor(equipmentItem) {
super(equipmentItem); super(equipmentItem);
this.watch['State'].add({ watches.add({
item: this.getPropertyItemName('State'),
targetState: 'ON', targetState: 'ON',
alertFunc: () => { this.stateItem.sendCommand('OFF'); }, alertFunc: () => { this.stateItem.sendCommand('OFF'); },
alertDelay: 'PT59M' alertDelay: 'PT59M'
@@ -403,7 +394,7 @@ class Window extends Equipment {
} }
const watches = new watch.Watch();
const eMgr = new Object(); const eMgr = new Object();
for (let equipmentItem of items.getItems().filter(element => { return (element.semantics.isEquipment == true) && (element.semantics.equipment == null) })) { for (let equipmentItem of items.getItems().filter(element => { return (element.semantics.isEquipment == true) && (element.semantics.equipment == null) })) {
@@ -430,6 +421,8 @@ cache.shared.put('eMgr', eMgr);
require('@runtime').lifecycleTracker.addDisposeHook(() => { require('@runtime').lifecycleTracker.addDisposeHook(() => {
console.log('Deinitialization of equipmentMgr'); console.log('Deinitialization of equipmentMgr');
watches.deleteAll();
for (let equipmentItemName of Object.keys(eMgr)) { for (let equipmentItemName of Object.keys(eMgr)) {
eMgr[equipmentItemName].gc(); eMgr[equipmentItemName].gc();
} }

View File

@@ -5,27 +5,12 @@ class Watch {
#watchItem #watchItem
#watchObjects = new Object(); #watchObjects = new Object();
#watchItems = new Object();
#timers = new timer.Timer(); #timers = new timer.Timer();
constructor(watchItem) { constructor() {
console.log('Initialization of watch helper class');
// Fetch item if provided itemName is a string
if (typeof watchItem === 'string' || watchItem instanceof String) {
this.#watchItem = items[watchItem];
} else {
this.#watchItem = watchItem;
}
// Throw error if item is not existing
if (this.#watchItem === null) {
throw(`Item ${watchItem} not existing`);
}
console.log(`Create new Watch instance for ${this.#watchItem.name}`);
// Create watch rule
this.#createWatchRule();
} }
add(params) { add(params) {
@@ -34,16 +19,24 @@ class Watch {
// Validate config for watchObject // Validate config for watchObject
if (!this.validateWatchConfig(params)) { if (!this.validateWatchConfig(params)) {
console.warn(`Failed to add watch object for ${this.#watchItem.name} because no valid config was provided`); console.warn(`Failed to add watch object because no valid config was provided`);
return; return;
} }
if (!this.#watchItems.hasOwnProperty(params['item'])) {
this.#createWatchRule(params['item']);
} else {
console.debug(`Watch rule for item ${params['item']} already existing`)
}
// Set default values if no config provided // Set default values if no config provided
let operator = (params['operator'] !== undefined) ? params['operator'] : '=='; let operator = (params['operator'] !== undefined) ? params['operator'] : '==';
// Create watch object and return UUID // Create watch object and return UUID
console.log(`Add watch object for item ${this.#watchItem.name} with state ${params['targetState']} and operator ${operator} with UUID ${watchUUID}`); console.log(`Add watch object for item ${params['item']} with state ${params['targetState']} and operator ${operator} with UUID ${watchUUID}`);
this.#watchObjects[watchUUID] = { this.#watchObjects[watchUUID] = {
item: params['item'],
targetState: params['targetState'], targetState: params['targetState'],
operator: operator, operator: operator,
alertFunc: params['alertFunc'], alertFunc: params['alertFunc'],
@@ -63,7 +56,10 @@ class Watch {
} }
delete(watchUUID) { delete(watchUUID) {
console.log(`Delete watch object for item ${this.#watchItem.name} with watchUUID ${watchUUID}`); // Get itemName
let watchItemName = this.#watchObjects[watchUUID].item;
console.log(`Delete watch object for item ${watchItemName} with watchUUID ${watchUUID}`);
// End repeatAlertTimer if existing // End repeatAlertTimer if existing
this.#timers.cancel('repeatAlarm ' + watchUUID); this.#timers.cancel('repeatAlarm ' + watchUUID);
@@ -73,10 +69,10 @@ class Watch {
delete this.#watchObjects[watchUUID]; delete this.#watchObjects[watchUUID];
// Delete watchRule if no more watchObjects are present // Delete watch rule if no more watchObjects for respective item are present
if (Object.keys(this.#watchObjects).length == 0) { if (Object.keys(this.#watchObjects).length == 0) {
console.debug(`Remove openHAB watch rule for item ${this.#watchItem.name}`); console.debug(`Remove openHAB watch rule for item ${watchItemName}`);
rules.removeRule(this.watchRuleID); rules.removeRule(this.#watchItems[watchItemName]);
} }
} }
@@ -88,6 +84,10 @@ class Watch {
validateWatchConfig(params) { validateWatchConfig(params) {
if (params['item'] === undefined) {
console.error('No item set');
return false;
}
if (params['targetState'] === undefined) { if (params['targetState'] === undefined) {
console.error('No targetState set'); console.error('No targetState set');
return false; return false;
@@ -114,10 +114,13 @@ class Watch {
} }
#checkAlertState(watchUUID) { #checkAlertState(watchUUID) {
console.debug(`Check if item is in alert state for watchObject ${watchUUID}`) // Get itemName
let watchItemName = this.#watchObjects[watchUUID].item;
console.debug(`Check if item ${watchItemName} is in alert state for watchObject ${watchUUID}`)
// Convert currentState for comparison // Convert currentState for comparison
let currentState = lib.convertValue(this.#watchItem.state); let currentState = lib.convertValue(items[watchItemName].state);
// Do comparison // Do comparison
if (lib.compare(currentState, this.#watchObjects[watchUUID].targetState, this.#watchObjects[watchUUID].operator)) { // Comparison successful if (lib.compare(currentState, this.#watchObjects[watchUUID].targetState, this.#watchObjects[watchUUID].operator)) { // Comparison successful
@@ -139,16 +142,17 @@ class Watch {
} }
} }
#createWatchRule() { #createWatchRule(item) {
// Create openHAB rule // Create openHAB rule
console.log(`Create openHAB watch rule for item ${this.#watchItem.name}`); console.log(`Create openHAB watch rule for item ${item}`);
this.watchRuleID = String(utils.randomUUID()); let watchRuleID = String(utils.randomUUID());
rules.JSRule({ rules.JSRule({
id: this.watchRuleID, id: watchRuleID,
name: 'Watch rule for ' + this.#watchItem.name, name: 'Watch rule for ' + item,
triggers: [triggers.ItemStateChangeTrigger(this.#watchItem.name)], triggers: [triggers.ItemStateChangeTrigger(item)],
execute: (event) => { this.#processItemEvent(event) }, execute: (event) => { this.#processItemEvent(event) },
}); });
this.#watchItems[item] = watchRuleID;
} }
#endAlert(watchUUID) { #endAlert(watchUUID) {
@@ -170,16 +174,17 @@ class Watch {
#processItemEvent(event) { #processItemEvent(event) {
// Skip if function is triggered without openHAB event // Skip if function is triggered without openHAB event
if (event === undefined || event.eventType === undefined) { if (event.eventType == 'manual') {
console.warn(`ProcessItemEvent triggered without openHAB event`); console.warn(`ProcessItemEvent triggered without openHAB event`);
return; return;
} }
console.log(`Processing state ${event.newState} for ${event.itemName}`); console.log(`Processing state ${event.newState} for ${event.itemName}`);
// Iterate through watchObjetcs // todo: rework to only fetch UUID for (const [id, watchObject] of Object.entries(this.#watchObjects)) {
for (let [watchUUID, watchObject] of Object.entries(this.#watchObjects)) { if (watchObject.item == event.itemName) {
this.#checkAlertState(watchUUID); this.#checkAlertState(id);
}
} }
} }