thermferm/mqtt.c

changeset 569
9c69d43bfb06
parent 566
776a605befa5
child 570
1e0192b295b9
equal deleted inserted replaced
568:eee0f52170e8 569:9c69d43bfb06
1 /***************************************************************************** 1 /*****************************************************************************
2 * Copyright (C) 2016-2018 2 * Copyright (C) 2016-2019
3 * 3 *
4 * Michiel Broek <mbroek at mbse dot eu> 4 * Michiel Broek <mbroek at mbse dot eu>
5 * 5 *
6 * This file is part of the mbsePi-apps 6 * This file is part of the mbsePi-apps
7 * 7 *
19 * along with ThermFerm; see the file COPYING. If not, write to the Free 19 * along with ThermFerm; see the file COPYING. If not, write to the Free
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 "logger.h"
25 #include "devices.h"
24 #include "xutil.h" 26 #include "xutil.h"
25 #include "mqtt.h" 27 #include "mqtt.h"
26 28
27 extern sys_config Config; 29 extern sys_config Config;
28 extern int debug; 30 extern int debug;
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 }

mercurial