1 #include "stdafx.h"
2 #include "DenkoviDevices.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 #define MAX_POLL_INTERVAL 3600*1000
13
14 #define DAE_DI_DEF "DigitalInput"
15 #define DAE_AI_DEF "AnalogInput"
16 #define DAE_TI_DEF "TemperatureInput"
17 #define DAE_AO_DEF "AnalogOutput"
18 #define DAE_PWM_DEF "PWM"
19 #define DAE_OUT_DEF "Output"
20 #define DAE_RELAY_DEF "Relay"
21 #define DAE_CH_DEF "Channel"
22
23
24 #define SDO_AI_DEF "AI"
25 #define SDO_DI_DEF "DI"
26 #define SDO_TI_DEF "TI"
27 #define SDO_RELAY_DEF "Relay"
28 #define SDO_MAIN_DEF "Main"
29
30 #define DAENETIP3_PORTA_MDO_DEF "ASG"//portA multiple output state
31 #define DAENETIP3_PORTA_SDO_DEF "AS"//portA single output state
32 #define DAENETIP3_PORTA_SNAME_DEF "AC"//portA signle output name
33
34 #define DAENETIP3_PORTB_MDI_DEF "BVG"//portB multiple input state
35 #define DAENETIP3_PORTB_SDI_DEF "BV"//portB single output state
36 #define DAENETIP3_PORTB_SNAME_DEF "BC"//portB signle input name
37
38 #define DAENETIP3_PORTC_SNAME_DEF "CC"//portC signle analog input name
39 #define DAENETIP3_PORTC_SDIM_DEF "CS"//portC signle analog input dimension
40 #define DAENETIP3_PORTC_SVAL_DEF "CD"//portC signle analog input value + dimension
41
42
43 #define MIN_DAENETIP3_RESPOND_LENGTH 105
44
45 #define DAE_VALUE_DEF "Value"
46 #define DAE_STATE_DEF "State"
47 #define DAE_RSTATE_DEF "RelayState"
48 #define DAE_MEASURE_DEF "Measure"
49 #define DAE_SCAL_VALUE_DEF "Scaled_Value"
50 #define DAE_NAME_DEF "Name"
51 #define DAE_LASTO_DEF "LastOpened"
52 #define DAE_LASTC_DEF "LastClosed"
53 #define DAE_COUNT_DEF "Count"
54
55 #define DAENETIP3_AI_VALUE 0
56 #define DAENETIP3_AI_DIMENSION 1
57 #define DAENETIP2_PORT_3_VAL 0
58 #define DAENETIP2_PORT_5_VAL 1
59 #define DAENETIP2_AI_VOLTAGE 0
60 #define DAENETIP2_AI_TEMPERATURE 1
61
62 enum _eDenkoviIOType
63 {
64 DIOType_DI = 0, //0
65 DIOType_DO, //1
66 DIOType_Relay, //2
67 DIOType_PWM, //3
68 DIOType_AO, //4
69 DIOType_AI, //5
70 DIOType_DIO, //6
71 DIOType_MCD, //7
72 DIOType_TXT //8
73 };
74
CDenkoviDevices(const int ID,const std::string & IPAddress,const unsigned short usIPPort,const std::string & password,const int pollInterval,const int model)75 CDenkoviDevices::CDenkoviDevices(const int ID, const std::string &IPAddress, const unsigned short usIPPort, const std::string &password, const int pollInterval, const int model) :
76 m_szIPAddress(IPAddress),
77 m_Password(CURLEncode::URLEncode(password)),
78 m_pollInterval(pollInterval)
79 {
80 m_HwdID = ID;
81 m_usIPPort = usIPPort;
82 m_bOutputLog = false;
83 m_iModel = model;
84 if (m_pollInterval < 500)
85 m_pollInterval = 500;
86 else if (m_pollInterval > MAX_POLL_INTERVAL)
87 m_pollInterval = MAX_POLL_INTERVAL;
88 Init();
89 }
90
91
~CDenkoviDevices()92 CDenkoviDevices::~CDenkoviDevices()
93 {
94 }
95
Init()96 void CDenkoviDevices::Init()
97 {
98 }
99
StartHardware()100 bool CDenkoviDevices::StartHardware()
101 {
102 RequestStart();
103
104 Init();
105
106 //Start worker thread
107 m_thread = std::make_shared<std::thread>(&CDenkoviDevices::Do_Work, this);
108 SetThreadNameInt(m_thread->native_handle());
109 m_bIsStarted = true;
110 sOnConnected(this);
111 switch (m_iModel) {
112 case DDEV_DAEnet_IP4:
113 _log.Log(LOG_STATUS, "DAEnetIP4: Started");
114 break;
115 case DDEV_SmartDEN_IP_16_Relays:
116 _log.Log(LOG_STATUS, "SmartDEN IP-16R: Started");
117 break;
118 case DDEV_SmartDEN_IP_32_In:
119 _log.Log(LOG_STATUS, "SmartDEN IP-32IN: Started");
120 break;
121 case DDEV_SmartDEN_IP_Maxi:
122 _log.Log(LOG_STATUS, "SmartDEN IP-Maxi: Started");
123 break;
124 case DDEV_SmartDEN_IP_Watchdog:
125 _log.Log(LOG_STATUS, "SmartDEN IP-Watchdog: Started");
126 break;
127 case DDEV_SmartDEN_Logger:
128 _log.Log(LOG_STATUS, "SmartDEN Logger: Started");
129 break;
130 case DDEV_SmartDEN_Notifier:
131 _log.Log(LOG_STATUS, "SmartDEN Notifier: Started");
132 break;
133 case DDEV_DAEnet_IP3:
134 _log.Log(LOG_STATUS, "DAEnetIP3: Started");
135 break;
136 case DDEV_DAEnet_IP2:
137 _log.Log(LOG_STATUS, "DAEnetIP2: Started");
138 break;
139 case DDEV_DAEnet_IP2_8_RELAYS:
140 _log.Log(LOG_STATUS, "DAEnetIP2 8 Relay Module - LM35DZ: Started");
141 break;
142 case DDEV_SmartDEN_Opener:
143 _log.Log(LOG_STATUS, "SmartDEN Opener: Started");
144 break;
145 case DDEV_SmartDEN_PLC:
146 _log.Log(LOG_STATUS, "SmartDEN PLC: Started");
147 break;
148 }
149 return (m_thread != NULL);
150 }
151
StopHardware()152 bool CDenkoviDevices::StopHardware()
153 {
154 if (m_thread != NULL)
155 {
156 RequestStop();
157 m_thread->join();
158 m_thread.reset();
159 }
160 m_bIsStarted = false;
161 return true;
162 }
163
Do_Work()164 void CDenkoviDevices::Do_Work()
165 {
166 int poll_interval = m_pollInterval / 100;
167 int poll_counter = poll_interval - 2;
168
169 while (!IsStopRequested(100))
170 {
171 poll_counter++;
172
173 if (poll_counter % 12 * 10 == 0) { //10 steps = 1 second (10 * 100)
174 m_LastHeartbeat = mytime(NULL);
175 }
176
177 if (poll_counter % poll_interval == 0)
178 {
179 GetMeterDetails();
180 }
181 }
182 switch (m_iModel) {
183 case DDEV_DAEnet_IP4:
184 _log.Log(LOG_STATUS, "DAEnetIP4: Worker stopped...");
185 break;
186 case DDEV_SmartDEN_IP_16_Relays:
187 _log.Log(LOG_STATUS, "SmartDEN IP-16R: Worker stopped...");
188 break;
189 case DDEV_SmartDEN_IP_32_In:
190 _log.Log(LOG_STATUS, "SmartDEN IP-32IN: Worker stopped...");
191 break;
192 case DDEV_SmartDEN_IP_Maxi:
193 _log.Log(LOG_STATUS, "SmartDEN IP-Maxi: Worker stopped...");
194 break;
195 case DDEV_SmartDEN_IP_Watchdog:
196 _log.Log(LOG_STATUS, "SmartDEN IP-Watchdog: Worker stopped...");
197 break;
198 case DDEV_SmartDEN_Logger:
199 _log.Log(LOG_STATUS, "SmartDEN Logger: Worker stopped...");
200 break;
201 case DDEV_SmartDEN_Notifier:
202 _log.Log(LOG_STATUS, "SmartDEN Notifier: Worker stopped...");
203 break;
204 case DDEV_DAEnet_IP3:
205 _log.Log(LOG_STATUS, "DAEnetIP3: Worker stopped...");
206 break;
207 case DDEV_DAEnet_IP2:
208 _log.Log(LOG_STATUS, "DAEnetIP2: Worker stopped...");
209 break;
210 case DDEV_DAEnet_IP2_8_RELAYS:
211 _log.Log(LOG_STATUS, "DAEnetIP2 8 Relay Module - LM35DZ: Worker stopped...");
212 break;
213 case DDEV_SmartDEN_Opener:
214 _log.Log(LOG_STATUS, "SmartDEN Opener: Worker stopped...");
215 break;
216 case DDEV_SmartDEN_PLC:
217 _log.Log(LOG_STATUS, "SmartDEN PLC: Worker stopped...");
218 break;
219 }
220 }
221
WriteToHardware(const char * pdata,const unsigned char)222 bool CDenkoviDevices::WriteToHardware(const char *pdata, const unsigned char /*length*/)
223 {
224 const _tGeneralSwitch *pSen1 = reinterpret_cast<const _tGeneralSwitch*>(pdata);
225 const tRBUF *pSen = reinterpret_cast<const tRBUF*>(pdata);
226
227 int ioType = pSen->LIGHTING2.id4;
228 int io;
229 int Relay;
230 uint8_t command;
231 uint8_t level;
232
233 if (ioType!=DIOType_DO && ioType!=DIOType_Relay && ioType!= DIOType_DIO && ioType!= DIOType_MCD)
234 {
235 ioType = pSen1->id;
236 io = pSen1->unitcode;
237 Relay = pSen1->unitcode;
238 command = pSen1->cmnd;
239 level = pSen1->level;
240 }
241 else
242 {
243 ioType = pSen->LIGHTING2.id4;
244 io = pSen->LIGHTING2.unitcode;
245 Relay = pSen->LIGHTING2.unitcode;
246 command = pSen->LIGHTING2.cmnd;
247 level = pSen->LIGHTING2.level;
248 }
249
250 if (m_Password.empty())
251 {
252 switch (m_iModel) {
253 case DDEV_DAEnet_IP4:
254 _log.Log(LOG_ERROR, "DAEnetIP4: Please enter a password.");
255 break;
256 case DDEV_SmartDEN_IP_16_Relays:
257 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Please enter a password.");
258 break;
259 case DDEV_SmartDEN_IP_32_In:
260 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: Please enter a password.");
261 break;
262 case DDEV_SmartDEN_IP_Maxi:
263 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Please enter a password.");
264 break;
265 case DDEV_SmartDEN_IP_Watchdog:
266 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Please enter a password.");
267 break;
268 case DDEV_SmartDEN_Logger:
269 _log.Log(LOG_ERROR, "SmartDEN Logger: Please enter a password.");
270 break;
271 case DDEV_SmartDEN_Notifier:
272 _log.Log(LOG_ERROR, "SmartDEN Notifier: Please enter a password.");
273 break;
274 case DDEV_DAEnet_IP3:
275 _log.Log(LOG_ERROR, "DAEnetIP3: Please enter a password.");
276 break;
277 case DDEV_DAEnet_IP2:
278 _log.Log(LOG_ERROR, "DAEnetIP2: Please enter a password.");
279 break;
280 case DDEV_DAEnet_IP2_8_RELAYS:
281 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Please enter a password.");
282 break;
283 case DDEV_SmartDEN_Opener:
284 _log.Log(LOG_ERROR, "SmartDEN Opener: Please enter a password.");
285 break;
286 case DDEV_SmartDEN_PLC:
287 _log.Log(LOG_ERROR, "SmartDEN PLC: Please enter a password.");
288 break;
289 }
290 return false;
291 }
292
293 switch (m_iModel) {
294 case DDEV_SmartDEN_Opener: {
295
296 if ((ioType != DIOType_MCD) && (ioType != DIOType_Relay))
297 {
298 _log.Log(LOG_ERROR, "SmartDEN Opener: Not a valid Relay or Main Controlled Device!");
299 return false;
300 }
301 //int io = pSen->unitcode;//Relay1, Relay2 and MCD
302 if (io > 3)
303 return false;
304
305 std::stringstream szURL;
306
307 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/current_state.xml";
308 if (!m_Password.empty())
309 szURL << "?pw=" << m_Password << "&";
310 else
311 szURL << "?";
312
313 if (ioType == DIOType_Relay)
314 szURL << "R" << io << "=";
315 else //DIOType_PWM:
316 szURL << "MS=";
317
318 if (ioType == DIOType_Relay) {
319 if (command== light2_sOff)
320 szURL << "0";
321 else if (command== light2_sOn)
322 szURL << "1";
323 else {
324 _log.Log(LOG_ERROR, "SmartDEN Opener: Not a valid command for Relay!");
325 return false;
326 }
327 }
328 else if (ioType == DIOType_MCD) {
329 if (command== blinds_sOpen)
330 szURL << "1";
331 else if (command== blinds_sClose)
332 szURL << "0";
333 else if (command== 0x11) //stop button
334 szURL << "2";
335 else {
336 _log.Log(LOG_ERROR, "SmartDEN Opener: Not a valid command for MCD!");
337 return false;
338 }
339 }
340
341 std::string sResult;
342 if (!HTTPClient::GET(szURL.str(), sResult)) {
343 _log.Log(LOG_ERROR, "SmartDEN Opener: Error sending command to: %s", m_szIPAddress.c_str());
344 return false;
345 }
346 if (sResult.find("Message") != std::string::npos) {
347 _log.Log(LOG_ERROR, "SmartDEN Opener: Error sending command to: %s", m_szIPAddress.c_str());
348 return false;
349 }
350 return true;
351 }
352 case DDEV_DAEnet_IP2_8_RELAYS: {
353 std::string sPass = m_Password;
354 sPass.replace(sPass.find("%3A"), 3, ":");
355 //int ioType = pSen->id;
356 if (ioType != DIOType_DIO && ioType != DIOType_Relay)
357 {
358 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Not a valid Digital Input/Output or Relay! ");
359 return false;
360 }
361 //int io = pSen->unitcode;//DIO1 to DIO16
362 if (io > 16)
363 return false;
364
365 std::stringstream szURL;
366 std::string sResult;
367
368 szURL << "http://" << sPass << "@" << m_szIPAddress << ":" << m_usIPPort << "/ioreg.js";
369 if (!HTTPClient::GET(szURL.str(), sResult)) {
370 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Error sending command to: %s", m_szIPAddress.c_str());
371 return false;
372 }
373 uint8_t port3 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_3_VAL);
374 uint8_t port5 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_5_VAL);
375 if (io < 9) { //DIO1 to DIO8 are from Port 3
376 if (command== light2_sOff)
377 port3 = port3 & (~(0x01 << (io - 1)));
378 else if (command== light2_sOn)
379 port3 = port3 | (0x01 << (io - 1));
380 else {
381 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Not a valid command. Digital Input/Output could be On or Off.");
382 return false;
383 }
384 }
385 else { //DIO9 to DIO16 are from Port 5
386 if (command== light2_sOff)
387 port5 = port5 & (~(0x01 << (io - 8 - 1)));
388 else if (command== light2_sOn)
389 port5 = port5 | (0x01 << (io - 8 - 1));
390 else {
391 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Not a valid command. Digital Input/Output could be On or Off.");
392 return false;
393 }
394 }
395 szURL.str("");
396 char port3Val[3], port5Val[3];
397 sprintf(port3Val, "%02X", port3);
398 sprintf(port5Val, "%02X", port5);
399 szURL << "http://" << sPass << "@" << m_szIPAddress << ":" << m_usIPPort << "/iochange.cgi?ref=re-io&01=" << port3Val << "&02=" << port5Val;
400 if (!HTTPClient::GET(szURL.str(), sResult)) {
401 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Error sending command to: %s", m_szIPAddress.c_str());
402 return false;
403 }
404 return true;
405 }
406 case DDEV_DAEnet_IP2: {
407 std::string sPass = m_Password;
408 sPass.replace(sPass.find("%3A"), 3, ":");
409 //int ioType = pSen->id;
410 if (ioType != DIOType_DIO)
411 {
412 _log.Log(LOG_ERROR, "DAEnetIP2: Not a valid Digital Input/Output! ");
413 return false;
414 }
415 //int io = pSen->unitcode;//DIO1 to DIO16
416 if (io > 16)
417 return false;
418
419 std::stringstream szURL;
420 std::string sResult;
421
422 szURL << "http://" << sPass << "@" << m_szIPAddress << ":" << m_usIPPort << "/ioreg.js";
423 if (!HTTPClient::GET(szURL.str(), sResult)) {
424 _log.Log(LOG_ERROR, "DAEnetIP2: Error sending command to: %s", m_szIPAddress.c_str());
425 return false;
426 }
427 uint8_t port3 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_3_VAL);
428 uint8_t port5 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_5_VAL);
429 if (io < 9) { //DIO1 to DIO8 are from Port 3
430 if (command== light2_sOff)
431 port3 = port3 & (~(0x01 << (io - 1)));
432 else if (command== light2_sOn)
433 port3 = port3 | (0x01 << (io - 1));
434 else {
435 _log.Log(LOG_ERROR, "DAEnetIP2: Not a valid command. Digital Input/Output could be On or Off.");
436 return false;
437 }
438 }
439 else { //DIO9 to DIO16 are from Port 5
440 if (command== light2_sOff)
441 port5 = port5 & (~(0x01 << (io - 8 - 1)));
442 else if (command== light2_sOn)
443 port5 = port5 | (0x01 << (io - 8 - 1));
444 else {
445 _log.Log(LOG_ERROR, "DAEnetIP2: Not a valid command. Digital Input/Output could be On or Off.");
446 return false;
447 }
448 }
449 szURL.str("");
450 char port3Val[3], port5Val[3];
451 sprintf(port3Val, "%02X", port3);
452 sprintf(port5Val, "%02X", port5);
453 szURL << "http://" << sPass << "@" << m_szIPAddress << ":" << m_usIPPort << "/iochange.cgi?ref=re-io&01=" << port3Val << "&02=" << port5Val;
454 if (!HTTPClient::GET(szURL.str(), sResult)) {
455 _log.Log(LOG_ERROR, "DAEnetIP2: Error sending command to: %s", m_szIPAddress.c_str());
456 return false;
457 }
458 return true;
459 }
460 case DDEV_DAEnet_IP3: {
461 //int ioType = pSen->id;
462 if (ioType != DIOType_DO)
463 {
464 _log.Log(LOG_ERROR, "DAEnetIP3: Not a valid Digital Output! ");
465 return false;
466 }
467 //int io = pSen->unitcode;//DO1 to DO16
468 if (io > 16)
469 return false;
470
471 std::stringstream szURL;
472
473 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/command.html";
474 if (!m_Password.empty())
475 szURL << "?P=" << m_Password << "&";
476 else
477 szURL << "?";
478
479 szURL << DAENETIP3_PORTA_SDO_DEF << std::uppercase << std::hex << io - 1 << "=";
480 if (command== light2_sOff)
481 szURL << "0&";
482 else if (command== light2_sOn) {
483 szURL << "1&";
484 }
485 else {
486 _log.Log(LOG_ERROR, "DAEnetIP3: Not a valid command. Digital Output could be On or Off.");
487 return false;
488 }
489 std::string sResult;
490 if (!HTTPClient::GET(szURL.str(), sResult)) {
491 _log.Log(LOG_ERROR, "DAEnetIP3: Error sending command to: %s", m_szIPAddress.c_str());
492 return false;
493 }
494 szURL.str("");
495 szURL << DAENETIP3_PORTA_SDO_DEF << std::uppercase << std::hex << io - 1;
496 if (sResult.find(szURL.str()) == std::string::npos) {
497 _log.Log(LOG_ERROR, "DAEnetIP3: Error setting Digital Output %u", io);
498 return false;
499 }
500 return true;
501
502 }
503 case DDEV_SmartDEN_Notifier: {
504 _log.Log(LOG_ERROR, "SmartDEN Notifier: This board does not have outputs! ");
505 return false;
506 }
507 case DDEV_SmartDEN_Logger: {
508 _log.Log(LOG_ERROR, "SmartDEN Logger: This board does not have outputs! ");
509 return false;
510 }
511 case DDEV_SmartDEN_IP_32_In: {
512 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: This board does not have outputs! ");
513 return false;
514 }
515 case DDEV_SmartDEN_PLC:
516 case DDEV_SmartDEN_IP_Maxi: {
517 //int ioType = pSen1->LIGHTING2.unitcode;//pSen->id;
518 if ((ioType != DIOType_AO) && (ioType != DIOType_Relay))
519 {
520 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Not a valid Relay or Analog Output!");
521 return false;
522 }
523 //int io = pSen1->LIGHTING2.id4;//Relay1 to Relay8 and AO1 to AO2
524 if (io > 8)
525 return false;
526
527 std::stringstream szURL;
528
529 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/current_state.xml";
530 if (!m_Password.empty())
531 szURL << "?pw=" << m_Password << "&";
532 else
533 szURL << "?";
534
535 if (ioType == DIOType_Relay)
536 szURL << "Relay" << io << "=";
537 else //DIOType_PWM:
538 szURL << "AnalogOutput" << io << "=";
539
540 if (command == light2_sOff)//pSen->cmnd
541 szURL << "0";
542 else if (command== light2_sSetLevel) {
543 double lvl = level*10.34;
544 int iLvl = (int)lvl;
545 szURL << std::to_string(iLvl);
546 }
547 else
548 szURL << "1";
549 std::string sResult;
550 if (!HTTPClient::GET(szURL.str(), sResult)) {
551 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Error sending command to: %s", m_szIPAddress.c_str());
552 return false;
553 }
554 if (sResult.find("CurrentState") == std::string::npos) {
555 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Error sending command to: %s", m_szIPAddress.c_str());
556 return false;
557 }
558 return true;
559 }
560 case DDEV_DAEnet_IP4: {
561 //int ioType = pSen->id;
562 if ((ioType != DIOType_DO) && (ioType != DIOType_PWM))
563 {
564 _log.Log(LOG_ERROR, "DAEnetIP4: Not a valid Digital or PWM output");
565 return false;
566 }
567 //int io = pSen->unitcode;//Output1 to Output16 and PWM1 to PWM2
568 if (io > 16)
569 return false;
570
571 std::stringstream szURL;
572
573 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/current_state.xml";
574 if (!m_Password.empty())
575 szURL << "?pw=" << m_Password << "&";
576 else
577 szURL << "?";
578
579 if (ioType == DIOType_DO)
580 szURL << "Output" << io << "=";
581 else //DIOType_PWM:
582 szURL << "PWM" << io << "=";
583
584 if (command== light2_sOff)
585 szURL << "0";
586 else if (command== light2_sSetLevel)
587 szURL << std::to_string(level);
588 else
589 szURL << "1";
590 std::string sResult;
591 if (!HTTPClient::GET(szURL.str(), sResult)) {
592 _log.Log(LOG_ERROR, "DAEnetIP4: Error sending command to: %s", m_szIPAddress.c_str());
593 return false;
594 }
595 if (sResult.find("CurrentState") == std::string::npos) {
596 _log.Log(LOG_ERROR, "DAEnetIP4: Error sending command to: %s", m_szIPAddress.c_str());
597 return false;
598 }
599 return true;
600 }
601 case DDEV_SmartDEN_IP_Watchdog:
602 case DDEV_SmartDEN_IP_16_Relays: {
603 //int ioType = pSen->id;
604 if (ioType != DIOType_Relay)
605 {
606 if (m_iModel == DDEV_SmartDEN_IP_Watchdog)
607 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Not a valid Relay switch.");
608 else
609 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Not a valid Relay switch.");
610 return false;
611 }
612 //int Relay = pSen->unitcode;
613 if (Relay > 16)
614 return false;
615
616 std::stringstream szURL;
617
618 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/current_state.xml";
619 if (!m_Password.empty())
620 szURL << "?pw=" << m_Password << "&Relay" << Relay << "=";
621 else
622 szURL << "?Relay" << Relay << "=";
623
624 if (command== light2_sOff)
625 szURL << "0";
626 else if (command== light2_sOn) {
627 szURL << "1";
628 }
629 else {
630 if (m_iModel == DDEV_SmartDEN_IP_Watchdog)
631 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Not a valid command. Relay could be On or Off.");
632 else
633 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Not a valid command. Relay could be On or Off.");
634 return false;
635 }
636 std::string sResult;
637 if (!HTTPClient::GET(szURL.str(), sResult))
638 {
639 if (m_iModel == DDEV_SmartDEN_IP_Watchdog)
640 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Error sending relay command to: %s", m_szIPAddress.c_str());
641 else
642 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Error sending relay command to: %s", m_szIPAddress.c_str());
643 return false;
644 }
645 if (sResult.find("CurrentState") == std::string::npos)
646 {
647 if (m_iModel == DDEV_SmartDEN_IP_Watchdog)
648 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Error sending relay command to: %s", m_szIPAddress.c_str());
649 else
650 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Error sending relay command to: %s", m_szIPAddress.c_str());
651 return false;
652 }
653 return true;
654 }
655 }
656 _log.Log(LOG_ERROR, "Denkovi: Unknown Device!");
657 return false;
658 }
659
DenkoviCheckForIO(std::string tmpstr,const std::string & tmpIoType)660 int CDenkoviDevices::DenkoviCheckForIO(std::string tmpstr, const std::string &tmpIoType) {
661 int Idx = -1;
662 std::string ioType = "<" + tmpIoType;
663 size_t pos1 = tmpstr.find(ioType);
664 if (pos1 != std::string::npos)
665 {
666 tmpstr = tmpstr.substr(pos1 + strlen(ioType.c_str()));
667 pos1 = tmpstr.find(">");
668 if (pos1 != std::string::npos)
669 Idx = atoi(tmpstr.substr(0, pos1).c_str());
670 }
671 return Idx;
672 }
673
DenkoviGetIntParameter(std::string tmpstr,const std::string & tmpParameter)674 int CDenkoviDevices::DenkoviGetIntParameter(std::string tmpstr, const std::string &tmpParameter) {
675 int lValue = -1;
676 std::string parameter = "<" + tmpParameter + ">";
677 size_t pos1 = tmpstr.find(parameter);
678 if (pos1 != std::string::npos)
679 {
680 tmpstr = tmpstr.substr(pos1 + strlen(parameter.c_str()));
681 pos1 = tmpstr.find('<');
682 if (pos1 != std::string::npos)
683 lValue = atoi(tmpstr.substr(0, pos1).c_str());
684 }
685 return lValue;
686 }
687
DenkoviGetStrParameter(std::string tmpstr,const std::string & tmpParameter)688 std::string CDenkoviDevices::DenkoviGetStrParameter(std::string tmpstr, const std::string &tmpParameter) {
689 std::string sMeasure = "";
690 std::string parameter = "<" + tmpParameter + ">";
691
692 size_t pos1 = tmpstr.find(parameter);
693 if (pos1 != std::string::npos)
694 {
695 tmpstr = tmpstr.substr(pos1 + strlen(parameter.c_str()));
696 pos1 = tmpstr.find('<');
697 if (pos1 != std::string::npos)
698 sMeasure = tmpstr.substr(0, pos1);
699 }
700 return sMeasure;
701 }
702
DenkoviGetFloatParameter(std::string tmpstr,const std::string & tmpParameter)703 float CDenkoviDevices::DenkoviGetFloatParameter(std::string tmpstr, const std::string &tmpParameter) {
704 float value = NAN;
705 std::string parameter = "<" + tmpParameter + ">";
706
707 size_t pos1 = tmpstr.find(parameter);
708 if (pos1 != std::string::npos)
709 {
710 tmpstr = tmpstr.substr(pos1 + strlen(parameter.c_str()));
711 pos1 = tmpstr.find('<');
712 if (pos1 != std::string::npos)
713 value = static_cast<float>(atof(tmpstr.substr(0, pos1).c_str()));
714 }
715 return value;
716 }
717
DAEnetIP3GetIo(std::string tmpstr,const std::string & tmpParameter)718 std::string CDenkoviDevices::DAEnetIP3GetIo(std::string tmpstr, const std::string &tmpParameter) {
719 std::string parameter = tmpParameter + "=";
720 size_t pos1 = tmpstr.find(parameter);
721 size_t pos2 = tmpstr.find(";", pos1);
722 return tmpstr.substr(pos1 + strlen(parameter.c_str()), pos2 - (pos1 + strlen(parameter.c_str()))).c_str();
723 }
724
DAEnetIP3GetAi(std::string tmpstr,const std::string & tmpParameter,const int & ciType)725 std::string CDenkoviDevices::DAEnetIP3GetAi(std::string tmpstr, const std::string &tmpParameter, const int &ciType) {
726 std::string parameter = tmpParameter + "=";
727 size_t pos1 = tmpstr.find(parameter);
728 size_t pos2;
729 if (ciType == DAENETIP3_AI_VALUE) {
730 pos2 = tmpstr.find("[", pos1);
731 return tmpstr.substr(pos1 + strlen(parameter.c_str()), pos2 - (pos1 + strlen(parameter.c_str()))).c_str();
732 }
733 else if (ciType == DAENETIP3_AI_DIMENSION) {
734 pos1 = tmpstr.find("[", pos1);
735 pos2 = tmpstr.find("]", pos1);
736 return tmpstr.substr(pos1 + 1, pos2 - (pos1 + 1)).c_str();
737 }
738 return "";// tmpstr.substr(pos1 + strlen(parameter.c_str()), pos2 - (pos1 + strlen(parameter.c_str()))).c_str();
739 }
740
DAEnetIP2GetIoPort(std::string tmpstr,const int & port)741 uint8_t CDenkoviDevices::DAEnetIP2GetIoPort(std::string tmpstr, const int &port) {
742 std::stringstream ss;
743 size_t pos1, pos2;
744 int b;
745 if (port == DAENETIP2_PORT_3_VAL) {
746 pos1 = tmpstr.find("(0x");
747 pos2 = tmpstr.find(",", pos1);
748 ss << std::hex << tmpstr.substr(pos1 + 3, pos2 - (pos1 + 3)).c_str();
749 ss >> b;
750 return (uint8_t)b;
751 }
752 else if (port == DAENETIP2_PORT_5_VAL) {
753 pos1 = tmpstr.find(",0x");
754 pos2 = tmpstr.find(",", pos1 + 3);
755 ss << std::hex << tmpstr.substr(pos1 + 3, pos2 - (pos1 + 3)).c_str();
756 ss >> b;
757 return (uint8_t)b;
758 }
759 return 0;
760 }
761
DAEnetIP2GetName(std::string tmpstr,const int & nmr)762 std::string CDenkoviDevices::DAEnetIP2GetName(std::string tmpstr, const int &nmr) {//nmr should be from 1 to 24
763 size_t pos1 = 0, pos2 = 0;
764 for (uint8_t ii = 0; ii < (((nmr - 1) * 2) + 1); ii++) {
765 pos1 = tmpstr.find("\"", pos1 + 1);
766 }
767 pos2 = tmpstr.find("\"", pos1 + 1);
768 return tmpstr.substr(pos1 + 1, pos2 - (pos1 + 1)).c_str();
769 }
770
DAEnetIP2GetAiValue(std::string tmpstr,const int & aiNmr)771 uint16_t CDenkoviDevices::DAEnetIP2GetAiValue(std::string tmpstr, const int &aiNmr) {
772 size_t pos1 = 0, pos2 = 0;
773 std::stringstream ss;
774 int b = 0;
775 for (uint8_t ii = 0; ii < aiNmr + 3; ii++) {
776 pos1 = tmpstr.find("0x", pos1 + 2);
777 }
778 pos2 = tmpstr.find(",", pos1 + 2);
779 ss << std::hex << tmpstr.substr(pos1 + 2, pos2 - (pos1 + 2)).c_str();
780 ss >> b;
781 return (uint8_t)b;
782 }
783
DAEnetIP2CalculateAi(int adc,const int & valType)784 float CDenkoviDevices::DAEnetIP2CalculateAi(int adc, const int &valType) {
785 if (valType == DAENETIP2_AI_TEMPERATURE) {
786 return static_cast<float>(10000 * ((1.2*204.8)*adc / (120 * 1024) + 0) / 100);
787 }
788 else if (valType == DAENETIP2_AI_VOLTAGE) {
789 return static_cast<float>(10000 * ((1.2*0.377)*adc / (4.7 * 1024) + 0) / 100);
790 }
791 return 0.0f;
792 }
793
SendDenkoviTextSensor(const int NodeID,const int ChildID,const int BatteryLevel,const std::string & textMessage,const std::string & defaultname)794 void CDenkoviDevices::SendDenkoviTextSensor(const int NodeID, const int ChildID, const int BatteryLevel, const std::string &textMessage, const std::string &defaultname)
795 {
796 //check if we have a change, if not do not update it
797 bool bExists;
798 std::string oldvalue = GetTextSensorText(NodeID, ChildID, bExists);
799 if (oldvalue.compare(textMessage)!=0)
800 SendTextSensor(NodeID, ChildID, BatteryLevel, textMessage, defaultname);
801 }
802
803
804
GetMeterDetails()805 void CDenkoviDevices::GetMeterDetails()
806 {
807 std::string sResult, sResult2;
808 std::stringstream szURL, szURL2;
809
810 if (m_Password.empty())
811 {
812 switch (m_iModel) {
813 case DDEV_DAEnet_IP4:
814 _log.Log(LOG_ERROR, "DAEnetIP4: Please enter a password.");
815 break;
816 case DDEV_SmartDEN_IP_16_Relays:
817 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Please enter a password.");
818 break;
819 case DDEV_SmartDEN_IP_32_In:
820 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: Please enter a password.");
821 break;
822 case DDEV_SmartDEN_IP_Maxi:
823 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Please enter a password.");
824 break;
825 case DDEV_SmartDEN_IP_Watchdog:
826 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Please enter a password.");
827 break;
828 case DDEV_SmartDEN_Logger:
829 _log.Log(LOG_ERROR, "SmartDEN Logger: Please enter a password.");
830 break;
831 case DDEV_SmartDEN_Notifier:
832 _log.Log(LOG_ERROR, "SmartDEN Notifier: Please enter a password.");
833 break;
834 case DDEV_DAEnet_IP3:
835 _log.Log(LOG_ERROR, "DAEnetIP3: Please enter a password.");
836 break;
837 case DDEV_DAEnet_IP2:
838 _log.Log(LOG_ERROR, "DAEnetIP2: Please enter a password.");
839 break;
840 case DDEV_DAEnet_IP2_8_RELAYS:
841 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Please enter a password.");
842 break;
843 case DDEV_SmartDEN_Opener:
844 _log.Log(LOG_ERROR, "SmartDEN Opener: Please enter a password.");
845 break;
846 case DDEV_SmartDEN_PLC:
847 _log.Log(LOG_ERROR, "SmartDEN PLC: Please enter a password.");
848 break;
849 }
850 return;
851 }
852
853 if (m_iModel == DDEV_DAEnet_IP2 || m_iModel == DDEV_DAEnet_IP2_8_RELAYS) {
854 std::string sPass = m_Password;
855 if (sPass.find("%3A") == std::string::npos) {
856 if (m_iModel == DDEV_DAEnet_IP2)
857 _log.Log(LOG_ERROR, "DAEnetIP2: Please enter username and password in format username:password. Example admin:admin.");
858 else if (m_iModel == DDEV_DAEnet_IP2_8_RELAYS)
859 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Please enter username and password in format username:password. Example admin:admin.");
860 return;
861 }
862 sPass.replace(sPass.find("%3A"), 3, ":");
863 szURL << "http://" << sPass << "@" << m_szIPAddress << ":" << m_usIPPort << "/ioreg.js";
864 }
865 else if (m_iModel == DDEV_DAEnet_IP3) {
866 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/command.html";
867 szURL2 << "http://" << m_szIPAddress << ":" << m_usIPPort << "/command.html";
868 if (!m_Password.empty()) {
869 szURL << "?P=" << m_Password;
870 szURL2 << "?P=" << m_Password;
871 }
872 szURL << "&ASG=?&BVG=?&CD0=?&CD1=?&CD2=?&CD3=?&CD4=?&CD5=?&CD6=?&CD7=?&AC0=?&AC1=?&AC2=?&AC3=?&AC4=?&AC5=?&AC6=?&AC7=?&AC8=?&AC9=?&ACA=?&ACB=?&ACC=?&ACD=?&ACE=?&ACF=?&";
873 szURL2 << "&BC0=?&BC1=?&BC2=?&BC3=?&BC4=?&BC5=?&BC6=?&BC7=?&CC0=?&CC1=?&CC2=?&CC3=?&CC4=?&CC5=?&CC6=?&CC7=?&";
874 }
875 else {
876 szURL << "http://" << m_szIPAddress << ":" << m_usIPPort << "/current_state.xml";
877 if (!m_Password.empty())
878 szURL << "?pw=" << m_Password;
879 }
880
881 if (!HTTPClient::GET(szURL.str(), sResult) || (m_iModel == DDEV_DAEnet_IP3 && !HTTPClient::GET(szURL2.str(), sResult2)))
882 {
883 switch (m_iModel) {
884 case DDEV_DAEnet_IP4:
885 _log.Log(LOG_ERROR, "DAEnetIP4: Error connecting to: %s", m_szIPAddress.c_str());
886 break;
887 case DDEV_SmartDEN_IP_16_Relays:
888 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Error connecting to: %s", m_szIPAddress.c_str());
889 break;
890 case DDEV_SmartDEN_IP_32_In:
891 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: Error connecting to: %s", m_szIPAddress.c_str());
892 break;
893 case DDEV_SmartDEN_IP_Maxi:
894 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Error connecting to: %s", m_szIPAddress.c_str());
895 break;
896 case DDEV_SmartDEN_IP_Watchdog:
897 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Error connecting to: %s", m_szIPAddress.c_str());
898 break;
899 case DDEV_SmartDEN_Logger:
900 _log.Log(LOG_ERROR, "SmartDEN Logger: Error connecting to: %s", m_szIPAddress.c_str());
901 break;
902 case DDEV_SmartDEN_Notifier:
903 _log.Log(LOG_ERROR, "SmartDEN Notifier: Error connecting to: %s", m_szIPAddress.c_str());
904 break;
905 case DDEV_DAEnet_IP3:
906 _log.Log(LOG_ERROR, "DAEnetIP3: Error connecting to: %s", m_szIPAddress.c_str());
907 break;
908 case DDEV_DAEnet_IP2:
909 _log.Log(LOG_ERROR, "DAEnetIP2: Error connecting to: %s", m_szIPAddress.c_str());
910 break;
911 case DDEV_SmartDEN_Opener:
912 _log.Log(LOG_ERROR, "SmartDEN Opener: Error connecting to: %s", m_szIPAddress.c_str());
913 break;
914 case DDEV_SmartDEN_PLC:
915 _log.Log(LOG_ERROR, "SmartDEN PLC: Error connecting to: %s", m_szIPAddress.c_str());
916 break;
917 }
918 return;
919 }
920 std::vector<std::string> results;
921 if (m_iModel == DDEV_SmartDEN_Opener)
922 StringSplit(sResult, "\n", results);
923 else
924 StringSplit(sResult, "\r\n", results);
925 //int z = strlen(sResult.c_str());
926 if (m_iModel != DDEV_DAEnet_IP3 && m_iModel != DDEV_DAEnet_IP2 && m_iModel != DDEV_DAEnet_IP2_8_RELAYS && results.size() < 8)
927 {
928 switch (m_iModel) {
929 case DDEV_DAEnet_IP4:
930 _log.Log(LOG_ERROR, "DAEnetIP4: Error connecting to: %s", m_szIPAddress.c_str());
931 break;
932 case DDEV_SmartDEN_IP_16_Relays:
933 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Error connecting to: %s", m_szIPAddress.c_str());
934 break;
935 case DDEV_SmartDEN_IP_32_In:
936 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: Error connecting to: %s", m_szIPAddress.c_str());
937 break;
938 case DDEV_SmartDEN_IP_Maxi:
939 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Error connecting to: %s", m_szIPAddress.c_str());
940 break;
941 case DDEV_SmartDEN_IP_Watchdog:
942 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Error connecting to: %s", m_szIPAddress.c_str());
943 break;
944 case DDEV_SmartDEN_Logger:
945 _log.Log(LOG_ERROR, "SmartDEN Logger: Error connecting to: %s", m_szIPAddress.c_str());
946 break;
947 case DDEV_SmartDEN_Notifier:
948 _log.Log(LOG_ERROR, "SmartDEN Notifier: Error connecting to: %s", m_szIPAddress.c_str());
949 break;
950 case DDEV_SmartDEN_Opener:
951 _log.Log(LOG_ERROR, "SmartDEN Opener: Error connecting to: %s", m_szIPAddress.c_str());
952 break;
953 case DDEV_SmartDEN_PLC:
954 _log.Log(LOG_ERROR, "SmartDEN PLC: Error connecting to: %s", m_szIPAddress.c_str());
955 break;
956 }
957 return;
958 }
959 else if (m_iModel == DDEV_DAEnet_IP3 && (strlen(sResult.c_str()) < MIN_DAENETIP3_RESPOND_LENGTH)) {
960 _log.Log(LOG_ERROR, "DAEnetIP3: Error connecting to: %s", m_szIPAddress.c_str());
961 return;
962 }
963 else if (m_iModel == DDEV_DAEnet_IP2 && sResult.find("var IO=new Array") == std::string::npos) {
964 _log.Log(LOG_ERROR, "DAEnetIP2: Error getting status from: %s", m_szIPAddress.c_str());
965 return;
966 }
967 else if (m_iModel == DDEV_DAEnet_IP2_8_RELAYS && sResult.find("var IO=new Array") == std::string::npos) {
968 _log.Log(LOG_ERROR, "DAEnetIP2 8 Relay Module - LM35DZ: Error getting status from: %s", m_szIPAddress.c_str());
969 return;
970 }
971
972 if (m_iModel != DDEV_DAEnet_IP3 && m_iModel != DDEV_DAEnet_IP2 && m_iModel != DDEV_DAEnet_IP2_8_RELAYS && results[0] != "<CurrentState>")
973 {
974 switch (m_iModel) {
975 case DDEV_DAEnet_IP4:
976 _log.Log(LOG_ERROR, "DAEnetIP4: Error getting status");
977 break;
978 case DDEV_SmartDEN_IP_16_Relays:
979 _log.Log(LOG_ERROR, "SmartDEN IP-16R: Error getting status");
980 break;
981 case DDEV_SmartDEN_IP_32_In:
982 _log.Log(LOG_ERROR, "SmartDEN IP-32IN: Error getting status");
983 case DDEV_SmartDEN_IP_Maxi:
984 _log.Log(LOG_ERROR, "SmartDEN IP-Maxi: Error getting status");
985 break;
986 case DDEV_SmartDEN_IP_Watchdog:
987 _log.Log(LOG_ERROR, "SmartDEN IP-Watchdog: Error getting status");
988 case DDEV_SmartDEN_Logger:
989 _log.Log(LOG_ERROR, "SmartDEN Logger: Error getting status");
990 break;
991 case DDEV_SmartDEN_Notifier:
992 _log.Log(LOG_ERROR, "SmartDEN Notifier: Error getting status");
993 break;
994 case DDEV_SmartDEN_Opener:
995 _log.Log(LOG_ERROR, "SmartDEN Opener: Error getting status");
996 break;
997 case DDEV_SmartDEN_PLC:
998 _log.Log(LOG_ERROR, "SmartDEN PLC: Error getting status");
999 break;
1000 }
1001 return;
1002 }
1003 else if (m_iModel == DDEV_DAEnet_IP3 && ((sResult.find(DAENETIP3_PORTA_MDO_DEF) == std::string::npos) || (sResult2.find(DAENETIP3_PORTB_SNAME_DEF) == std::string::npos))) {
1004 _log.Log(LOG_ERROR, "DAEnetIP3: Error getting status");
1005 return;
1006 }
1007
1008 int ii;
1009 std::string tmpstr;
1010 std::string tmp_counter;
1011 std::string tmp_adc_raw_value;
1012 int tmpState = 0;
1013 int tmpValue = 0;
1014 float tmpTiValue = NAN;
1015 std::string tmpMeasure;
1016
1017 std::string tmpName;
1018 std::string name;
1019 int Idx = -1;
1020
1021 switch (m_iModel) {
1022 case DDEV_SmartDEN_Opener: {//has DI, AI, TI, Relays, MCD
1023 bool bHaveDigitalInput = false;
1024 bool bHaveMCD = false;
1025 bool bHaveAnalogInput = false;
1026 bool bHaveTemperatureInput = false;
1027 bool bHaveRelay = false;
1028 for (ii = 1; ii < (int)results.size(); ii++)
1029 {
1030 tmpstr = stdstring_trim(results[ii]);
1031
1032 if (Idx == -1) {
1033 if (!bHaveDigitalInput && ((Idx = DenkoviCheckForIO(tmpstr, SDO_DI_DEF)) != -1))
1034 {
1035 bHaveDigitalInput = true;
1036 continue;
1037 }
1038
1039 if (!bHaveAnalogInput && ((Idx = DenkoviCheckForIO(tmpstr, SDO_AI_DEF)) != -1))
1040 {
1041 bHaveAnalogInput = true;
1042 continue;
1043 }
1044
1045 if (!bHaveMCD && ((Idx = DenkoviCheckForIO(tmpstr, SDO_MAIN_DEF)) != -1))
1046 {
1047 bHaveMCD = true;
1048 continue;
1049 }
1050
1051 if (!bHaveTemperatureInput && ((Idx = DenkoviCheckForIO(tmpstr, SDO_TI_DEF)) != -1))
1052 {
1053 bHaveTemperatureInput = true;
1054 continue;
1055 }
1056
1057 if (!bHaveRelay && ((Idx = DenkoviCheckForIO(tmpstr, SDO_RELAY_DEF)) != -1))
1058 {
1059 bHaveRelay = true;
1060 continue;
1061 }
1062 }
1063
1064 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1065 name = tmpName;
1066 continue;
1067 }
1068
1069 if (bHaveDigitalInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_STATE_DEF)) != -1))
1070 {
1071 name = "Digital Input " + std::to_string(Idx) + " (" + name + ")";
1072 SendSwitch(DIOType_DI, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, name);
1073 Idx = -1;
1074 bHaveDigitalInput = false;
1075 continue;
1076 }
1077
1078 if (bHaveAnalogInput && (Idx != -1) && ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_SCAL_VALUE_DEF)) != ""))
1079 {
1080 std::vector<std::string> vMeasure;
1081 StringSplit(tmpMeasure, " ", vMeasure);
1082 int len = tmpMeasure.length() - tmpMeasure.find_first_of('.', 0) - 2;
1083 std::string units = tmpMeasure.substr(tmpMeasure.find_first_of('.',0)+2, len);
1084 SendCustomSensor(Idx, 1, 255, static_cast<float>(atof(vMeasure[0].c_str())), "Analog Input Scaled (" + name + ")", units);
1085
1086 std::vector<std::string> vRaw;
1087 tmpstr = results[ii - 1];
1088 std::string tmpRawValue = DenkoviGetStrParameter(tmpstr, DAE_VALUE_DEF);
1089 StringSplit(tmpRawValue, " ", vRaw);
1090 SendCustomSensor(Idx+1, 1, 255, static_cast<float>(atof(vRaw[0].c_str())), "Analog Input (" + name + ")", "");
1091
1092 Idx = -1;
1093 bHaveAnalogInput = false;
1094 continue;
1095 }
1096
1097 if (bHaveTemperatureInput && (Idx != -1) && ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_VALUE_DEF)) != ""))
1098 {
1099 name = "Temperature Input (" + name + ")";
1100 std::vector<std::string> vMeasure;
1101 StringSplit(tmpMeasure, " ", vMeasure);
1102 tmpTiValue = static_cast<float>(atof(tmpMeasure.c_str()));
1103 if (tmpMeasure.find("F") != std::string::npos)
1104 tmpTiValue = (float)ConvertToCelsius((double)tmpTiValue);
1105 SendTempSensor(Idx, 255, tmpTiValue, name);
1106
1107 Idx = -1;
1108 bHaveTemperatureInput = false;
1109 continue;
1110 }
1111
1112 if (bHaveRelay && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_STATE_DEF)) != -1))
1113 {
1114 name = "Relay " + std::to_string(Idx) + " (" + name + ")";
1115 SendSwitch(DIOType_Relay, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, name);
1116 Idx = -1;
1117 bHaveRelay = false;
1118 continue;
1119 }
1120
1121 if (bHaveMCD && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_STATE_DEF)) != -1))
1122 {
1123 std::string tmpN = "";
1124 tmpN = "MCD (" + name + ")";
1125 if (tmpValue == 1 || tmpValue == 3)
1126 tmpValue = blinds_sOpen;
1127 else if (tmpValue == 0 || tmpValue == 4)
1128 tmpValue = blinds_sClose;
1129 else
1130 tmpValue = 0x11;
1131 SendSwitch(DIOType_MCD, (uint8_t)Idx, 255, tmpValue, 0, tmpN);
1132 ii = ii + 4;
1133 tmpstr = stdstring_trim(results[ii]);
1134 tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_LASTO_DEF);
1135 SendDenkoviTextSensor(DIOType_TXT, ++Idx, 255, tmpMeasure, name + " Last Opened");
1136 ii = ii + 1;
1137 tmpstr = stdstring_trim(results[ii]);
1138 tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_LASTC_DEF);
1139 SendDenkoviTextSensor(DIOType_TXT, ++Idx, 255, tmpMeasure, name + " Last Closed");
1140 Idx = -1;
1141 bHaveMCD = false;
1142 continue;
1143 }
1144 }
1145 break;
1146 }
1147 case DDEV_DAEnet_IP2_8_RELAYS: {
1148 uint8_t port3 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_3_VAL);
1149 uint8_t port5 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_5_VAL);
1150 for (ii = 0; ii < 8; ii++)//8 digital inputs/outputs from port3
1151 {
1152 tmpName = DAEnetIP2GetName(sResult, ii + 1);
1153 name = "Digital IO " + std::to_string(ii + 1) + " (" + tmpName + ")";
1154 SendSwitch(DIOType_DIO, (uint8_t)(ii + 1), 255, ((port3&(0x01 << ii)) != 0) ? true : false, 0, name);
1155 }
1156 for (ii = 0; ii < 8; ii++)//8 digital inputs/outputs from port5
1157 {
1158 tmpName = DAEnetIP2GetName(sResult, ii + 8 + 1);
1159 name = "Relay " + std::to_string(ii + 1) + " (" + tmpName + ")";
1160 SendSwitch(DIOType_Relay, (uint8_t)(ii + 8 + 1), 255, ((port5&(0x01 << ii)) != 0) ? true : false, 0, name);
1161 }
1162 for (ii = 0; ii < 8; ii++)//8 analog inputs
1163 {
1164 tmpName = DAEnetIP2GetName(sResult, ii + 16 + 1);
1165 tmpValue = DAEnetIP2GetAiValue(sResult, ii + 1);
1166 name = "Analog Input " + std::to_string(ii + 1) + " (" + tmpName + ")";
1167 SendCustomSensor(DIOType_AI, (uint8_t)(ii + 16 + 1), 255, static_cast<float>(tmpValue), name, "");
1168 //float voltageValue = (float)(10.44*(tmpValue / 1024));
1169 float voltageValue = DAEnetIP2CalculateAi(tmpValue, DAENETIP2_AI_VOLTAGE);
1170 SendVoltageSensor(DIOType_AI, ii + 24 + 1, 255, voltageValue, name);
1171 //float temperatureValue = (float)(2.05*(tmpValue / 1024));
1172 float temperatureValue = DAEnetIP2CalculateAi(tmpValue, DAENETIP2_AI_TEMPERATURE);
1173 SendTempSensor(ii + 1, 255, temperatureValue, name);
1174 }
1175 break;
1176 }
1177 case DDEV_DAEnet_IP2: {
1178 uint8_t port3 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_3_VAL);
1179 uint8_t port5 = DAEnetIP2GetIoPort(sResult, DAENETIP2_PORT_5_VAL);
1180 for (ii = 0; ii < 8; ii++)//8 digital inputs/outputs from port3
1181 {
1182 tmpName = DAEnetIP2GetName(sResult, ii + 1);
1183 name = "Digital IO " + std::to_string(ii + 1) + " (" + tmpName + ")";
1184 SendSwitch(DIOType_DIO, (uint8_t)(ii + 1), 255, ((port3&(0x01 << ii)) != 0) ? true : false, 0, name);
1185 }
1186 for (ii = 0; ii < 8; ii++)//8 digital inputs/outputs from port5
1187 {
1188 tmpName = DAEnetIP2GetName(sResult, ii + 8 + 1);
1189 name = "Digital IO " + std::to_string(ii + 8 + 1) + " (" + tmpName + ")";
1190 SendSwitch(DIOType_DIO, (uint8_t)(ii + 8 + 1), 255, ((port5&(0x01 << ii)) != 0) ? true : false, 0, name);
1191 }
1192 for (ii = 0; ii < 8; ii++)//8 analog inputs
1193 {
1194 tmpName = DAEnetIP2GetName(sResult, ii + 16 + 1);
1195 tmpValue = DAEnetIP2GetAiValue(sResult, ii + 1);
1196 name = "Analog Input " + std::to_string(ii + 1) + " (" + tmpName + ")";
1197 SendCustomSensor(DIOType_AI, (uint8_t)(ii + 16 + 1), 255, static_cast<float>(tmpValue), name, "");
1198 }
1199 break;
1200 }
1201 case DDEV_DAEnet_IP3: {
1202 unsigned int pins = std::stoul(DAEnetIP3GetIo(sResult, DAENETIP3_PORTA_MDO_DEF), nullptr, 16);
1203 for (ii = 0; ii < 16; ii++)//16 digital outputs
1204 {
1205 std::stringstream io;
1206 io << std::uppercase << std::hex << ii;
1207 tmpName = DAEnetIP3GetIo(sResult, DAENETIP3_PORTA_SNAME_DEF + io.str());
1208 name = "Digital Output " + std::to_string(ii + 1) + " (" + tmpName + ")";
1209 SendSwitch(DIOType_DO, (uint8_t)(ii + 1), 255, ((pins&(0x0001 << ii)) != 0) ? true : false, 0, name);
1210 }
1211
1212 pins = std::stoul(DAEnetIP3GetIo(sResult, DAENETIP3_PORTB_MDI_DEF), nullptr, 16);
1213 for (ii = 0; ii < 8; ii++)//8 digital inputs
1214 {
1215 std::stringstream io;
1216 io << std::uppercase << std::hex << ii;
1217 tmpName = DAEnetIP3GetIo(sResult2, DAENETIP3_PORTB_SNAME_DEF + io.str());
1218 name = "Digital Input " + std::to_string(ii + 1) + " (" + tmpName + ")";
1219 SendSwitch(DIOType_DI, (uint8_t)(ii + 1), 255, ((pins&(0x01 << ii)) != 0) ? true : false, 0, name);
1220 }
1221
1222 for (ii = 0; ii < 8; ii++)//8 analog inputs
1223 {
1224 tmpMeasure = DAEnetIP3GetAi(sResult, (DAENETIP3_PORTC_SVAL_DEF + std::to_string(ii)), DAENETIP3_AI_VALUE);
1225 tmpstr = DAEnetIP3GetAi(sResult, (DAENETIP3_PORTC_SVAL_DEF + std::to_string(ii)), DAENETIP3_AI_DIMENSION);
1226 tmpName = DAEnetIP3GetIo(sResult2, DAENETIP3_PORTC_SNAME_DEF + std::to_string(ii));
1227 SendCustomSensor(DIOType_AI, (uint8_t)(ii + 1), 255, static_cast<float>(atoi(tmpMeasure.c_str())), "Analog Input Scaled " + std::to_string(ii + 1) + " (" + tmpName + ")", tmpstr);
1228 }
1229 }
1230 case DDEV_SmartDEN_IP_16_Relays: {//has only relays
1231 bool bHaveRelays = false;
1232 for (ii = 1; ii < (int)results.size(); ii++)
1233 {
1234 tmpstr = stdstring_trim(results[ii]);
1235
1236 if (!bHaveRelays && ((Idx = DenkoviCheckForIO(tmpstr, DAE_RELAY_DEF)) != -1))
1237 {
1238 bHaveRelays = true;
1239 continue;
1240 }
1241
1242 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1243 name = tmpName;
1244 continue;
1245 }
1246
1247 if (bHaveRelays && (Idx != -1) && ((tmpState = DenkoviGetIntParameter(tmpstr, DAE_STATE_DEF)) != -1))
1248 {
1249 std::stringstream sstr;
1250 sstr << "Relay " << Idx << " (" << name << ")";
1251 SendSwitch(DIOType_Relay, (uint8_t)Idx, 255, (tmpState == 1) ? true : false, 0, sstr.str());
1252 Idx = -1;
1253 bHaveRelays = false;
1254 continue;
1255 }
1256 }
1257 break;
1258 }
1259 case DDEV_SmartDEN_IP_Watchdog: {//has only relays
1260 bool bHaveRelays = false;
1261 for (ii = 1; ii < (int)results.size(); ii++)
1262 {
1263 tmpstr = stdstring_trim(results[ii]);
1264
1265 if (!bHaveRelays && ((Idx = DenkoviCheckForIO(tmpstr, DAE_CH_DEF)) != -1))
1266 {
1267 bHaveRelays = true;
1268 continue;
1269 }
1270
1271 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1272 name = tmpName;
1273 continue;
1274 }
1275
1276 if (bHaveRelays && (Idx != -1) && ((tmpState = DenkoviGetIntParameter(tmpstr, DAE_RSTATE_DEF)) != -1))
1277 {
1278 name = "Relay " + std::to_string(Idx) + "(" + name + ")";
1279 SendSwitch(DIOType_Relay, (uint8_t)Idx, 255, (tmpState == 1) ? true : false, 0, name);
1280 Idx = -1;
1281 bHaveRelays = false;
1282 continue;
1283 }
1284 }
1285 break;
1286 }
1287 case DDEV_SmartDEN_Notifier:
1288 case DDEV_SmartDEN_Logger: {
1289 bool bHaveDigitalInput = false;
1290 bool bHaveAnalogInput = false;
1291 bool bHaveTemperatureInput = false;
1292 for (ii = 1; ii < (int)results.size(); ii++)
1293 {
1294 tmpstr = stdstring_trim(results[ii]);
1295
1296 if (Idx == -1) {
1297 if (!bHaveDigitalInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_DI_DEF)) != -1))
1298 {
1299 bHaveDigitalInput = true;
1300 continue;
1301 }
1302
1303 if (!bHaveAnalogInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_AI_DEF)) != -1))
1304 {
1305 bHaveAnalogInput = true;
1306 continue;
1307 }
1308
1309 if (!bHaveTemperatureInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_TI_DEF)) != -1))
1310 {
1311 bHaveTemperatureInput = true;
1312 continue;
1313 }
1314 }
1315
1316 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1317 name = tmpName;
1318 continue;
1319 }
1320
1321 if (bHaveDigitalInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1322 {
1323 SendSwitch(DIOType_DI, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, "Digital Input " + std::to_string(Idx) + " (" + name + ")");
1324
1325 //Check if there is counter
1326 tmpstr = stdstring_trim(results[ii + 1]);
1327 if ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_COUNT_DEF)) != -1)
1328 {
1329 SendDenkoviTextSensor(DIOType_TXT, Idx + 8, 255, DenkoviGetStrParameter(tmpstr, DAE_COUNT_DEF), "Digital Input Counter " + std::to_string(Idx) + " (" + name + ")");
1330 }
1331 Idx = -1;
1332 bHaveDigitalInput = false;
1333 continue;
1334 }
1335
1336 if (bHaveAnalogInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1337 {
1338 SendCustomSensor(Idx + 8, 1, 255, static_cast<float>(tmpValue), "Analog Input " + std::to_string(Idx) + " (" + name + ")", "");
1339
1340 //Check if there is sclaed value
1341 tmpstr = stdstring_trim(results[ii + 1]);
1342 if ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_MEASURE_DEF)) != "")
1343 {
1344 std::vector<std::string> vMeasure;
1345 StringSplit(tmpMeasure, " ", vMeasure);
1346 if (vMeasure.size() == 2)
1347 {
1348 SendCustomSensor(Idx, 1, 255, static_cast<float>(atof(vMeasure[0].c_str())), "Analog Input Scaled " + std::to_string(Idx) + " (" + name + ")", vMeasure[1]);
1349 }
1350 }
1351 Idx = -1;
1352 bHaveAnalogInput = false;
1353 continue;
1354 }
1355
1356 if (bHaveTemperatureInput && (Idx != -1) && ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_VALUE_DEF)) != ""))
1357 {
1358 name = "Temperature Input " + std::to_string(Idx) + " (" + name + ")";
1359 std::vector<std::string> vMeasure;
1360 StringSplit(tmpMeasure, " ", vMeasure);
1361
1362 if ((tmpMeasure.find("---") == std::string::npos))
1363 {
1364 tmpTiValue = static_cast<float>(atof(tmpMeasure.c_str()));
1365
1366 if (tmpMeasure[tmpMeasure.size() - 1] == -119)//Check if F is found
1367 tmpTiValue = (float)ConvertToCelsius((double)tmpTiValue);
1368 }
1369 else
1370 tmpTiValue = 0;
1371
1372 SendTempSensor(Idx, 255, tmpTiValue, name);
1373 Idx = -1;
1374 bHaveTemperatureInput = false;
1375 continue;
1376 }
1377 }
1378 break;
1379 }
1380 case DDEV_SmartDEN_IP_32_In: {
1381 bool bHaveDigitalInput = false;
1382 bool bHaveAnalogInput = false;
1383 bool bHaveTemperatureInput = false;
1384 for (ii = 1; ii < (int)results.size(); ii++)
1385 {
1386 tmpstr = stdstring_trim(results[ii]);
1387
1388 if (Idx == -1) {
1389 if (!bHaveDigitalInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_DI_DEF)) != -1))
1390 {
1391 bHaveDigitalInput = true;
1392 continue;
1393 }
1394
1395 if (!bHaveAnalogInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_AI_DEF)) != -1))
1396 {
1397 bHaveAnalogInput = true;
1398 continue;
1399 }
1400
1401 if (!bHaveTemperatureInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_TI_DEF)) != -1))
1402 {
1403 bHaveTemperatureInput = true;
1404 continue;
1405 }
1406 }
1407
1408 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1409 name = tmpName;
1410 continue;
1411 }
1412
1413 if (bHaveDigitalInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1414 {
1415 SendSwitch(DIOType_DI, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, "Digital Input " + std::to_string(Idx) + " (" + name + ")");
1416
1417 //Check if there is counter
1418 tmpstr = stdstring_trim(results[ii + 1]);
1419 if ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_COUNT_DEF)) != -1)
1420 {
1421 SendDenkoviTextSensor(DIOType_TXT, Idx + 8, 255, DenkoviGetStrParameter(tmpstr, DAE_COUNT_DEF), "Digital Input Counter " + std::to_string(Idx) + " (" + name + ")");
1422 }
1423 Idx = -1;
1424 bHaveDigitalInput = false;
1425 continue;
1426 }
1427
1428 if (bHaveAnalogInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1429 {
1430 SendCustomSensor(Idx+8, 1, 255, static_cast<float>(tmpValue), "Analog Input " + std::to_string(Idx) + " (" + name + ")", "");
1431
1432 //Check if there is sclaed value
1433 tmpstr = stdstring_trim(results[ii + 1]);
1434 if ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_MEASURE_DEF)) != "")
1435 {
1436 std::vector<std::string> vMeasure;
1437 StringSplit(tmpMeasure, " ", vMeasure);
1438 if (vMeasure.size() == 2)
1439 {
1440 SendCustomSensor(Idx, 1, 255, static_cast<float>(atof(vMeasure[0].c_str())), "Analog Input Scaled " + std::to_string(Idx) + " (" + name + ")", vMeasure[1]);
1441 }
1442 }
1443 Idx = -1;
1444 bHaveAnalogInput = false;
1445 continue;
1446 }
1447 if (bHaveTemperatureInput && (Idx != -1) && ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_VALUE_DEF)) != ""))
1448 {
1449 name = "Temperature Input " + std::to_string(Idx) + " (" + name + ")";
1450 std::vector<std::string> vMeasure;
1451 StringSplit(tmpMeasure, " ", vMeasure);
1452
1453 if ((tmpMeasure.find("---") == std::string::npos))
1454 {
1455 tmpTiValue = static_cast<float>(atof(tmpMeasure.c_str()));
1456
1457 if (tmpMeasure[tmpMeasure.size() - 1] == -119)//Check if F is found
1458 tmpTiValue = (float)ConvertToCelsius((double)tmpTiValue);
1459 }
1460 else
1461 tmpTiValue = 0;
1462
1463 SendTempSensor(Idx, 255, tmpTiValue, name);
1464 Idx = -1;
1465 bHaveTemperatureInput = false;
1466 continue;
1467 }
1468 }
1469 break;
1470 }
1471 case DDEV_SmartDEN_PLC:
1472 case DDEV_SmartDEN_IP_Maxi: {//has DI, AO, AI, Relays
1473 bool bHaveDigitalInput = false;
1474 bool bHaveAnalogOutput = false;
1475 bool bHaveAnalogInput = false;
1476 bool bHaveRelay = false;
1477 for (ii = 1; ii < (int)results.size(); ii++)
1478 {
1479 tmpstr = stdstring_trim(results[ii]);
1480
1481 if (Idx == -1) {
1482 if (!bHaveDigitalInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_DI_DEF)) != -1))
1483 {
1484 bHaveDigitalInput = true;
1485 continue;
1486 }
1487
1488 if (!bHaveAnalogInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_AI_DEF)) != -1))
1489 {
1490 bHaveAnalogInput = true;
1491 continue;
1492 }
1493
1494 if (!bHaveAnalogOutput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_AO_DEF)) != -1))
1495 {
1496 bHaveAnalogOutput = true;
1497 continue;
1498 }
1499
1500 if (!bHaveRelay && ((Idx = DenkoviCheckForIO(tmpstr, DAE_RELAY_DEF)) != -1))
1501 {
1502 bHaveRelay = true;
1503 continue;
1504 }
1505 }
1506
1507 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1508 name = tmpName;
1509 continue;
1510 }
1511
1512 if (bHaveDigitalInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1513 { //Value
1514 name = "Digital Input " + std::to_string(Idx) + " (" + name + ")";
1515 SendSwitch(DIOType_DI, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, name);
1516 //Counter
1517 tmp_counter = stdstring_trim(results[ii+1]);
1518 SendDenkoviTextSensor(DIOType_TXT, Idx + 8, 255, DenkoviGetStrParameter(tmp_counter, DAE_COUNT_DEF), name + " Counter");
1519 Idx = -1;
1520 bHaveDigitalInput = false;
1521 continue;
1522 }
1523
1524
1525 if (bHaveAnalogInput && (Idx != -1) && ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_MEASURE_DEF)) != ""))
1526 {
1527 std::vector<std::string> vMeasure;
1528 StringSplit(tmpMeasure, " ", vMeasure);
1529 if (Idx <= 4)
1530 {
1531 //scaled value
1532 SendCustomSensor(Idx, DIOType_AI, 255, static_cast<float>(atof(vMeasure[0].c_str())), "Analog Input Scaled " + std::to_string(Idx) + " (" + name + ")", vMeasure[1]);
1533 //raw value
1534 tmp_adc_raw_value = stdstring_trim(results[ii-1]);
1535 SendCustomSensor(Idx+8, DIOType_AI, 255, DenkoviGetFloatParameter(tmp_adc_raw_value, DAE_VALUE_DEF), "Analog Input Raw " + std::to_string(Idx) + " (" + name + ")","");
1536
1537 }
1538 else {
1539 name = "Analog Input " + std::to_string(Idx) + " (" + name + ")";
1540 if (vMeasure.size() == 2) {
1541 tmpTiValue = static_cast<float>(atof(vMeasure[0].c_str()));
1542 if (vMeasure[1] == "degF")
1543 tmpTiValue = (float)ConvertToCelsius((double)tmpTiValue);
1544 SendTempSensor(Idx, 255, tmpTiValue, name);
1545 }
1546 else
1547 SendTempSensor(Idx, 255, NAN, name);
1548 }
1549 Idx = -1;
1550 bHaveAnalogInput = false;
1551 continue;
1552 }
1553
1554 if (bHaveRelay && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1555 {
1556 name = "Relay " + std::to_string(Idx) + " (" + name + ")";
1557 SendSwitch(DIOType_Relay, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, name);
1558 Idx = -1;
1559 bHaveRelay = false;
1560 continue;
1561 }
1562
1563 if (bHaveAnalogOutput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1564 {
1565 name = "Analog Output " + std::to_string(Idx) + " (" + name + ")";
1566 double val = (100 * tmpValue) / 1023;
1567 SendGeneralSwitch(DIOType_AO, Idx, 255, (tmpValue > 0) ? true : false, (uint8_t)val, name);
1568 Idx = -1;
1569 bHaveAnalogOutput = false;
1570 continue;
1571 }
1572 }
1573 break;
1574 }
1575 case DDEV_DAEnet_IP4: {//has DI, DO, AI, PWM
1576 bool bHaveDigitalInput = false;
1577 bool bHaveDigitalOutput = false;
1578 bool bHaveAnalogInput = false;
1579 bool bHavePWM = false;
1580 for (ii = 1; ii < (int)results.size(); ii++)
1581 {
1582 tmpstr = stdstring_trim(results[ii]);
1583
1584 if (Idx == -1) {
1585 if (!bHaveDigitalInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_DI_DEF)) != -1))
1586 {
1587 bHaveDigitalInput = true;
1588 continue;
1589 }
1590
1591 if (!bHaveAnalogInput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_AI_DEF)) != -1))
1592 {
1593 bHaveAnalogInput = true;
1594 continue;
1595 }
1596
1597 if (!bHaveDigitalOutput && ((Idx = DenkoviCheckForIO(tmpstr, DAE_OUT_DEF)) != -1))
1598 {
1599 bHaveDigitalOutput = true;
1600 continue;
1601 }
1602
1603 if (!bHavePWM && ((Idx = DenkoviCheckForIO(tmpstr, DAE_PWM_DEF)) != -1))
1604 {
1605 bHavePWM = true;
1606 continue;
1607 }
1608 }
1609
1610 if ((tmpName = DenkoviGetStrParameter(tmpstr, DAE_NAME_DEF)) != "") {
1611 name = tmpName;
1612 continue;
1613 }
1614
1615
1616 if (bHaveDigitalInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1617 {
1618 SendSwitch(DIOType_DI, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, "Digital Input " + std::to_string(Idx) + " (" + name + ")");
1619
1620 //Check if there is counter
1621 tmpstr = stdstring_trim(results[ii + 1]);
1622 if ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_COUNT_DEF)) != -1)
1623 {
1624 SendDenkoviTextSensor(DIOType_TXT, Idx + 8, 255, DenkoviGetStrParameter(tmpstr, DAE_COUNT_DEF), "Digital Input Counter " + std::to_string(Idx) + " (" + name + ")");
1625 }
1626 Idx = -1;
1627 bHaveDigitalInput = false;
1628 continue;
1629 }
1630
1631 if (bHaveAnalogInput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1632 {
1633 SendCustomSensor(Idx + 8, 1, 255, static_cast<float>(tmpValue), "Analog Input " + std::to_string(Idx) + " (" + name + ")", "");
1634
1635 //Check if there is sclaed value
1636 tmpstr = stdstring_trim(results[ii + 1]);
1637 if ((tmpMeasure = DenkoviGetStrParameter(tmpstr, DAE_MEASURE_DEF)) != "")
1638 {
1639 std::vector<std::string> vMeasure;
1640 StringSplit(tmpMeasure, " ", vMeasure);
1641 if (vMeasure.size() == 2)
1642 {
1643 SendCustomSensor(Idx, 1, 255, static_cast<float>(atof(vMeasure[0].c_str())), "Analog Input Scaled " + std::to_string(Idx) + " (" + name + ")", vMeasure[1]);
1644 }
1645 }
1646 Idx = -1;
1647 bHaveAnalogInput = false;
1648 continue;
1649 }
1650
1651 if (bHaveDigitalOutput && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1652 {
1653 name = "Digital Output " + std::to_string(Idx) + " (" + name + ")";
1654 SendSwitch(DIOType_DO, (uint8_t)Idx, 255, (tmpValue == 1) ? true : false, 0, name);
1655 Idx = -1;
1656 bHaveDigitalOutput = false;
1657 continue;
1658 }
1659
1660 if (bHavePWM && (Idx != -1) && ((tmpValue = DenkoviGetIntParameter(tmpstr, DAE_VALUE_DEF)) != -1))
1661 {
1662 name = "PWM " + std::to_string(Idx) + " (" + name + ")";
1663 SendGeneralSwitch(DIOType_PWM, Idx, 255, (tmpValue > 0) ? true : false, (uint8_t)tmpValue, name);
1664 Idx = -1;
1665 bHavePWM = false;
1666 continue;
1667 }
1668 }
1669 break;
1670 }
1671 }
1672 }
1673