EL_dev_arduino 2.2.1
読み取り中…
検索中…
一致する文字列を見つけられません
/Users/sugimura/EL_dev_arduino/EL.cpp
[詳解]
1
8#include "ELOBJ.h"
9#include "EL.h"
10
19EL::EL(WiFiUDP &udp, byte eoj0, byte eoj1, byte eoj2)
20{
21 _udp = &udp;
22 _eoj[0] = eoj0;
23 _eoj[1] = eoj1;
24 _eoj[2] = eoj2;
25
27 memset(_sBuffer, 0, EL_BUFFER_SIZE);
28 memset(_rBuffer, 0, EL_BUFFER_SIZE);
29
30 _multi = IPAddress(224, 0, 23, 0);
31
32 _broad[0] = 192;
33 _broad[1] = 168;
34 _broad[2] = 1;
35 _broad[3] = 255;
36
37 deviceCount = 1;
39 _eojs = new byte[deviceCount * sizeof(byte[3])];
40 _eojs[0] = eoj0;
41 _eojs[1] = eoj1;
42 _eojs[2] = eoj2;
43}
44
45// 複数のオブジェクトをサポートする。
46EL::EL(WiFiUDP &udp, byte eoj[][3], int count)
47{
48 _udp = &udp;
49
50 deviceCount = count;
51 _eojs = new byte[deviceCount * sizeof(byte[3])];
53 for (int i = 0; i < deviceCount; i++)
54 {
55 _eojs[i * 3 + 0] = eoj[i][0];
56 _eojs[i * 3 + 1] = eoj[i][1];
57 _eojs[i * 3 + 2] = eoj[i][2];
58 }
59
61 memset(_sBuffer, 0, EL_BUFFER_SIZE);
62 memset(_rBuffer, 0, EL_BUFFER_SIZE);
63
64 _multi = IPAddress(224, 0, 23, 0);
65
66 _broad[0] = 192;
67 _broad[1] = 168;
68 _broad[2] = 1;
69 _broad[3] = 255;
70}
71
72void EL::begin(void)
73{
74 Serial.printf("deviceCount: %d", deviceCount);
75 Serial.println();
76 for (int i = 0; i < deviceCount; i++)
77 {
78 Serial.printf("eojs[%d] = %02x%02x%02x", i, *(_eojs + i * 3 + 0), *(_eojs + i * 3 + 1), *(_eojs + i * 3 + 2));
79 Serial.println();
80 }
81
82 // udp
83 if (_udp->begin(EL_PORT))
84 {
85 Serial.println("EL.udp.begin successful.");
86 }
87 else
88 {
89 Serial.println("Reseiver udp.begin failed."); // localPort
90 }
91
92 if (_udp->beginMulticast(_multi, EL_PORT))
93 {
94 Serial.println("EL.udp.beginMulticast successful.");
95 }
96 else
97 {
98 Serial.println("Reseiver EL.udp.beginMulticast failed."); // localPort
99 }
100
101 // profile object
102 profile[0x80] = new byte[2]{0x01, 0x30}; // power
103 profile[0x81] = new byte[2]{0x01, 0x00}; // position
104 profile[0x82] = new byte[5]{0x04, 0x01, 0x0a, 0x01, 0x00}; // Ver 1.10 (type 1)
105 profile[0x83] = new byte[19]{0x12, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // identification number
106 profile[0x88] = new byte[4]{0x01, 0x42}; // error status
107 profile[0x8a] = new byte[4]{0x03, 0x00, 0x00, 0x77}; // maker KAIT
108 profile[0x9d] = new byte[3]{0x02, 0x01, 0x80}; // inf property map
109 profile[0x9e] = new byte[3]{0x02, 0x01, 0x80}; // set property map
110 profile[0x9f] = new byte[16]{0x0f, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x88, 0x8a, 0x9d, 0x9e, 0x9f, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7}; // get property map
111 profile[0xd3] = new byte[4]{0x03, 0x00, 0x00, byte(deviceCount)}; // total instance number
112 profile[0xd4] = new byte[3]{0x02, 0x00, byte(deviceCount + 1)}; // total class number
113 profile[0xd5] = new byte[2 + deviceCount * sizeof(byte[3])]{byte(1 + deviceCount * 3), byte(deviceCount)}; // obj list
114 profile[0xd6] = new byte[2 + deviceCount * sizeof(byte[3])]{byte(1 + deviceCount * 3), byte(deviceCount)}; // obj list
115 profile[0xd7] = new byte[2 + deviceCount * sizeof(byte[2])]{byte(1 + deviceCount * 2), byte(deviceCount)}; // class list
116 for (int i = 0; i < deviceCount; i++)
117 {
118 memcpy(&profile[0xd5][2 + i * sizeof(byte[3])], &_eojs[i * sizeof(byte[3])], sizeof(byte[3]));
119 memcpy(&profile[0xd6][2 + i * sizeof(byte[3])], &_eojs[i * sizeof(byte[3])], sizeof(byte[3]));
120 memcpy(&profile[0xd7][2 + i * sizeof(byte[2])], &_eojs[i * sizeof(byte[3])], sizeof(byte[2]));
121 }
122
123 // device object
124 details[0x80] = new byte[2]{0x01, 0x30}; // power
125 details[0x81] = new byte[2]{0x01, 0x00}; // position
126 details[0x82] = new byte[5]{0x04, 0x00, 0x00, 0x4b, 0x00}; // release K
127 details[0x83] = new byte[19]{0x12, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // identification number
128 details[0x88] = new byte[4]{0x01, 0x42}; // error status
129 details[0x8a] = new byte[4]{0x03, 0x00, 0x00, 0x77}; // maker KAIT
130 details[0x9d] = new byte[4]{0x03, 0x02, 0x80, 0xd6}; // inf property map
131 details[0x9e] = new byte[3]{0x02, 0x01, 0xe0}; // set property map
132 details[0x9f] = new byte[11]{0x0a, 0x09, 0x80, 0x81, 0x82, 0x83, 0x88, 0x8a, 0x9d, 0x9e, 0x9f}; // get property map
133
135}
136
138// details change
139void EL::update(const byte epc, byte pdcedt[])
140{
141 details.SetPDCEDT(epc, pdcedt); // power
142}
143
144byte *EL::at(const byte epc)
145{
146 return details.GetPDCEDT(epc);
147}
148
149void EL::update(const int devId, const byte epc, byte pdcedt[])
150{
151 if (devId < deviceCount)
152 devices[devId].SetPDCEDT(epc, pdcedt); // power
153}
154
155byte *EL::at(const int devId, const byte epc)
156{
157 if (devId < deviceCount)
158 return devices[devId].GetPDCEDT(epc);
159 else
160 return nullptr;
161}
162
164// sender
165
166// ブロードキャストによる送信
167void EL::sendBroad(byte sBuffer[], int size)
168{
169 if (_udp->beginPacket(_broad, EL_PORT))
170 {
171 // Serial.println("UDP beginPacket(B) Successful.");
172 _udp->write(sBuffer, size);
173 }
174
175 if (_udp->endPacket())
176 {
177 // Serial.println("UDP endPacket(B) Successful.");
178 }
179 else
180 {
181 Serial.println("UDP endPacket(B) failed.");
182 }
183}
184
185// マルチと見せかけてブロードキャストによる送信
186// このようにしておくとArduinoがマルチ対応したときに互換性を保てるハズ
187void EL::sendMulti(byte sBuffer[], int size)
188{
189 // sendBroad(sBuffer, size);
190
191 if (_udp->beginMulticastPacket())
192 {
193 // Serial.println("UDP beginPacket(B) Successful.");
194 _udp->write(sBuffer, size);
195 }
196
197 if (_udp->endPacket())
198 {
199 // Serial.println("UDP endPacket(B) Successful.");
200 }
201 else
202 {
203 Serial.println("UDP endPacket(M) failed.");
204 }
205}
206
207// OPC一個用のマルチキャスト関数(変なミスが少なくなるはず)
208void EL::sendMultiOPC1(const byte *tid, const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
209{
210 _sBuffer[EL_EHD1] = 0x10;
211 _sBuffer[EL_EHD2] = 0x81;
212 _sBuffer[EL_TID] = tid[0];
213 _sBuffer[EL_TID + 1] = tid[1];
214 _sBuffer[EL_SEOJ] = seoj[0];
215 _sBuffer[EL_SEOJ + 1] = seoj[1];
216 _sBuffer[EL_SEOJ + 2] = seoj[2];
217 _sBuffer[EL_DEOJ] = deoj[0];
218 _sBuffer[EL_DEOJ + 1] = deoj[1];
219 _sBuffer[EL_DEOJ + 2] = deoj[2];
220 _sBuffer[EL_ESV] = esv;
221 _sBuffer[EL_OPC] = 0x01;
222 _sBuffer[EL_EPC] = epc;
223
224 if (pdcedt != nullptr)
225 {
226 memcpy(&_sBuffer[EL_PDC], pdcedt, pdcedt[0] + 1); // size = pcd + edt
228 }
229 else
230 {
231 _sBuffer[EL_PDC] = 0x00;
233 }
235
236#ifdef EL_DEBUG
237 Serial.print("sendMultiOPC1 packet: ");
238 for (int i = 0; i < _sendPacketSize; i += 1)
239 {
240 Serial.print(_sBuffer[i], HEX);
241 Serial.print(" ");
242 }
243 Serial.println(".");
244#endif
245}
246
247// OPC一個用のマルチキャスト関数(変なミスが少なくなるはず)
248void EL::sendMultiOPC1(const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
249{
250 const byte tid[] = {0x00, 0x00};
251 sendMultiOPC1(tid, seoj, deoj, esv, epc, pdcedt);
252}
253
254// OPC一個用のマルチキャスト関数(変なミスが少なくなるはず)
255void EL::sendMultiOPC1(const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
256{
257 const byte tid[] = {0x00, 0x00};
258 sendMultiOPC1(tid, _eoj, deoj, esv, epc, pdcedt);
259}
260void EL::sendMultiOPC1(const int devId, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
261{
262 if (devId < deviceCount)
263 {
264 const byte tid[] = {0x00, 0x00};
265 const byte seoj[] = {
266 _eojs[devId * 3 + 0],
267 _eojs[devId * 3 + 1],
268 _eojs[devId * 3 + 2],
269 };
270 sendMultiOPC1(tid, seoj, deoj, esv, epc, pdcedt);
271 }
272}
273
274// IP指定による送信
275void EL::send(IPAddress toip, byte sBuffer[], int size)
276{
277
278 if (_udp->beginPacket(toip, EL_PORT))
279 {
280 // Serial.println("UDP beginPacket Successful.");
281 _udp->write(sBuffer, size);
282 }
283 else
284 {
285 Serial.println("UDP beginPacket failed.");
286 }
287
288 if (_udp->endPacket())
289 {
290 // Serial.println("UDP endPacket Successful.");
291 }
292 else
293 {
294 Serial.println("UDP endPacket failed.");
295 }
296}
297
298// OPC1指定による送信(SEOJも指定する,ほぼ内部関数)
299void EL::sendOPC1(const IPAddress toip, const byte *tid, const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
300{
301 _sBuffer[EL_EHD1] = 0x10;
302 _sBuffer[EL_EHD2] = 0x81;
303 _sBuffer[EL_TID] = tid[0];
304 _sBuffer[EL_TID + 1] = tid[1];
305 _sBuffer[EL_SEOJ] = seoj[0];
306 _sBuffer[EL_SEOJ + 1] = seoj[1];
307 _sBuffer[EL_SEOJ + 2] = seoj[2];
308 _sBuffer[EL_DEOJ] = deoj[0];
309 _sBuffer[EL_DEOJ + 1] = deoj[1];
310 _sBuffer[EL_DEOJ + 2] = deoj[2];
311 _sBuffer[EL_ESV] = esv;
312 _sBuffer[EL_OPC] = 0x01;
313 _sBuffer[EL_EPC] = epc;
314
315 if (pdcedt != nullptr)
316 {
317 memcpy(&_sBuffer[EL_PDC], pdcedt, pdcedt[0] + 1); // size = pcd + edt
319 }
320 else
321 {
322 _sBuffer[EL_PDC] = 0x00;
324 }
326
327#ifdef EL_DEBUG
328 Serial.print("sendOPC1 packet: ");
329 for (int i = 0; i < _sendPacketSize; i += 1)
330 {
331 Serial.print(_sBuffer[i], HEX);
332 Serial.print(" ");
333 }
334 Serial.println(".");
335#endif
336}
337
338// OPC1指定による送信(SEOJも指定する,ほぼ内部関数)
339void EL::sendOPC1(const IPAddress toip, const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
340{
341 const byte tid[] = {0x00, 0x00};
342 sendOPC1(toip, tid, seoj, deoj, esv, epc, pdcedt);
343}
344
345// OPC1指定による送信(SEOJは初期化時に指定したものを使う)
346void EL::sendOPC1(const IPAddress toip, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
347{
348 const byte tid[] = {0x00, 0x00};
349 sendOPC1(toip, tid, _eoj, deoj, esv, epc, pdcedt);
350}
351void EL::sendOPC1(const IPAddress toip, const int devId, const byte *deoj, const byte esv, const byte epc, const byte *pdcedt)
352{
353 const byte tid[] = {0x00, 0x00};
354 const byte seoj[] = {
355 _eojs[devId * 3 + 0],
356 _eojs[devId * 3 + 1],
357 _eojs[devId * 3 + 2],
358 };
359 sendOPC1(toip, tid, seoj, deoj, esv, epc, pdcedt);
360}
361
363// reseiver
365{
366 return _udp->parsePacket();
367}
368
369IPAddress EL::remoteIP(void)
370{
371 return _udp->remoteIP();
372}
373
374int EL::read(void)
375{
377
378 if (_readPacketSize)
379 {
380 _udp->read(_rBuffer, EL_BUFFER_SIZE); // 受け取った内容読み取り
381 }
382 return _readPacketSize;
383}
384
385// details
386void EL::returner(void)
387{
389 // 動作状態の変更
390 IPAddress remIP = remoteIP();
391 byte tid[] = {_rBuffer[EL_TID], _rBuffer[EL_TID + 1]};
392 byte seoj[] = {_rBuffer[EL_SEOJ], _rBuffer[EL_SEOJ + 1], _rBuffer[EL_SEOJ + 2]};
393 byte deoj[] = {_rBuffer[EL_DEOJ], _rBuffer[EL_DEOJ + 1], _rBuffer[EL_DEOJ + 2]};
394 const byte esv = _rBuffer[EL_ESV];
395 const byte epc = _rBuffer[EL_EPC];
396 byte *pdcedt = nullptr;
397
398 // 要求されたオブジェクトについて調べる
399 if (deoj[0] == 0x0e && deoj[1] == 0xf0)
400 { // 0ef0xx ならprofile object
401 deoj[2] = 0x01; // search等,インスタンス番号が0で送信される時があるので
402 pdcedt = profile[epc];
403 }
404 else if (deoj[0] == _eoj[0] && deoj[1] == _eoj[1])
405 { // 持っていないdevice objectは無視
406 pdcedt = details[epc]; // その他はdevice object
407 }
408 else
409 {
410 // pdcedt = details[0][epc]; // その他はdevice object
411 boolean noDevice = true;
412 for (int i = 0; i < deviceCount; i++)
413 {
414 const byte eoj0 = _eojs[i * sizeof(byte[3]) + 0];
415 const byte eoj1 = _eojs[i * sizeof(byte[3]) + 1];
416 Serial.printf("%d, esv:%02x, epc:%02x, eoj0:%02x == %02x, eoj1:%02x == %02x", i, esv, epc, eoj0, deoj[0], eoj1, deoj[1]);
417 Serial.println();
418 if (deoj[0] == eoj0 && deoj[1] == eoj1)
419 {
420 pdcedt = devices[i][epc];
421 noDevice = false;
422 Serial.printf("pdcedt: %p", pdcedt);
423 Serial.println();
424 break;
425 }
426 }
427 if (noDevice)
428 return;
429 }
430
431 // esvの要求にこたえる
432 switch (esv)
433 {
434 case EL_SETI:
435 break; // SetIは返信しない
437 // SETC, Get, INF_REQ は返信処理がある
438 case EL_SETC:
439 case EL_GET:
440 Serial.print("SETC or GET: ");
441 Serial.println(epc, HEX);
442
443 if (pdcedt)
444 { // そのEPCがある場合
445 // Serial.println("There is pdcedt.");
446 sendOPC1(remIP, tid, deoj, seoj, (esv + 0x10), epc, pdcedt);
447 }
448 else
449 {
450 // Serial.println("No pdcedt.");
451 sendOPC1(remIP, tid, deoj, seoj, (esv - 0x10), epc, nullptr);
452 }
453 break;
454
455 // ユニキャストへの返信ここまで,INFはマルチキャスト
456 case EL_INF_REQ:
457 Serial.print("INF_REQ: ");
458 Serial.println(epc, HEX);
459 if (pdcedt)
460 { // そのEPCがある場合、マルチキャスト
461 sendMultiOPC1(tid, deoj, seoj, (esv + 0x10), epc, pdcedt);
462 }
463 else
464 { // ない場合はエラーなのでユニキャストで返信
465 pdcedt[0] = 0x00;
466 sendOPC1(remIP, tid, deoj, seoj, (esv - 0x10), epc, nullptr);
467 }
468 break;
469 // INF_REQここまで
470
471 default: // 解釈不可能なESV
472 break;
473 }
474}
475// EL処理ここまで
476
477// byte[] を安全にdeleteする
478inline void EL::delPtr(byte ptr[])
479{
480 if (ptr != nullptr)
481 {
482 delete[] ptr;
483 ptr = nullptr;
484 }
485}
486
488// EOF
ECHONET Lite protocol for Arduino
#define EL_BUFFER_SIZE
Definition: EL.h:46
#define EL_EHD1
Definition: EL.h:20
#define EL_OPC
Definition: EL.h:26
#define EL_DEOJ
Definition: EL.h:24
#define EL_PDC
Definition: EL.h:28
#define EL_TID
Definition: EL.h:22
#define EL_SETC
Definition: EL.h:36
#define EL_SEOJ
Definition: EL.h:23
#define EL_GET
Definition: EL.h:37
#define EL_ESV
Definition: EL.h:25
#define EL_INF_REQ
Definition: EL.h:38
#define EL_SETI
Definition: EL.h:35
#define EL_EPC
Definition: EL.h:27
#define EL_PORT
ECHONET Lite port
Definition: EL.h:19
#define EL_EHD2
Definition: EL.h:21
#define EL_EDT
Definition: EL.h:29
Subclasses for ECHONET Lite protocol
#define byte
Definition: ELOBJ.h:16
WiFiUDP * _udp
Definition: EL.h:162
void update(const byte epc, byte pdcedt[])
Definition: EL.cpp:139
void begin(void)
Definition: EL.cpp:72
void delPtr(byte ptr[])
Definition: EL.cpp:478
void sendMulti(byte sBuffer[], int size)
Definition: EL.cpp:187
int parsePacket(void)
Definition: EL.cpp:364
void returner(void)
Definition: EL.cpp:386
int _sendPacketSize
Definition: EL.h:159
void send(IPAddress toip, byte sBuffer[], int size)
Definition: EL.cpp:275
ELOBJ profile
profile object (for specialist)
Definition: EL.h:169
void sendMultiOPC1(const byte *tid, const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *edt)
Definition: EL.cpp:208
byte _rBuffer[EL_BUFFER_SIZE]
receive buffer
Definition: EL.h:172
byte _broad[4]
broadcast address
Definition: EL.h:156
byte * at(const byte epc)
Definition: EL.cpp:144
ELOBJ details
device object (for simple eoj)
Definition: EL.h:170
byte _sBuffer[EL_BUFFER_SIZE]
send buffer
Definition: EL.h:161
byte * _eojs
for multi eojs obj
Definition: EL.h:158
ELOBJ * devices
device objects (for multi eoj)
Definition: EL.h:171
void sendOPC1(const IPAddress toip, const byte *tid, const byte *seoj, const byte *deoj, const byte esv, const byte epc, const byte *edt)
Definition: EL.cpp:299
int _readPacketSize
Definition: EL.h:160
int read()
Definition: EL.cpp:374
EL(WiFiUDP &udp, byte eoj0, byte eoj1, byte eoj2)
オブジェクトを一つだけサポートする場合のコンストラクタ
Definition: EL.cpp:19
int deviceCount
Definition: EL.h:163
void sendBroad(byte sBuffer[], int size)
Definition: EL.cpp:167
IPAddress _multi
multicast address
Definition: EL.h:155
byte _eoj[3]
for simple eoj obj
Definition: EL.h:157
IPAddress remoteIP(void)
Definition: EL.cpp:369
EL Object
Definition: ELOBJ.h:52
const PDCEDT SetPDCEDT(const byte epc, const PDCEDT pdcedt)
Definition: ELOBJ.cpp:136
void printAll() const
Definition: ELOBJ.cpp:169
const PDCEDT GetPDCEDT(const byte epc) const
Definition: ELOBJ.cpp:129
byte * pdcedt
Definition: main.cpp:56