Android SDK - Initial commit and build system updates
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SoftSensorPlugin / DiscomfortIndexSensor / src / DiscomfortIndexSensor.cpp
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics 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 /**
22  * This file contains the exported symbol.
23  */
24 #include <stdlib.h>
25 #include <map>
26 #include <string>
27 #include <sstream>
28 #include <iostream>
29
30 #include "DiscomfortIndexSensor.h"
31 #include "SysTimer.h"
32
33 #ifdef __ANDROID__
34 #include "OCAndroid.h"
35 #endif
36
37 using namespace DiscomfortIndexSensorName;
38
39 #define SENSOR_NAME "DiscomfortIndexSensor"
40
41 char *inputName[2] =
42 { (char *)"temperature", (char *)"humidity" };
43
44 physicalInput DiscomfortIndexSensor::s_PHYSICAL_SOFTSENSORs[PHYSICAL_EA] =
45 {
46     { (char *)"Thing_TempHumSensor", 2, (void *) &inputName },
47     { (char *)"Thing_TempHumSensor1", 2, (void *) &inputName }
48 };
49
50 ICtxDelegate *g_pDelegate;
51
52 void InitializeContext(ICtxDelegate *pDelegate)
53 {
54     std::vector < ContextData > contextData;
55
56     DiscomfortIndexSensor *eventCls = new DiscomfortIndexSensor();
57     pDelegate->registerCallback(eventCls);
58     g_pDelegate = pDelegate;
59
60     std::cout << "DiscomfortIndexSensor loaded" << std::endl;
61
62     return;
63 }
64
65 DiscomfortIndexSensor::DiscomfortIndexSensor()
66 {
67     m_result.m_timestamp = "";
68     m_result.m_humidity = "";
69     m_result.m_temperature = "";
70     m_result.m_discomfortIndex = "";
71 }
72
73 void DiscomfortIndexSensor::onCtxEvent(enum CTX_EVENT_TYPE eventType,
74                                        std::vector< ContextData > contextDataList)
75 {
76     switch (eventType)
77     {
78         case SPF_START:
79             runLogic(contextDataList);
80             break;
81         default:
82             std::cout << "Not support onCtxEvent" << std::endl;
83             break;
84     }
85 }
86
87 int DiscomfortIndexSensor::runLogic(std::vector< ContextData > &contextDataList)
88 {
89     std::cout << "[DiscomfortIndexSensor] DiscomfortIndexSensor::" << __func__ << " is called."
90               << std::endl;
91
92     DIResult result;
93
94     if (getInput(contextDataList, m_DI) == SUCCESS)
95     {
96         if ((result = makeDiscomfortIndex(m_DI)) != SUCCESS)
97         {
98             std::cout << "Error : makeDiscomfortIndex() result = " << result << std::endl;
99             return -1;
100         }
101
102         std::vector < ContextData > outList;
103         ContextData out = setOutput(4, m_DI);
104
105         outList.push_back(out);
106         g_pDelegate->addOutput(outList);
107
108         return 0;
109     }
110
111     return -1;
112 }
113
114 /**
115  * Get Input data (temperature, humidity) using resource Client of Iotivity base.
116  */
117 DIResult DiscomfortIndexSensor::getInput(std::vector< ContextData > &contextDataList, InValue *data)
118 {
119     int result_flag = 0;
120     int contextSize = 0;
121
122     if ((contextSize = contextDataList.size()) == 0)
123     {
124         std::cout << "Physical Context data is not exist." << std::endl;
125         return ERROR;
126     }
127
128     for (int i = 0; i < contextSize; i++)
129     {
130         for (int k = 0; k < PHYSICAL_EA; k++)
131         {
132             if (contextDataList[i].rootName == s_PHYSICAL_SOFTSENSORs[k].m_thingName)
133             {
134                 std::vector < std::map< std::string, std::string > > lVector =
135                     contextDataList[i].outputProperty;
136                 int requiredInputNum = s_PHYSICAL_SOFTSENSORs[k].m_inputNum;
137                 char **pchar = (char **) (s_PHYSICAL_SOFTSENSORs[k].m_pInputStruct);
138                 if (requiredInputNum == 0)
139                 {
140                     std::cout << "No input List." << std::endl;
141                     return ERROR;
142                 }
143
144                 for (unsigned int j = 0; j < lVector.size(); j++)
145                 {
146                     std::string name = lVector[j]["name"];
147
148                     if (name.compare(*pchar) == 0)
149                     {
150                         data->m_temperature = lVector[j]["value"];
151                         requiredInputNum--;
152                     }
153                     else if (name.compare(*(++pchar)) == 0)
154                     {
155                         data->m_humidity = lVector[j]["value"];
156                         requiredInputNum--;
157                     }
158                 }
159
160                 if (requiredInputNum == 0)
161                 {
162                     data++;
163                     result_flag++;
164                 }
165                 break;
166             } // if
167         } // for
168     }
169
170     if (result_flag == PHYSICAL_EA)
171     {
172         std::cout << "Success : getInput()" << std::endl;
173         return SUCCESS;
174     }
175
176     return ERROR;
177 }
178
179 /**
180  * Calculation of DiscomfortIndex with TEMP&HUMI of InValue.
181  */
182 DIResult DiscomfortIndexSensor::makeDiscomfortIndex(InValue *data)
183 {
184     int discomfortIndex = (int) ERROR;
185     double sumDI = 0.0;
186
187     m_result.m_temperature = "";
188     m_result.m_humidity = "";
189
190     for (int i = 0; i < PHYSICAL_EA; i++)
191     {
192         if (i != 0)
193         {
194             m_result.m_temperature += ", ";
195             m_result.m_humidity += ", ";
196         }
197
198         double dI = 0.0;
199         int t = std::stoi((data + i)->m_temperature);
200         int h = std::stoi((data + i)->m_humidity);
201         double F = (9.0 * (double) t) / 5.0 + 32.0;
202
203         std::cout << "Device Number : " << i << std::endl;
204
205         dI = F - (F - 58.0) * (double) ((100 - h) * 55) / 10000.0;
206
207         std::cout << "Discomfort level : " << dI << ", Temperature :" << t << ", Humidity :" << h
208                   << std::endl;
209
210         (data + i)->m_discomfortIndex = std::to_string(0);
211         m_result.m_temperature += std::to_string(t) + ", ";
212         m_result.m_humidity += std::to_string(h) + ", ";
213         sumDI += dI;
214     }
215
216     sumDI = sumDI / PHYSICAL_EA;
217     std::cout << "[result] Avg. DI level : " << sumDI << std::endl;
218     if (sumDI >= 80.0)
219     {
220         discomfortIndex = (int) ALL_DISCOMPORT;
221         std::cout << "DI : " << discomfortIndex << " : All person discomfort. : " << sumDI
222                   << std::endl;
223     }
224     else if (sumDI >= 75.0)
225     {
226         discomfortIndex = (int) HALF_DISCOMPORT;
227         std::cout << "DI : " << discomfortIndex << " : Half of person discomfort. : " << sumDI
228                   << std::endl;
229     }
230     else if (sumDI >= 68.0)
231     {
232         discomfortIndex = (int) LITTLE_DISCOMPORT;
233         std::cout << "DI : " << discomfortIndex << " : A little person discomfort. : " << sumDI
234                   << std::endl;
235     }
236     else
237     {
238         discomfortIndex = (int) ALL_COMPORT;
239         std::cout << "DI : " << discomfortIndex << " : All person comfort. : " << sumDI
240                   << std::endl;
241     }
242
243     m_result.m_discomfortIndex = std::to_string(discomfortIndex);
244     std::cout << "[result] Discomfort Index : " << m_result.m_discomfortIndex << std::endl;
245
246     return SUCCESS;
247 }
248
249 ContextData DiscomfortIndexSensor::setOutput(int property_count, InValue *data)
250 {
251     ContextData out;
252
253     std::map < std::string, std::string > output_property;
254
255     out.rootName = SENSOR_NAME;
256     out.outputPropertyCount = property_count;
257
258     output_property.insert(std::make_pair("name", "timestamp"));
259     output_property.insert(std::make_pair("type", "string"));
260     output_property.insert(std::make_pair("value", m_result.m_timestamp));
261
262     out.outputProperty.push_back(output_property);
263
264     output_property.clear();
265     output_property.insert(std::make_pair("name", "temperature"));
266     output_property.insert(std::make_pair("type", "string"));
267     output_property.insert(std::make_pair("value", m_result.m_temperature));
268
269     out.outputProperty.push_back(output_property);
270
271     output_property.clear();
272     output_property.insert(std::make_pair("name", "humidity"));
273     output_property.insert(std::make_pair("type", "string"));
274     output_property.insert(std::make_pair("value", m_result.m_humidity));
275
276     out.outputProperty.push_back(output_property);
277
278     output_property.clear();
279     output_property.insert(std::make_pair("name", "discomfortIndex"));
280     output_property.insert(std::make_pair("type", "int"));
281     output_property.insert(std::make_pair("value", m_result.m_discomfortIndex));
282
283     out.outputProperty.push_back(output_property);
284
285     return out;
286 }
287