+static void mqtt_msg_callback(struct mosquitto *mosq UNUSED, void *obj UNUSED, const struct mosquitto_message *m)
+{
+ char val[256];
+ if (m->payloadlen >= sizeof(val) - 1) {
+ msg(L_ERROR, "Invalid value for topic %s", m->topic);
+ return;
+ }
+ memcpy(val, m->payload, m->payloadlen);
+ val[m->payloadlen] = 0;
+ msg(L_DEBUG, "MQTT < %s %s", m->topic, val);
+
+ if (!strcmp(m->topic, "burrow/air/bypass")) {
+ uint x;
+ const char *err;
+ if ((err = str_to_uint(&x, val, NULL, 10 | STN_WHOLE)) || x >= 2) {
+ msg(L_ERROR, "Received invalid bypass setting %s: %s", val, err);
+ return;
+ }
+ if (modbus_write_bit(modbus, AIRCON_COIL_EXCHANGER_BYPASS, x) < 0)
+ mb_error("coil write", false);
+ } else if (!strcmp(m->topic, "burrow/air/exchanger-fan")) {
+ uint x;
+ const char *err;
+ if ((err = str_to_uint(&x, val, NULL, 10 | STN_WHOLE)) || x >= 256) {
+ msg(L_ERROR, "Received invalid exchanger fan setting %s: %s", val, err);
+ return;
+ }
+ if (modbus_write_register(modbus, AIRCON_HREG_EXCHANGER_FAN, x) < 0)
+ mb_error("fan register write", false);
+ } else if (!strcmp(m->topic, "burrow/air/aircon-remote")) {
+ if (strlen(val) != 1) {
+ msg(L_ERROR, "Received invalid aircon remote command %s", val);
+ return;
+ }
+ if (modbus_write_register(modbus, AIRCON_HREG_REMOTE_CONTROL, val[0]) < 0)
+ mb_error("remote control register write", false);
+ }
+}
+