diff --git a/.homeycompose/flow/actions/garagedoor_close_if_open.json b/.homeycompose/flow/actions/garagedoor_close_if_open.json new file mode 100644 index 0000000..5c1ec77 --- /dev/null +++ b/.homeycompose/flow/actions/garagedoor_close_if_open.json @@ -0,0 +1,19 @@ +{ + "id": "garagedoor_close_if_open", + "highlight": true, + "title": { + "en": "Close if open", + "no": "Lukk hvis åpen" + }, + "hint": { + "en": "Will fetch garage door status from the API and close it if it's open\n\nOnly applicable for Remootio Device API", + "no": "Vil hente status for garasjeporten fra API'et og lukke den hvis den er åpen\n\nGjelder kun for Remootio Device API" + }, + "args": [ + { + "type": "device", + "name": "device", + "filter": "class_id=garagedoor&driver_id=remootio-device-api" + } + ] +} diff --git a/.homeycompose/flow/actions/garagedoor_open_if_closed.json b/.homeycompose/flow/actions/garagedoor_open_if_closed.json new file mode 100644 index 0000000..38c3f96 --- /dev/null +++ b/.homeycompose/flow/actions/garagedoor_open_if_closed.json @@ -0,0 +1,19 @@ +{ + "id": "garagedoor_open_if_closed", + "highlight": true, + "title": { + "en": "Open if closed", + "no": "Åpne hvis lukket" + }, + "hint": { + "en": "Will fetch garage door status from the API and open it if it's closed\n\nOnly applicable for Remootio Device API", + "no": "Vil hente status for garasjeporten fra API'et og åpne den hvis den er lukket\n\nGjelder kun for Remootio Device API" + }, + "args": [ + { + "type": "device", + "name": "device", + "filter": "class_id=garagedoor&driver_id=remootio-device-api" + } + ] +} diff --git a/README.md b/README.md index fcdce54..4f54739 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,8 @@ For any other issues, see [Remootio Installation Guide](https://documents.remoot ## Changelog +- 1.7.0 + - Added action cards `Close if open` and `Open if closed` for **Remootio Device API** - 1.6.2 - Dependency updates - 1.6.1 diff --git a/app.js b/app.js index 3c2beb3..a257587 100644 --- a/app.js +++ b/app.js @@ -73,6 +73,57 @@ class Remootio extends Homey.App { device.triggerCapabilityListener(id, !device.getFreeRelayState()) return true }) + + // add action listeners (only applicable for driver remootio-device-api + this.homey.flow.getActionCard('garagedoor_close_if_open') + .registerRunListener(async args => { + const { device } = args + const { success, closed } = await device.getApiDeviceStatus() + if (!success) { + device.log(`${device.getName()} -- garagedoor_close_if_open failed to fetch status`) + return false + } + + if (!closed) { + const garageCapabilityId = device.getGarageDoorCapabilityId() + if (garageCapabilityId) { + device.log(`${device.getName()} -- garagedoor_close_if_open called`) + device.triggerCapabilityListener(garageCapabilityId, false) + return true + } else { + device.log(`${device.getName()} -- garagedoor_close_if_open -- Garagedoor capability not found`) + return false + } + } + + device.log(`${device.getName()} -- garagedoor_close_if_open did nothing since its already closed`) + return true + }) + + this.homey.flow.getActionCard('garagedoor_open_if_closed') + .registerRunListener(async args => { + const { device } = args + const { success, closed } = await device.getApiDeviceStatus() + if (!success) { + device.log(`${device.getName()} -- garagedoor_open_if_closed failed to fetch status`) + return false + } + + if (closed) { + const garageCapabilityId = device.getGarageDoorCapabilityId() + if (garageCapabilityId) { + device.log(`${device.getName()} -- garagedoor_open_if_closed called`) + device.triggerCapabilityListener(garageCapabilityId, false) + return true + } else { + device.log(`${device.getName()} -- garagedoor_open_if_closed -- Garagedoor capability not found`) + return false + } + } + + device.log(`${device.getName()} -- garagedoor_open_if_closed did nothing since its already open`) + return true + }) } } diff --git a/app.json b/app.json index cf43194..11c4f54 100644 --- a/app.json +++ b/app.json @@ -125,6 +125,25 @@ } ], "actions": [ + { + "id": "garagedoor_close_if_open", + "highlight": true, + "title": { + "en": "Close if open", + "no": "Lukk hvis åpen" + }, + "hint": { + "en": "Will fetch garage door status from the API and close it if it's open\n\nOnly applicable for Remootio Device API", + "no": "Vil hente status for garasjeporten fra API'et og lukke den hvis den er åpen\n\nGjelder kun for Remootio Device API" + }, + "args": [ + { + "type": "device", + "name": "device", + "filter": "class_id=garagedoor&driver_id=remootio-device-api" + } + ] + }, { "id": "garagedoor_close_sub", "highlight": true, @@ -144,6 +163,25 @@ } ] }, + { + "id": "garagedoor_open_if_closed", + "highlight": true, + "title": { + "en": "Open if closed", + "no": "Åpne hvis lukket" + }, + "hint": { + "en": "Will fetch garage door status from the API and open it if it's closed\n\nOnly applicable for Remootio Device API", + "no": "Vil hente status for garasjeporten fra API'et og åpne den hvis den er lukket\n\nGjelder kun for Remootio Device API" + }, + "args": [ + { + "type": "device", + "name": "device", + "filter": "class_id=garagedoor&driver_id=remootio-device-api" + } + ] + }, { "id": "garagedoor_open_sub", "highlight": true, diff --git a/lib/device/remootio-device-api.js b/lib/device/remootio-device-api.js index c1bb07a..48e2cc5 100644 --- a/lib/device/remootio-device-api.js +++ b/lib/device/remootio-device-api.js @@ -33,6 +33,34 @@ class RemootioDeviceAPI extends Device { }) this.log(`${this.getName()} -- ${garageDoorCapabilityId} capability listener registered`) + this.getApiDeviceStatus = async () => { + const response = await this.queryStatus() + if (!response.success) { + // didn't reach Device API + this.log(`[ERROR] -- ${this.getName()} -- getApiDeviceStatus -- Query -- device-api communication failed : ${response.status} -- ${response.statusText} --`, response.data) + return { + success: false, + closed: undefined + } + } else if (!response.data.success) { + // reached Device API, but query failed + this.log(`[WARN] -- ${this.getName()} -- getApiDeviceStatus -- Query -- device-api communication success but query failed : ${response.data.errorMessage}`) + return { + success: false, + closed: undefined + } + } + + return { + success: true, + closed: response.data.deviceState.openStatus === 'closed' + } + } + + this.getGarageDoorCapabilityId = () => { + return garageDoorCapabilityId + } + const statusQueryHours = this.getSetting('hoursToQueryStatus') if (Number.isInteger(statusQueryHours) && statusQueryHours > 0) { this.statusQueryIntervalId = this.homey.setInterval(() => this.queryDevice(), statusQueryHours * 60 * 60 * 1000) @@ -49,9 +77,7 @@ class RemootioDeviceAPI extends Device { * queryDevice is called on device init, after a successfull toggle and every x hours (if enabled) */ async queryDevice () { - this.log(`${this.getName()} -- queryDevice -- Query sent`) - const response = await query(this.getStoreValue('token')) - this.log(`${this.getName()} -- queryDevice -- Query response --`, response) + const response = await this.queryStatus() if (!response.success) { // didn't reach Device API this.log(`[ERROR] -- ${this.getName()} -- queryDevice -- Query -- device-api communication failed : ${response.status} -- ${response.statusText} --`, response.data) @@ -94,6 +120,13 @@ class RemootioDeviceAPI extends Device { } } + async queryStatus () { + this.log(`${this.getName()} -- queryStatus -- Query sent`) + const response = await query(this.getStoreValue('token')) + this.log(`${this.getName()} -- queryStatus -- Query response --`, response) + return response + } + /** * onAdded is called when the user adds the device, called just after pairing. */ @@ -111,6 +144,19 @@ class RemootioDeviceAPI extends Device { */ async onSettings ({ oldSettings, newSettings, changedKeys }) { this.log(`${this.getName()} -- onSettings -- These device settings were changed:`, changedKeys) + + if (changedKeys.includes('hoursToQueryStatus')) { + if (oldSettings.hoursToQueryStatus > 0 && this.statusQueryIntervalId !== undefined) { + this.homey.clearInterval(this.statusQueryIntervalId) + } + if (newSettings.hoursToQueryStatus > 0) { + this.statusQueryIntervalId = this.homey.setInterval(() => this.queryDevice(), newSettings.hoursToQueryStatus * 60 * 60 * 1000) + this.log(`${this.getName()} -- Automatic status query enabled every ${newSettings.hoursToQueryStatus} hours`) + } + if (newSettings.hoursToQueryStatus === 0) { + this.log(`${this.getName()} -- Automatic status query not enabled`) + } + } } /**