+require('ds18b20')
+require('mqtt')
+require('gpio')
+
+dofile('config.lua')
+
+function mqtt_build_message()
+    local r = {}
+    for id,t in pairs(ds18b20.values) do
+        local t1 = t / 10000
+        local t2 = (t >= 0 and t % 10000) or (10000 - t % 10000)
+        table.insert(r, string.format("{\"id\":\"%s\",\"temp\":%d.%04d}", id, t1, t2))
+    end
+    return "[" .. table.concat(r, ",") .. "]"
+end
+
+function mqtt_publish(m, prefix)
+   local topic = prefix .. '/' .. node.chipid()
+   m:publish(topic .. '/temperature', mqtt_build_message(), 0, 0, nil)
+end
+
+function mqtt_create_client(server, prefix, timerid, interval)
+   local m = mqtt.Client(node.chipid(), 60, MQTT_USERNAME, MQTT_PASSWORD, 0)
+   m:lwt(prefix .. '/' .. node.chipid() .. '/error', 'disconnected', 0, 0)
+   m:on("connect", function(client)
+           mqtt_publish(client, prefix)
+           -- max time is 6870947 (1:54:30.947)
+           tmr.alarm(timerid, interval, 1, function() mqtt_publish(client, prefix) end)
+   end)
+   m:on("offline", function(client)
+           tmr.stop(timerid)
+           m:connect(server, MQTT_PORT, 0, 1)
+   end)
+   m:connect(server, MQTT_PORT, 0, 1)
+   return m
+end
+
+function mqtt_start()
+   local clients = {}
+   ds18b20.update()
+   tmr.alarm(SENSOR_TIMER, SENSOR_INTERVAL * 1000, tmr.ALARM_AUTO, ds18b20.update)
+   for index,broker in ipairs(MQTT_BROKERS) do
+      local interval = broker.interval * 1000
+      local m = mqtt_create_client(broker.host, broker.prefix, broker.timer, interval)
+      table.insert(clients, m)
+   end
+   return clients
+end
+
+function mqtt_stop()
+   print("mqtt_stop")
+   for index,broker in ipairs(MQTT_BROKERS) do
+      tmr.stop(broker.timer)
+      tmr.unregister(broker.timer)
+   end
+   for index,client in ipairs(clients) do
+      if pcall(client.close) then
+         print("closed client")
+      else
+         print("failed to close client")
+      end
+   end
+   tmr.stop(SENSOR_TIMER)
+   tmr.unregister(SENSOR_TIMER)
+end
+
+LED_STATE = 1
+
+function blink()
+   if LED_STATE == 1 then
+      LED_STATE = 0
+   else
+      LED_STATE = 1
+   end
+   gpio.write(LED_PIN, LED_STATE)
+end
+
+function blink_start()
+   gpio.mode(LED_PIN, gpio.OUTPUT)
+   tmr.alarm(LED_TIMER, LED_INTERVAL, tmr.ALARM_AUTO, blink)
+end
+
+function blink_stop()
+   tmr.stop(LED_TIMER)
+   tmr.unregister(LED_TIMER)
+end
+
+ds18b20.init(SENSOR_PIN)
+blink_start()
+clients = mqtt_start()