-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathZIGBEE_PAIR.ino
172 lines (150 loc) · 6.7 KB
/
ZIGBEE_PAIR.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
void pairOnActionflag() {
//start with setup the coordinator
//can we pair when the radio is up for normal operation
char term[20];
sprintf(term, "inverter %d" , Inv_Prop[iKeuze].invSerial);
Update_Log(4, term);
if( !coordinator(false) ) {
//term="pairing failed, zb down";
Update_Log(4, "failed");
consoleOut("pairing failed, zb down");
return;
}
consoleOut("trying pair inv " + String(iKeuze));
// now that we know that the radio is up, we don't need to test this in the pairing routine
if( pairing(iKeuze) ) {
//DebugPrintln("pairing success, saving configfile");
String term = "success, inverter got id " + String(Inv_Prop[iKeuze].invID);
Update_Log(2, "success");
consoleOut(term);
//} else if(diagNose==2){ws.textAll(term);}
} else {
strncpy(Inv_Prop[iKeuze].invID, "0000", 6);
String term = "failed, inverter got id " + String(Inv_Prop[iKeuze].invID);
Update_Log(4, "failed");
consoleOut(term);
}
String bestand = "/Inv_Prop" + String(iKeuze) + ".str"; // /Inv_Prop0.str
writeStruct(bestand, iKeuze); // alles opslaan in SPIFFS
//after successfull pairing we issue the command for normal ops
sendNO();
checkCoordinator(); // updates the log
}
void handlePair(AsyncWebServerRequest *request) {
strncpy(Inv_Prop[iKeuze].invID, "1111", 4); // this value makes the pairing page visable
actionFlag = 60; // we do this because no delay is alowed within an async request
toSend=FPSTR(WAIT_PAIR);
toSend.replace("{#}", String(iKeuze));
request->send(200, "text/html", toSend); //send the html code to the client
}
bool pairing(int which) {
//the pairing process consistst of 4 commands sent to the coordinator
char pairCmd[254]={0};
char s_d[250]={0};
char ecu_id_reverse[13];
ECU_REVERSE().toCharArray(ecu_id_reverse, 13);
char ecu_short[5]={0};
strncat(ecu_short, ECU_ID + 2, 2); // D8A3011B9780 should be A3D8
strncat(ecu_short, ECU_ID, 2);
//ecu_short[5]='\0'; no need for as strncat terminates with \0
String term = "";
bool success=false;
for ( int y = 0; y < 4; y++) {
switch (y) {
case 0:// command 0
// build command 0 this is "24020FFFFFFFFFFFFFFFFF14FFFF14" + "0D0200000F1100" + String(invSerial) + "FFFF10FFFF" + ecu_id_reverse
snprintf(pairCmd, sizeof(pairCmd), "24020FFFFFFFFFFFFFFFFF14FFFF140D0200000F1100%sFFFF10FFFF%s", Inv_Prop[which].invSerial , ecu_id_reverse);
break;
case 1:
// build command 1 this is "24020FFFFFFFFFFFFFFFFF14FFFF14" + "0C0201000F0600" + inv serial,
snprintf(pairCmd, sizeof(pairCmd), "24020FFFFFFFFFFFFFFFFF14FFFF140C0201000F0600%s", Inv_Prop[which].invSerial );
break;
case 2:
// build command 2 this is "24020FFFFFFFFFFFFFFFFF14FFFF14" + "0F0102000F1100" + invSerial + short ecu_id_reverse, + 10FFF + ecu_id_reverse
snprintf(pairCmd, sizeof(pairCmd), "24020FFFFFFFFFFFFFFFFF14FFFF140F0102000F1100%s%s10FFFF%s", Inv_Prop[which].invSerial, ecu_short, ecu_id_reverse);
break;
case 3:
// now build command 3 this is "24020FFFFFFFFFFFFFFFFF14FFFF14" + "010103000F0600" + ecu_id_reverse,
snprintf(pairCmd, sizeof(pairCmd), "24020FFFFFFFFFFFFFFFFF14FFFF14010103000F0600%s", ecu_id_reverse);
}
delayMicroseconds(250);
// send
term = "pair command " + String(y) + " = " + String(pairCmd);
consoleOut(term);
//else if(diagNose == 2) ws.textAll(term);
sendZB(pairCmd);
delay(1500); // give the inverter the chance to answer
//check if anything was received
// after sending cmd 1 or 2 we can expect an answer to decode
// we let decodePairMessage retrieve the answer then.
// the answers on cmd0 or cmd3 are flushed
if(y == 1 || y == 2) {
// if y 1 or 2 we catch and decode the answer
if ( decodePairMessage(which) )
{
success = true; // if at least one of these 2 where true we had success
}
} else {
// if not y == 1 or y == 2 we waste the received message
readZB(s_d);
}
}
//now all 4 commands have been sent
if(success) {return true; } else { return false;} // when paired 0x103A
}
bool decodePairMessage(int which)
{
char messageToDecode[CC2530_MAX_SERIAL_BUFFER_SIZE] = {0};
char _CC2530_answer_string[] = "44810000";
char _noAnswerFromInverter[32] = "FE0164010064FE034480CD14011F";
char * result;
char temp[13];
char s_d[250]={0};
String term = "";
strcpy(messageToDecode, readZB(s_d));
//Serial.println("messageToDecode = " + String(messageToDecode));
consoleOut("decoding : " + String(messageToDecode));
if (readCounter == 0 || strlen(messageToDecode) < 6 ) // invalid message
{
consoleOut("no usable code, returning..");
messageToDecode[0]='\0';
return false;
}
// can we conclude that a valid pair answer cannot be less than 60 bytes
if (strlen(messageToDecode) > 222 || readCounter < 60 || strlen(messageToDecode) < 6)
{
//term = "no pairing code, returning...";
consoleOut(F("no valid pairing code, returning..."));
messageToDecode[0]='\0';
return false;
}
// the message is shorter but not too short so continueing
if (!strstr(messageToDecode, Inv_Prop[which].invSerial)) {
consoleOut("not found serialnr, returning");
//if(diagNose==1) Serial.println(term); else if(diagNose==2) ws.textAll(term);
messageToDecode[0]='\0';
return false;
}
if ( strstr(messageToDecode, Inv_Prop[which].invSerial) ) {
result = split(messageToDecode, Inv_Prop[which].invSerial);
}
consoleOut("result after 1st splitting = " + String(result));
// now we keep splitting as long as result contains the serial nr
while ( strstr(result, Inv_Prop[which].invSerial) )
{
result = split(result, Inv_Prop[which].invSerial);
}
consoleOut("result after splitting = " + String(result));
// result are the bytes behind the serialnr
// now we know that it is what we expect, a string right behind the last occurence of the serialnr
memset(&Inv_Prop[which].invID, 0, sizeof(Inv_Prop[which].invID)); //zero out the
delayMicroseconds(250);
strncpy(Inv_Prop[which].invID, result, 4); // take the 1st 4 bytes
term = "found invID = " + String(Inv_Prop[which].invID);
consoleOut(term);
// why is this? Can it get this value?
if ( String(Inv_Prop[which].invID) == "0000" ) {
return false;
}
return true;
}