157 |
159 |
158 |
160 |
159 |
161 |
160 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message) |
162 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message) |
161 { |
163 { |
162 char *message_type; |
164 char *message_type, *message_node, *message_alias; |
163 struct json_object *jobj, *metric, *val; |
165 units_list *unit; |
|
166 struct json_object *jobj, *metric, *val, *setpoint; |
164 time_t timestamp; |
167 time_t timestamp; |
165 int timediff; |
168 int timediff; |
166 |
169 |
167 if (message->payloadlen) { |
170 if (message->payloadlen) { |
168 /* |
171 /* |
169 * Process received commands |
172 * Process received commands |
170 */ |
173 */ |
171 strtok(message->topic, "/"); // Ignore mbv1.0 |
174 strtok(message->topic, "/"); // Ignore mbv1.0 |
172 strtok(NULL, "/"); // Ignore group_id |
175 strtok(NULL, "/"); // Ignore group_id |
173 message_type = strtok(NULL, "/"); |
176 message_type = strtok(NULL, "/"); |
|
177 message_node = strtok(NULL, "/\0"); |
|
178 message_alias = strtok(NULL, "\0"); |
174 |
179 |
175 jobj = json_tokener_parse(message->payload); |
180 jobj = json_tokener_parse(message->payload); |
176 if (json_object_object_get_ex(jobj, "timestamp", &val)) { |
181 if (json_object_object_get_ex(jobj, "timestamp", &val)) { |
177 timestamp = json_object_get_int(val); |
182 timestamp = json_object_get_int(val); |
178 timediff = (int)timestamp - time(NULL); |
183 timediff = (int)timestamp - time(NULL); |
197 syslog(LOG_NOTICE, "MQTT: `Node Control/Rebirth' command"); |
202 syslog(LOG_NOTICE, "MQTT: `Node Control/Rebirth' command"); |
198 publishNData(true, 0); |
203 publishNData(true, 0); |
199 publishDBirthAll(); |
204 publishDBirthAll(); |
200 return; |
205 return; |
201 } |
206 } |
|
207 } |
|
208 if ((strcmp(message_type, "DCMD") == 0) && message_node && message_alias) { |
|
209 syslog(LOG_NOTICE, "%s", (char *)json_object_get_string(metric)); |
|
210 for (unit = Config.units ; unit; unit = unit->next) { |
|
211 if (strcmp(unit->alias, message_alias) == 0) { |
|
212 syslog(LOG_NOTICE, "MQTT: DCMD for %s/%s", (char *)message_node, (char *)message_alias); |
|
213 if (json_object_object_get_ex(metric, "stage", &val)) { |
|
214 // syslog(LOG_NOTICE, "Change state %s", UNITSTAGE[unit->stage]); |
|
215 for (int i = 0; i < 4; i++) { |
|
216 if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) { |
|
217 if (unit->stage != i) { |
|
218 syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", message_alias, UNITSTAGE[i]); |
|
219 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
220 unit->stage = i; |
|
221 } |
|
222 break; |
|
223 } |
|
224 } |
|
225 } |
|
226 printf("start mode\n"); |
|
227 if (json_object_object_get_ex(metric, "mode", &val)) { |
|
228 for (int i = 0; i < 4; i++) { |
|
229 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) { |
|
230 if (unit->mode != i) { |
|
231 syslog(LOG_NOTICE, "DCMD change fermenter %s: mode to %s", message_alias, UNITMODE[i]); |
|
232 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
233 /* Initialize log if the unit is turned on */ |
|
234 if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) { |
|
235 initlog(unit->product_code, unit->product_name); |
|
236 unit->mqtt_flag |= MQTT_FLAG_BIRTH; |
|
237 } else if ((unit->mode != UNITMODE_OFF) && (i == UNITMODE_OFF)) { |
|
238 unit->mqtt_flag |= MQTT_FLAG_DEATH; |
|
239 } |
|
240 syslog(LOG_NOTICE, "Fermenter unit %s mode %s to %s", unit->uuid, UNITMODE[unit->mode], UNITMODE[i]); |
|
241 unit->mode = i; |
|
242 /* Allways turn everything off after a mode change */ |
|
243 unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0; |
|
244 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE; |
|
245 unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = 0; |
|
246 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; |
|
247 device_out(unit->heater_address, unit->heater_state); |
|
248 device_out(unit->cooler_address, unit->cooler_state); |
|
249 device_out(unit->fan_address, unit->fan_state); |
|
250 device_out(unit->light_address, unit->light_state); |
|
251 if (unit->mode == UNITMODE_PROFILE) { |
|
252 /* |
|
253 * Set a sane default until it will be overruled by the |
|
254 * main processing loop. |
|
255 */ |
|
256 unit->prof_target_lo = unit->prof_target_hi = 20.0; |
|
257 unit->prof_fridge_mode = 0; |
|
258 if (unit->profile) { |
|
259 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
260 } |
|
261 } |
|
262 } |
|
263 break; |
|
264 } |
|
265 } |
|
266 } |
|
267 printf("start setpoint\n"); |
|
268 if (json_object_object_get_ex(metric, "setpoint", &setpoint)) { |
|
269 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) { |
|
270 /* |
|
271 * Only set new setpoints if running as FRIDGE or in BEER mode. |
|
272 */ |
|
273 if (json_object_object_get_ex(setpoint, "low", &val)) { |
|
274 unit->PID_heat->SetP = json_object_get_double(val); |
|
275 } |
|
276 if (json_object_object_get_ex(setpoint, "high", &val)) { |
|
277 unit->PID_cool->SetP = json_object_get_double(val); |
|
278 } |
|
279 if (unit->mode == UNITMODE_FRIDGE) { |
|
280 unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); |
|
281 } else { |
|
282 unit->beer_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); |
|
283 } |
|
284 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
285 syslog(LOG_NOTICE, "DCMD change fermenter %s: setpoints %.1f %.1f", message_alias, unit->PID_heat->SetP, unit->PID_cool->SetP); |
|
286 } |
|
287 } |
|
288 printf("start heater\n"); |
|
289 if ((json_object_object_get_ex(metric, "heater", &setpoint)) && (unit->mode == UNITMODE_NONE)) { |
|
290 if (json_object_object_get_ex(setpoint, "state", &val)) { |
|
291 if (json_object_get_int(val) != unit->heater_state) { |
|
292 unit->heater_state = json_object_get_int(val); |
|
293 if (unit->heater_state) // Safety |
|
294 unit->cooler_state = 0; |
|
295 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
296 syslog(LOG_NOTICE, "DCMD change fermenter %s: heater_state to %d", message_alias, unit->heater_state); |
|
297 } |
|
298 } |
|
299 } |
|
300 if ((json_object_object_get_ex(metric, "cooler", &setpoint)) && (unit->mode == UNITMODE_NONE)) { |
|
301 if (json_object_object_get_ex(setpoint, "state", &val)) { |
|
302 if (json_object_get_int(val) != unit->cooler_state) { |
|
303 unit->cooler_state = json_object_get_int(val); |
|
304 if (unit->cooler_state) |
|
305 unit->heater_state = 0; |
|
306 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
307 syslog(LOG_NOTICE, "DCMD change fermenter %s: cooler_state to %d", message_alias, unit->cooler_state); |
|
308 } |
|
309 } |
|
310 } |
|
311 if ((json_object_object_get_ex(metric, "fan", &setpoint)) && (unit->mode == UNITMODE_NONE)) { |
|
312 if (json_object_object_get_ex(setpoint, "state", &val)) { |
|
313 if (json_object_get_int(val) != unit->fan_state) { |
|
314 unit->fan_state = json_object_get_int(val); |
|
315 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
316 syslog(LOG_NOTICE, "DCMD change fermenter %s: fan_state to %d", message_alias, unit->fan_state); |
|
317 } |
|
318 } |
|
319 } |
|
320 if ((json_object_object_get_ex(metric, "light", &setpoint)) && (unit->mode == UNITMODE_NONE)) { |
|
321 if (json_object_object_get_ex(setpoint, "state", &val)) { |
|
322 if (json_object_get_int(val) != unit->light_state) { |
|
323 unit->light_state = json_object_get_int(val); |
|
324 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
325 syslog(LOG_NOTICE, "DCMD change fermenter %s: light_state to %d", message_alias, unit->light_state); |
|
326 } |
|
327 } |
|
328 } |
|
329 printf("start product\n"); |
|
330 if ((json_object_object_get_ex(metric, "product", &setpoint)) && (unit->mode == UNITMODE_OFF)) { |
|
331 if (json_object_object_get_ex(setpoint, "code", &val)) { |
|
332 if (strcmp((char *)json_object_get_string(val), unit->product_code)) { |
|
333 free(unit->product_code); |
|
334 unit->product_code = xstrcpy((char *)json_object_get_string(val)); |
|
335 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
336 syslog(LOG_NOTICE, "DCMD change fermenter %s: product_code to `%s'", message_alias, unit->product_code); |
|
337 } |
|
338 } |
|
339 if (json_object_object_get_ex(setpoint, "name", &val)) { |
|
340 if (strcmp((char *)json_object_get_string(val), unit->product_name)) { |
|
341 free(unit->product_name); |
|
342 unit->product_name = xstrcpy((char *)json_object_get_string(val)); |
|
343 unit->mqtt_flag |= MQTT_FLAG_DATA; |
|
344 syslog(LOG_NOTICE, "DCMD change fermenter %s: product_name to `%s'", message_alias, unit->product_name); |
|
345 } |
|
346 } |
|
347 } |
|
348 } |
|
349 if (unit->mqtt_flag) { |
|
350 printf("do mqtt flag\n"); |
|
351 if (debug) |
|
352 fprintf(stdout, "flag value %d\n", unit->mqtt_flag); |
|
353 if (unit->mqtt_flag & MQTT_FLAG_BIRTH) { |
|
354 publishDBirth(unit); |
|
355 } else { |
|
356 publishDData(unit); |
|
357 } |
|
358 if (unit->mqtt_flag & MQTT_FLAG_DEATH) { |
|
359 publishDDeath(unit); |
|
360 } |
|
361 unit->mqtt_flag |= MQTT_FLAG_DLOG; // Something to log |
|
362 } |
|
363 printf("einde unit %s\n", unit->alias); |
|
364 } |
|
365 printf("return\n"); |
|
366 return; |
202 } |
367 } |
203 printf("metric: %s\n", (char *)json_object_get_string(metric)); |
368 printf("metric: %s\n", (char *)json_object_get_string(metric)); |
204 syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload); |
369 syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload); |
205 return; |
370 return; |
206 } |
371 } |