1 #include "stdafx.h"
2 #include "Sterbox.h"
3 #include "../main/Helper.h"
4 #include "../main/Logger.h"
5 #include "../httpclient/HTTPClient.h"
6 #include "hardwaretypes.h"
7 #include "../main/localtime_r.h"
8 #include "../main/mainworker.h"
9 #include "../main/SQLHelper.h"
10 #include <sstream>
11
12 //http://sterbox.eu/index.php/sterbox
13
14 #define STERBOX_POLL_INTERVAL 8
15
CSterbox(const int ID,const std::string & IPAddress,const unsigned short usIPPort,const std::string & username,const std::string & password)16 CSterbox::CSterbox(const int ID, const std::string &IPAddress, const unsigned short usIPPort, const std::string &username, const std::string &password) :
17 m_szIPAddress(IPAddress),
18 m_Username(username),
19 m_Password(password)
20 {
21 m_HwdID=ID;
22 m_usIPPort=usIPPort;
23 m_bOutputLog = false;
24 Init();
25 }
26
~CSterbox(void)27 CSterbox::~CSterbox(void)
28 {
29 }
30
Init()31 void CSterbox::Init()
32 {
33 }
34
StartHardware()35 bool CSterbox::StartHardware()
36 {
37 RequestStart();
38
39 Init();
40 //Start worker thread
41 m_thread = std::make_shared<std::thread>(&CSterbox::Do_Work, this);
42 SetThreadNameInt(m_thread->native_handle());
43 m_bIsStarted=true;
44 sOnConnected(this);
45 _log.Log(LOG_STATUS, "Sterbox: Started");
46 return (m_thread != nullptr);
47 }
48
StopHardware()49 bool CSterbox::StopHardware()
50 {
51 if (m_thread)
52 {
53 RequestStop();
54 m_thread->join();
55 m_thread.reset();
56 }
57 m_bIsStarted=false;
58 return true;
59 }
60
Do_Work()61 void CSterbox::Do_Work()
62 {
63 int sec_counter = STERBOX_POLL_INTERVAL - 2;
64
65 while (!IsStopRequested(1000))
66 {
67 sec_counter++;
68
69 if (sec_counter % 12 == 0) {
70 m_LastHeartbeat=mytime(NULL);
71 }
72
73 if (sec_counter % STERBOX_POLL_INTERVAL == 0)
74 {
75 GetMeterDetails();
76 }
77 }
78 _log.Log(LOG_STATUS,"Sterbox: Worker stopped...");
79 }
80
WriteToHardware(const char * pdata,const unsigned char length)81 bool CSterbox::WriteToHardware(const char *pdata, const unsigned char length)
82 {
83 const tRBUF *pSen = reinterpret_cast<const tRBUF*>(pdata);
84
85 unsigned char packettype = pSen->ICMND.packettype;
86 //unsigned char subtype = pSen->ICMND.subtype;
87
88 if (packettype == pTypeLighting2)
89 {
90 //light command
91
92 int Relay = pSen->LIGHTING2.unitcode;
93 if (Relay > 20)
94 return false;
95
96 std::stringstream szURL;
97 //std::stringstream szhex;
98 //szhex << std::hex << Relay;
99 //std::string strhex = szhex.str();
100 //_log.Log(LOG_ERROR, "Sterbox: Size od szhex: %s", strhex.c_str());
101
102
103 //if (m_Password.empty())
104 //{
105 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort;
106 //}
107 //else
108 //{
109 // szURL << "http://" << m_Username << ":" << m_Password << "@" << m_szIPAddress << ":" << m_usIPPort;
110 //}
111
112 szURL << "/x?x00" << std::uppercase << std::hex << Relay;
113
114 if (pSen->LIGHTING2.cmnd == light2_sOff)
115 {
116 szURL << "=0";
117 }
118 else
119 {
120 szURL << "=0";
121 }
122 std::string sResult;
123 if (!HTTPClient::GET(szURL.str(), sResult))
124 {
125 _log.Log(LOG_ERROR, "Sterbox: Protocol Error sending relay command to: %s", m_szIPAddress.c_str());
126 return false;
127 }
128 std::string strhex = szURL.str();
129 _log.Log(LOG_STATUS, "Sterbox: sending relay command to: %s", strhex.c_str());
130
131 return true;
132 }
133 return false;
134 }
135
UpdateSwitch(const unsigned char Idx,const int SubUnit,const bool bOn,const double Level,const std::string & defaultname)136 void CSterbox::UpdateSwitch(const unsigned char Idx, const int SubUnit, const bool bOn, const double Level, const std::string &defaultname)
137 {
138 double rlevel = (15.0 / 100)*Level;
139 int level = int(rlevel);
140
141 char szIdx[10];
142 sprintf(szIdx, "%X%02X%02X%02X", 0, 0, 0, Idx);
143 std::vector<std::vector<std::string> > result;
144 result = m_sql.safe_query("SELECT Name,nValue,sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Unit==%d)", m_HwdID, szIdx, SubUnit);
145 if (!result.empty())
146 {
147 //check if we have a change, if not do not update it
148 int nvalue = atoi(result[0][1].c_str());
149 if ((!bOn) && (nvalue == 0))
150 return;
151 if ((bOn && (nvalue != 0)))
152 {
153 //Check Level
154 int slevel = atoi(result[0][2].c_str());
155 if (slevel == level)
156 return;
157 }
158 }
159
160 //Send as Lighting 2
161 tRBUF lcmd;
162 memset(&lcmd, 0, sizeof(RBUF));
163 lcmd.LIGHTING2.packetlength = sizeof(lcmd.LIGHTING2) - 1;
164 lcmd.LIGHTING2.packettype = pTypeLighting2;
165 lcmd.LIGHTING2.subtype = sTypeAC;
166 lcmd.LIGHTING2.id1 = 0;
167 lcmd.LIGHTING2.id2 = 0;
168 lcmd.LIGHTING2.id3 = 0;
169 lcmd.LIGHTING2.id4 = Idx;
170 lcmd.LIGHTING2.unitcode = SubUnit;
171 if (!bOn)
172 {
173 lcmd.LIGHTING2.cmnd = light2_sOff;
174 }
175 else
176 {
177 lcmd.LIGHTING2.cmnd = light2_sOn;
178 }
179 lcmd.LIGHTING2.level = level;
180 lcmd.LIGHTING2.filler = 0;
181 lcmd.LIGHTING2.rssi = 12;
182 sDecodeRXMessage(this, (const unsigned char *)&lcmd.LIGHTING2, defaultname.c_str(), 255);
183 }
184
GetMeterDetails()185 void CSterbox::GetMeterDetails()
186 {
187 std::string sResult;
188 std::stringstream szURL;
189
190 //if(m_Password.empty())
191 //{
192 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort;
193 //}
194 //else
195 //{
196 // szURL << "http://" << m_Username << ":" << m_Password << "@" << m_szIPAddress << ":" << m_usIPPort;
197 //}
198
199 szURL << "/x.cgi";
200
201 if (!HTTPClient::GET(szURL.str(),sResult))
202 {
203 _log.Log(LOG_ERROR,"Sterbox: Error connecting to: %s", m_szIPAddress.c_str());
204 return;
205 }
206 std::vector<std::string> results;
207 std::vector<std::string> outputs;
208 std::vector<std::string> inputs;
209 std::vector<std::string> analog;
210 StringSplit(sResult, "<br>", results);
211 if (results.size()<8)
212 {
213 _log.Log(LOG_ERROR,"Sterbox: Result 8 Error connecting to: %s", m_szIPAddress.c_str());
214 return;
215 }
216 //if (results[0] != "<body>")
217 std::string tmpstr;
218 std::string tmpstr2;
219 std::string tmpinp;
220 tmpstr = results[0];
221 size_t ii;
222 size_t jj;
223 int pos1;
224
225 if (m_Username.empty())
226 {
227 StringSplit("o,o,o,o,i,i,i,i", ",", inputs);
228 }
229 else
230 {
231 StringSplit(m_Username, ",", inputs);
232 //_log.Log(LOG_ERROR,"Sterbox: Username : %s , IP: %s", m_Username.c_str(), m_szIPAddress.c_str());
233 }
234
235 for (ii = 1; ii < results.size(); ii++)
236 {
237 tmpstr = results[ii];
238 if (tmpstr.find("OU") != std::string::npos)
239 {
240 tmpstr = tmpstr.substr(strlen("OU"));
241 pos1 = tmpstr.find("=");
242 if (pos1 != std::string::npos)
243 {
244 tmpstr = tmpstr.substr(pos1+1);
245 //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str());
246 StringSplit(tmpstr, ",", outputs);
247 for (jj = 0; jj < inputs.size(); jj++)
248 {
249 tmpinp = inputs[jj];
250 //if (( jj < 4 || jj > 7 ))
251 pos1 = tmpinp.find("o");
252 if (pos1 != std::string::npos)
253 {
254 int lValue = 0;
255 //tmpstr = tmpstr.substr(pos1+1);
256 tmpstr2 = outputs[jj];
257 //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());
258 pos1 = tmpstr2.find("s");
259 if (pos1 != std::string::npos)
260 {
261 lValue = 1;
262 }
263 else
264 {
265 lValue = 0;
266 }
267 std::stringstream sstr;
268 sstr << "Relay " << jj;
269 UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str());
270 }
271 }
272 }
273 }
274 else if (tmpstr.find("IN") != std::string::npos)
275 {
276 tmpstr = tmpstr.substr(strlen("IN"));
277 pos1 = tmpstr.find("=");
278 if (pos1 != std::string::npos)
279 {
280 tmpstr = tmpstr.substr(pos1+1);
281 //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str());
282 StringSplit(tmpstr, ",", outputs);
283 for (jj = 0; jj < inputs.size(); jj++)
284 {
285 tmpinp = inputs[jj];
286 //if (( jj > 3 && jj < 8 ))
287 pos1 = tmpinp.find("i");
288 if (pos1 != std::string::npos)
289 {
290 int lValue = 0;
291 //tmpstr = tmpstr.substr(pos1+1);
292 tmpstr2 = outputs[jj];
293 //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());
294 pos1 = tmpstr2.find("S");
295 if (pos1 != std::string::npos)
296 {
297 lValue = 1;
298 }
299 else
300 {
301 lValue = 0;
302 }
303 std::stringstream sstr;
304 sstr << "Relay " << jj;
305 UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str());
306 }
307 }
308 }
309 }
310 else if (tmpstr.find("AN") != std::string::npos)
311 {
312 tmpstr = tmpstr.substr(strlen("AN"));
313 pos1 = tmpstr.find("=");
314 if (pos1 != std::string::npos)
315 {
316 tmpstr = tmpstr.substr(pos1+1);
317 StringSplit(tmpstr, ",", outputs);
318 if (m_Password.empty())
319 {
320 StringSplit("t,t,t", ",", analog);
321 }
322 else
323 {
324 //StringSplit("t,t,t", ",", inputs);
325 StringSplit(m_Password, ",", analog);
326 //_log.Log(LOG_ERROR,"Sterbox: Pass : %s", m_Password.c_str());
327
328 }
329 for (jj = 0; jj < 3; jj++)
330 {
331 tmpstr2 = outputs[jj];
332 tmpinp = analog[jj];
333 tmpstr2 = tmpstr2.substr(1, 10);
334
335 float lValue = (float)atof(tmpstr2.c_str());
336 std::stringstream sstr;
337 sstr << "Analog " << jj;
338 pos1 = tmpinp.find("t");
339 if (pos1 != std::string::npos)
340 {
341 SendTempSensor(jj,255,lValue, sstr.str());
342 }
343 pos1 = tmpinp.find("v");
344 if (pos1 != std::string::npos)
345 {
346 SendVoltageSensor(0, (uint8_t)jj, 255, lValue, sstr.str());
347 }
348 pos1 = tmpinp.find("l");
349 if (pos1 != std::string::npos)
350 {
351 SendLuxSensor(0, (uint8_t)jj, 255,lValue, sstr.str());
352 }
353 pos1 = tmpinp.find("h");
354 if (pos1 != std::string::npos)
355 {
356 SendHumiditySensor(jj,255,int(lValue), sstr.str());
357 }
358
359 //SendTempSensor(jj,255,lValue, sstr.str());
360 //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());
361
362 }
363 //int Idx = atoi(tmpstr.substr(0, pos1).c_str());
364 //tmpstr = tmpstr.substr(pos1 + 1);
365 //pos1 = tmpstr.find("<");
366 //if (pos1 != std::string::npos)
367 //{
368 // int lValue = atoi(tmpstr.substr(0, pos1).c_str());
369 // float voltage = (float)(5.0f / 1023.0f)*lValue;
370 // if (voltage > 5.0f)
371 // voltage = 5.0f;
372 // std::stringstream sstr;
373 // sstr << "Voltage " << Idx;
374 // SendVoltageSensor(0, Idx, 255, voltage, sstr.str());
375 //}
376 }
377 }
378 }
379 }
380