diff --git a/3_28_Sinope_Thermo b/3_28_Sinope_Thermo new file mode 100644 index 0000000..6c9c63f --- /dev/null +++ b/3_28_Sinope_Thermo @@ -0,0 +1,474 @@ +preferences { + input("username", "text", title: "Username", description: "Your neviweb username (usually an email address)") + input("password", "password", title: "Password", description: "Your neviweb password") + input("devicid", "text", title: "Device Id:", description: "Device number for the thermostat (from 1 to 255)") +} +metadata { + definition (name: "Sinope Thermostat ", namespace: "Mdbashi", author: "Moustafa Dalal Bachi") { + capability "Polling" + capability "Thermostat" + capability "Temperature Measurement" + + capability "Sensor" + + command "away" + command "present" + command "setPresence" + command "heatingSetpointUp" + command "heatingSetpointDown" + command "setFahrenheit" + command "setCelsius" + command "logout" + + attribute "temperatureUnit", "string" + } + + simulator { + // TODO: define status and reply messages here + } + + tiles (scale: 2) { + valueTile("temperature", "device.temperature", canChangeIcon: true, canChangeBackground:true, width: 2, height: 2) { + state("temperature", label: '${currentValue}°', backgroundColors: [ + // Celsius Color Range + [value: 0, color: "#153591"], + [value: 7, color: "#1e9cbb"], + [value: 15, color: "#90d2a7"], + [value: 23, color: "#44b621"], + [value: 29, color: "#f1d801"], + [value: 33, color: "#d04e00"], + [value: 36, color: "#bc2323"], + // Fahrenheit Color Range + [value: 40, color: "#153591"], + [value: 44, color: "#1e9cbb"], + [value: 59, color: "#90d2a7"], + [value: 74, color: "#44b621"], + [value: 84, color: "#f1d801"], + [value: 92, color: "#d04e00"], + [value: 96, color: "#bc2323"] + ] + ) + } + + valueTile("heatingSetpoint", "device.heatingSetpoint", width: 2, height: 2) { + state "default", label:'${currentValue}°', backgroundColor:"#bc2323" + } + + + valueTile("thermostatOperatingState", "device.thermostatOperatingState", width: 2, height: 2,canChangeIcon: true,canChangeBackground:true) { + state "default", label:'Heating power \n ${currentValue}%', backgroundColors: [ + // Celsius Color Range + [value: 0, color: "#153591"], + [value: 7, color: "#1e9cbb"], + [value: 15, color: "#90d2a7"], + [value: 23, color: "#44b621"], + [value: 29, color: "#f1d801"], + [value: 33, color: "#d04e00"], + [value: 36, color: "#bc2323"], + // Fahrenheit Color Range + [value: 40, color: "#153591"], + [value: 44, color: "#1e9cbb"], + [value: 59, color: "#90d2a7"], + [value: 74, color: "#44b621"], + [value: 84, color: "#f1d801"], + [value: 92, color: "#d04e00"], + [value: 96, color: "#bc2323"] + ] + + } + + standardTile("presence", "device.presence", inactiveLabel: false, width: 2, height: 2, decoration: "flat") + { + state ("Auto", label:'', action:"off", icon: "st.thermostat.auto") + state ("Standby", label:'', action:"auto", icon: "st.thermostat.heating-cooling-off") + //state ("Manual", label:'', action:"manual", icon: "st.thermostat.heat") + } + + valueTile("realdeviceName", "device.realname", inactiveLabel: true, height: 1, width:5, decoration: "flat") { + state "default", label:'${currentValue}' //, backgroundColor: "#359115" + } + + standardTile("refresh", "device.thermostatMode", inactiveLabel: false, width: 2, height: 2, decoration: "flat") { + state "default", action:"polling.poll", icon:"st.secondary.refresh" + } + + valueTile("temperatureUnit", "device.temperatureUnit", width: 2, height: 2, canChangeIcon: false) { + state "fahrenheit", label: "°F" + state "celsius", label: "°C" + } + + controlTile("heatSliderControl", "device.heatingSetpoint", "slider", width: 2, height: 2, inactiveLabel: false) { + state "setHeatingSetpoint", label:'Set temperature to', action:"thermostat.setHeatingSetpoint" + } + + standardTile("heatingSetpointUp", "device.heatingSetpoint", canChangeIcon: false, width: 2, height: 2, inactiveLabel: false, decoration: "flat") { + state "heatingSetpointUp", label:' ', action:"heatingSetpointUp", icon:"st.thermostat.thermostat-up", backgroundColor:"#bc2323" + } + + standardTile("heatingSetpointDown", "device.heatingSetpoint", canChangeIcon: false, width: 2, height: 2, inactiveLabel: false, decoration: "flat") { + state "heatingSetpointDown", label:' ', action:"heatingSetpointDown", icon:"st.thermostat.thermostat-down", backgroundColor:"#bc2323" + } + + main(["temperature", "thermostatOperatingState"]) + details(["realdeviceName","temperature", "thermostatOperatingState","presence","heatingSetpointDown", "heatingSetpoint", "heatingSetpointUp","temperatureUnit" , "refresh"]) + + } + +} + +def parse(String description) { + +} + +// handle commands +def setHeatingSetpoint(temp) +{ + def latestThermostatMode = device.latestState('thermostatMode') + def temperatureUnit = device.latestValue('temperatureUnit') + + if(!isLoggedIn()) + { + log.debug "Need to login" + login(method, args, success) + + } + def thermostatID=data.devices.id [settings.devicid.toInteger()-1] + switch (temperatureUnit) { + case "celsius": + temp=temp + break; + default: + temp=fToC(Math.round(temp)) + break; + } + if (temp) { + if (temp < 1) { + temp = 1 + } + if (temp > 31) { + temp = 31 + } + + } + def params = [ + uri: "https://neviweb.com/api/device/${thermostatID}/setpoint", + headers: ['Session-Id' : data.auth.session], + body: "temperature=${temp}" + ] + + + httpPut(params){resp -> + log.debug resp.data + } + + + switch (temperatureUnit) + { + case "celsius": + sendEvent(name: 'heatingSetpoint', value: temp, unit: temperatureUnit, state: "heat") + break; + default: + sendEvent(name: 'heatingSetpoint', value: Math.round(cToF(temp)), unit: temperatureUnit, state: "heat") + break; + } + + runIn(10, poll) +} + + + + +def heatingSetpointUp(){ + def temperatureUnit = device.latestValue('temperatureUnit') + Double newSetpoint=0.0 + switch (temperatureUnit) { + case "celsius": + newSetpoint = device.currentValue("heatingSetpoint") + 0.5 + break; + default: + newSetpoint = Math.round(device.currentValue("heatingSetpoint") + 1) + break; + } + + log.debug "Setting heat set point up to: ${newSetpoint}" + setHeatingSetpoint(newSetpoint) +} + +def heatingSetpointDown() + { + Double newSetpoint=0.0 + def temperatureUnit = device.latestValue('temperatureUnit') + switch (temperatureUnit) { + case "celsius": + newSetpoint = device.currentValue("heatingSetpoint") - 0.5 + break; + default: + newSetpoint = Math.round(device.currentValue("heatingSetpoint") - 1) + break; + } + log.debug "Setting heat set point down to: ${newSetpoint}" + setHeatingSetpoint(newSetpoint) +} + +def setFahrenheit() { + def temperatureUnit = "fahrenheit" + log.debug "Setting temperatureUnit to: ${temperatureUnit}" + sendEvent(name: "temperatureUnit", value: temperatureUnit) + +} + +def setCelsius() { + def temperatureUnit = "celsius" + log.debug "Setting temperatureUnit to: ${temperatureUnit}" + sendEvent(name: "temperatureUnit", value: temperatureUnit) + +} + +def manual() + { + if(!isLoggedIn()) + { + log.debug "Need to login" + login(method, args, success) + + } + def thermostatID=data.devices.id [settings.devicid.toInteger()-1] + def params = [ + uri: "https://neviweb.com/api/device/${thermostatID}/mode", + headers: ['Session-Id' : data.auth.session], + body: ['mode': 2] + ] + httpPut(params) + {resp -> + log.debug resp.data + } + sendEvent(name: 'presence', value: 'Manual') +} + +def off() + { + if(!isLoggedIn()) + { + log.debug "Need to login" + login(method, args, success) + + } + def thermostatID=data.devices.id [settings.devicid.toInteger()-1] + + def params = [ + uri: "https://neviweb.com/api/device/${thermostatID}/mode", + headers: ['Session-Id' : data.auth.session], + body: ['mode': 0] + ] + httpPut(params) + {resp -> + log.debug resp.data + } + sendEvent(name: 'presence', value: 'Standby') +} + +def auto() + { + if(!isLoggedIn()) + { + log.debug "Need to login" + login(method, args, success) + + } + def thermostatID=data.devices.id [settings.devicid.toInteger()-1] + def params = [ + uri: "https://neviweb.com/api/device/${thermostatID}/mode", + headers: ['Session-Id' : data.auth.session], + body: ['mode': 3] + ] + httpPut(params) + {resp -> + log.debug resp.data + } + sendEvent(name: 'presence', value: 'Auto') +} + +def poll() + { + if (data.status.mode== 0 /*| data.status.mode== 5 | data.status.mode== 133 */ ) + { + sendEvent(name: 'presence', value: 'Standby') + log.debug "Thermostat is off" + } + if (data.status.mode== 3 /*| data.status.mode== 5 | data.status.mode== 133 */ ) + { + sendEvent(name: 'presence', value: 'Auto') + log.debug "Thermostat is on Auto Mode" + } + if (data.status.mode== 2 /*| data.status.mode== 5 | data.status.mode== 133 */ ) + { + sendEvent(name: 'presence', value: 'Manual') + log.debug "Thermostat is on Manual Mode" + } + def temperatureUnit = device.latestValue('temperatureUnit') + if(!isLoggedIn()) + { + log.debug "Need to login" + login(method, args, success) + } + + log.debug "Executing 'poll'" + + def thermostatID=data.devices.id [settings.devicid.toInteger()-1] + + def params = [ + uri: "https://neviweb.com/api/device/${thermostatID}/data", + requestContentType: "application/x-www-form-urlencoded; charset=UTF-8", + headers: ['Session-Id' : data.auth.session] + ] + + httpGet(params) + {resp -> + data.status = resp.data + } + //log.debug "after status.... ${data}" + if (data.auth.user.format.temperature=='c') + { + setCelsius () + } + else + { + setFahrenheit() + } + Double bd1 = new Double(data.status.temperature); + def temperature = Math.round(bd1*10)/10 + def MyheatingSetpoint = 0.0 + if (data.status.setpoint== null) + { + MyheatingSetpoint = "NA" + temperature = Math.round(cToF(bd1)) + } + else + { + Double bd2 = new Double(data.status.setpoint); + switch (temperatureUnit) { + case "celsius": + MyheatingSetpoint =Math.round(bd2*10)/10 + + break; + default: + MyheatingSetpoint =Math.round(cToF(bd2)) + temperature =Math.round(cToF(bd1)) + + break; + } + + } + + + sendEvent(name: 'temperature', value: temperature, unit: temperatureUnit, state: temperatureType) + sendEvent(name: 'heatingSetpoint', value: MyheatingSetpoint, unit: temperatureUnit, state: "heat") + log.debug "My setpoint is .....${MyheatingSetpoint}" + log.debug "My temperature is .....${temperature}" + + + sendEvent(name: 'thermostatOperatingState', value: "${data.status.heatLevel}") + def mydevice=data.devices.name[settings.devicid.toInteger() - 1] + + sendEvent(name: 'realname', value: "${mydevice}") + def ipaddress=settings.pwrmeterip + + + + runIn(60, poll) + logout() +} + + +def logout(method = null, args = [], success = {}) { + def params = [ + uri: "https://neviweb.com", + path: "/api/logout", + requestContentType: "application/x-www-form-urlencoded; charset=UTF-8", + headers: ['Session-Id' : data.auth.session] + ] + + httpGet(params) {resp -> + data.auth = resp.data + } + log.debug "logout.. " +} +def login(method = null, args = [], success = {}) { + def params = [ + uri: "https://neviweb.com", + path: "/api/login", + body: "email=${settings.username}&password=${settings.password}&stayConnected=0", + requestContentType: "application/x-www-form-urlencoded; charset=UTF-8" + ] + httpPost(params) {response -> + data.auth = response.data + + } + if(!data.auth) { + log.debug "Problem in Login, unable to get data auth." + return + } + + + params = [ + uri: "https://neviweb.com", + path: "/api/gateway", + requestContentType: "application/json, text/javascript, */*; q=0.01", + headers: ['Session-Id' : data.auth.session] + ] + httpGet(params) {resp -> + data.gateway = resp.data + } + + params = [ + uri: "https://neviweb.com", + path: "/api/device", + query: ['gatewayId' : data.gateway.id], + requestContentType: "application/json, text/javascript, */*; q=0.01", + headers: ['Session-Id' : data.auth.session] + ] + + httpGet(params) {resp -> + data.devices = resp.data + } + log.debug "Loged in.." +} + +def isLoggedIn() { + log.debug "Is it login?..." + try{ + def params = [ + uri: "https://neviweb.com", + path: "/api/gateway", + requestContentType: "application/json, text/javascript, */*; q=0.01", + headers: ['Session-Id' : data.auth.session] + ] + httpGet(params) {resp -> + if (resp.data.sessionExpired==true){ + log.debug "No session Expired" + data.auth="" + } + } + + + if(!data.auth) { + log.debug "No, data auth. missing " + return false + } else { + log.debug "Yes.." + return true + } + }catch (e){ + log.debug "No.." + return false + } +} + +def cToF(temp) +{ + return (temp * 1.8 + 32).toDouble() +} + +def fToC(temp) { + return ((temp - 32) / 1.8).toDouble() +}