thermferm/thermferm.c

changeset 497
18ace27338e5
parent 496
5cf6f099c897
child 498
4903b4da9d40
equal deleted inserted replaced
496:5cf6f099c897 497:18ace27338e5
64 unsigned char CoolONOFF[8] = { 0b00000, 0b01110, 0b01000, 0b01000, 0b01000, 0b01000, 0b01110, 0b00000 }; // [3] Cool Symbol 64 unsigned char CoolONOFF[8] = { 0b00000, 0b01110, 0b01000, 0b01000, 0b01000, 0b01000, 0b01110, 0b00000 }; // [3] Cool Symbol
65 unsigned char RevCoolONOFF[8] = { 0b11111, 0b10001, 0b10111, 0b10111, 0b10111, 0b10111, 0b10001, 0b11111 }; // [4] Reverse Cool Symbol 65 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 66 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 67 unsigned char RevHeatONOFF[8] = { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 }; // [6] reverse HEAT symbol
68 68
69
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
69 89
70 int server(void); 90 int server(void);
71 void help(void); 91 void help(void);
72 void die(int); 92 void die(int);
73 void stopLCD(void); 93 void stopLCD(void);
940 syslog(LOG_NOTICE, "Finished, rc=%d", rc); 960 syslog(LOG_NOTICE, "Finished, rc=%d", rc);
941 return rc; 961 return rc;
942 } 962 }
943 963
944 964
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
945 1015
946 int server(void) 1016 int server(void)
947 { 1017 {
948 char buf[1024], *filename, target_lo[40], target_hi[40], heater[40], cooler[40], fan[40], door[40]; 1018 char buf[1024], *filename, target_lo[40], target_hi[40], heater[40], cooler[40], fan[40], door[40];
949 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40]; 1019 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40];
960 int current_step, valid_step, time_until_now, previous_fridge_mode; 1030 int current_step, valid_step, time_until_now, previous_fridge_mode;
961 float previous_target_lo, previous_target_hi; 1031 float previous_target_lo, previous_target_hi;
962 float LCDair, LCDbeer, LCDspL, LCDspH; 1032 float LCDair, LCDbeer, LCDspL, LCDspH;
963 unsigned char LCDstatC, LCDstatH; 1033 unsigned char LCDstatC, LCDstatH;
964 int LCDunit; 1034 int LCDunit;
965 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
966 1041
967 if (lockprog((char *)"thermferm")) { 1042 if (lockprog((char *)"thermferm")) {
968 syslog(LOG_NOTICE, "Can't lock"); 1043 syslog(LOG_NOTICE, "Can't lock");
969 return 1; 1044 return 1;
970 } 1045 }
1046
1047
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
971 1126
972 if ((rc = devices_detect())) { 1127 if ((rc = devices_detect())) {
973 syslog(LOG_NOTICE, "Detected %d new devices", rc); 1128 syslog(LOG_NOTICE, "Detected %d new devices", rc);
974 wrconfig(); 1129 wrconfig();
975 } 1130 }
1029 } else { 1184 } else {
1030 t++; 1185 t++;
1031 #endif 1186 #endif
1032 } 1187 }
1033 #endif 1188 #endif
1189
1034 1190
1035 /* 1191 /*
1036 * Initialize units for processing 1192 * Initialize units for processing
1037 */ 1193 */
1038 for (unit = Config.units; unit; unit = unit->next) { 1194 for (unit = Config.units; unit; unit = unit->next) {
1039 /* 1195 /*
1040 * Safety, turn everything off 1196 * Safety, turn everything off
1041 */ 1197 */
1042 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 1198 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
1043 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; 1199 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
1200 #ifdef HAVE_MOSQUITTO_H
1201 if (mqtt_use && (unit->mode != UNITMODE_OFF)) {
1202 sprintf(buf, "1");
1203 snprintf(topic, 1023, "fermenter/%s/%s/state", hostname, unit->uuid);
1204 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1205 sprintf(buf, "%s", unit->name);
1206 snprintf(topic, 1023, "fermenter/%s/%s/name", hostname, unit->uuid);
1207 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1208 sprintf(buf, "0");
1209 if (unit->heater_address) {
1210 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid);
1211 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
1212 }
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
1044 if (unit->mode == UNITMODE_PROFILE) { 1226 if (unit->mode == UNITMODE_PROFILE) {
1045 if (!unit->profile) 1227 if (!unit->profile)
1046 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name); 1228 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name);
1047 else 1229 else
1048 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); 1230 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
1053 } else if (unit->mode == UNITMODE_NONE) { 1235 } else if (unit->mode == UNITMODE_NONE) {
1054 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name); 1236 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name);
1055 } else { 1237 } else {
1056 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name); 1238 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name);
1057 } 1239 }
1058 } 1240
1059 1241 /*
1060 #ifdef HAVE_WIRINGPI_H 1242 * Initialize logfile
1061 piLock(LOCK_LCD); 1243 */
1062 #endif
1063 lcd_buf_write(1, (char *)" ThermFerm ");
1064 lcd_buf_write(2, (char *)" Version %s ", VERSION);
1065 #ifdef HAVE_WIRINGPI_H
1066 piUnlock(LOCK_LCD);
1067 #endif
1068
1069 /*
1070 * Initialize logfiles for each unit
1071 */
1072 for (unit = Config.units; unit; unit = unit->next) {
1073 if (unit->mode != UNITMODE_OFF) { 1244 if (unit->mode != UNITMODE_OFF) {
1074 initlog(unit->name); 1245 initlog(unit->name);
1075 } 1246 }
1076 } 1247 }
1248
1249 #ifdef HAVE_WIRINGPI_H
1250 piLock(LOCK_LCD);
1251 #endif
1252 lcd_buf_write(1, (char *)" ThermFerm ");
1253 lcd_buf_write(2, (char *)" Version %s ", VERSION);
1254 #ifdef HAVE_WIRINGPI_H
1255 piUnlock(LOCK_LCD);
1256 #endif
1257
1077 1258
1078 do { 1259 do {
1079 if (my_shutdown) 1260 if (my_shutdown)
1080 run = 0; 1261 run = 0;
1081 1262
1126 #endif 1307 #endif
1127 1308
1128 #ifdef HAVE_WIRINGPI_H 1309 #ifdef HAVE_WIRINGPI_H
1129 piLock(LOCK_LCD); 1310 piLock(LOCK_LCD);
1130 #endif 1311 #endif
1131 lcd_buf_write(row, "Room temp N/A ", Config.temp_value / 1000.0, 0x01); 1312 lcd_buf_write(row, "Room temp N/A ");
1132 #ifdef HAVE_WIRINGPI_H 1313 #ifdef HAVE_WIRINGPI_H
1133 piUnlock(LOCK_LCD); 1314 piUnlock(LOCK_LCD);
1134 #endif 1315 #endif
1135 if (Config.temp_address) { 1316 if (Config.temp_address) {
1136 rc = device_in(Config.temp_address, &temp); 1317 rc = device_in(Config.temp_address, &temp);
1137 if (rc == DEVPRESENT_YES) { 1318 if (rc == DEVPRESENT_YES) {
1319 #ifdef HAVE_MOSQUITTO_H
1320 if (mqtt_use && (Config.temp_value != temp)) {
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
1138 Config.temp_value = temp; 1326 Config.temp_value = temp;
1139 Config.temp_state = 0; 1327 Config.temp_state = 0;
1140 #ifdef HAVE_WIRINGPI_H 1328 #ifdef HAVE_WIRINGPI_H
1141 piLock(LOCK_LCD); 1329 piLock(LOCK_LCD);
1142 #endif 1330 #endif
1153 row++; 1341 row++;
1154 1342
1155 #ifdef HAVE_WIRINGPI_H 1343 #ifdef HAVE_WIRINGPI_H
1156 piLock(LOCK_LCD); 1344 piLock(LOCK_LCD);
1157 #endif 1345 #endif
1158 lcd_buf_write(row, " Humidity N/A ", Config.hum_value / 1000.0); 1346 lcd_buf_write(row, " Humidity N/A ");
1159 #ifdef HAVE_WIRINGPI_H 1347 #ifdef HAVE_WIRINGPI_H
1160 piUnlock(LOCK_LCD); 1348 piUnlock(LOCK_LCD);
1161 #endif 1349 #endif
1162 1350
1163 if (Config.hum_address) { 1351 if (Config.hum_address) {
1164 rc = device_in(Config.hum_address, &temp); 1352 rc = device_in(Config.hum_address, &temp);
1165 if (rc == DEVPRESENT_YES) { 1353 if (rc == DEVPRESENT_YES) {
1354 #ifdef HAVE_MOSQUITTO_H
1355 if (mqtt_use && (Config.hum_value != temp)) {
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
1166 Config.hum_value = temp; 1361 Config.hum_value = temp;
1167 Config.hum_state = 0; 1362 Config.hum_state = 0;
1168 #ifdef HAVE_WIRINGPI_H 1363 #ifdef HAVE_WIRINGPI_H
1169 piLock(LOCK_LCD); 1364 piLock(LOCK_LCD);
1170 #endif 1365 #endif
1195 * Maximum error is 40 degrees for now. 1390 * Maximum error is 40 degrees for now.
1196 */ 1391 */
1197 deviation = 40000; 1392 deviation = 40000;
1198 if ((unit->air_temperature == 0) || 1393 if ((unit->air_temperature == 0) ||
1199 (unit->air_temperature && (temp > (int)unit->air_temperature - deviation) && (temp < ((int)unit->air_temperature + deviation)))) { 1394 (unit->air_temperature && (temp > (int)unit->air_temperature - deviation) && (temp < ((int)unit->air_temperature + deviation)))) {
1395 #ifdef HAVE_MOSQUITTO_H
1396 if (mqtt_use && (unit->air_temperature != temp)) {
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
1200 unit->air_temperature = temp; 1402 unit->air_temperature = temp;
1201 unit->air_state = 0; 1403 unit->air_state = 0;
1202 } else { 1404 } else {
1203 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->air_temperature, temp); 1405 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->air_temperature, temp);
1204 if (debug) { 1406 if (debug) {
1216 rc = device_in(unit->beer_address, &temp); 1418 rc = device_in(unit->beer_address, &temp);
1217 if (rc == DEVPRESENT_YES) { 1419 if (rc == DEVPRESENT_YES) {
1218 deviation = 40000; 1420 deviation = 40000;
1219 if ((unit->beer_temperature == 0) || 1421 if ((unit->beer_temperature == 0) ||
1220 (unit->beer_temperature && (temp > (int)unit->beer_temperature - deviation) && (temp < ((int)unit->beer_temperature + deviation)))) { 1422 (unit->beer_temperature && (temp > (int)unit->beer_temperature - deviation) && (temp < ((int)unit->beer_temperature + deviation)))) {
1221 unit->beer_temperature = temp; 1423 #ifdef HAVE_MOSQUITTO_H
1424 if (mqtt_use && (unit->beer_temperature != temp)) {
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;
1222 unit->beer_state = 0; 1431 unit->beer_state = 0;
1223 } else { 1432 } else {
1224 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->beer_temperature, temp); 1433 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->beer_temperature, temp);
1225 if (debug) { 1434 if (debug) {
1226 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->beer_temperature, temp); 1435 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->beer_temperature, temp);
1238 */ 1447 */
1239 unit->door_state = 1; 1448 unit->door_state = 1;
1240 if (unit->door_address) { 1449 if (unit->door_address) {
1241 rc = device_in(unit->door_address, &temp); 1450 rc = device_in(unit->door_address, &temp);
1242 if (rc == DEVPRESENT_YES) { 1451 if (rc == DEVPRESENT_YES) {
1452 #ifdef HAVE_MOSQUITTO_H
1453 snprintf(topic, 1023, "fermenter/%s/%s/door", hostname, unit->uuid);
1454 #endif
1243 if (temp) { 1455 if (temp) {
1244 if (unit->door_state == 0) { 1456 if (unit->door_state == 0) {
1245 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name); 1457 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name);
1246 unit->door_state = 1; 1458 unit->door_state = 1;
1459 #ifdef HAVE_MOSQUITTO_H
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
1247 } 1465 }
1248 } else { 1466 } else {
1249 if (unit->door_state) { 1467 if (unit->door_state) {
1250 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name); 1468 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name);
1251 unit->door_state = 0; 1469 unit->door_state = 0;
1470 #ifdef HAVE_MOSQUITTO_H
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
1252 } 1476 }
1253 } 1477 }
1254 } 1478 }
1255 } 1479 }
1256 1480
1598 } else { 1822 } else {
1599 int power = round(unit->PID_heat->OutP); 1823 int power = round(unit->PID_heat->OutP);
1600 if (unit->heater_state != power) { 1824 if (unit->heater_state != power) {
1601 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power); 1825 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power);
1602 unit->heater_state = power; 1826 unit->heater_state = power;
1827 #ifdef HAVE_MOSQUITTO_H
1828 if (mqtt_use && unit->heater_address) {
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
1603 } 1834 }
1604 } 1835 }
1605 } else { 1836 } else {
1606 if (unit->heater_wait > 0) { 1837 if (unit->heater_wait > 0) {
1607 unit->heater_wait--; 1838 unit->heater_wait--;
1608 } else { 1839 } else {
1609 if (unit->heater_state) { 1840 if (unit->heater_state) {
1610 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name); 1841 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name);
1611 unit->heater_state = 0; 1842 unit->heater_state = 0;
1843 #ifdef HAVE_MOSQUITTO_H
1844 if (mqtt_use && unit->heater_address) {
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
1612 } 1850 }
1613 } 1851 }
1614 } 1852 }
1615 if (unit->door_state) 1853 if (unit->door_state)
1616 device_out(unit->heater_address, unit->heater_state); 1854 device_out(unit->heater_address, unit->heater_state);
1625 } else { 1863 } else {
1626 int power = round(unit->PID_cool->OutP); 1864 int power = round(unit->PID_cool->OutP);
1627 if (unit->cooler_state != power) { 1865 if (unit->cooler_state != power) {
1628 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power); 1866 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power);
1629 unit->cooler_state = power; 1867 unit->cooler_state = power;
1868 #ifdef HAVE_MOSQUITTO_H
1869 if (mqtt_use && unit->cooler_address) {
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
1630 } 1875 }
1631 } 1876 }
1632 } else { 1877 } else {
1633 if (unit->cooler_wait > 0) { 1878 if (unit->cooler_wait > 0) {
1634 unit->cooler_wait--; 1879 unit->cooler_wait--;
1635 } else { 1880 } else {
1636 if (unit->cooler_state) { 1881 if (unit->cooler_state) {
1637 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name); 1882 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name);
1638 unit->cooler_state = 0; 1883 unit->cooler_state = 0;
1884 #ifdef HAVE_MOSQUITTO_H
1885 if (mqtt_use && unit->cooler_address) {
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
1639 } 1891 }
1640 } 1892 }
1641 } 1893 }
1642 if (unit->door_state) 1894 if (unit->door_state)
1643 device_out(unit->cooler_address, unit->cooler_state); 1895 device_out(unit->cooler_address, unit->cooler_state);
1658 unit->fan_wait++; 1910 unit->fan_wait++;
1659 } else { 1911 } else {
1660 if (! unit->fan_state) { 1912 if (! unit->fan_state) {
1661 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name); 1913 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name);
1662 unit->fan_state = 100; 1914 unit->fan_state = 100;
1915 #ifdef HAVE_MOSQUITTO_H
1916 if (mqtt_use && unit->fan_address) {
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
1663 } 1922 }
1664 } 1923 }
1665 } else { 1924 } else {
1666 if (unit->fan_wait > 0) { 1925 if (unit->fan_wait > 0) {
1667 unit->fan_wait--; 1926 unit->fan_wait--;
1668 } else { 1927 } else {
1669 if (unit->fan_state) { 1928 if (unit->fan_state) {
1670 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name); 1929 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name);
1671 unit->fan_state = 0; 1930 unit->fan_state = 0;
1931 #ifdef HAVE_MOSQUITTO_H
1932 if (mqtt_use && unit->fan_address) {
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
1672 } 1938 }
1673 } 1939 }
1674 } 1940 }
1675 device_out(unit->fan_address, unit->fan_state); 1941 device_out(unit->fan_address, unit->fan_state);
1676 } 1942 }
1706 if (unit->prof_state != PROFILE_OFF) { 1972 if (unit->prof_state != PROFILE_OFF) {
1707 LCDspL = unit->prof_target_lo; 1973 LCDspL = unit->prof_target_lo;
1708 LCDspH = unit->prof_target_hi; 1974 LCDspH = unit->prof_target_hi;
1709 } 1975 }
1710 } 1976 }
1977 #ifdef HAVE_MOSQUITTO_H
1978 if (mqtt_use && (seconds == 60)) {
1979 sprintf(buf, "%.1f", LCDspH);
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
1711 #ifdef HAVE_WIRINGPI_H 1987 #ifdef HAVE_WIRINGPI_H
1712 piLock(LOCK_LCD); 1988 piLock(LOCK_LCD);
1713 #endif 1989 #endif
1714 /* 1990 /*
1715 * Write 4 rows to the LCD to display the unit state 1991 * Write 4 rows to the LCD to display the unit state
1831 2107
1832 /* 2108 /*
1833 * Stop units processing in a neat way 2109 * Stop units processing in a neat way
1834 */ 2110 */
1835 for (unit = Config.units; unit; unit = unit->next) { 2111 for (unit = Config.units; unit; unit = unit->next) {
2112
2113 #ifdef HAVE_MOSQUITTO_H
2114 if (mqtt_use && (unit->mode != UNITMODE_OFF)) {
2115 sprintf(buf, "0");
2116 if (unit->heater_address) {
2117 snprintf(topic, 1023, "fermenter/%s/%s/heater", hostname, unit->uuid);
2118 mosquitto_publish(mosq, &mqtt_mid_sent, topic, strlen(buf), buf, mqtt_qos, 1);
2119 }
2120 if (unit->cooler_address) {
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 }
2131 #endif
2132
1836 /* 2133 /*
1837 * Turn everything off 2134 * Turn everything off
1838 */ 2135 */
1839 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 2136 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
1840 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; 2137 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
1843 device_out(unit->fan_address, unit->fan_state); 2140 device_out(unit->fan_address, unit->fan_state);
1844 device_out(unit->light_address, unit->light_state); 2141 device_out(unit->light_address, unit->light_state);
1845 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]); 2142 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]);
1846 } 2143 }
1847 2144
2145 #ifdef HAVE_MOSQUITTO_H
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
1848 syslog(LOG_NOTICE, "Out of loop"); 2176 syslog(LOG_NOTICE, "Out of loop");
1849 if (debug) 2177 if (debug)
1850 fprintf(stdout, (char *)"Out of loop\n"); 2178 fprintf(stdout, (char *)"Out of loop\n");
1851 2179
1852 /* 2180 /*

mercurial