thermferm/mqtt.c

branch
stable
changeset 601
44d41db09466
parent 598
363dc36d2450
child 602
ca795b871158
equal deleted inserted replaced
590:1ff1a95a7614 601:44d41db09466
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/ 21 *****************************************************************************/
22 22
23 #include "thermferm.h" 23 #include "thermferm.h"
24 #include "rdconfig.h" 24 #include "rdconfig.h"
25 #include "logger.h"
26 #include "devices.h" 25 #include "devices.h"
27 #include "xutil.h" 26 #include "xutil.h"
28 #include "mqtt.h" 27 #include "mqtt.h"
29 28
30 extern sys_config Config; 29 extern sys_config Config;
57 struct mosquitto *mosq = NULL; 56 struct mosquitto *mosq = NULL;
58 char *state = NULL; 57 char *state = NULL;
59 char my_hostname[256]; 58 char my_hostname[256];
60 59
61 60
61 #ifndef HAVE_WIRINGPI_H
62
63 /*
64 * Code from wiringPi written by Gordon Henderson.
65 * Copied here to have some sort of hardware detection without wiringPi.
66 */
67 const char *piModelNames [20] =
68 {
69 "Model A", // 0
70 "Model B", // 1
71 "Model A+", // 2
72 "Model B+", // 3
73 "Pi 2", // 4
74 "Alpha", // 5
75 "CM", // 6
76 "Unknown07", // 07
77 "Pi 3", // 08
78 "Pi Zero", // 09
79 "CM3", // 10
80 "Unknown11", // 11
81 "Pi Zero-W", // 12
82 "Pi 3B+", // 13
83 "Pi 3A+", // 14
84 "Unknown15", // 15
85 "CM3+", // 16
86 "Unknown17", // 17
87 "Unknown18", // 18
88 "Unknown19", // 19
89 };
90 const char *piRevisionNames [16] =
91 {
92 "00",
93 "01",
94 "02",
95 "03",
96 "04",
97 "05",
98 "06",
99 "07",
100 "08",
101 "09",
102 "10",
103 "11",
104 "12",
105 "13",
106 "14",
107 "15",
108 } ;
109 const char *piMakerNames [16] =
110 {
111 "Sony", // 0
112 "Egoman", // 1
113 "Embest", // 2
114 "Unknown", // 3
115 "Embest", // 4
116 "Unknown05", // 5
117 "Unknown06", // 6
118 "Unknown07", // 7
119 "Unknown08", // 8
120 "Unknown09", // 9
121 "Unknown10", // 10
122 "Unknown11", // 11
123 "Unknown12", // 12
124 "Unknown13", // 13
125 "Unknown14", // 14
126 "Unknown15", // 15
127 } ;
128 const int piMemorySize [8] =
129 {
130 256, // 0
131 512, // 1
132 1024, // 2
133 0, // 3
134 0, // 4
135 0, // 5
136 0, // 6
137 0, // 7
138 } ;
139
140 void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
141 {
142 FILE *cpuFd ;
143 char line [120] ;
144 char *c ;
145 unsigned int revision ;
146 int bRev, bType, bProc, bMfg, bMem, bWarranty ;
147
148 *model = -1; // Mark no info
149 if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) {
150 syslog(LOG_NOTICE, "Unable to open /proc/cpuinfo") ;
151 return;
152 }
153
154 while (fgets (line, 120, cpuFd) != NULL)
155 if (strncmp (line, "Revision", 8) == 0)
156 break ;
157
158 fclose (cpuFd) ;
159
160 if (strncmp (line, "Revision", 8) != 0) {
161 syslog(LOG_NOTICE, "No \"Revision\" line");
162 return;
163 }
164
165 // Chomp trailing CR/NL
166
167 for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
168 *c = 0 ;
169
170 if (debug)
171 fprintf(stdout, "piBoardId: Revision string: %s\n", line) ;
172
173 // Need to work out if it's using the new or old encoding scheme:
174
175 // Scan to the first character of the revision number
176
177 for (c = line ; *c ; ++c)
178 if (*c == ':')
179 break ;
180
181 if (*c != ':') {
182 syslog(LOG_NOTICE, "Bogus \"Revision\" line (no colon)") ;
183 return;
184 }
185
186 // Chomp spaces
187
188 ++c ;
189 while (isspace (*c))
190 ++c ;
191
192 if (!isxdigit (*c))
193 syslog(LOG_NOTICE, "Bogus \"Revision\" line (no hex digit at start of revision)") ;
194
195 revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x
196
197 // Check for new way:
198
199 if ((revision & (1 << 23)) != 0) { // New way
200 if (debug)
201 fprintf(stdout, "piBoardId: New Way: revision is: %08X\n", revision) ;
202
203 bRev = (revision & (0x0F << 0)) >> 0 ;
204 bType = (revision & (0xFF << 4)) >> 4 ;
205 bProc = (revision & (0x0F << 12)) >> 12 ; // Not used for now.
206 bMfg = (revision & (0x0F << 16)) >> 16 ;
207 bMem = (revision & (0x07 << 20)) >> 20 ;
208 bWarranty = (revision & (0x03 << 24)) != 0 ;
209
210 *model = bType ;
211 *rev = bRev ;
212 *mem = bMem ;
213 *maker = bMfg ;
214 *warranty = bWarranty ;
215
216 if (debug)
217 fprintf(stdout, "piBoardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d\n", bRev, bType, bProc, bMfg, bMem, bWarranty) ;
218 } else { // Old way
219 if (debug)
220 fprintf(stdout, "piBoardId: Old Way: revision is: %s\n", c) ;
221
222 if (!isdigit (*c)) {
223 syslog(LOG_NOTICE, "Bogus \"Revision\" line (no digit at start of revision)") ;
224 return;
225 }
226
227 // Make sure its long enough
228
229 if (strlen (c) < 4) {
230 syslog(LOG_NOTICE, "Bogus \"Revision\" line (not long enough)") ;
231 return;
232 }
233
234 // If longer than 4, we'll assume it's been overvolted
235
236 *warranty = strlen (c) > 4 ;
237
238 // Extract last 4 characters:
239
240 c = c + strlen (c) - 4 ;
241
242 // Fill out the replys as appropriate
243
244 /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
245 else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
246
247 else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
248 else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
249 else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
250
251 else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
252 else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; }
253 else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
254
255 else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
256 else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
257 else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
258
259 else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
260 else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
261 else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
262 else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
263 else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
264 else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
265 else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
266 else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
267
268 else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
269 else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
270 else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
271 else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
272
273 else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; }
274 }
275 }
276 #endif
277
278
62 279
63 char *payload_header(void) 280 char *payload_header(void)
64 { 281 {
65 char *tmp, buf[128]; 282 char *tmp, buf[128];
66 283
151 368
152 369
153 370
154 void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str) 371 void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str)
155 { 372 {
156 // syslog(LOG_NOTICE, "MQTT: %s", str); 373 // if (debug)
157 if (debug) 374 // fprintf(stdout, "MQTT: %s\n", str);
158 fprintf(stdout, "MQTT: %s\n", str);
159 } 375 }
160 376
161 377
162 378
163 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message) 379 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message)
236 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) { 452 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) {
237 if (unit->mode != i) { 453 if (unit->mode != i) {
238 unit->mqtt_flag |= MQTT_FLAG_DATA; 454 unit->mqtt_flag |= MQTT_FLAG_DATA;
239 /* Initialize log if the unit is turned on */ 455 /* Initialize log if the unit is turned on */
240 if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) { 456 if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) {
241 initlog(unit->product_code, unit->product_name);
242 unit->mqtt_flag |= MQTT_FLAG_BIRTH; 457 unit->mqtt_flag |= MQTT_FLAG_BIRTH;
243 } else if ((unit->mode != UNITMODE_OFF) && (i == UNITMODE_OFF)) { 458 } else if ((unit->mode != UNITMODE_OFF) && (i == UNITMODE_OFF)) {
244 unit->mqtt_flag |= MQTT_FLAG_DEATH; 459 unit->mqtt_flag |= MQTT_FLAG_DEATH;
245 } 460 }
246 if (i == UNITMODE_PROFILE) { 461 if (i == UNITMODE_PROFILE) {
440 } 655 }
441 free(cmd); 656 free(cmd);
442 cmd = NULL; 657 cmd = NULL;
443 } 658 }
444 } else if (json_object_object_get_ex(profile, "uuid", &profile1)) { 659 } else if (json_object_object_get_ex(profile, "uuid", &profile1)) {
445 // syslog(LOG_NOTICE, "profile new profile");
446 if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) { 660 if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) {
447 if (unit->profile_uuid) 661 if (unit->profile_uuid)
448 free(unit->profile_uuid); 662 free(unit->profile_uuid);
449 if (unit->profile_name) 663 if (unit->profile_name)
450 free(unit->profile_name); 664 free(unit->profile_name);
456 free(step); 670 free(step);
457 } 671 }
458 } 672 }
459 unit->profile_steps = NULL; 673 unit->profile_steps = NULL;
460 unit->profile_duration = unit->profile_totalsteps = 0; 674 unit->profile_duration = unit->profile_totalsteps = 0;
461 // syslog(LOG_NOTICE, "profile new profile: old cleared");
462
463 unit->profile_uuid = xstrcpy((char *)json_object_get_string(profile1)); 675 unit->profile_uuid = xstrcpy((char *)json_object_get_string(profile1));
464 if (json_object_object_get_ex(profile, "name", &val)) { 676 if (json_object_object_get_ex(profile, "name", &val)) {
465 unit->profile_name = xstrcpy((char *)json_object_get_string(val)); 677 unit->profile_name = xstrcpy((char *)json_object_get_string(val));
466 } 678 }
467 if (json_object_object_get_ex(profile, "inittemp", &setpoint)) { 679 if (json_object_object_get_ex(profile, "inittemp", &setpoint)) {
1172 void publishNData(bool birth, int flag) 1384 void publishNData(bool birth, int flag)
1173 { 1385 {
1174 char *topic = NULL, *payload = NULL, sidx[10], buf[64]; 1386 char *topic = NULL, *payload = NULL, sidx[10], buf[64];
1175 struct utsname ubuf; 1387 struct utsname ubuf;
1176 bool comma = false; 1388 bool comma = false;
1389 int model, rev, mem, maker, warranty;
1177 1390
1178 payload = payload_header(); 1391 payload = payload_header();
1179 payload = xstrcat(payload, (char *)"{"); 1392 payload = xstrcat(payload, (char *)"{");
1180 1393
1181 if (birth) { 1394 if (birth) {
1184 payload = xstrcat(payload, (char *)"\","); 1397 payload = xstrcat(payload, (char *)"\",");
1185 #ifdef HAVE_WIRINGPI_H 1398 #ifdef HAVE_WIRINGPI_H
1186 /* 1399 /*
1187 * Get the info from the WiringPi libary 1400 * Get the info from the WiringPi libary
1188 */ 1401 */
1189 int model, rev, mem, maker, warranty;
1190 piBoardId (&model, &rev, &mem, &maker, &warranty); 1402 piBoardId (&model, &rev, &mem, &maker, &warranty);
1191 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Raspberry Pi "); 1403 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Raspberry Pi ");
1192 payload = xstrcat(payload, (char *)piMakerNames[maker]); 1404 payload = xstrcat(payload, (char *)piMakerNames[maker]);
1193 payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\""); 1405 payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\"");
1194 payload = xstrcat(payload, (char *)piModelNames[model]); 1406 payload = xstrcat(payload, (char *)piModelNames[model]);
1195 payload = xstrcat(payload, (char *)" rev "); 1407 payload = xstrcat(payload, (char *)" rev ");
1196 payload = xstrcat(payload, (char *)piRevisionNames[rev]); 1408 payload = xstrcat(payload, (char *)piRevisionNames[rev]);
1197 payload = xstrcat(payload, (char *)"\""); 1409 payload = xstrcat(payload, (char *)"\"");
1198 #else 1410 #else
1199 if (uname(&ubuf) == 0) { 1411 /*
1412 * Get the info from the internal function
1413 */
1414 piBoardId (&model, &rev, &mem, &maker, &warranty);
1415 if (model != -1) {
1416 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Raspberry Pi ");
1417 payload = xstrcat(payload, (char *)piMakerNames[maker]);
1418 payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\"");
1419 payload = xstrcat(payload, (char *)piModelNames[model]);
1420 payload = xstrcat(payload, (char *)" rev ");
1421 payload = xstrcat(payload, (char *)piRevisionNames[rev]);
1422 payload = xstrcat(payload, (char *)"\"");
1423 } else if (uname(&ubuf) == 0) {
1200 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\""); 1424 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"");
1201 payload = xstrcat(payload, ubuf.machine); 1425 payload = xstrcat(payload, ubuf.machine);
1202 payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\"Unknown\""); 1426 payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\"Unknown\"");
1203 } else { 1427 } else {
1204 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Unknown\",\"hardwaremodel\":\"Unknown\""); 1428 payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Unknown\",\"hardwaremodel\":\"Unknown\"");

mercurial