thermferm/thermferm.c

changeset 506
cdcd07bbee30
parent 504
862de87f9f89
child 507
80344f433a78
equal deleted inserted replaced
504:862de87f9f89 506:cdcd07bbee30
1 /***************************************************************************** 1 /*****************************************************************************
2 * Copyright (C) 2014-2016 2 * Copyright (C) 2014-2017
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 *
1063 */ 1063 */
1064 for (unit = Config.units; unit; unit = unit->next) { 1064 for (unit = Config.units; unit; unit = unit->next) {
1065 /* 1065 /*
1066 * Safety, turn everything off 1066 * Safety, turn everything off
1067 */ 1067 */
1068 unit->mqtt_flag = MQTT_FLAG_MODE; 1068 unit->mqtt_flag = 0;
1069 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;
1070 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;
1071 mqtt_publish_int(unit->alias, (char *)"state", (unit->mode != UNITMODE_OFF) ? 1 : 0);
1072 if (unit->name)
1073 mqtt_publish_str(unit->alias, (char *)"name", unit->name);
1074 else
1075 mqtt_publish_clear(unit->alias, (char *)"name");
1076 if (unit->heater_address)
1077 mqtt_publish_int(unit->alias, (char *)"heater", 0);
1078 else
1079 mqtt_publish_clear(unit->alias, (char *)"heater");
1080 if (unit->cooler_address)
1081 mqtt_publish_int(unit->alias, (char *)"cooler", 0);
1082 else
1083 mqtt_publish_clear(unit->alias, (char *)"cooler");
1084 if (unit->fan_address)
1085 mqtt_publish_int(unit->alias, (char *)"fan", 0);
1086 else
1087 mqtt_publish_clear(unit->alias, (char *)"fan");
1088 if (unit->air_address)
1089 unit->mqtt_flag |= MQTT_FLAG_AIR;
1090 if (unit->beer_address)
1091 unit->mqtt_flag |= MQTT_FLAG_BEER;
1092 if (unit->mode == UNITMODE_PROFILE) { 1071 if (unit->mode == UNITMODE_PROFILE) {
1093 if (!unit->profile) 1072 if (!unit->profile)
1094 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name); 1073 syslog(LOG_NOTICE, "Starting unit `%s' in profile mode, no profile defined.", unit->name);
1095 else { 1074 else {
1096 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); 1075 syslog(LOG_NOTICE, "Starting unit `%s' in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
1097 unit->mqtt_flag |= MQTT_FLAG_SP;
1098 unit->mqtt_flag |= MQTT_FLAG_PROFILE;
1099 } 1076 }
1100 } else if (unit->mode == UNITMODE_BEER) { 1077 } else if (unit->mode == UNITMODE_BEER) {
1101 syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set); 1078 syslog(LOG_NOTICE, "Starting unit `%s' beer cooler at %.1f degrees", unit->name, unit->beer_set);
1102 unit->mqtt_flag |= MQTT_FLAG_SP;
1103 } else if (unit->mode == UNITMODE_FRIDGE) { 1079 } else if (unit->mode == UNITMODE_FRIDGE) {
1104 syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set); 1080 syslog(LOG_NOTICE, "Starting unit `%s' as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
1105 unit->mqtt_flag |= MQTT_FLAG_SP;
1106 } else if (unit->mode == UNITMODE_NONE) { 1081 } else if (unit->mode == UNITMODE_NONE) {
1107 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name); 1082 syslog(LOG_NOTICE, "Starting unit `%s' in inactive state", unit->name);
1108 } else { 1083 } else {
1109 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name); 1084 syslog(LOG_NOTICE, "Starting unit `%s' in off state", unit->name);
1110 } 1085 }
1182 #endif 1157 #endif
1183 lcd_buf_write(row, "Room temp N/A "); 1158 lcd_buf_write(row, "Room temp N/A ");
1184 #ifdef HAVE_WIRINGPI_H 1159 #ifdef HAVE_WIRINGPI_H
1185 piUnlock(LOCK_LCD); 1160 piUnlock(LOCK_LCD);
1186 #endif 1161 #endif
1162 bool updateHT = false;
1187 if (Config.temp_address) { 1163 if (Config.temp_address) {
1188 rc = device_in(Config.temp_address, &temp); 1164 rc = device_in(Config.temp_address, &temp);
1189 if (rc == DEVPRESENT_YES) { 1165 if (rc == DEVPRESENT_YES) {
1190 if (Config.temp_value != temp) 1166 if (Config.temp_value != temp)
1191 mqtt_publish_float((char *)"room", (char *)"temperature", temp / 1000.0, 1); 1167 updateHT = true;
1192 Config.temp_value = temp; 1168 Config.temp_value = temp;
1193 Config.temp_state = 0; 1169 Config.temp_state = 0;
1194 #ifdef HAVE_WIRINGPI_H 1170 #ifdef HAVE_WIRINGPI_H
1195 piLock(LOCK_LCD); 1171 piLock(LOCK_LCD);
1196 #endif 1172 #endif
1216 1192
1217 if (Config.hum_address) { 1193 if (Config.hum_address) {
1218 rc = device_in(Config.hum_address, &temp); 1194 rc = device_in(Config.hum_address, &temp);
1219 if (rc == DEVPRESENT_YES) { 1195 if (rc == DEVPRESENT_YES) {
1220 if (Config.hum_value != temp) 1196 if (Config.hum_value != temp)
1221 mqtt_publish_float((char *)"room", (char *)"humidity", temp / 1000.0, 1); 1197 updateHT = true;
1222 Config.hum_value = temp; 1198 Config.hum_value = temp;
1223 Config.hum_state = 0; 1199 Config.hum_state = 0;
1224 #ifdef HAVE_WIRINGPI_H 1200 #ifdef HAVE_WIRINGPI_H
1225 piLock(LOCK_LCD); 1201 piLock(LOCK_LCD);
1226 #endif 1202 #endif
1233 } else { 1209 } else {
1234 Config.hum_state = 2; 1210 Config.hum_state = 2;
1235 } 1211 }
1236 } 1212 }
1237 row++; 1213 row++;
1214 if (updateHT)
1215 publishNData(false, MQTT_NODE_HT);
1238 1216
1239 LCDunit = 0; 1217 LCDunit = 0;
1240 for (unit = Config.units; unit; unit = unit->next) { 1218 for (unit = Config.units; unit; unit = unit->next) {
1241 LCDunit++; 1219 LCDunit++;
1220 unit->mqtt_flag = 0;
1221
1242 if (unit->air_address) { 1222 if (unit->air_address) {
1243 rc = device_in(unit->air_address, &temp); 1223 rc = device_in(unit->air_address, &temp);
1244 if (rc == DEVPRESENT_YES) { 1224 if (rc == DEVPRESENT_YES) {
1245 /* 1225 /*
1246 * It is possible to have read errors or extreme values. 1226 * It is possible to have read errors or extreme values.
1295 if (rc == DEVPRESENT_YES) { 1275 if (rc == DEVPRESENT_YES) {
1296 if (temp) { 1276 if (temp) {
1297 if (unit->door_state == 0) { 1277 if (unit->door_state == 0) {
1298 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name); 1278 syslog(LOG_NOTICE, "Unit `%s' door closed", unit->name);
1299 unit->door_state = 1; 1279 unit->door_state = 1;
1300 mqtt_publish_str(unit->alias, (char *)"door", (char *)"closed"); 1280 unit->mqtt_flag |= MQTT_FLAG_DOOR;
1301 } 1281 }
1302 } else { 1282 } else {
1303 if (unit->door_state) { 1283 if (unit->door_state) {
1304 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name); 1284 syslog(LOG_NOTICE, "Unit `%s' door opened", unit->name);
1305 unit->door_state = 0; 1285 unit->door_state = 0;
1306 mqtt_publish_str(unit->alias, (char *)"door", (char *)"open"); 1286 unit->mqtt_flag |= MQTT_FLAG_DOOR;
1307 } 1287 }
1308 } 1288 }
1309 } else { 1289 } else {
1310 unit->door_state = 1; 1290 unit->door_state = 1;
1311 } 1291 }
1321 if (rc == DEVPRESENT_YES) { 1301 if (rc == DEVPRESENT_YES) {
1322 if (temp) { 1302 if (temp) {
1323 if (unit->psu_state == 0) { 1303 if (unit->psu_state == 0) {
1324 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->name); 1304 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is on", unit->name);
1325 unit->psu_state = 1; 1305 unit->psu_state = 1;
1326 mqtt_publish_str(unit->alias, (char *)"12volt", (char *)"on"); 1306 unit->mqtt_flag |= MQTT_FLAG_PSU;
1327 } 1307 }
1328 } else { 1308 } else {
1329 if (unit->psu_state) { 1309 if (unit->psu_state) {
1330 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->name); 1310 syslog(LOG_NOTICE, "Unit `%s' PSU (12 volt) is off", unit->name);
1331 unit->psu_state = 0; 1311 unit->psu_state = 0;
1332 mqtt_publish_str(unit->alias, (char *)"12volt", (char *)"off"); 1312 unit->mqtt_flag |= MQTT_FLAG_PSU;
1333 } 1313 }
1334 } 1314 }
1335 } else { 1315 } else {
1336 unit->psu_state = 1; 1316 unit->psu_state = 1;
1337 } 1317 }
1408 unit->prof_primary_done = time(NULL); 1388 unit->prof_primary_done = time(NULL);
1409 syslog(LOG_NOTICE, "Profile `%s' primary fermentation is ready (cooler mode)", profile->name); 1389 syslog(LOG_NOTICE, "Profile `%s' primary fermentation is ready (cooler mode)", profile->name);
1410 } 1390 }
1411 } else { 1391 } else {
1412 /* 1392 /*
1413 * This method works if the unit has no cooling or if the profile allowd the 1393 * This method works if the unit has no cooling or if the profile allowed the
1414 * beer temperature to rise freely. 1394 * beer temperature to rise freely.
1415 */ 1395 */
1416 if ((unit->beer_temperature / 1000.0) < (unit->prof_peak_abs - 0.5)) { 1396 if ((unit->beer_temperature / 1000.0) < (unit->prof_peak_abs - 0.5)) {
1417 unit->prof_primary_done = time(NULL); 1397 unit->prof_primary_done = time(NULL);
1418 syslog(LOG_NOTICE, "Profile `%s' primary fermentation is ready (free rise mode)", profile->name); 1398 syslog(LOG_NOTICE, "Profile `%s' primary fermentation is ready (free rise mode)", profile->name);
1559 if (unit->light_wait > 0) { 1539 if (unit->light_wait > 0) {
1560 unit->light_wait--; 1540 unit->light_wait--;
1561 } else { 1541 } else {
1562 unit->light_state = 0; 1542 unit->light_state = 0;
1563 syslog(LOG_NOTICE, "Unit `%s' lights On => Off", unit->name); 1543 syslog(LOG_NOTICE, "Unit `%s' lights On => Off", unit->name);
1544 unit->mqtt_flag |= MQTT_FLAG_LIGHT;
1564 } 1545 }
1565 } 1546 }
1566 if (!unit->door_state && !unit->light_state) { 1547 if (!unit->door_state && !unit->light_state) {
1567 unit->light_wait = unit->light_delay; /* No delay to turn lights on */ 1548 unit->light_wait = unit->light_delay; /* No delay to turn lights on */
1568 unit->light_state = 1; 1549 unit->light_state = 1;
1550 unit->mqtt_flag |= MQTT_FLAG_LIGHT;
1569 syslog(LOG_NOTICE, "Unit `%s' lights Off => On", unit->name); 1551 syslog(LOG_NOTICE, "Unit `%s' lights Off => On", unit->name);
1570 } 1552 }
1571 device_out(unit->light_address, unit->light_state); 1553 device_out(unit->light_address, unit->light_state);
1572 } 1554 }
1573 1555
1668 int power = round(unit->PID_heat->OutP); 1650 int power = round(unit->PID_heat->OutP);
1669 if (unit->heater_state != power) { 1651 if (unit->heater_state != power) {
1670 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power); 1652 syslog(LOG_NOTICE, "Unit `%s' heater %d%% => %d%%", unit->name, unit->heater_state, power);
1671 unit->heater_state = power; 1653 unit->heater_state = power;
1672 if (unit->heater_address) 1654 if (unit->heater_address)
1673 mqtt_publish_int(unit->alias, (char *)"heater", unit->heater_state); 1655 unit->mqtt_flag |= MQTT_FLAG_HEATER;
1674 } 1656 }
1675 } 1657 }
1676 } else { 1658 } else {
1677 if (unit->heater_wait > 0) { 1659 if (unit->heater_wait > 0) {
1678 unit->heater_wait--; 1660 unit->heater_wait--;
1679 } else { 1661 } else {
1680 if (unit->heater_state) { 1662 if (unit->heater_state) {
1681 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name); 1663 syslog(LOG_NOTICE, "Unit `%s' heater On => Off", unit->name);
1682 unit->heater_state = 0; 1664 unit->heater_state = 0;
1683 if (unit->heater_address) 1665 if (unit->heater_address)
1684 mqtt_publish_int(unit->alias, (char *)"heater", 0); 1666 unit->mqtt_flag |= MQTT_FLAG_HEATER;
1685 } 1667 }
1686 } 1668 }
1687 } 1669 }
1688 if (unit->door_state) 1670 if (unit->door_state)
1689 device_out(unit->heater_address, unit->heater_state); 1671 device_out(unit->heater_address, unit->heater_state);
1699 int power = round(unit->PID_cool->OutP); 1681 int power = round(unit->PID_cool->OutP);
1700 if (unit->cooler_state != power) { 1682 if (unit->cooler_state != power) {
1701 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power); 1683 syslog(LOG_NOTICE, "Unit `%s' cooler %d%% => %d%%", unit->name, unit->cooler_state, power);
1702 unit->cooler_state = power; 1684 unit->cooler_state = power;
1703 if (unit->cooler_address) 1685 if (unit->cooler_address)
1704 mqtt_publish_int(unit->alias, (char *)"cooler", unit->cooler_state); 1686 unit->mqtt_flag |= MQTT_FLAG_COOLER;
1705 } 1687 }
1706 } 1688 }
1707 } else { 1689 } else {
1708 if (unit->cooler_wait > 0) { 1690 if (unit->cooler_wait > 0) {
1709 unit->cooler_wait--; 1691 unit->cooler_wait--;
1710 } else { 1692 } else {
1711 if (unit->cooler_state) { 1693 if (unit->cooler_state) {
1712 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name); 1694 syslog(LOG_NOTICE, "Unit `%s' cooler On => Off", unit->name);
1713 unit->cooler_state = 0; 1695 unit->cooler_state = 0;
1714 if (unit->cooler_address) 1696 if (unit->cooler_address)
1715 mqtt_publish_int(unit->alias, (char *)"cooler", 0); 1697 unit->mqtt_flag |= MQTT_FLAG_COOLER;
1716 } 1698 }
1717 } 1699 }
1718 } 1700 }
1719 if (unit->door_state) 1701 if (unit->door_state)
1720 device_out(unit->cooler_address, unit->cooler_state); 1702 device_out(unit->cooler_address, unit->cooler_state);
1736 } else { 1718 } else {
1737 if (! unit->fan_state) { 1719 if (! unit->fan_state) {
1738 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name); 1720 syslog(LOG_NOTICE, "Unit `%s' Fan Off => On", unit->name);
1739 unit->fan_state = 100; 1721 unit->fan_state = 100;
1740 if (unit->fan_address) 1722 if (unit->fan_address)
1741 mqtt_publish_int(unit->alias, (char *)"fan", 100); 1723 unit->mqtt_flag |= MQTT_FLAG_FAN;
1742 } 1724 }
1743 } 1725 }
1744 } else { 1726 } else {
1745 if (unit->fan_wait > 0) { 1727 if (unit->fan_wait > 0) {
1746 unit->fan_wait--; 1728 unit->fan_wait--;
1747 } else { 1729 } else {
1748 if (unit->fan_state) { 1730 if (unit->fan_state) {
1749 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name); 1731 syslog(LOG_NOTICE, "Unit `%s' Fan On => Off", unit->name);
1750 unit->fan_state = 0; 1732 unit->fan_state = 0;
1751 if (unit->fan_address) 1733 if (unit->fan_address)
1752 mqtt_publish_int(unit->alias, (char *)"fan", 0); 1734 unit->mqtt_flag |= MQTT_FLAG_FAN;
1753 } 1735 }
1754 } 1736 }
1755 } 1737 }
1756 device_out(unit->fan_address, unit->fan_state); 1738 device_out(unit->fan_address, unit->fan_state);
1757 } 1739 }
1807 #endif 1789 #endif
1808 1790
1809 /* 1791 /*
1810 * Publish MQTT messages set in flag 1792 * Publish MQTT messages set in flag
1811 */ 1793 */
1812 if (unit->mqtt_flag & MQTT_FLAG_SP) { 1794 if (unit->mqtt_flag) {
1813 mqtt_publish_float(unit->alias, (char *)"setpoint/high", LCDspH, 1); 1795 publishDData(unit);
1814 mqtt_publish_float(unit->alias, (char *)"setpoint/low", LCDspL, 1);
1815 } 1796 }
1816 if (unit->mqtt_flag & MQTT_FLAG_AIR) {
1817 mqtt_publish_float(unit->alias, (char *)"air/temperature", unit->air_temperature / 1000.0, 3);
1818 }
1819 if (unit->mqtt_flag & MQTT_FLAG_BEER) {
1820 mqtt_publish_float(unit->alias, (char *)"beer/temperature", unit->beer_temperature / 1000.0, 3);
1821 }
1822 if (unit->mqtt_flag & MQTT_FLAG_MODE) {
1823 mqtt_publish_str(unit->alias, (char *)"mode", (char *)UNITMODE[unit->mode]);
1824 }
1825 if (unit->mqtt_flag & MQTT_FLAG_PROFILE) {
1826 mqtt_publish_str(unit->alias, (char *)"profile/uuid", unit->profile);
1827 mqtt_publish_str(unit->alias, (char *)"profile/state", (char *)PROFSTATE[unit->prof_state]);
1828 for (profile = Config.profiles; profile; profile = profile->next) {
1829 if (strcmp(unit->profile, profile->uuid) == 0) {
1830 mqtt_publish_str(unit->alias, (char *)"profile/name", profile->name);
1831 mqtt_publish_int(unit->alias, (char *)"profile/fridgemode", profile->fridge_mode);
1832 }
1833 }
1834 }
1835 if (unit->mqtt_flag & MQTT_FLAG_PERCENT) {
1836 mqtt_publish_int(unit->alias, (char *)"profile/percent", unit->prof_percent);
1837 }
1838 unit->mqtt_flag = 0;
1839 } /* for units */ 1797 } /* for units */
1840 1798
1841 #ifdef HAVE_WIRINGPI_H 1799 #ifdef HAVE_WIRINGPI_H
1842 piLock(LOCK_MENU); 1800 piLock(LOCK_MENU);
1843 #endif 1801 #endif
1946 1904
1947 /* 1905 /*
1948 * Stop units processing in a neat way 1906 * Stop units processing in a neat way
1949 */ 1907 */
1950 for (unit = Config.units; unit; unit = unit->next) { 1908 for (unit = Config.units; unit; unit = unit->next) {
1951
1952 if (unit->mode != UNITMODE_OFF) {
1953 if (unit->heater_address) {
1954 mqtt_publish_int(unit->alias, (char *)"heater", 0);
1955 mqtt_publish_clear(unit->alias, (char *)"heater");
1956 }
1957 if (unit->cooler_address) {
1958 mqtt_publish_int(unit->alias, (char *)"cooler", 0);
1959 mqtt_publish_clear(unit->alias, (char *)"cooler");
1960 }
1961 if (unit->fan_address) {
1962 mqtt_publish_int(unit->alias, (char *)"fan", 0);
1963 mqtt_publish_clear(unit->alias, (char *)"fan");
1964 }
1965 mqtt_publish_int(unit->alias, (char *)"state", 0);
1966 mqtt_publish_clear(unit->alias, (char *)"state");
1967 }
1968 mqtt_publish_clear(unit->alias, (char *)"air/temperature");
1969 mqtt_publish_clear(unit->alias, (char *)"air");
1970 mqtt_publish_clear(unit->alias, (char *)"beer/temperature");
1971 mqtt_publish_clear(unit->alias, (char *)"beer");
1972 mqtt_publish_clear(unit->alias, (char *)"setpoint/high");
1973 mqtt_publish_clear(unit->alias, (char *)"setpoint/low");
1974 mqtt_publish_clear(unit->alias, (char *)"setpoint");
1975 mqtt_publish_clear(unit->alias, (char *)"door");
1976 mqtt_publish_clear(unit->alias, (char *)"name");
1977 mqtt_publish_clear(unit->alias, (char *)"mode");
1978 mqtt_publish_clear(unit->alias, (char *)"12volt");
1979 mqtt_publish_clear(unit->alias, (char *)"profile/uuid");
1980 mqtt_publish_clear(unit->alias, (char *)"profile/state");
1981 mqtt_publish_clear(unit->alias, (char *)"profile/name");
1982 mqtt_publish_clear(unit->alias, (char *)"profile/fridgemode");
1983 mqtt_publish_clear(unit->alias, (char *)"profile/percent");
1984
1985 /* 1909 /*
1986 * Turn everything off 1910 * Turn everything off
1987 */ 1911 */
1988 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0; 1912 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->light_state = 0;
1989 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0; 1913 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
1990 device_out(unit->heater_address, unit->heater_state); 1914 device_out(unit->heater_address, unit->heater_state);
1991 device_out(unit->cooler_address, unit->cooler_state); 1915 device_out(unit->cooler_address, unit->cooler_state);
1992 device_out(unit->fan_address, unit->fan_state); 1916 device_out(unit->fan_address, unit->fan_state);
1993 device_out(unit->light_address, unit->light_state); 1917 device_out(unit->light_address, unit->light_state);
1918 unit->mqtt_flag = MQTT_FLAG_HEATER | MQTT_FLAG_COOLER | MQTT_FLAG_FAN | MQTT_FLAG_LIGHT;
1919 publishDData(unit);
1994 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]); 1920 syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->name, UNITMODE[unit->mode]);
1995 } 1921 }
1996 1922
1997 mqtt_disconnect(); 1923 mqtt_disconnect();
1998 1924

mercurial