Initial plugin "Nest Plugin" for bridging project.
[iotivity.git] / bridging / plugins / nest_plugin / nest_objects / nest_thermostat.cpp
1 //******************************************************************
2 //
3 // Copyright 2017 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <stdio.h>
22 #include <string>
23 #include "nest_thermostat.h"
24 #include "nest_defs.h"
25 #include "rapidjson.h"
26 #include "document.h"
27 #include "json_helper.h"
28 #include "writer.h"
29 #include "stringbuffer.h"
30 #include "curl_client.h"
31 #include "logger.h"
32
33 #define TAG "NEST_THERMOSTAT"
34
35 NestThermostat::NestThermostat(const std::string &token,uint16_t hum, uint32_t hvac,
36                                 uint16_t temp, uint32_t scale, const char * devId) : m_token(token)
37 {
38     m_thermostat.humidity = hum;
39     m_thermostat.targetTempF = temp;
40     m_thermostat.temperature = (TEMPERATURE_SCALE) scale;
41     m_thermostat.hvacMode = (HVAC_MODE) hvac;
42     m_thermostat.devInfo.id = devId;
43 }
44 NestThermostat::NestThermostat(const std::string &token, const std::string &thermostat)
45         : m_token(token)
46 {
47     buildThermostat(thermostat);
48 }
49
50 NestThermostat::HVAC_MODE NestThermostat::getHVACmode(const std::string &hvacMode)
51 {
52     NestThermostat::HVAC_MODE result = HVAC_UNDEFINED;
53     if (hvacMode == NEST_HVAC_HEAT)
54     {
55         result = HVAC_HEAT;
56     }
57     else if (hvacMode == NEST_HVAC_COOL)
58     {
59         result = HVAC_COOL;
60     }
61     else if (hvacMode == NEST_HVAC_MIXED)
62     {
63         result = HVAC_MIXED;
64     }
65     else if (hvacMode == NEST_HVAC_OFF)
66     {
67         result = HVAC_OFF;
68     }
69     return result;
70 }
71
72 NestThermostat::TEMPERATURE_SCALE NestThermostat::getTemperatureScale(const std::string &tempScale)
73 {
74     NestThermostat::TEMPERATURE_SCALE result = TEMP_UNDEFINED;
75     if (tempScale == NEST_TEMP_SCALE_C)
76     {
77         result = TEMP_CELCIUS;
78     }
79     else if (tempScale == NEST_TEMP_SCALE_F)
80     {
81         result = TEMP_FAHRENHEIT;
82     }
83     return result;
84 }
85
86 int NestThermostat::buildThermostat(const std::string &thermostat)
87 {
88     if (thermostat.empty())
89     {
90         return GW_RESULT_INVALID_DATA;
91     }
92
93     rapidjson::Document doc;
94     doc.SetObject();
95
96     if (doc.Parse<0>(thermostat.c_str()).HasParseError())
97     {
98         return GW_RESULT_JSON_ERROR;
99     }
100
101     // Read the general/common device infor structure (common for all Nest devices)
102     m_thermostat.devInfo.version = doc[NEST_SW_VER_TAG.c_str()].GetString();
103     m_thermostat.devInfo.locale = doc[NEST_LOCALE_TAG.c_str()].GetString();
104     m_thermostat.devInfo.nameLong = doc[NEST_NAME_LONG_TAG.c_str()].GetString();
105     m_thermostat.devInfo.id = doc[NEST_DEVICE_ID_TAG.c_str()].GetString();
106     m_thermostat.devInfo.name = doc[NEST_NAME_TAG.c_str()].GetString();
107     m_thermostat.devInfo.structId = doc[NEST_STRUCT_ID_TAG.c_str()].GetString();
108
109     // Read the details of the thermostat
110     m_thermostat.humidity = doc[NEST_HUMIDITY_TAG.c_str()].GetInt();
111     m_thermostat.hasFan = doc[NEST_FAN_TAG.c_str()].GetBool();
112     m_thermostat.hasLeaf = doc[NEST_LEAF_TAG.c_str()].GetBool();
113     m_thermostat.canHeat = doc[NEST_HEAT_TAG.c_str()].GetBool();
114     m_thermostat.canCool = doc[NEST_COOL_TAG.c_str()].GetBool();
115     m_thermostat.targetTempC = doc[NEST_TARGET_TEMP_C_TAG.c_str()].GetDouble();
116     m_thermostat.targetTempF = doc[NEST_TARGET_TEMP_F_TAG.c_str()].GetUint();
117     m_thermostat.targetTempHighC = doc[NEST_TARGET_TEMP_HIGH_C_TAG.c_str()].GetDouble();
118     m_thermostat.targetTempHighF = doc[NEST_TARGET_TEMP_HIGH_F_TAG.c_str()].GetUint();
119     m_thermostat.targetTempLowC = doc[NEST_TARGET_TEMP_LOW_C_TAG.c_str()].GetDouble();
120     m_thermostat.targetTempLowF = doc[NEST_TARGET_TEMP_LOW_F_TAG.c_str()].GetUint();
121     m_thermostat.ambientTempC = doc[NEST_AMBIENT_TEMP_C_TAG.c_str()].GetDouble();
122     m_thermostat.ambientTempF = doc[NEST_AMBIENT_TEMP_F_TAG.c_str()].GetDouble();
123     m_thermostat.awayTempHighC = doc[NEST_AWAY_TEMP_HIGH_C_TAG.c_str()].GetDouble();
124     m_thermostat.awayTempHighF = doc[NEST_AWAY_TEMP_HIGH_F_TAG.c_str()].GetDouble();
125     m_thermostat.awayTempLowC = doc[NEST_AWAY_TEMP_LOW_C_TAG.c_str()].GetDouble();
126     m_thermostat.awayTempLowF = doc[NEST_AWAY_TEMP_LOW_F_TAG.c_str()].GetDouble();
127     m_thermostat.fanTimerActive = doc[NEST_FAN_TIMER_ACTIVE_TAG.c_str()].GetBool();
128     m_thermostat.isOnline = doc[NEST_ONLINE_TAG.c_str()].GetBool();
129     m_thermostat.hvacMode = getHVACmode(doc[NEST_HVAC_MODE_TAG.c_str()].GetString());
130     m_thermostat.temperature = getTemperatureScale(doc[NEST_TEMP_SCALE.c_str()].GetString());
131
132     return GW_RESULT_OK;
133 }
134
135 int NestThermostat::setTemperature(uint16_t targetTemp)
136 {
137     std::string scale;
138     std::string request = "{ }";
139     rapidjson::StringBuffer sb;
140     rapidjson::Document doc;
141
142     if (m_thermostat.temperature == TEMP_FAHRENHEIT)
143     {
144         scale = NEST_TARGET_TEMP_F_TAG;
145     }
146     else
147     {
148         scale = NEST_TARGET_TEMP_C_TAG;
149     }
150
151     std::string uri(NEST_BASE_URL);
152     uri += NEST_DEVICES_THERMOSTAT_STR + m_thermostat.devInfo.id + NEST_AUTH_STR + m_token;
153
154     doc.SetObject();
155     JsonHelper::setMember(doc, scale, targetTemp);
156     request = JsonHelper::toString(doc);
157
158     CurlClient cc = CurlClient("PUT", uri)
159                  .addRequestHeader(CURL_HEADER_ACCEPT_JSON)
160                  .addRequestHeader(CURL_CONTENT_TYPE_JSON)
161                  .setRequestBody(request);
162
163      int curlCode = cc.send();
164      std::string response = cc.getResponseBody();
165
166      if (curlCode != GW_RESULT_OK)
167      {
168          OIC_LOG_V(ERROR, TAG,"Set temperature failed. Error code %d", curlCode);
169          return GW_RESULT_INTERNAL_ERROR;
170      }
171
172      return GW_RESULT_OK;
173 }