# HG changeset patch # User Michiel Broek # Date 1547134422 -3600 # Node ID 9c69d43bfb0660eabdca1101d260f478e9d95514 # Parent eee0f52170e83dfa4d3f36a4f0d216a22cbb387f Version 0.9.0. Implemented DCMD via mqtt to set stage, mode, setpoint low and high. Implemeted DCMD via mqtt to set heater, cooler, fan and light state. Implemented DCMD via mqtt to set product code and name. Set the PID's in fridge mode without idle range offset, that was an old leftover setting that was obsolete. diff -r eee0f52170e8 -r 9c69d43bfb06 configure --- a/configure Mon Jan 07 13:23:17 2019 +0100 +++ b/configure Thu Jan 10 16:33:42 2019 +0100 @@ -2035,9 +2035,9 @@ PACKAGE="mbsePi-apps" -VERSION="0.8.9" -COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved" -CYEARS="2014-2018" +VERSION="0.9.0" +COPYRIGHT="Copyright (C) 2014-2019 Michiel Broek, All Rights Reserved" +CYEARS="2014-2019" diff -r eee0f52170e8 -r 9c69d43bfb06 configure.ac --- a/configure.ac Mon Jan 07 13:23:17 2019 +0100 +++ b/configure.ac Thu Jan 10 16:33:42 2019 +0100 @@ -8,9 +8,9 @@ dnl General settings dnl After changeing the version number, run autoconf! PACKAGE="mbsePi-apps" -VERSION="0.8.9" -COPYRIGHT="Copyright (C) 2014-2018 Michiel Broek, All Rights Reserved" -CYEARS="2014-2018" +VERSION="0.9.0" +COPYRIGHT="Copyright (C) 2014-2019 Michiel Broek, All Rights Reserved" +CYEARS="2014-2019" AC_SUBST(PACKAGE) AC_SUBST(VERSION) AC_SUBST(COPYRIGHT) diff -r eee0f52170e8 -r 9c69d43bfb06 thermferm/Makefile --- a/thermferm/Makefile Mon Jan 07 13:23:17 2019 +0100 +++ b/thermferm/Makefile Thu Jan 10 16:33:42 2019 +0100 @@ -55,7 +55,7 @@ # DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT # Dependencies generated by make depend rc-switch.o: thermferm.h xutil.h rc-switch.h -mqtt.o: thermferm.h xutil.h mqtt.h +mqtt.o: thermferm.h logger.h devices.h xutil.h mqtt.h slcd.o: thermferm.h slcd.h futil.h xutil.h panel.o: thermferm.h lcd-pcf8574.h slcd.h panel.h devices.o: thermferm.h devices.h rc-switch.h panel.h xutil.h diff -r eee0f52170e8 -r 9c69d43bfb06 thermferm/mqtt.c --- a/thermferm/mqtt.c Mon Jan 07 13:23:17 2019 +0100 +++ b/thermferm/mqtt.c Thu Jan 10 16:33:42 2019 +0100 @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (C) 2016-2018 + * Copyright (C) 2016-2019 * * Michiel Broek * @@ -21,6 +21,8 @@ *****************************************************************************/ #include "thermferm.h" +#include "logger.h" +#include "devices.h" #include "xutil.h" #include "mqtt.h" @@ -159,8 +161,9 @@ void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message) { - char *message_type; - struct json_object *jobj, *metric, *val; + char *message_type, *message_node, *message_alias; + units_list *unit; + struct json_object *jobj, *metric, *val, *setpoint; time_t timestamp; int timediff; @@ -171,6 +174,8 @@ strtok(message->topic, "/"); // Ignore mbv1.0 strtok(NULL, "/"); // Ignore group_id message_type = strtok(NULL, "/"); + message_node = strtok(NULL, "/\0"); + message_alias = strtok(NULL, "\0"); jobj = json_tokener_parse(message->payload); if (json_object_object_get_ex(jobj, "timestamp", &val)) { @@ -200,6 +205,166 @@ return; } } + if ((strcmp(message_type, "DCMD") == 0) && message_node && message_alias) { + syslog(LOG_NOTICE, "%s", (char *)json_object_get_string(metric)); + for (unit = Config.units ; unit; unit = unit->next) { + if (strcmp(unit->alias, message_alias) == 0) { + syslog(LOG_NOTICE, "MQTT: DCMD for %s/%s", (char *)message_node, (char *)message_alias); + if (json_object_object_get_ex(metric, "stage", &val)) { + // syslog(LOG_NOTICE, "Change state %s", UNITSTAGE[unit->stage]); + for (int i = 0; i < 4; i++) { + if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) { + if (unit->stage != i) { + syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", message_alias, UNITSTAGE[i]); + unit->mqtt_flag |= MQTT_FLAG_DATA; + unit->stage = i; + } + break; + } + } + } + printf("start mode\n"); + if (json_object_object_get_ex(metric, "mode", &val)) { + for (int i = 0; i < 4; i++) { + if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) { + if (unit->mode != i) { + syslog(LOG_NOTICE, "DCMD change fermenter %s: mode to %s", message_alias, UNITMODE[i]); + unit->mqtt_flag |= MQTT_FLAG_DATA; + /* Initialize log if the unit is turned on */ + if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) { + initlog(unit->product_code, unit->product_name); + unit->mqtt_flag |= MQTT_FLAG_BIRTH; + } else if ((unit->mode != UNITMODE_OFF) && (i == UNITMODE_OFF)) { + unit->mqtt_flag |= MQTT_FLAG_DEATH; + } + syslog(LOG_NOTICE, "Fermenter unit %s mode %s to %s", unit->uuid, UNITMODE[unit->mode], UNITMODE[i]); + unit->mode = i; + /* Allways turn everything off after a mode change */ + unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0; + unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE; + unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = 0; + unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; + device_out(unit->heater_address, unit->heater_state); + device_out(unit->cooler_address, unit->cooler_state); + device_out(unit->fan_address, unit->fan_state); + device_out(unit->light_address, unit->light_state); + if (unit->mode == UNITMODE_PROFILE) { + /* + * Set a sane default until it will be overruled by the + * main processing loop. + */ + unit->prof_target_lo = unit->prof_target_hi = 20.0; + unit->prof_fridge_mode = 0; + if (unit->profile) { + unit->mqtt_flag |= MQTT_FLAG_DATA; + } + } + } + break; + } + } + } + printf("start setpoint\n"); + if (json_object_object_get_ex(metric, "setpoint", &setpoint)) { + if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) { + /* + * Only set new setpoints if running as FRIDGE or in BEER mode. + */ + if (json_object_object_get_ex(setpoint, "low", &val)) { + unit->PID_heat->SetP = json_object_get_double(val); + } + if (json_object_object_get_ex(setpoint, "high", &val)) { + unit->PID_cool->SetP = json_object_get_double(val); + } + if (unit->mode == UNITMODE_FRIDGE) { + unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); + } else { + unit->beer_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); + } + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: setpoints %.1f %.1f", message_alias, unit->PID_heat->SetP, unit->PID_cool->SetP); + } + } + printf("start heater\n"); + if ((json_object_object_get_ex(metric, "heater", &setpoint)) && (unit->mode == UNITMODE_NONE)) { + if (json_object_object_get_ex(setpoint, "state", &val)) { + if (json_object_get_int(val) != unit->heater_state) { + unit->heater_state = json_object_get_int(val); + if (unit->heater_state) // Safety + unit->cooler_state = 0; + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: heater_state to %d", message_alias, unit->heater_state); + } + } + } + if ((json_object_object_get_ex(metric, "cooler", &setpoint)) && (unit->mode == UNITMODE_NONE)) { + if (json_object_object_get_ex(setpoint, "state", &val)) { + if (json_object_get_int(val) != unit->cooler_state) { + unit->cooler_state = json_object_get_int(val); + if (unit->cooler_state) + unit->heater_state = 0; + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: cooler_state to %d", message_alias, unit->cooler_state); + } + } + } + if ((json_object_object_get_ex(metric, "fan", &setpoint)) && (unit->mode == UNITMODE_NONE)) { + if (json_object_object_get_ex(setpoint, "state", &val)) { + if (json_object_get_int(val) != unit->fan_state) { + unit->fan_state = json_object_get_int(val); + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: fan_state to %d", message_alias, unit->fan_state); + } + } + } + if ((json_object_object_get_ex(metric, "light", &setpoint)) && (unit->mode == UNITMODE_NONE)) { + if (json_object_object_get_ex(setpoint, "state", &val)) { + if (json_object_get_int(val) != unit->light_state) { + unit->light_state = json_object_get_int(val); + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: light_state to %d", message_alias, unit->light_state); + } + } + } + printf("start product\n"); + if ((json_object_object_get_ex(metric, "product", &setpoint)) && (unit->mode == UNITMODE_OFF)) { + if (json_object_object_get_ex(setpoint, "code", &val)) { + if (strcmp((char *)json_object_get_string(val), unit->product_code)) { + free(unit->product_code); + unit->product_code = xstrcpy((char *)json_object_get_string(val)); + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: product_code to `%s'", message_alias, unit->product_code); + } + } + if (json_object_object_get_ex(setpoint, "name", &val)) { + if (strcmp((char *)json_object_get_string(val), unit->product_name)) { + free(unit->product_name); + unit->product_name = xstrcpy((char *)json_object_get_string(val)); + unit->mqtt_flag |= MQTT_FLAG_DATA; + syslog(LOG_NOTICE, "DCMD change fermenter %s: product_name to `%s'", message_alias, unit->product_name); + } + } + } + } + if (unit->mqtt_flag) { + printf("do mqtt flag\n"); + if (debug) + fprintf(stdout, "flag value %d\n", unit->mqtt_flag); + if (unit->mqtt_flag & MQTT_FLAG_BIRTH) { + publishDBirth(unit); + } else { + publishDData(unit); + } + if (unit->mqtt_flag & MQTT_FLAG_DEATH) { + publishDDeath(unit); + } + unit->mqtt_flag |= MQTT_FLAG_DLOG; // Something to log + } + printf("einde unit %s\n", unit->alias); + } + printf("return\n"); + return; + } printf("metric: %s\n", (char *)json_object_get_string(metric)); syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload); return; diff -r eee0f52170e8 -r 9c69d43bfb06 thermferm/thermferm.c --- a/thermferm/thermferm.c Mon Jan 07 13:23:17 2019 +0100 +++ b/thermferm/thermferm.c Thu Jan 10 16:33:42 2019 +0100 @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (C) 2014-2018 + * Copyright (C) 2014-2019 * * Michiel Broek * @@ -1628,8 +1628,8 @@ */ unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE; if (unit->mode == UNITMODE_FRIDGE) { - unit->PID_cool->SetP = unit->fridge_set + unit->PID_cool->idleRange; - unit->PID_heat->SetP = unit->fridge_set - unit->PID_heat->idleRange; + unit->PID_cool->SetP = unit->fridge_set; // + unit->PID_cool->idleRange; + unit->PID_heat->SetP = unit->fridge_set; // - unit->PID_heat->idleRange; unit->PID_cool->Input = unit->PID_heat->Input = unit->air_temperature / 1000.0; unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_BOO; } else if (unit->mode == UNITMODE_BEER) { diff -r eee0f52170e8 -r 9c69d43bfb06 thermferm/thermferm.h --- a/thermferm/thermferm.h Mon Jan 07 13:23:17 2019 +0100 +++ b/thermferm/thermferm.h Thu Jan 10 16:33:42 2019 +0100 @@ -211,6 +211,7 @@ #define UNITSTAGE_PRIMARY 0 /* Fermentation primary stage */ #define UNITSTAGE_SECONDARY 1 /* Fermentation secondary stage */ #define UNITSTAGE_TERTIARY 2 /* Fermentation tertiary stage */ +#define UNITSTAGE_CARBONATION 3 /* Carbonation packaged beer */ #define MQTT_FLAG_DATA 0x0001 /* Show updated data values */ #define MQTT_FLAG_BIRTH 0x0002 /* Show birth instead of data */