diff --git a/apps/homebridge-v2.groovy b/apps/homebridge-v2.groovy index 840e7b1..8e8c886 100644 --- a/apps/homebridge-v2.groovy +++ b/apps/homebridge-v2.groovy @@ -116,12 +116,12 @@ preferences { "acceleration", "airQualityIndex", "alarmSystemStatus", "battery", "button", "carbonDioxideMeasurement", "carbonMonoxide", "colorTemperature", "contact", "coolingSetpoint", "door", "doubleTapped", "energy", "fanMode", "fanState", "fanTargetState", "heatingSetpoint", "held", "hue", "humidity", "illuminance", "level", "level", "lock", "motion", "mute", "outlet", "pm25", "position", "power", "powerSource", "presence", "pushed", "saturation", "smoke", "speed", "switch", - "tamper", "temperature", "thermostatFanMode", "thermostatMode", "thermostatOperatingState", "thermostatSetPoint", "valve", "volume", "water", "windowShade", + "tamper", "temperature", "thermostatFanMode", "thermostatMode", "thermostatOperatingState", "thermostatSetPoint", "valve", "volume", "water", "waterLevel", "windowShade", ], capabilities: [ "AccelerationSensor", "Actuator", "AirQuality", "Alarm", "AlarmSystemStatus", "Audio Mute", "Audio Volume", "Battery", "Bulb", "Button", - "CarbonDioxideMeasurement", "CarbonMonoxideDetector", "ColorControl", "ColorTemperature", "ContactSensor", "DoorControl", - "DoubleTapableButton", "EnergyMeter", "Fan", "FanControl", "FanLight", "GarageDoorControl", "HoldableButton", "IlluminanceMeasurement", "Light", + "CarbonDioxideMeasurement", "CarbonMonoxideDetector", "ColorControl", "ColorTemperature", "ContactSensor", "Door", "DoorControl", + "DoubleTapableButton", "EnergyMeter", "Fan", "FanControl", "FanLight", "GarageDoorControl", "HoldableButton", "HumidityControl", "Humidifier", "Dehumidifier", "IlluminanceMeasurement", "Light", "LightBulb", "Lock", "LockCodes", "Mode", "MotionSensor", "Outlet", "Piston", "PowerMeter", "PowerSource", "PresenceSensor", "PushableButton", "RelativeHumidityMeasurement", // "ReleasableButton", @@ -133,7 +133,7 @@ preferences { "armAway", "armHome", "disarm", "auto","heat","cool", "channelDown", "channelUp", "nextTrack", "previousTrack", "emergencyHeat", "fanAuto", "fanCirculate", "fanOn", "flip", "mute", "on", "off", "open", "close", "pause", "push", "hold", "doubleTap", "setColorTemperature", "setHue", "setSaturation", "setCoolingSetpoint", "setFanSpeed", "setHeatingSetpoint", "setLevel", "setPosition", "setSchedule", "setSpeed", - "setThermostatFanMode", "setThermostatMode","setThermostatSetpoint","setTiltLevel", "setVolume", "start", "stop", "unmute", "volumeDown", "volumeUp" + "setThermostatFanMode", "setThermostatMode","setThermostatSetpoint", "setTargetHumidity", "setTiltLevel", "setVolume", "start", "stop", "unmute", "volumeDown", "volumeUp" ], ] @@ -340,6 +340,11 @@ def deviceSelectPage() { input 'tstatHeatList', 'capability.thermostat', title: inTS1("Heat Only Thermostats: (${tstatHeatList ? tstatHeatList.size() : 0} Selected)", 'thermostat'), description: inputFooter(sTTS, sCLRGRY, true), multiple: true, submitOnChange: true, required: false } + // section(sectHead('Humidity Control:')) { + // input 'humidifierList', 'capability.relativeHumidityMeasurement', title: inTS1("Humidifier: (${humidifierList ? humidifierList.size() : 0} Selected)", 'humidity'), description: inputFooter(sTTS, sCLRGRY, true), multiple: true, submitOnChange: true, required: false + // input 'dehumidifierList', 'capability.relativeHumidityMeasurement', title: inTS1("Dehumidifier: (${dehumidifierList ? dehumidifierList.size() : 0} Selected)", 'humidity'), description: inputFooter(sTTS, sCLRGRY, true), multiple: true, submitOnChange: true, required: false + // } + section(sectHead('All Other Devices:')) { input 'sensorList', 'capability.sensor', title: inTS1("Sensors: (${sensorList ? sensorList.size() : 0} Selected)", 'sensors'), description: inputFooter(sTTS, sCLRGRY, true), multiple: true, submitOnChange: true, required: false input 'switchList', sCAP_SW, title: inTS1("Switches: (${switchList ? switchList.size() : 0} Selected)", sSW), description: inputFooter(sTTS, sCLRGRY, true), multiple: true, submitOnChange: true, required: false @@ -1566,6 +1571,8 @@ Map deviceCapabilityList(device) { if (isDeviceInInput('tstatFanList', devid)) { capItems['Thermostat'] = 1; capItems['ThermostatOperatingState'] = 1 } if (isDeviceInInput('tstatCoolList', devid)) { capItems['Thermostat'] = 1; capItems['ThermostatOperatingState'] = 1; capItems.remove('ThermostatHeatingSetpoint') } if (isDeviceInInput('tstatHeatList', devid)) { capItems['Thermostat'] = 1; capItems['ThermostatOperatingState'] = 1; capItems.remove('ThermostatCoolingSetpoint') } + // if (isDeviceInInput('humidifierList', devId)) { capItems['HumidityControl'] = 1; capItems['Humidifier'] = 1 } + // if (isDeviceInInput('dehumidifierList', devId)) { capItems['HumidityControl'] = 1; capItems['Dehumidifier'] = 1 } //switchList, deviceList if (getBoolSetting('noTemp') && capItems['TemperatureMeasurement'] && (capItems['ContactSensor'] || capItems['WaterSensor'])) { @@ -1732,6 +1739,7 @@ static Map deviceSettingKeys() { 'speakerList': 'Speaker Devices', 'shadesList': 'Window Shade Devices', 'securityKeypadsList': 'Security Keypad Devices', 'garageList': 'Garage Door Devices', 'tstatList': 'T-Stat Devices', 'tstatFanList': 'T-Stat + Fan Devices', 'tstatHeatList': 'T-Stat (HeatOnly) Devices', 'tstatCoolList': 'T-Stat (CoolOnly) Devices', 'sensorList': 'Sensor Devices', 'switchList': 'Switch Devices', 'deviceList': 'Other Devices', + // 'humidifierList': "Humidifiers", 'dehumidifierList': "Dehumidifiers", ] } diff --git a/src/HE_Client.js b/src/HE_Client.js index 6ee3029..aa0e249 100644 --- a/src/HE_Client.js +++ b/src/HE_Client.js @@ -24,13 +24,13 @@ module.exports = class ST_Client { } registerEvtListeners() { - this.appEvts.on("event:device_command", async(devData, cmd, vals) => { + this.appEvts.on("event:device_command", async (devData, cmd, vals) => { await this.sendDeviceCommand(devData, cmd, vals); }); - this.appEvts.on("event:plugin_upd_status", async() => { + this.appEvts.on("event:plugin_upd_status", async () => { await this.sendUpdateStatus(); }); - this.appEvts.on("event:plugin_start_direct", async() => { + this.appEvts.on("event:plugin_start_direct", async () => { await this.sendStartDirect(); }); } @@ -67,17 +67,17 @@ module.exports = class ST_Client { let that = this; return new Promise((resolve) => { axios({ - method: "get", - url: `${that.configItems.use_cloud ? that.configItems.app_url_cloud : that.configItems.app_url_local}${that.configItems.app_id}/devices`, - params: { - access_token: that.configItems.access_token, - }, - headers: { - "Content-Type": "application/json", - isLocal: that.configItems.use_cloud ? "false" : "true", - }, - timeout: 10000, - }) + method: "get", + url: `${that.configItems.use_cloud ? that.configItems.app_url_cloud : that.configItems.app_url_local}${that.configItems.app_id}/devices`, + params: { + access_token: that.configItems.access_token, + }, + headers: { + "Content-Type": "application/json", + isLocal: that.configItems.use_cloud ? "false" : "true", + }, + timeout: 10000, + }) .then((response) => { resolve(response.data); }) @@ -108,7 +108,7 @@ module.exports = class ST_Client { }; // console.log("config: ", config); try { - that.logNotice(`Sending Device Command: ${cmd}${vals ? " | Value: " + JSON.stringify(vals) : ""} | Name: (${devData.name}) | DeviceID: (${devData.deviceid}) | UsingCloud: (${that.configItems.use_cloud === true})`); + this.logWarn(`[Device Command]: Name: (${devData.name}) | CMD: ${cmd}${vals ? " | Value: " + JSON.stringify(vals) : ""} | DeviceID: (${devData.deviceid}) | UsingCloud: (${that.configItems.use_cloud === true})`); axios(config) .then((response) => { // console.log("command response:", response); @@ -130,23 +130,23 @@ module.exports = class ST_Client { this.platform.myUtils.checkVersion().then((res) => { this.logNotice(`Sending Plugin Status to Hubitat | UpdateAvailable: ${res.hasUpdate}${res.newVersion ? " | newVersion: " + res.newVersion : ""}`); axios({ - method: "post", - url: `${this.configItems.use_cloud ? this.configItems.app_url_cloud : this.configItems.app_url_local}${this.configItems.app_id}/pluginStatus`, - params: { - access_token: this.configItems.access_token, - }, - headers: { - "Content-Type": "application/json", - }, - data: { - hasUpdate: res.hasUpdate, - newVersion: res.newVersion, - version: pluginVersion, - isLocal: this.configItems.use_cloud ? "false" : "true", - accCount: Object.keys(this.platform.HEAccessories.getAllAccessoriesFromCache()).length || null, - }, - timeout: 10000, - }) + method: "post", + url: `${this.configItems.use_cloud ? this.configItems.app_url_cloud : this.configItems.app_url_local}${this.configItems.app_id}/pluginStatus`, + params: { + access_token: this.configItems.access_token, + }, + headers: { + "Content-Type": "application/json", + }, + data: { + hasUpdate: res.hasUpdate, + newVersion: res.newVersion, + version: pluginVersion, + isLocal: this.configItems.use_cloud ? "false" : "true", + accCount: Object.keys(this.platform.HEAccessories.getAllAccessoriesFromCache()).length || null, + }, + timeout: 10000, + }) .then((response) => { // console.log(response.data); if (response.data) { @@ -205,4 +205,4 @@ module.exports = class ST_Client { } }); } -}; \ No newline at end of file +}; diff --git a/src/HE_DeviceCharacteristics.js b/src/HE_DeviceCharacteristics.js index 058f5ee..1d8d6c5 100644 --- a/src/HE_DeviceCharacteristics.js +++ b/src/HE_DeviceCharacteristics.js @@ -336,6 +336,24 @@ module.exports = class DeviceCharacteristics { return _accessory; } + humidifier(_accessory, _service) { + if (_accessory.hasCapability("Humidifier") && _accessory.hasCapability("Dehumidifier")) { + _accessory.getOrAddService(_service).setCharacteristic(Characteristic.TargetHumidifierDehumidifierState, Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER_OR_DEHUMIDIFIER); + } else if (_accessory.hasCapability("Humidifier")) { + _accessory.getOrAddService(_service).setCharacteristic(Characteristic.TargetHumidifierDehumidifierState, Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER); + _accessory.getOrAddService(_service).setCharacteristic(Characteristic.CurrentHumidifierDehumidifierState, Characteristic.CurrentHumidifierDehumidifierState.HUMIDIFYING); + } else if (_accessory.hasCapability("Dehumidifier")) { + _accessory.getOrAddService(_service).setCharacteristic(Characteristic.TargetHumidifierDehumidifierState, Characteristic.TargetHumidifierDehumidifierState.DEHUMIDIFIER); + _accessory.getOrAddService(_service).setCharacteristic(Characteristic.CurrentHumidifierDehumidifierState, Characteristic.CurrentHumidifierDehumidifierState.DEHUMIDIFYING); + } + _accessory.manageGetCharacteristic(_service, _accessory, Characteristic.CurrentRelativeHumidity, "humidity"); + _accessory.manageGetSetCharacteristic(_service, _accessory, Characteristic.Active, "switch"); + + _accessory.manageGetCharacteristic(_service, _accessory, Characteristic.WaterLevel, "waterLevel"); + _accessory.context.deviceGroups.push("humidifier"); + return _accessory; + } + humidity_sensor(_accessory, _service) { _accessory.manageGetCharacteristic(_service, _accessory, Characteristic.CurrentRelativeHumidity, "humidity"); _accessory.manageGetCharacteristic(_service, _accessory, Characteristic.StatusActive, "status"); diff --git a/src/HE_ServiceTypes.js b/src/HE_ServiceTypes.js index bf3397a..887cbdf 100644 --- a/src/HE_ServiceTypes.js +++ b/src/HE_ServiceTypes.js @@ -34,6 +34,7 @@ module.exports = class ServiceTypes { // energy_meter: Service.Switch, fan: Service.Fanv2, garage_door: Service.GarageDoorOpener, + humidifier: Service.HumidifierDehumidifier, humidity_sensor: Service.HumiditySensor, illuminance_sensor: Service.LightSensor, light: Service.Lightbulb, @@ -135,7 +136,8 @@ const serviceTests = [ new ServiceTest("acceleration_sensor", (accessory) => accessory.hasCapability("Acceleration Sensor")), new ServiceTest("water_sensor", (accessory) => accessory.hasCapability("Water Sensor")), new ServiceTest("presence_sensor", (accessory) => accessory.hasCapability("PresenceSensor")), - new ServiceTest("humidity_sensor", (accessory) => accessory.hasCapability("RelativeHumidityMeasurement") && accessory.hasAttribute("humidity") && !(accessory.hasCapability("Thermostat") || accessory.hasCapability("ThermostatOperatingState") || accessory.hasAttribute("thermostatOperatingState"))), + new ServiceTest("humidity_sensor", (accessory) => accessory.hasCapability("RelativeHumidityMeasurement") && accessory.hasAttribute("humidity") && !(accessory.hasCapability("Thermostat") || accessory.hasCapability("ThermostatOperatingState") || accessory.hasCapability("HumidityControl") || accessory.hasAttribute("thermostatOperatingState"))), + new ServiceTest("humidifier", (accessory) => accessory.hasCapability("HumidityControl") && (accessory.hasCapability("Humidifier") || accessory.hasCapability("Dehumidifier")) && accessory.hasAttribute("waterLevel") && accessory.hasAttribute("targetHumidity") && accessory.hasCommand("setTargetHumidity")), new ServiceTest("temperature_sensor", (accessory) => accessory.hasCapability("TemperatureMeasurement") && !(accessory.hasCapability("Thermostat") || accessory.hasCapability("ThermostatOperatingState") || accessory.hasAttribute("thermostatOperatingState"))), new ServiceTest("illuminance_sensor", (accessory) => accessory.hasCapability("IlluminanceMeasurement")), new ServiceTest("contact_sensor", (accessory) => accessory.hasCapability("ContactSensor") && !accessory.hasCapability("GarageDoorControl")), diff --git a/src/HE_Transforms.js b/src/HE_Transforms.js index 317161d..33ffc92 100644 --- a/src/HE_Transforms.js +++ b/src/HE_Transforms.js @@ -75,7 +75,11 @@ module.exports = class Transforms { case "airQualityIndex": return this.aqiToPm25(val); case "switch": - return val === "on"; + if (charName === "Active") { + return val === "on" ? Characteristic.Active.ACTIVE : Characteristic.Active.INACTIVE; + } else { + return val === "on"; + } case "door": switch (val) { case "open": diff --git a/src/libs/Constants.js b/src/libs/Constants.js index 0437921..c090c6f 100644 --- a/src/libs/Constants.js +++ b/src/libs/Constants.js @@ -32,6 +32,9 @@ module.exports = { // "FanLight", "GarageDoorControl", "HoldableButton", + "HumidityControl", + "Humidifier", + "Dehumidifier", "IlluminanceMeasurement", "Light", "LightBulb",