Hello Community,
I’m getting really frustrated about the lack of Informations about how to create a Service Manager with a Device Handler. I really need someone who can help me out of that. So first of all I want to explain what my project is about. I want to integrate a Thermostat, that communicates with a cloud. I want that Smartthings just talks to the 3rd Party Cloud. For this I need a Service Manager. I created a Service Manager with all functions I need, and all work when I try them in the Initialize method. So the Functions are not the Problem, they work fine. The Problem is, now I got a Smart App ( The Service Manager ) with all functions. I also created a Device Handler with the Capability “Thermostat”.
Now.
- How do I make, that if I install the Service Manager and configurate my Device, that a Device Type gets created so I can Control the Device with the Tiles.
- How can I call the functions from the Service Manager in de Device Handler? I know that I must do it with “parent.function()” but I dont know how I connect the Service Manager with the Device Handler. Do I need to install both?
- How can I save the return Value of the Service Manager in a Attribute of the thermostat capability?
Im really frustrated and would be happy if someone could Help me.
Here is the code for the Service Manager:
////////////////////////////////////////
Code for the Device Type:
////////////////////////////////////////
/**
- SmartThermostatDeviceHandler
- Copyright 2017 Dany Van der Meij
- Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
- in compliance with the License. You may obtain a copy of the License at:
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
- on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
- for the specific language governing permissions and limitations under the License.
*/
metadata {
definition (name: “SmartThermostatDeviceHandler”, namespace: “Dany Van der Meij”, author: “Dany Van der Meij”) {
capability “thermostat”
}
simulator {
// TODO: define status and reply messages here
}
tiles (scale: 2) {
multiAttributeTile(name:"thermostatFull", type:"thermostat", width:6, height:4) {
tileAttribute("device.temperature", key: "PRIMARY_CONTROL") {
attributeState("temp", label:'${currentValue}', unit:"dF", defaultState: true)
}
tileAttribute("device.heatingSetpoint", key: "VALUE_CONTROL") {
attributeState("VALUE_UP", action: "tempUp")
attributeState("VALUE_DOWN", action: "tempDown")
}
tileAttribute("device.humidity", key: "SECONDARY_CONTROL") {
attributeState("humidity", label:'${currentValue}', unit:"%", defaultState: true)
}
tileAttribute("device.thermostatOperatingState", key: "OPERATING_STATE") {
attributeState("idle", backgroundColor:"#00A0DC")
attributeState("heating", backgroundColor:"#e86d13")
attributeState("cooling", backgroundColor:"#00A0DC")
}
tileAttribute("device.thermostatMode", key: "THERMOSTAT_MODE") {
attributeState("off", label:'${name}')
attributeState("heat", label:'${name}')
attributeState("cool", label:'${name}')
attributeState("auto", label:'${name}')
}
tileAttribute("device.heatingSetpoint", key: "HEATING_SETPOINT") {
attributeState("heatingSetpoint", label:'${currentValue}', unit:"dF", defaultState: true)
}
tileAttribute("device.coolingSetpoint", key: "COOLING_SETPOINT") {
attributeState("coolingSetpoint", label:'${currentValue}', unit:"dF", defaultState: true)
}
}
}
}
def installed(){
log.debug "Installed"
initialize()
}
def initialize(){
log.debug “Initialize”
}
def poll(){
log.debug “Executing poll”
}
private getUpdate(){
}
// parse events into attributes
def parse(Map description) {
}
/************** Betriebsfunktionen **************/
def auto()
{
log.debug “auto()”
}
def cool()
{
log.debug “cool()”
}
def emergencyHeat()
{
log.debug “emergencyHeat()”
}
def fanAuto()
{
log.debug “fanAuto()”
}
def fanCirculate()
{
log.debug “fanCirculate()”
}
def fanOn()
{
log.debug “fanOn()”
}
def heat()
{
log.debug “heat()”
}
def off()
{
log.debug “off()”
}
/************** Setter Methods **************/
def tempup()
{
log.debug “Tempup()”
}
def tempdown()
{
log.debug “Tempdown()”
}
def setCoolingSetpoint(Number setpoint)
{
log.debug “setCoolingSetpoint()”
}
def setHeatingSetpoint(Number setpoint)
{
log.debug “setHeatingSetpoint()”
}
def setThermostatFanMode(Enum fanmode)
{
log.debug “setThermostatFanMode()”
}
def setThermostatMode(Enum mode)
{
log.debug “setThermostatMode()”
}
/////////////////////////////////////////////////
Code for the Service Manager:
////////////////////////////////////////////////
/**
- ClimatixIc (Connect)
- Copyright 2017 Dany Van der Meij
- Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
- in compliance with the License. You may obtain a copy of the License at:
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
- on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
- for the specific language governing permissions and limitations under the License.
*/
/****************************************/
/************************************** CONTENTS /
//
// 1) Librarys
// 2) Setter Methods
// 3) Preferences
// 4) Installed Method
// 5) Updated Method
// 6) Initialzie Method
//
//
// 7) Climatix API Calls
// 7.1) Getter Calls
// 7.1.1) GetClimatixToken()
// 7.1.2) GetRoomTemp()
// 7.1.3) GetRoomHumidity()
// 7.1.4) GetAirQuality()
// 7.1.5) GetOperatingMode()
// 7.1.6) GetRoomSetpoint()
// 7.1.7) GetComfortSetpoint()
// 7.1.8) GetEcoSetpoint()
// 7.1.9) GetPreComfortSetpoint()
// 7.2) Setter Calls
// 7.2.1) UpdateRoomOperatingMode()
// 7.2.2) UpdateRoomSetpoint()
// 7.2.3) UpdateComfortSetpoint()
// 7.2.4) UpdatePreComfortSetpoint()
// 7.2.5) UpdateEcoSetpoint()
//
//
/****************************************************************************************/
/********************************************/
// 1) Librarys
include 'localization’
include ‘asynchttp_v1’
/********************************************/
// 2) Definitions
definition(
name: “ClimatixIc (Connect)”,
namespace: “Dany3337”,
author: “Dany Van der Meij”,
description: "This is the Service Manager for ClimatixIc ",
category: “”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”,
iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)
/********************************************/
// 3) Preferences
preferences {
input name: “climatix_username”, type: “text”, title: “Email”, description: “Enter Text”, required: true
input name: “climatix_password”, type: “text”, title: “Password”, description: “Enter Text”, required: true
input name: “climatix_device”, type: “text”, title: “Device”, description: “Enter Text”, required: true
}
/********************************************/
// 4) Installed Method
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
/********************************************/
// 5) Updated Method
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
/********************************************/
// 6) Initialize Method
def initialize() {
// Initialize Variables
state.ClimatixToken = ""
state.ClimatixUser = climatix_username
state.ClimatixPassword = climatix_password
state.ClimatixDevice = climatix_device
state.ClimatixKey = “2733467e26b541d7969f76f2e6dac966”
// Check if Token is already set
if(state.ClimatixToken == ""){
// Get the Token
getClimatixToken()
}
else{
log.error "Token schon vorhanden"
}
// Methods
//UpdateRoomSetpoint(25)
//UpdateOperatingMode(1)
UpdateEcoSetpoint(16)
UpdatePrecomfortSetpoint(18)
getRoomTemp()
getRoomSetpoint()
getRoomHumidity()
getComfortSetpoint()
getEcoSetpoint()
getPreComfortSetpoint()
getRoomAirQuality()
getOperatingMode()
}
def pollChildren(){
def pollParams = [
uri: “https://api.thirdpartysite.com”,
path: “/device”,
requestContentType: “application/json”,
query: [format:“json”,body: jsonRequestBody]
]
httpGet(pollParams)
{ resp ->
state.devices = resp.data.devices
{ collector, stat ->
def dni = [ app.id, stat.identifier ].join('.')
def data = [
attribute1: stat.attributeValue,
attribute2: stat.attribute2Value
]
collector[dni] = [data:data]
return collector
}
}
}
//
//
/********************************************/
// 7) Climtiax API Calls
//
//
/********************************************/
// 7.1) Getter Calls
//
//
// 7.1.1) GetClimatixToken | Function to get the API Token
def getClimatixToken(){
def bodystr = "grant_type=password&username=${state.ClimatixUser}&password=${state.ClimatixPassword}"
def Params = [
uri: “https://api.climatixic.com/Staging/Token”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”],
body: “${bodystr}”
]
try {
httpPost(Params) { resp ->
// Set Token
state.ClimatixToken = “${resp.data.token_type} ${resp.data.access_token}”
}
} catch (e) {
log.error "Fehler bei getClimatixToken"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.2) GetRoomTemp | Function to get the actual Room Temperature
def getRoomTemp(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000086000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Temperature = resp.data.values."${state.ClimatixDevice};1!002000086000055".value.value
log.debug “Actual Temperature: ${Temperature}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.3) GetRoomHumidity | Function to get Room Humidity
def getRoomHumidity(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000085000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Setpoint = resp.data.values."${state.ClimatixDevice};1!002000085000055".value.value
log.debug “Room Humidity: ${Setpoint}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.4) GetRoomAirQuality | Function to get Room Air Quality
def getRoomAirQuality(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!0020000CD000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def quality = resp.data.values."${state.ClimatixDevice};1!0020000CD000055".value.value
log.debug “Room Air Quality: ${quality}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.5) GetRoomOperatingMode | Function to get Operating Mode
def getOperatingMode(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!01300005A000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def mode = resp.data.values."${state.ClimatixDevice};1!01300005A000055".value.value
log.debug “Operating Mode: ${mode}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.6) GetRoomSetpoint | Function to get the Room Setpoint
def getRoomSetpoint(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000083000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Setpoint = resp.data.values."${state.ClimatixDevice};1!002000083000055".value.value
log.debug “Actual Setpoint: ${Setpoint}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.7) GetComfortSetpoint | Function to get Comfort Setpoint
def getComfortSetpoint(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!00200007F000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Setpoint = resp.data.values."${state.ClimatixDevice};1!00200007F000055".value.value
log.debug “Comfort Setpoint: ${Setpoint}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.8) GetEcoSetpoint | Function to get Eco Setpoint
def getEcoSetpoint(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000080000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Setpoint = resp.data.values."${state.ClimatixDevice};1!002000080000055".value.value
log.debug “Pre-Comfort Setpoint: ${Setpoint}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.1.9) GetPreComfortSetpoint | Function to get Pre-Comfort Setpoint
def getPreComfortSetpoint(){
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000081000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”]
]
try {
httpGet(Params) { resp ->
def Setpoint = resp.data.values."${state.ClimatixDevice};1!002000081000055".value.value
log.debug “Economy Setpoint: ${Setpoint}”
}
} catch (e) {
log.error "SS Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
//
//
// 7.2) Setter Calls
//
//
// 7.2.1) SetOperatingMode | Function to Set the Operating Mode of the SmartThermostat
def UpdateOperatingMode(Pmode){
def bodystr = ‘{“value”:’+Pmode+’}'
log.debug “Bodystring: ${bodystr}“
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!01300005A000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”, “Content-Type” : “application/json”],
body: bodystr
]
try {
httpPut(Params) { resp ->
log.debug “UpdateOperatingMode Status: ${resp.data.stateTexts.”${state.ClimatixDevice};1!01300005A000055”}”
}
} catch (e) {
log.error "SetSmartSetpoint Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.2.2) SetRoomSetpoint | Function to set the Setpoint of the Room
def UpdateRoomSetpoint(Psetpoint){
def bodystr = ‘{“value”:’+Psetpoint+’}'
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000083000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”, “Content-Type” : “application/json”],
body: bodystr
]
try {
httpPut(Params) { resp ->
log.debug “UpdateRoomSetpoint Status: ${resp.data.stateTexts.”${state.ClimatixDevice};1!002000083000055"}"
}
} catch (e) {
log.error "SetSmartSetpoint Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.2.3) SetComfortSetpoint | Function to set the Setpoint of the Comfort Mode
def UpdateComfortSetpoint(Psetpoint){
def bodystr = ‘{“value”:’+Psetpoint+’}'
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000083000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”, “Content-Type” : “application/json”],
body: bodystr
]
try {
httpPut(Params) { resp ->
log.debug “UpdateRoomSetpoint Status: ${resp.data.stateTexts.”${state.ClimatixDevice};1!002000083000055"}"
}
} catch (e) {
log.error "SetSmartSetpoint Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.2.4) SetPreComfortSetpoint | Function to Set the Setpoint of the Precomfort Mode
def UpdatePrecomfortSetpoint(Psetpoint){
def bodystr = ‘{“value”:’+Psetpoint+’}'
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000081000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”, “Content-Type” : “application/json”],
body: bodystr
]
try {
httpPut(Params) { resp ->
log.debug “UpdatePrecomfortSetpoint Status: ${resp.data.stateTexts.”${state.ClimatixDevice};1!002000081000055"}"
}
} catch (e) {
log.error "SetSmartSetpoint Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
/********************************************/
// 7.2.5) SetEcoSetpoint | Function to Set the Setpoint of the Ecomode
def UpdateEcoSetpoint(Psetpoint){
def bodystr = ‘{“value”:’+Psetpoint+’}'
def Params = [
uri: “https://api.climatixic.com/Staging/Datapoints/${state.ClimatixDevice};1!002000080000055”,
headers: [‘Ocp-Apim-Subscription-Key’: “${state.ClimatixKey}”, Authorization: “${state.ClimatixToken}”, “Content-Type” : “application/json”],
body: bodystr
]
try {
httpPut(Params) { resp ->
log.debug “UpdateEcoSetpoint Status: ${resp.data.stateTexts.”${state.ClimatixDevice};1!002000080000055"}"
}
} catch (e) {
log.error "SetSmartSetpoint Fehler bei der Anfrage"
log.error “Fehler: ${e}”
}
}
//
//