diff --git a/lib/ConditionCardAnyDeviceTurnedOn.ts b/lib/ConditionCardAnyDeviceTurnedOn.ts index 46d84e3..b7ed72e 100644 --- a/lib/ConditionCardAnyDeviceTurnedOn.ts +++ b/lib/ConditionCardAnyDeviceTurnedOn.ts @@ -23,68 +23,61 @@ export default class ConditionCardAnyDeviceTurnedOn { } private async setup(): Promise { - try { - this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); - this.conditionCard.registerArgumentAutocompleteListener('deviceType', - async (query: string): Promise => { - const deviceClasses = HomeyLib.Device.getClasses(); - - const results = [{ - name: this.homey.__('any_type') ?? "Any type", - id: 'any_type', - }]; - - const languageCode = this.homey.i18n.getLanguage(); - results.push(...Object.entries(deviceClasses).map(([key, deviceClass]) => { - return { - name: deviceClass.title[languageCode], - description: deviceClass.description?.[languageCode], - id: key, - }; - })); - - return results.filter((result) => { - return result.name.toLowerCase().includes(query.toLowerCase()); - }); - } + this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); + this.conditionCard.registerArgumentAutocompleteListener('deviceType', + async (query: string): Promise => { + const deviceClasses = HomeyLib.Device.getClasses(); + + const results = [{ + name: this.homey.__('any_type') ?? "Any type", + id: 'any_type', + }]; + + const languageCode = this.homey.i18n.getLanguage(); + results.push(...Object.entries(deviceClasses).map(([key, deviceClass]) => { + return { + name: deviceClass.title[languageCode], + description: deviceClass.description?.[languageCode], + id: key, + }; + })); + + return results.filter((result) => { + return result.name.toLowerCase().includes(query.toLowerCase()); + }); + } + ); + + + this.conditionCard.registerRunListener(async (args, _state) => { + this.log(`Checking devices in zone '${args.zone.id}' with class '${args.deviceType.id}'.`); + + const zone = await this.zonesDb.getZone(args.zone.id); + + if (zone == null) + throw new Error(`Zone with id '${args.zone.id}' not found.`); + + const zonesToCheck = [zone]; + if (args.includeDescendants === "1") + zonesToCheck.push(...await this.zonesDb.getAllChildren(zone.id)); + + const allDevices = await this.homeyApi.devices.getDevices(); + const devicesToCheck = Object.values(allDevices).filter(device => + zonesToCheck.some(zone => device.zone === zone.id) && + (args.deviceType.id === 'any_type' || device.class === args.deviceType.id) && + device.capabilities.includes('onoff') && + device.capabilitiesObj['onoff'] !== null ); - } catch (error) { - this.log('Error updating condition card arguments:', error); - } - - try { - this.conditionCard.registerRunListener(async (args, _state) => { - this.log(`Checking devices in zone '${args.zone.id}' with class '${args.deviceType.id}'.`); - - const zone = await this.zonesDb.getZone(args.zone.id); - - if (zone == null) - throw new Error(`Zone with id '${args.zone.id}' not found.`); - const zonesToCheck = [zone]; - if (args.includeDescendants === "1") - zonesToCheck.push(...await this.zonesDb.getAllChildren(zone.id)); + this.log(`Checking ${devicesToCheck.length} devices in zone '${zone.name}' with class '${args.deviceType.id}' with the onoff capability.`, { devicesToCheck: devicesToCheck.map(device => device.name) }); - const allDevices = await this.homeyApi.devices.getDevices(); - const devicesToCheck = Object.values(allDevices).filter(device => - zonesToCheck.some(zone => device.zone === zone.id) && - (args.deviceType.id === 'any_type' || device.class === args.deviceType.id) && - device.capabilities.includes('onoff') && - device.capabilitiesObj['onoff'] !== null - ); + if (devicesToCheck.length === 0) { + this.log(`No devices with class '${args.deviceType.id}' found in zone '${zone.name}'.`, { args, zone }); + // Throwing this error will make sure that the flow card will not be triggered if there are no devices in the zone. + throw new Error(`No devices found in zone '${zone.name}' with class '${args.deviceType.id}'.`); + } - this.log(`Checking ${devicesToCheck.length} devices in zone '${zone.name}' with class '${args.deviceType.id}' with the onoff capability.`, { devicesToCheck: devicesToCheck.map(device => device.name) }); - - if (devicesToCheck.length === 0) { - this.log(`No devices with class '${args.deviceType.id}' found in zone '${zone.name}'.`, { args, zone }); - // Throwing this error will make sure that the flow card will not be triggered if there are no devices in the zone. - throw new Error(`No devices found in zone '${zone.name}' with class '${args.deviceType.id}'.`); - } - - return devicesToCheck.some(device => device.capabilitiesObj['onoff'].value === true); - }); - } catch (error) { - this.log('Error registering run listener:', error); - } + return devicesToCheck.some(device => device.capabilitiesObj['onoff'].value === true); + }); } } diff --git a/lib/ConditionCardEvaluateSensorCapabilities.ts b/lib/ConditionCardEvaluateSensorCapabilities.ts index d8f8f51..082d2be 100644 --- a/lib/ConditionCardEvaluateSensorCapabilities.ts +++ b/lib/ConditionCardEvaluateSensorCapabilities.ts @@ -21,94 +21,84 @@ export default class ConditionCardEvaluateSensorCapabilities { } private async setup(): Promise { - try { - this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); - this.conditionCard.registerArgumentAutocompleteListener('capability', - async (query: string): Promise => { - - const capabilities = HomeyLib.Capability.getCapabilities(); - - const languageCode = this.homey.i18n.getLanguage(); - const results = [...Object.entries(capabilities) - .filter(([_key, capability]) => - capability.uiComponent === 'sensor' && capability.type === 'number' - ) - .map(([key, capability]) => { - return { - name: capability.title[languageCode], - description: capability.desc?.[languageCode], - id: key, - }; - })]; - - return results.filter((result) => { - return result.name.toLowerCase().includes(query.toLowerCase()); - }); - } + this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); + this.conditionCard.registerArgumentAutocompleteListener('capability', + async (query: string): Promise => { + + const capabilities = HomeyLib.Capability.getCapabilities(); + + const languageCode = this.homey.i18n.getLanguage(); + const results = [...Object.entries(capabilities) + .filter(([_key, capability]) => + capability.uiComponent === 'sensor' && capability.type === 'number' + ) + .map(([key, capability]) => { + return { + name: capability.title[languageCode], + description: capability.desc?.[languageCode], + id: key, + }; + })]; + + return results.filter((result) => { + return result.name.toLowerCase().includes(query.toLowerCase()); + }); + } + ); + + this.conditionCard.registerRunListener(async (args, _state) => { + const capability = args.capability.id; + this.log(`Checking sensors in zone '${args.zone.id}' with capability '${capability}'.`); + const zone = await this.zonesDb.getZone(args.zone.id); + + if (zone == null) + throw new Error(`Zone with id '${args.zone.id}' not found.`); + + const zonesToCheck = [zone]; + if (args.includeDescendants === "1") + zonesToCheck.push(...await this.zonesDb.getAllChildren(zone.id)); + + const allDevices = await this.homeyApi.devices.getDevices(); + const devicesToCheck = Object.values(allDevices).filter(device => + zonesToCheck.some(zone => device.zone === zone.id) && + device.capabilities.includes(capability) && + device.capabilitiesObj[capability] !== null && + typeof device.capabilitiesObj[capability].value === 'number' ); - } catch (error) { - this.log('Error updating condition card arguments:', error); - } - - try { - - this.conditionCard.registerRunListener(async (args, _state) => { - const capability = args.capability.id; - this.log(`Checking sensors in zone '${args.zone.id}' with capability '${capability}'.`); - const zone = await this.zonesDb.getZone(args.zone.id); - - if (zone == null) - throw new Error(`Zone with id '${args.zone.id}' not found.`); - - const zonesToCheck = [zone]; - if (args.includeDescendants === "1") - zonesToCheck.push(...await this.zonesDb.getAllChildren(zone.id)); - - const allDevices = await this.homeyApi.devices.getDevices(); - const devicesToCheck = Object.values(allDevices).filter(device => - zonesToCheck.some(zone => device.zone === zone.id) && - device.capabilities.includes(capability) && - device.capabilitiesObj[capability] !== null && - typeof device.capabilitiesObj[capability].value === 'number' - ); - - this.log(`Checking ${devicesToCheck.length} devices in zone '${zone.name}' with capability '${capability}'.`, { devicesToCheck: devicesToCheck.map(device => device.name) }); - - if (devicesToCheck.length === 0) { - this.log(`No devices with capability '${capability}' found in zone '${zone.name}'.`, { args, zone }); - // Throwing this error will make sure that the flow card will not be triggered if there are no devices in the zone. - throw new Error(`No devices found in zone '${zone.name}' with capability '${capability}'.`); + this.log(`Checking ${devicesToCheck.length} devices in zone '${zone.name}' with capability '${capability}'.`, { devicesToCheck: devicesToCheck.map(device => device.name) }); + + if (devicesToCheck.length === 0) { + this.log(`No devices with capability '${capability}' found in zone '${zone.name}'.`, { args, zone }); + // Throwing this error will make sure that the flow card will not be triggered if there are no devices in the zone. + throw new Error(`No devices found in zone '${zone.name}' with capability '${capability}'.`); + } + + const equation = args.equation; + const otherValue = args.value; + return devicesToCheck.some(device => { + const value = device.capabilitiesObj[capability].value as number; + switch (equation) { + case 'equals': { + const result = value === otherValue; + this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'equal' : 'not equal'} to '${otherValue}'.`, { device: device.name, args }); + return result; + } + case 'is-greater-than': { + const result = value > otherValue; + this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'greater' : 'not greater'} than '${otherValue}'.`, { device: device.name, args }); + return result; + } + case 'is-less-than': { + const result = value < otherValue; + this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'less' : 'not less'} than '${otherValue}'.`, { device: device.name, args }); + return result; + } + default: + throw new Error(`Unknown equation '${equation}'.`); } - - const equation = args.equation; - const otherValue = args.value; - return devicesToCheck.some(device => { - const value = device.capabilitiesObj[capability].value as number; - switch (equation) { - case 'equals': { - const result = value === otherValue; - this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'equal' : 'not equal'} to '${otherValue}'.`, { device: device.name, args }); - return result; - } - case 'is-greater-than': { - const result = value > otherValue; - this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'greater' : 'not greater'} than '${otherValue}'.`, { device: device.name, args }); - return result; - } - case 'is-less-than': { - const result = value < otherValue; - this.log(`Device '${device.name}' has value '${value}' for capability '${capability}' which is ${result ? 'less' : 'not less'} than '${otherValue}'.`, { device: device.name, args }); - return result; - } - default: - throw new Error(`Unknown equation '${equation}'.`); - } - }); - }); - } catch (error) { - this.log('Error registering run listener:', error); - } + + }); } } diff --git a/lib/ConditionCardZoneActiveForMinutes.ts b/lib/ConditionCardZoneActiveForMinutes.ts index 4a944d6..0e0aa55 100644 --- a/lib/ConditionCardZoneActiveForMinutes.ts +++ b/lib/ConditionCardZoneActiveForMinutes.ts @@ -20,39 +20,30 @@ export default class ConditionCardZoneActiveForMinutes { } private async setup(): Promise { - try { - this.conditionCard.registerRunListener(async (args, _state) => { - const zone = await this.zonesDb.getZone(args.zone.id); - if (zone == null) - throw new Error(`Zone with id '${args.zone.id}' not found.`); - - const now = new Date(); - const checkIsActive = args.state === 'active'; - - if(checkIsActive) { - const isZoneActive = (zone.activeLastUpdated !== null && zone.active); - const activeForGivenMinutes = (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; - const isActive = isZoneActive && activeForGivenMinutes; - this.log(`Zone '${zone.name}' is considered ${isActive ? 'active' : 'inactive'}.`, { args, zone }); - return isActive; - - } else { - const isZoneInactive = !(zone.activeLastUpdated === null ? false : zone.active); - const lastUpdatedWithinGivenMinutes = (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; - const isInactive = isZoneInactive && lastUpdatedWithinGivenMinutes; - this.log(`Zone '${zone.name}' is considered ${isInactive ? 'inactive' : 'active'}.`, { args, zone }); - return isInactive; - } - }); - } catch (error) { - this.log('Error registering run listener:', error); - } - - try { - this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); - } - catch (error) { - this.log('Error updating condition card arguments:', error); - } + this.conditionCard.registerRunListener(async (args, _state) => { + const zone = await this.zonesDb.getZone(args.zone.id); + if (zone == null) + throw new Error(`Zone with id '${args.zone.id}' not found.`); + + const now = new Date(); + const checkIsActive = args.state === 'active'; + + if(checkIsActive) { + const isZoneActive = (zone.activeLastUpdated !== null && zone.active); + const activeForGivenMinutes = (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; + const isActive = isZoneActive && activeForGivenMinutes; + this.log(`Zone '${zone.name}' is considered ${isActive ? 'active' : 'inactive'}.`, { args, zone }); + return isActive; + + } else { + const isZoneInactive = !(zone.activeLastUpdated === null ? false : zone.active); + const lastUpdatedWithinGivenMinutes = (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; + const isInactive = isZoneInactive && lastUpdatedWithinGivenMinutes; + this.log(`Zone '${zone.name}' is considered ${isInactive ? 'inactive' : 'active'}.`, { args, zone }); + return isInactive; + } + }); + + this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); } } diff --git a/lib/ConditionCardZoneInactiveForMinutes.ts b/lib/ConditionCardZoneInactiveForMinutes.ts index eb669b0..e276305 100644 --- a/lib/ConditionCardZoneInactiveForMinutes.ts +++ b/lib/ConditionCardZoneInactiveForMinutes.ts @@ -23,28 +23,19 @@ export default class ConditionCardZoneInactiveForMinutes { } private async setup(): Promise { - try { - this.conditionCard.registerRunListener(async (args, _state) => { - const zone = await this.zonesDb.getZone(args.zone.id); - if (zone == null) - throw new Error(`Zone with id '${args.zone.id}' not found.`); + this.conditionCard.registerRunListener(async (args, _state) => { + const zone = await this.zonesDb.getZone(args.zone.id); + if (zone == null) + throw new Error(`Zone with id '${args.zone.id}' not found.`); - const now = new Date(); - const isInactive = zone.activeLastUpdated === null ? true - : zone.active ? false : (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; + const now = new Date(); + const isInactive = zone.activeLastUpdated === null ? true + : zone.active ? false : (now.getTime() - new Date(zone.activeLastUpdated).getTime()) >= args.minutes * 60 * 1000; - this.log(`Zone '${zone.name}' is considered ${isInactive ? 'inactive' : 'active'}.`, { args, zone }); - return isInactive; - }); - } catch (error) { - this.log('Error registering run listener:', error); - } + this.log(`Zone '${zone.name}' is considered ${isInactive ? 'inactive' : 'active'}.`, { args, zone }); + return isInactive; + }); - try { - this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); - } - catch (error) { - this.log('Error updating condition card arguments:', error); - } + this.conditionCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); } } diff --git a/lib/TriggerCardAnyDeviceOnOff.ts b/lib/TriggerCardAnyDeviceOnOff.ts index 25626b6..7439708 100644 --- a/lib/TriggerCardAnyDeviceOnOff.ts +++ b/lib/TriggerCardAnyDeviceOnOff.ts @@ -85,59 +85,51 @@ export default class TriggerCardAnyDeviceTurnedOn { this.homeyApi.devices.on('device.delete', (device: ExtendedDevice) => this.deleteDeviceCapabilityObserver(device)); - try { - this.triggerCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); - this.triggerCard.registerArgumentAutocompleteListener('deviceClass', - async (query: string): Promise => { - const deviceClasses = HomeyLib.Device.getClasses(); - - const results = [{ - name: this.homey.__('any_type') ?? "Any type", - id: 'any_type', - }]; - - const languageCode = this.homey.i18n.getLanguage(); - results.push(...Object.entries(deviceClasses).map(([key, deviceClass]) => { - return { - name: deviceClass.title[languageCode], - description: deviceClass.description?.[languageCode], - id: key, - }; - })); - - return results.filter((result) => { - return result.name.toLowerCase().includes(query.toLowerCase()); - }); - } - ); - } catch (error) { - this.log('Error updating condition card arguments:', error); - } + this.triggerCard.registerArgumentAutocompleteListener('zone', async (query: string) => await handleZoneAutocomplete(query, this.zonesDb)); + this.triggerCard.registerArgumentAutocompleteListener('deviceClass', + async (query: string): Promise => { + const deviceClasses = HomeyLib.Device.getClasses(); + + const results = [{ + name: this.homey.__('any_type') ?? "Any type", + id: 'any_type', + }]; + + const languageCode = this.homey.i18n.getLanguage(); + results.push(...Object.entries(deviceClasses).map(([key, deviceClass]) => { + return { + name: deviceClass.title[languageCode], + description: deviceClass.description?.[languageCode], + id: key, + }; + })); + + return results.filter((result) => { + return result.name.toLowerCase().includes(query.toLowerCase()); + }); + } + ); - try { - this.triggerCard.registerRunListener(async (args, state) => { - if(args.zone.id !== state.zone) { - if(args.includeDescendants === '1') { - const childZones = await this.zonesDb.getAllChildren(args.zone.id); - if (!childZones.some((zone) => zone.id === state.zone)) - return false; - } else { + this.triggerCard.registerRunListener(async (args, state) => { + if(args.zone.id !== state.zone) { + if(args.includeDescendants === '1') { + const childZones = await this.zonesDb.getAllChildren(args.zone.id); + if (!childZones.some((zone) => zone.id === state.zone)) return false; - } + } else { + return false; } + } - if (args.deviceClass.id !== 'any_type' && args.deviceClass.id !== state.deviceClass) - return false; + if (args.deviceClass.id !== 'any_type' && args.deviceClass.id !== state.deviceClass) + return false; - const stateToCheck = args.state === '1'; - if(state.onoff !== stateToCheck) - return false; + const stateToCheck = args.state === '1'; + if(state.onoff !== stateToCheck) + return false; - this.log(`Zone activity card triggered for zone '${args.zone.id}' because device '${state.deviceName}' was turned ${state.onoff ? 'on' : 'off'}.`); - return true; - }); - } catch (error) { - this.log('Error registering run listener:', error); - } + this.log(`Zone activity card triggered for zone '${args.zone.id}' because device '${state.deviceName}' was turned ${state.onoff ? 'on' : 'off'}.`); + return true; + }); } }