thermferm/thermferm.c

changeset 499
602d9968960f
parent 498
4903b4da9d40
child 500
5aa914eb644e
equal deleted inserted replaced
498:4903b4da9d40 499:602d9968960f
1 /***************************************************************************** 1 /*****************************************************************************
2 * Copyright (C) 2014-2015 2 * Copyright (C) 2014-2016
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 *
32 #include "slcd.h" 32 #include "slcd.h"
33 #include "panel.h" 33 #include "panel.h"
34 #include "futil.h" 34 #include "futil.h"
35 #include "xutil.h" 35 #include "xutil.h"
36 #include "pid.h" 36 #include "pid.h"
37 #include "mqtt.h"
37 38
38 39
39 int my_shutdown = FALSE; 40 int my_shutdown = FALSE;
40 static pid_t pgrp, mypid; 41 static pid_t pgrp, mypid;
41 int run_pause = FALSE; 42 int run_pause = FALSE;
65 unsigned char RevCoolONOFF[8] = { 0b11111, 0b10001, 0b10111, 0b10111, 0b10111, 0b10111, 0b10001, 0b11111 }; // [4] Reverse Cool Symbol 66 unsigned char RevCoolONOFF[8] = { 0b11111, 0b10001, 0b10111, 0b10111, 0b10111, 0b10111, 0b10001, 0b11111 }; // [4] Reverse Cool Symbol
66 unsigned char HeatONOFF[8] = { 0b00000, 0b01010, 0b01010, 0b01110, 0b01110, 0b01010, 0b01010, 0b00000 }; // [5] HEAT symbol 67 unsigned char HeatONOFF[8] = { 0b00000, 0b01010, 0b01010, 0b01110, 0b01110, 0b01010, 0b01010, 0b00000 }; // [5] HEAT symbol
67 unsigned char RevHeatONOFF[8] = { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 }; // [6] reverse HEAT symbol 68 unsigned char RevHeatONOFF[8] = { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 }; // [6] reverse HEAT symbol
68 69
69 70
70 #ifdef HAVE_MOSQUITTO_H
71
72 #define STATUS_CONNECTING 0
73 #define STATUS_CONNACK_RECVD 1
74 #define STATUS_WAITING 2
75
76 /* Global variables for use in callbacks. */
77 static int mqtt_qos = 0;
78 static int mqtt_status = STATUS_CONNECTING;
79 static int mqtt_mid_sent = 0;
80 static int mqtt_last_mid = -1;
81 static int mqtt_last_mid_sent = -1;
82 static int mqtt_connected = TRUE;
83 static int mqtt_disconnect_sent = FALSE;
84 static int mqtt_connect_lost = FALSE;
85 static int mqtt_my_shutdown = FALSE;
86 static int mqtt_use = FALSE;
87
88 #endif
89
90 int server(void); 71 int server(void);
91 void help(void); 72 void help(void);
92 void die(int); 73 void die(int);
93 void stopLCD(void); 74 void stopLCD(void);
94 #ifdef HAVE_WIRINGPI_H 75 #ifdef HAVE_WIRINGPI_H
95 void sendRCswitch(char *, int); 76 void sendRCswitch(char *, int);
96 void stopRCswitch(void); 77 void stopRCswitch(void);
97 #endif 78 #endif
98 79
80
81 #ifdef HAVE_MOSQUITTO_H
82
83 extern int mqtt_qos;
84 extern int mqtt_last_mid;
85 extern int mqtt_last_mid_sent;
86 extern int mqtt_mid_sent;
87 extern int mqtt_disconnect_sent;
88 extern int mqtt_connected;
89 extern int mqtt_status;
90 extern int mqtt_use;
91 extern struct mosquitto *mosq;
92 extern char *state;
93
94 #endif
99 95
100 96
101 void help(void) 97 void help(void)
102 { 98 {
103 fprintf(stdout, "mbsePi-apps thermferm v%s starting\n\n", VERSION); 99 fprintf(stdout, "mbsePi-apps thermferm v%s starting\n\n", VERSION);
397 { 393 {
398 if ((current_unit->mode == UNITMODE_OFF) && (mode != UNITMODE_OFF)) 394 if ((current_unit->mode == UNITMODE_OFF) && (mode != UNITMODE_OFF))
399 initlog(current_unit->name); 395 initlog(current_unit->name);
400 syslog(LOG_NOTICE, "Mode from %s to %s via panel interface", UNITMODE[current_unit->mode], UNITMODE[mode]); 396 syslog(LOG_NOTICE, "Mode from %s to %s via panel interface", UNITMODE[current_unit->mode], UNITMODE[mode]);
401 current_unit->mode = mode; 397 current_unit->mode = mode;
398 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_MODE);
402 /* Allways turn everything off after a mode change */ 399 /* Allways turn everything off after a mode change */
403 current_unit->PID_cool->OutP = current_unit->PID_heat->OutP = 0.0; 400 current_unit->PID_cool->OutP = current_unit->PID_heat->OutP = 0.0;
404 current_unit->PID_cool->Mode = current_unit->PID_heat->Mode = PID_MODE_NONE; 401 current_unit->PID_cool->Mode = current_unit->PID_heat->Mode = PID_MODE_NONE;
405 current_unit->heater_state = current_unit->cooler_state = current_unit->fan_state = current_unit->light_state = 0; 402 current_unit->heater_state = current_unit->cooler_state = current_unit->fan_state = current_unit->light_state = 0;
406 current_unit->heater_wait = current_unit->cooler_wait = current_unit->fan_wait = current_unit->light_wait = 0; 403 current_unit->heater_wait = current_unit->cooler_wait = current_unit->fan_wait = current_unit->light_wait = 0;
611 } 608 }
612 if (key == KEY_CONFIRM) { 609 if (key == KEY_CONFIRM) {
613 if (temp_temp != current_unit->fridge_set) { 610 if (temp_temp != current_unit->fridge_set) {
614 syslog(LOG_NOTICE, "Fridge temperature changed from %.1f to %.1f degrees from the panel", current_unit->fridge_set, temp_temp); 611 syslog(LOG_NOTICE, "Fridge temperature changed from %.1f to %.1f degrees from the panel", current_unit->fridge_set, temp_temp);
615 current_unit->fridge_set = temp_temp; 612 current_unit->fridge_set = temp_temp;
613 current_unit->mqtt_flag |= MQTT_FLAG_SP;
616 } 614 }
617 go_menu(MENU_MODE_FRIDGE); 615 go_menu(MENU_MODE_FRIDGE);
618 } 616 }
619 break; 617 break;
620 618
651 } 649 }
652 if (key == KEY_CONFIRM) { 650 if (key == KEY_CONFIRM) {
653 if (temp_temp != current_unit->beer_set) { 651 if (temp_temp != current_unit->beer_set) {
654 syslog(LOG_NOTICE, "Beer temperature changed from %.1f to %.1f degrees from the panel", current_unit->beer_set, temp_temp); 652 syslog(LOG_NOTICE, "Beer temperature changed from %.1f to %.1f degrees from the panel", current_unit->beer_set, temp_temp);
655 current_unit->beer_set = temp_temp; 653 current_unit->beer_set = temp_temp;
654 current_unit->mqtt_flag |= MQTT_FLAG_SP;
656 } 655 }
657 go_menu(MENU_MODE_BEER); 656 go_menu(MENU_MODE_BEER);
658 } 657 }
659 break; 658 break;
660 659
732 current_unit->prof_state = PROFILE_RUN; 731 current_unit->prof_state = PROFILE_RUN;
733 current_unit->prof_started = time(NULL); 732 current_unit->prof_started = time(NULL);
734 current_unit->prof_paused = current_unit->prof_primary_done = 0; 733 current_unit->prof_paused = current_unit->prof_primary_done = 0;
735 current_unit->prof_peak_abs = current_unit->prof_peak_rel = 0.0; 734 current_unit->prof_peak_abs = current_unit->prof_peak_rel = 0.0;
736 syslog(LOG_NOTICE, "Profile started from the panel"); 735 syslog(LOG_NOTICE, "Profile started from the panel");
736 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_PROFILE | MQTT_FLAG_PERCENT);
737 go_menu(MENU_MODE_PROFILE); 737 go_menu(MENU_MODE_PROFILE);
738 } 738 }
739 break; 739 break;
740 740
741 case MENU_PROFILE_PAUSE: 741 case MENU_PROFILE_PAUSE:
743 go_menu(MENU_MODE_PROFILE); 743 go_menu(MENU_MODE_PROFILE);
744 if ((key == KEY_DOWN) || (key == KEY_UP)) 744 if ((key == KEY_DOWN) || (key == KEY_UP))
745 go_menu(MENU_PROFILE_ABORT); 745 go_menu(MENU_PROFILE_ABORT);
746 if (key == KEY_ENTER) { 746 if (key == KEY_ENTER) {
747 current_unit->prof_state = PROFILE_PAUSE; 747 current_unit->prof_state = PROFILE_PAUSE;
748 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_PROFILE | MQTT_FLAG_PERCENT);
748 syslog(LOG_NOTICE, "Profile pause from the panel"); 749 syslog(LOG_NOTICE, "Profile pause from the panel");
749 go_menu(MENU_MODE_PROFILE); 750 go_menu(MENU_MODE_PROFILE);
750 } 751 }
751 break; 752 break;
752 753
761 } 762 }
762 if ((key == KEY_ENTER) && ((current_unit->prof_state == PROFILE_RUN) || (current_unit->prof_state == PROFILE_PAUSE))) { 763 if ((key == KEY_ENTER) && ((current_unit->prof_state == PROFILE_RUN) || (current_unit->prof_state == PROFILE_PAUSE))) {
763 current_unit->prof_state = PROFILE_OFF; 764 current_unit->prof_state = PROFILE_OFF;
764 current_unit->prof_started = 0; 765 current_unit->prof_started = 0;
765 syslog(LOG_NOTICE, "Profile aborted from the panel"); 766 syslog(LOG_NOTICE, "Profile aborted from the panel");
767 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_PROFILE | MQTT_FLAG_PERCENT);
766 go_menu(MENU_MODE_PROFILE); 768 go_menu(MENU_MODE_PROFILE);
767 } 769 }
768 break; 770 break;
769 771
770 case MENU_PROFILE_RESUME: 772 case MENU_PROFILE_RESUME:
773 if ((key == KEY_DOWN) || (key == KEY_UP)) 775 if ((key == KEY_DOWN) || (key == KEY_UP))
774 go_menu(MENU_PROFILE_ABORT); 776 go_menu(MENU_PROFILE_ABORT);
775 if (key == KEY_ENTER) { 777 if (key == KEY_ENTER) {
776 current_unit->prof_state = PROFILE_RUN; 778 current_unit->prof_state = PROFILE_RUN;
777 syslog(LOG_NOTICE, "Profile resume from the panel"); 779 syslog(LOG_NOTICE, "Profile resume from the panel");
780 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_PROFILE | MQTT_FLAG_PERCENT);
778 go_menu(MENU_MODE_PROFILE); 781 go_menu(MENU_MODE_PROFILE);
779 } 782 }
780 break; 783 break;
781 784
782 case MENU_PROFILE_GOOFF: 785 case MENU_PROFILE_GOOFF:
783 if (key == KEY_ESCAPE) 786 if (key == KEY_ESCAPE)
784 go_menu(MENU_MODE_PROFILE); 787 go_menu(MENU_MODE_PROFILE);
785 if (key == KEY_ENTER) { 788 if (key == KEY_ENTER) {
786 if (current_unit->prof_state == PROFILE_DONE) { 789 if (current_unit->prof_state == PROFILE_DONE) {
787 current_unit->prof_state = PROFILE_OFF; 790 current_unit->prof_state = PROFILE_OFF;
791 current_unit->mqtt_flag |= (MQTT_FLAG_SP | MQTT_FLAG_PROFILE | MQTT_FLAG_PERCENT);
788 syslog(LOG_NOTICE, "Profile from done to off from the panel"); 792 syslog(LOG_NOTICE, "Profile from done to off from the panel");
789 } 793 }
790 } 794 }
791 break; 795 break;
792 796
960 syslog(LOG_NOTICE, "Finished, rc=%d", rc); 964 syslog(LOG_NOTICE, "Finished, rc=%d", rc);
961 return rc; 965 return rc;
962 } 966 }
963 967
964 968
965 #ifdef HAVE_MOSQUITTO_H
966
967 void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
968 {
969 if (mqtt_connect_lost) {
970 mqtt_connect_lost = FALSE;
971 syslog(LOG_NOTICE, "Reconnect: %s", mosquitto_connack_string(result));
972 }
973
974 if (!result) {
975 mqtt_status = STATUS_CONNACK_RECVD;
976 } else {
977 syslog(LOG_NOTICE, "my_connect_callback: %s\n", mosquitto_connack_string(result));
978 }
979 }
980
981
982
983 void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
984 {
985 if (mqtt_my_shutdown) {
986 syslog(LOG_NOTICE, "Acknowledged DISCONNECT from %s", Config.mosq_host);
987 mqtt_connected = FALSE;
988 } else {
989 /*
990 * The remote server was brought down. We must keep running
991 */
992 syslog(LOG_NOTICE, "Received DISCONNECT from %s, connection lost", Config.mosq_host);
993 mqtt_connect_lost = TRUE;
994 }
995 }
996
997
998 void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
999 {
1000 mqtt_last_mid_sent = mid;
1001 }
1002
1003
1004
1005 void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
1006 {
1007 syslog(LOG_NOTICE, "MQTT: %s", str);
1008 printf("MQTT: %s\n", str);
1009 mqtt_my_shutdown = TRUE;
1010 }
1011
1012
1013 #endif
1014
1015 969
1016 int server(void) 970 int server(void)
1017 { 971 {
1018 char buf[1024], *filename, target_lo[40], target_hi[40], heater[40], cooler[40], fan[40], door[40]; 972 char buf[1024], *filename, target_lo[40], target_hi[40], heater[40], cooler[40], fan[40], door[40];
1019 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40]; 973 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40];
1030 int current_step, valid_step, time_until_now, previous_fridge_mode; 984 int current_step, valid_step, time_until_now, previous_fridge_mode;
1031 float previous_target_lo, previous_target_hi; 985 float previous_target_lo, previous_target_hi;
1032 float LCDair, LCDbeer, LCDspL, LCDspH; 986 float LCDair, LCDbeer, LCDspL, LCDspH;
1033 unsigned char LCDstatC, LCDstatH; 987 unsigned char LCDstatC, LCDstatH;
1034 int LCDunit; 988 int LCDunit;
1035 #ifdef HAVE_MOSQUITTO_H
1036 char *id = NULL, *state = NULL, hostname[256], topic[1024], err[1024];
1037 struct mosquitto *mosq = NULL;
1038 int keepalive = 60;
1039 unsigned int max_inflight = 20;
1040 #endif
1041 989
1042 if (lockprog((char *)"thermferm")) { 990 if (lockprog((char *)"thermferm")) {
1043 syslog(LOG_NOTICE, "Can't lock"); 991 syslog(LOG_NOTICE, "Can't lock");
1044 return 1; 992 return 1;
1045 } 993 }
1046 994
1047 995 mqtt_connect();
1048 #ifdef HAVE_MOSQUITTO_H
1049 /*
1050 * Initialize mosquitto communication
1051 */
1052 gethostname(hostname, 255);
1053 mosquitto_lib_init();
1054 id = xstrcpy((char *)"thermferm/");
1055 id = xstrcat(id, hostname);
1056 if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH) {
1057 /*
1058 * Enforce maximum client id length of 23 characters
1059 */
1060 id[MOSQ_MQTT_ID_MAX_LENGTH] = '\0';
1061 }
1062
1063 mosq = mosquitto_new(id, true, NULL);
1064 if(!mosq) {
1065 switch(errno) {
1066 case ENOMEM:
1067 syslog(LOG_NOTICE, "mosquitto_new: Out of memory");
1068 break;
1069 case EINVAL:
1070 syslog(LOG_NOTICE, "mosquitto_new: Invalid id");
1071 break;
1072 }
1073 mosquitto_lib_cleanup();
1074 return 1;
1075 }
1076
1077 if (debug) {
1078 mosquitto_log_callback_set(mosq, my_log_callback);
1079 }
1080
1081 /*
1082 * Set our will
1083 */
1084 state = xstrcpy((char *)"clients/");
1085 state = xstrcat(state, hostname);
1086 state = xstrcat(state, (char *)"/thermferm/state");
1087 sprintf(buf, "0");
1088 if ((rc = mosquitto_will_set(mosq, state, strlen(buf), buf, mqtt_qos, TRUE))) {
1089 if (rc == MOSQ_ERR_INVAL) {
1090 syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid");
1091 } else if (rc == MOSQ_ERR_NOMEM) {
1092 syslog(LOG_NOTICE, "mosquitto_will_set: Out of Memory");
1093 } else if (rc == MOSQ_ERR_PAYLOAD_SIZE) {
1094 syslog(LOG_NOTICE, "mosquitto_will_set: invalid payload size");
1095 }
1096 mosquitto_lib_cleanup();
1097 return rc;
1098 }
1099
1100 mosquitto_max_inflight_messages_set(mosq, max_inflight);
1101 mosquitto_connect_callback_set(mosq, my_connect_callback);
1102 mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
1103 mosquitto_publish_callback_set(mosq, my_publish_callback);
1104
1105 if ((rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive))) {
1106 if (rc == MOSQ_ERR_ERRNO) {
1107 strerror_r(errno, err, 1024);
1108 syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err);
1109 } else {
1110 syslog(LOG_NOTICE, "mosquitto_connect: unable to connect (%d)", rc);
1111 }
1112 mosquitto_lib_cleanup();
1113 } else {
1114 mqtt_use = TRUE;
1115 syslog(LOG_NOTICE, "MQTT connected with %s:%d", Config.mosq_host, Config.mosq_port);
1116
1117 /*
1118 * Initialise is complete, report our presence state
1119 */
1120 mosquitto_loop_start(mosq);
1121 sprintf(buf, "1");
1122 rc = mosquitto_publish(mosq, &mqtt_mid_sent, state, strlen(buf), buf, mqtt_qos, 1);
1123 }
1124 #endif
1125
1126 996
1127 if ((rc = devices_detect())) { 997 if ((rc = devices_detect())) {
1128 syslog(LOG_NOTICE, "Detected %d new devices", rc); 998 syslog(LOG_NOTICE, "Detected %d new devices", rc);
1129 wrconfig(); 999 wrconfig();
1130 } 1000 }
1193 */ 1063 */
1194 for (unit = Config.units; unit; unit = unit->next) { 1064 for (unit = Config.units; unit; unit = unit->next) {
1195 /* 1065 /*
1196 * Safety, turn everything off 1066 * Safety, turn everything off
1197 */ 1067 */
1068 unit->mqtt_flag = MQTT_FLAG_MODE;
1198 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 1069 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
1199 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; 1070 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
1200 #ifdef HAVE_MOSQUITTO_H 1071 mqtt_publish_int(unit->uuid, (char *)"state", (unit->mode != UNITMODE_OFF) ? 1 : 0);
1201 if (mqtt_use && (unit->mode != UNITMODE_OFF)) { 1072 if (unit->name)
1202 sprintf(buf, "1"); 1073 mqtt_publish_str(unit->uuid, (char *)"name", unit->name);
1203 snprintf(topic, 1023, "fermenter/%s/%s/state", hostname, unit->uuid); 1074 if (unit->heater_address)
1204 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1); 1075 mqtt_publish_int(unit->uuid, (char *)"heater", 0);
1205 sprintf(buf, "%s", unit->name); 1076 if (unit->cooler_address)
1206 snprintf(topic, 1023, "fermenter/%s/%s/name", hostname, unit->uuid); 1077 mqtt_publish_int(unit->uuid, (char *)"cooler", 0);
1207 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1); 1078 if (unit->fan_address)
1208 sprintf(buf, "0"); 1079 mqtt_publish_int(unit->uuid, (char *)"fan", 0);
1209 if (unit->heater_address) { 1080 if (unit->air_address)
1210 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid); 1081 unit->mqtt_flag |= MQTT_FLAG_AIR;
1211 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1); 1082 if (unit->beer_address)
1212 } 1083 unit->mqtt_flag |= MQTT_FLAG_BEER;
1213 if (unit->cooler_address) {
1214 snprintf(topic, 1023, "fermenter/%s/%s/cooler", hostname, unit->uuid);
1215 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1216 }
1217 if (unit->fan_address) {
1218 snprintf(topic, 1023, "fermenter/%s/%s/fan", hostname, unit->uuid);
1219 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1220 }
1221 snprintf(topic, 1023, "fermenter/%s/%s/mode", hostname, unit->uuid);
1222 sprintf(buf, "%s", UNITMODE[unit->mode]);
1223 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1224 }
1225 #endif
1226 if (unit->mode == UNITMODE_PROFILE) { 1084 if (unit->mode == UNITMODE_PROFILE) {
1227 if (!unit->profile) 1085 if (!unit->profile)
1228 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name); 1086 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name);
1229 else 1087 else {
1230 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); 1088 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
1089 unit->mqtt_flag |= MQTT_FLAG_SP;
1090 unit->mqtt_flag |= MQTT_FLAG_PROFILE;
1091 }
1231 } else if (unit->mode == UNITMODE_BEER) { 1092 } else if (unit->mode == UNITMODE_BEER) {
1232 syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set); 1093 syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set);
1094 unit->mqtt_flag |= MQTT_FLAG_SP;
1233 } else if (unit->mode == UNITMODE_FRIDGE) { 1095 } else if (unit->mode == UNITMODE_FRIDGE) {
1234 syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set); 1096 syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
1097 unit->mqtt_flag |= MQTT_FLAG_SP;
1235 } else if (unit->mode == UNITMODE_NONE) { 1098 } else if (unit->mode == UNITMODE_NONE) {
1236 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name); 1099 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name);
1237 } else { 1100 } else {
1238 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name); 1101 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name);
1239 } 1102 }
1314 piUnlock(LOCK_LCD); 1177 piUnlock(LOCK_LCD);
1315 #endif 1178 #endif
1316 if (Config.temp_address) { 1179 if (Config.temp_address) {
1317 rc = device_in(Config.temp_address, &temp); 1180 rc = device_in(Config.temp_address, &temp);
1318 if (rc == DEVPRESENT_YES) { 1181 if (rc == DEVPRESENT_YES) {
1319 #ifdef HAVE_MOSQUITTO_H 1182 if (Config.temp_value != temp)
1320 if (mqtt_use && (Config.temp_value != temp)) { 1183 mqtt_publish_float((char *)"room", (char *)"temperature", temp / 1000.0, 1);
1321 sprintf(buf, "%.1f", temp / 1000.0);
1322 snprintf(topic, 1023, "fermenter/%s/room/temperature", hostname);
1323 rc = mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1324 }
1325 #endif
1326 Config.temp_value = temp; 1184 Config.temp_value = temp;
1327 Config.temp_state = 0; 1185 Config.temp_state = 0;
1328 #ifdef HAVE_WIRINGPI_H 1186 #ifdef HAVE_WIRINGPI_H
1329 piLock(LOCK_LCD); 1187 piLock(LOCK_LCD);
1330 #endif 1188 #endif
1349 #endif 1207 #endif
1350 1208
1351 if (Config.hum_address) { 1209 if (Config.hum_address) {
1352 rc = device_in(Config.hum_address, &temp); 1210 rc = device_in(Config.hum_address, &temp);
1353 if (rc == DEVPRESENT_YES) { 1211 if (rc == DEVPRESENT_YES) {
1354 #ifdef HAVE_MOSQUITTO_H 1212 if (Config.hum_value != temp)
1355 if (mqtt_use && (Config.hum_value != temp)) { 1213 mqtt_publish_float((char *)"room", (char *)"humidity", temp / 1000.0, 1);
1356 sprintf(buf, "%.1f", temp / 1000.0);
1357 snprintf(topic, 1023, "fermenter/%s/room/humidity", hostname);
1358 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1359 }
1360 #endif
1361 Config.hum_value = temp; 1214 Config.hum_value = temp;
1362 Config.hum_state = 0; 1215 Config.hum_state = 0;
1363 #ifdef HAVE_WIRINGPI_H 1216 #ifdef HAVE_WIRINGPI_H
1364 piLock(LOCK_LCD); 1217 piLock(LOCK_LCD);
1365 #endif 1218 #endif
1390 * Maximum error is 40 degrees for now. 1243 * Maximum error is 40 degrees for now.
1391 */ 1244 */
1392 deviation = 40000; 1245 deviation = 40000;
1393 if ((unit->air_temperature == 0) || 1246 if ((unit->air_temperature == 0) ||
1394 (unit->air_temperature && (temp > (int)unit->air_temperature - deviation) && (temp < ((int)unit->air_temperature + deviation)))) { 1247 (unit->air_temperature && (temp > (int)unit->air_temperature - deviation) && (temp < ((int)unit->air_temperature + deviation)))) {
1395 #ifdef HAVE_MOSQUITTO_H 1248 if (unit->air_temperature != temp)
1396 if (mqtt_use && (unit->air_temperature != temp)) { 1249 unit->mqtt_flag |= MQTT_FLAG_AIR;
1397 sprintf(buf, "%.3f", temp / 1000.0);
1398 snprintf(topic, 1023, "fermenter/%s/%s/air/temperature", hostname, unit->uuid);
1399 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1400 }
1401 #endif
1402 unit->air_temperature = temp; 1250 unit->air_temperature = temp;
1403 unit->air_state = 0; 1251 unit->air_state = 0;
1404 } else { 1252 } else {
1405 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->air_temperature, temp); 1253 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->air_temperature, temp);
1406 if (debug) {
1407 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->air_temperature, temp);
1408 }
1409 } 1254 }
1410 } else if (rc == DEVPRESENT_ERROR) { 1255 } else if (rc == DEVPRESENT_ERROR) {
1411 unit->air_state = 1; 1256 unit->air_state = 1;
1412 } else { 1257 } else {
1413 unit->air_state = 2; 1258 unit->air_state = 2;
1418 rc = device_in(unit->beer_address, &temp); 1263 rc = device_in(unit->beer_address, &temp);
1419 if (rc == DEVPRESENT_YES) { 1264 if (rc == DEVPRESENT_YES) {
1420 deviation = 40000; 1265 deviation = 40000;
1421 if ((unit->beer_temperature == 0) || 1266 if ((unit->beer_temperature == 0) ||
1422 (unit->beer_temperature && (temp > (int)unit->beer_temperature - deviation) && (temp < ((int)unit->beer_temperature + deviation)))) { 1267 (unit->beer_temperature && (temp > (int)unit->beer_temperature - deviation) && (temp < ((int)unit->beer_temperature + deviation)))) {
1423 #ifdef HAVE_MOSQUITTO_H 1268 if (unit->beer_temperature != temp)
1424 if (mqtt_use && (unit->beer_temperature != temp)) { 1269 unit->mqtt_flag |= MQTT_FLAG_BEER;
1425 sprintf(buf, "%.3f", temp / 1000.0);
1426 snprintf(topic, 1023, "fermenter/%s/%s/beer/temperature", hostname, unit->uuid);
1427 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1428 }
1429 #endif
1430 unit->beer_temperature = temp; 1270 unit->beer_temperature = temp;
1431 unit->beer_state = 0; 1271 unit->beer_state = 0;
1432 } else { 1272 } else {
1433 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->beer_temperature, temp); 1273 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->beer_temperature, temp);
1434 if (debug) {
1435 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->beer_temperature, temp);
1436 }
1437 } 1274 }
1438 } else if (rc == DEVPRESENT_ERROR) { 1275 } else if (rc == DEVPRESENT_ERROR) {
1439 unit->beer_state = 1; 1276 unit->beer_state = 1;
1440 } else { 1277 } else {
1441 unit->beer_state = 2; 1278 unit->beer_state = 2;
1447 */ 1284 */
1448 unit->door_state = 1; 1285 unit->door_state = 1;
1449 if (unit->door_address) { 1286 if (unit->door_address) {
1450 rc = device_in(unit->door_address, &temp); 1287 rc = device_in(unit->door_address, &temp);
1451 if (rc == DEVPRESENT_YES) { 1288 if (rc == DEVPRESENT_YES) {
1452 #ifdef HAVE_MOSQUITTO_H
1453 snprintf(topic, 1023, "fermenter/%s/%s/door", hostname, unit->uuid);
1454 #endif
1455 if (temp) { 1289 if (temp) {
1456 if (unit->door_state == 0) { 1290 if (unit->door_state == 0) {
1457 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name); 1291 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name);
1458 unit->door_state = 1; 1292 unit->door_state = 1;
1459 #ifdef HAVE_MOSQUITTO_H 1293 mqtt_publish_str(unit->uuid, (char *)"door", (char *)"closed");
1460 if (mqtt_use) {
1461 sprintf(buf, "closed");
1462 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1463 }
1464 #endif
1465 } 1294 }
1466 } else { 1295 } else {
1467 if (unit->door_state) { 1296 if (unit->door_state) {
1468 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name); 1297 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name);
1469 unit->door_state = 0; 1298 unit->door_state = 0;
1470 #ifdef HAVE_MOSQUITTO_H 1299 mqtt_publish_str(unit->uuid, (char *)"door", (char *)"open");
1471 if (mqtt_use) {
1472 sprintf(buf, "open");
1473 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1474 }
1475 #endif
1476 } 1300 }
1477 } 1301 }
1478 } 1302 }
1479 } 1303 }
1480 1304
1487 if (rc == DEVPRESENT_YES) { 1311 if (rc == DEVPRESENT_YES) {
1488 if (temp) { 1312 if (temp) {
1489 if (unit->psu_state == 0) { 1313 if (unit->psu_state == 0) {
1490 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->name); 1314 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->name);
1491 unit->psu_state = 1; 1315 unit->psu_state = 1;
1316 mqtt_publish_str(unit->uuid, (char *)"12volt", (char *)"on");
1492 } 1317 }
1493 } else { 1318 } else {
1494 if (unit->psu_state) { 1319 if (unit->psu_state) {
1495 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->name); 1320 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->name);
1496 unit->psu_state = 0; 1321 unit->psu_state = 0;
1322 mqtt_publish_str(unit->uuid, (char *)"12volt", (char *)"off");
1497 } 1323 }
1498 } 1324 }
1499 } 1325 }
1500 } 1326 }
1501 1327
1640 if (((minutes == 10) || (minutes == 40)) && (seconds == 1)) { 1466 if (((minutes == 10) || (minutes == 40)) && (seconds == 1)) {
1641 syslog(LOG_NOTICE, "Profile `%s' running %dd %02d:%02d in step %d, %d%% done, target %s %.3f..%.3f degrees", 1467 syslog(LOG_NOTICE, "Profile `%s' running %dd %02d:%02d in step %d, %d%% done, target %s %.3f..%.3f degrees",
1642 profile->name, run_hours / 24, run_hours % 24, run_minutes % 60, current_step, 1468 profile->name, run_hours / 24, run_hours % 24, run_minutes % 60, current_step,
1643 unit->prof_percent, unit->prof_fridge_mode ? (char *)"air":(char *)"beer", 1469 unit->prof_percent, unit->prof_fridge_mode ? (char *)"air":(char *)"beer",
1644 unit->prof_target_lo, unit->prof_target_hi); 1470 unit->prof_target_lo, unit->prof_target_hi);
1471 unit->mqtt_flag |= (MQTT_FLAG_PERCENT | MQTT_FLAG_PROFILE | MQTT_FLAG_SP);
1645 } 1472 }
1646 } else { 1473 } else {
1647 /* 1474 /*
1648 * No more steps to do 1475 * No more steps to do
1649 */ 1476 */
1650 unit->prof_state = PROFILE_DONE; 1477 unit->prof_state = PROFILE_DONE;
1651 unit->prof_percent = 100; 1478 unit->prof_percent = 100;
1652 syslog(LOG_NOTICE, "Profile `%s' is done", profile->name); 1479 syslog(LOG_NOTICE, "Profile `%s' is done", profile->name);
1480 unit->mqtt_flag |= (MQTT_FLAG_PERCENT | MQTT_FLAG_PROFILE | MQTT_FLAG_SP);
1653 } 1481 }
1654 break; 1482 break;
1655 1483
1656 case PROFILE_DONE: 1484 case PROFILE_DONE:
1657 /* 1485 /*
1822 } else { 1650 } else {
1823 int power = round(unit->PID_heat->OutP); 1651 int power = round(unit->PID_heat->OutP);
1824 if (unit->heater_state != power) { 1652 if (unit->heater_state != power) {
1825 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power); 1653 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power);
1826 unit->heater_state = power; 1654 unit->heater_state = power;
1827 #ifdef HAVE_MOSQUITTO_H 1655 if (unit->heater_address)
1828 if (mqtt_use && unit->heater_address) { 1656 mqtt_publish_int(unit->uuid, (char *)"heater", unit->heater_state);
1829 sprintf(buf, "%d", unit->heater_state);
1830 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid);
1831 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1832 }
1833 #endif
1834 } 1657 }
1835 } 1658 }
1836 } else { 1659 } else {
1837 if (unit->heater_wait > 0) { 1660 if (unit->heater_wait > 0) {
1838 unit->heater_wait--; 1661 unit->heater_wait--;
1839 } else { 1662 } else {
1840 if (unit->heater_state) { 1663 if (unit->heater_state) {
1841 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name); 1664 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name);
1842 unit->heater_state = 0; 1665 unit->heater_state = 0;
1843 #ifdef HAVE_MOSQUITTO_H 1666 if (unit->heater_address)
1844 if (mqtt_use && unit->heater_address) { 1667 mqtt_publish_int(unit->uuid, (char *)"heater", 0);
1845 sprintf(buf, "0");
1846 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid);
1847 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1848 }
1849 #endif
1850 } 1668 }
1851 } 1669 }
1852 } 1670 }
1853 if (unit->door_state) 1671 if (unit->door_state)
1854 device_out(unit->heater_address, unit->heater_state); 1672 device_out(unit->heater_address, unit->heater_state);
1863 } else { 1681 } else {
1864 int power = round(unit->PID_cool->OutP); 1682 int power = round(unit->PID_cool->OutP);
1865 if (unit->cooler_state != power) { 1683 if (unit->cooler_state != power) {
1866 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power); 1684 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power);
1867 unit->cooler_state = power; 1685 unit->cooler_state = power;
1868 #ifdef HAVE_MOSQUITTO_H 1686 if (unit->cooler_address)
1869 if (mqtt_use && unit->cooler_address) { 1687 mqtt_publish_int(unit->uuid, (char *)"cooler", unit->cooler_state);
1870 sprintf(buf, "%d", unit->cooler_state);
1871 snprintf(topic, 1023, "fermenter/%s/%s/cooler", hostname, unit->uuid);
1872 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1873 }
1874 #endif
1875 } 1688 }
1876 } 1689 }
1877 } else { 1690 } else {
1878 if (unit->cooler_wait > 0) { 1691 if (unit->cooler_wait > 0) {
1879 unit->cooler_wait--; 1692 unit->cooler_wait--;
1880 } else { 1693 } else {
1881 if (unit->cooler_state) { 1694 if (unit->cooler_state) {
1882 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name); 1695 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name);
1883 unit->cooler_state = 0; 1696 unit->cooler_state = 0;
1884 #ifdef HAVE_MOSQUITTO_H 1697 if (unit->cooler_address)
1885 if (mqtt_use && unit->cooler_address) { 1698 mqtt_publish_int(unit->uuid, (char *)"cooler", 0);
1886 sprintf(buf, "0");
1887 snprintf(topic, 1023, "fermenter/%s/%s/cooler", hostname, unit->uuid);
1888 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1889 }
1890 #endif
1891 } 1699 }
1892 } 1700 }
1893 } 1701 }
1894 if (unit->door_state) 1702 if (unit->door_state)
1895 device_out(unit->cooler_address, unit->cooler_state); 1703 device_out(unit->cooler_address, unit->cooler_state);
1910 unit->fan_wait++; 1718 unit->fan_wait++;
1911 } else { 1719 } else {
1912 if (! unit->fan_state) { 1720 if (! unit->fan_state) {
1913 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name); 1721 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name);
1914 unit->fan_state = 100; 1722 unit->fan_state = 100;
1915 #ifdef HAVE_MOSQUITTO_H 1723 if (unit->fan_address)
1916 if (mqtt_use && unit->fan_address) { 1724 mqtt_publish_int(unit->uuid, (char *)"fan", 100);
1917 sprintf(buf, "100");
1918 snprintf(topic, 1023, "fermenter/%s/%s/fan", hostname, unit->uuid);
1919 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1920 }
1921 #endif
1922 } 1725 }
1923 } 1726 }
1924 } else { 1727 } else {
1925 if (unit->fan_wait > 0) { 1728 if (unit->fan_wait > 0) {
1926 unit->fan_wait--; 1729 unit->fan_wait--;
1927 } else { 1730 } else {
1928 if (unit->fan_state) { 1731 if (unit->fan_state) {
1929 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name); 1732 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name);
1930 unit->fan_state = 0; 1733 unit->fan_state = 0;
1931 #ifdef HAVE_MOSQUITTO_H 1734 if (unit->fan_address)
1932 if (mqtt_use && unit->fan_address) { 1735 mqtt_publish_int(unit->uuid, (char *)"fan", 0);
1933 sprintf(buf, "0");
1934 snprintf(topic, 1023, "fermenter/%s/%s/fan", hostname, unit->uuid);
1935 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1936 }
1937 #endif
1938 } 1736 }
1939 } 1737 }
1940 } 1738 }
1941 device_out(unit->fan_address, unit->fan_state); 1739 device_out(unit->fan_address, unit->fan_state);
1942 } 1740 }
1972 if (unit->prof_state != PROFILE_OFF) { 1770 if (unit->prof_state != PROFILE_OFF) {
1973 LCDspL = unit->prof_target_lo; 1771 LCDspL = unit->prof_target_lo;
1974 LCDspH = unit->prof_target_hi; 1772 LCDspH = unit->prof_target_hi;
1975 } 1773 }
1976 } 1774 }
1977 #ifdef HAVE_MOSQUITTO_H 1775 if ((seconds == 60) && ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE))) {
1978 if (mqtt_use && (seconds == 60) && ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER) || (unit->mode == UNITMODE_PROFILE))) { 1776 unit->mqtt_flag |= MQTT_FLAG_SP;
1979 sprintf(buf, "%.1f", LCDspH); 1777 }
1980 snprintf(topic, 1023, "fermenter/%s/%s/setpoint/high", hostname, unit->uuid);
1981 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1982 sprintf(buf, "%.1f", LCDspL);
1983 snprintf(topic, 1023, "fermenter/%s/%s/setpoint/low", hostname, unit->uuid);
1984 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1985 }
1986 #endif
1987 #ifdef HAVE_WIRINGPI_H 1778 #ifdef HAVE_WIRINGPI_H
1988 piLock(LOCK_LCD); 1779 piLock(LOCK_LCD);
1989 #endif 1780 #endif
1990 /* 1781 /*
1991 * Write 4 rows to the LCD to display the unit state 1782 * Write 4 rows to the LCD to display the unit state
1995 lcd_buf_write(row++, "%c%5.1f\2 A%6.2f\1 ", LCDstatC, LCDspH, LCDair); 1786 lcd_buf_write(row++, "%c%5.1f\2 A%6.2f\1 ", LCDstatC, LCDspH, LCDair);
1996 lcd_buf_write(row++, "%c%5.1f\2 B%6.2f\1 ", LCDstatH, LCDspL, LCDbeer); 1787 lcd_buf_write(row++, "%c%5.1f\2 B%6.2f\1 ", LCDstatH, LCDspL, LCDbeer);
1997 #ifdef HAVE_WIRINGPI_H 1788 #ifdef HAVE_WIRINGPI_H
1998 piUnlock(LOCK_LCD); 1789 piUnlock(LOCK_LCD);
1999 #endif 1790 #endif
1791
1792 /*
1793 * Publish MQTT messages set in flag
1794 */
1795 if (unit->mqtt_flag & MQTT_FLAG_SP) {
1796 mqtt_publish_float(unit->uuid, (char *)"setpoint/high", LCDspH, 1);
1797 mqtt_publish_float(unit->uuid, (char *)"setpoint/low", LCDspL, 1);
1798 }
1799 if (unit->mqtt_flag & MQTT_FLAG_AIR) {
1800 mqtt_publish_float(unit->uuid, (char *)"air/temperature", unit->air_temperature / 1000.0, 3);
1801 }
1802 if (unit->mqtt_flag & MQTT_FLAG_BEER) {
1803 mqtt_publish_float(unit->uuid, (char *)"beer/temperature", unit->beer_temperature / 1000.0, 3);
1804 }
1805 if (unit->mqtt_flag & MQTT_FLAG_MODE) {
1806 mqtt_publish_str(unit->uuid, (char *)"mode", (char *)UNITMODE[unit->mode]);
1807 }
1808 if (unit->mqtt_flag & MQTT_FLAG_PROFILE) {
1809 mqtt_publish_str(unit->uuid, (char *)"profile/uuid", unit->profile);
1810 mqtt_publish_str(unit->uuid, (char *)"profile/state", (char *)PROFSTATE[unit->prof_state]);
1811 }
1812 if (unit->mqtt_flag & MQTT_FLAG_PERCENT) {
1813 mqtt_publish_int(unit->uuid, (char *)"profile/percent", unit->prof_percent);
1814 }
1815 unit->mqtt_flag = 0;
2000 } /* for units */ 1816 } /* for units */
2001 1817
2002 #ifdef HAVE_WIRINGPI_H 1818 #ifdef HAVE_WIRINGPI_H
2003 piLock(LOCK_MENU); 1819 piLock(LOCK_MENU);
2004 #endif 1820 #endif
2108 /* 1924 /*
2109 * Stop units processing in a neat way 1925 * Stop units processing in a neat way
2110 */ 1926 */
2111 for (unit = Config.units; unit; unit = unit->next) { 1927 for (unit = Config.units; unit; unit = unit->next) {
2112 1928
2113 #ifdef HAVE_MOSQUITTO_H 1929 if (unit->mode != UNITMODE_OFF) {
2114 if (mqtt_use && (unit->mode != UNITMODE_OFF)) { 1930 if (unit->heater_address)
2115 sprintf(buf, "0"); 1931 mqtt_publish_int(unit->uuid, (char *)"heater", 0);
2116 if (unit->heater_address) { 1932 if (unit->cooler_address)
2117 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid); 1933 mqtt_publish_int(unit->uuid, (char *)"cooler", 0);
2118 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1); 1934 if (unit->fan_address)
2119 } 1935 mqtt_publish_int(unit->uuid, (char *)"fan", 0);
2120 if (unit->cooler_address) { 1936 mqtt_publish_int(unit->uuid, (char *)"state", 0);
2121 snprintf(topic, 1023, "fermenter/%s/%s/cooler", hostname, unit->uuid);
2122 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
2123 }
2124 if (unit->fan_address) {
2125 snprintf(topic, 1023, "fermenter/%s/%s/fan", hostname, unit->uuid);
2126 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
2127 }
2128 snprintf(topic, 1023, "fermenter/%s/%s/state", hostname, unit->uuid);
2129 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
2130 } 1937 }
2131 #endif
2132 1938
2133 /* 1939 /*
2134 * Turn everything off 1940 * Turn everything off
2135 */ 1941 */
2136 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 1942 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
2140 device_out(unit->fan_address, unit->fan_state); 1946 device_out(unit->fan_address, unit->fan_state);
2141 device_out(unit->light_address, unit->light_state); 1947 device_out(unit->light_address, unit->light_state);
2142 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]); 1948 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]);
2143 } 1949 }
2144 1950
2145 #ifdef HAVE_MOSQUITTO_H 1951 mqtt_disconnect();
2146
2147 if (mqtt_use) {
2148 /*
2149 * Final publish 0 to clients/<hostname>/thermferm/state
2150 */
2151 syslog(LOG_NOTICE, "MQTT disconnecting");
2152 sprintf(buf, "0");
2153 mosquitto_publish(mosq, &mqtt_mid_sent, state, strlen(buf), buf, mqtt_qos, true);
2154 mqtt_last_mid = mqtt_mid_sent;
2155 mqtt_status = STATUS_WAITING;
2156
2157 do {
2158 if (mqtt_status == STATUS_WAITING) {
2159 if (debug)
2160 fprintf(stdout, (char *)"Waiting\n");
2161 if (mqtt_last_mid_sent == mqtt_last_mid && mqtt_disconnect_sent == FALSE) {
2162 mosquitto_disconnect(mosq);
2163 mqtt_disconnect_sent = TRUE;
2164 }
2165 usleep(100000);
2166 }
2167 rc = MOSQ_ERR_SUCCESS;
2168 } while (rc == MOSQ_ERR_SUCCESS && mqtt_connected);
2169
2170 mosquitto_loop_stop(mosq, FALSE);
2171 mosquitto_destroy(mosq);
2172 mosquitto_lib_cleanup();
2173 }
2174 #endif
2175 1952
2176 syslog(LOG_NOTICE, "Out of loop"); 1953 syslog(LOG_NOTICE, "Out of loop");
2177 if (debug) 1954 if (debug)
2178 fprintf(stdout, (char *)"Out of loop\n"); 1955 fprintf(stdout, (char *)"Out of loop\n");
2179 1956

mercurial