summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirte Kristina Friesel <derf@finalrewind.org>2024-02-04 14:39:20 +0100
committerBirte Kristina Friesel <derf@finalrewind.org>2024-02-04 14:39:20 +0100
commit80280a5d28ccf04262e35917ac9f806b3c91cf59 (patch)
tree79cdbfaab09a003255360158cacd08cb2b86099e
initial commitHEADmain
-rw-r--r--.gitignore1
-rw-r--r--.reuse/dep59
-rw-r--r--README.md103
-rw-r--r--firmware/nodemcu-master-15-modules-2017-01-03-14-04-53-integer.binbin0 -> 416483 bytes
-rw-r--r--init.lua96
5 files changed, 209 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..338c30b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+config.lua
diff --git a/.reuse/dep5 b/.reuse/dep5
new file mode 100644
index 0000000..55e41dd
--- /dev/null
+++ b/.reuse/dep5
@@ -0,0 +1,9 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+Files: init.lua
+Copyright: 2024 Birte Kristina Friesel
+License: BSD-2-Clause
+
+Files: README.md .gitignore
+Copyright: 2024 Birte Kristina Friesel
+License: CC0-1.0
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..619b268
--- /dev/null
+++ b/README.md
@@ -0,0 +1,103 @@
+# ESP8266 Lua/NodeMCU MQTT to UART bridge
+
+[esp8266-nodemcu-uart-bridge](https://finalrewind.org/projects/esp8266-nodemcu-uart-bridge/)
+provides an ESP8266 NodeMCU Lua application (`init.lua`) that mirrors
+incoming MQTT messages to the ESP8266's UART and can also transmit messages
+received by UART to an MQTT broker or to InfluxDB. This way, it can add simple
+MQTT/InfluxDB connectivity to devices that do not have a WiFi / ethernet
+connection.
+
+## Dependencies
+
+`init.lua` has been tested with Lua 5.1 on NodeMCU firmware 1.5.4.1(39cb9a32)
+(commit 81ec3665cb5fe68eb8596612485cc206b65659c9, integer build). This allows
+it to run on old ESP8266-01 boards with just 512kB of Flash. It requires the
+following modules.
+
+* http
+* mqtt
+* node
+* tmr
+* wifi
+
+## Usage
+
+### Startup
+
+Once connected, the ESP8266 will output the following lines on its TX line:
+
+* `WiFi:Rdy` *IP-address*
+* `MQTT:Rdy` *MQTT-prefix*
+
+The default MQTT prefix is `uart/esp8266_`*Chip-ID*, e.g.
+`uart/esp8266_82B45C`. Additionally, the ESP8266 will publish a retained
+"online" message under *MQTT-prefix*/**state** and subscribe to
+*MQTT-prefix*/**in**.
+
+### MQTT to UART
+
+The ESP8266 prints each received *message* with an "RX:" prefix on its TX line,
+like so:
+
+`RX:`*message*
+
+### UART to MQTT
+
+When the ESP8266 receives **publish_mqtt**(*topic*, *payload*, *retain*) on its
+RX line, it will publish the specified payload under the specified topic.
+The *retain* flag defaults to false. For instance, the following input will
+publish "hello" under `uart/esp8266_`*Chip-ID*`/out`:
+
+`publish_mqtt(mqtt_prefix .. "/out", "hello")`
+
+If the message has been sent out successfully, it will reply with `MQTT:OK` or
+`> MQTT:OK`. Otherwise, it will reply with `MQTT:Err` or `> MQTT:Err`
+
+### Watchdog
+
+If none of the following four events happen for a time span of 90 seconds, the
+ESP8266 will reset itself, causing a re-connection to WiFi and MQTT server.
+
+* The ESP8266 receives a message via MQTT
+* The ESP8266 receives a **publish_mqtt** command via RX and the command
+ completes successfully
+* The ESP8266 receives a **publish_influx** command via RX and the command
+ completes successfully
+* The ESP8266 receiveds a **wdr()** command via RX.
+
+### Error Handling
+
+The following messages on the ESP8266 TX line indicate errors.
+Note that some errors can have several reasons.
+
+* `MQTT:Err` or `> MQTT:Err` – Failed to publish MQTT message (another message was still being
+ processed)
+* `MQTT:Err` or `> MQTT:Err` – Connection to MQTT broker has been lost
+* `WiFi:Err` or `> WiFi:Err` – Unable to establish WiFi connection
+* `WiFi:Err` or `> WiFi:Err` – WiFi connection has been lost
+* `Watchdog:Err` or `> Watchdog: Err` – watchdog timeout, the device will reset (see above)
+
+## Configuration
+
+To use this application, you need to create a **config.lua** file with WiFI and
+MQTT settings:
+
+```lua
+station_cfg = {ssid = "...", pwd = "..."}
+mqtt_host = "..."
+```
+
+To use InfluxDB, configure URL and (optional) header:
+
+```lua
+influx_url = "..."
+influx_header = "..."
+```
+
+## Resources
+
+Mirrors of this repository are maintained at the following locations:
+
+* [Chaosdorf](https://chaosdorf.de/git/derf/esp8266-nodemcu-uart-bridge)
+* [git.finalrewind.org](https://git.finalrewind.org/esp8266-nodemcu-uart-bridge/)
+* [GitHub](https://github.com/derf/esp8266-nodemcu-uart-bridge)
diff --git a/firmware/nodemcu-master-15-modules-2017-01-03-14-04-53-integer.bin b/firmware/nodemcu-master-15-modules-2017-01-03-14-04-53-integer.bin
new file mode 100644
index 0000000..90ac0b9
--- /dev/null
+++ b/firmware/nodemcu-master-15-modules-2017-01-03-14-04-53-integer.bin
Binary files differ
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..8277536
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,96 @@
+publishing_mqtt = false
+publishing_http = false
+
+watchdog = tmr.create()
+chip_id = string.format("%06X", node.chipid())
+device_id = "esp8266_" .. chip_id
+mqtt_prefix = "uart/" .. device_id
+mqttclient = mqtt.Client(device_id, 120)
+
+dofile("config.lua")
+
+function wdr()
+ watchdog:stop()
+ watchdog:start()
+end
+
+function wd_err()
+ print("Watchdog:Err")
+ node.restart()
+end
+
+function mqtt_err(client)
+ print("MQTT:Err")
+end
+
+function wifi_err()
+ print("WiFi:Err " .. wifi.sta.status())
+end
+
+function setup_client()
+ print("MQTT:Rdy " .. mqtt_prefix)
+ publishing_mqtt = true
+ mqttclient:publish(mqtt_prefix .. "/state", "online", 0, 1, function(client)
+ client:subscribe(mqtt_prefix .. "/in", 0)
+ publishing_mqtt = false
+ end)
+end
+
+function connect_mqtt()
+ print("")
+ print("WiFi:Rdy " .. wifi.sta.getip())
+ mqttclient:on("connect", setup_client)
+ mqttclient:on("offline", mqtt_err)
+ --mqttclient:on("connfail", mqtt_err)
+ mqttclient:on("message", print_mqtt)
+ mqttclient:lwt(mqtt_prefix .. "/state", "offline", 0, 1)
+ mqttclient:connect(mqtt_host)
+end
+
+function connect_wifi()
+ wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, connect_mqtt)
+ wifi.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT, wifi_err)
+ wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_err)
+ wifi.setmode(wifi.STATION)
+ wifi.sta.config(station_cfg)
+ wifi.sta.connect()
+end
+
+function print_mqtt(client, topic, message)
+ print("RX:" .. message)
+ wdr()
+ collectgarbage()
+end
+
+function publish_mqtt(topic, payload, retain)
+ if publishing_mqtt then
+ print("MQTT:Err")
+ else
+ publishing_mqtt = true
+ mqttclient:publish(topic, payload, 0, retain or 0, function(client)
+ publishing_mqtt = false
+ print("MQTT:OK")
+ wdr()
+ collectgarbage()
+ end)
+ end
+end
+
+function publish_influx(payload)
+ if publishing_http then
+ print("Influx:Err")
+ else
+ publishing_http = true
+ http.post(influx_url, influx_header, payload, function(code, data)
+ publishing_http = false
+ print("Influx:OK")
+ wdr()
+ collectgarbage()
+ end)
+ end
+end
+
+watchdog:register(90 * 1000, tmr.ALARM_SEMI, wd_err)
+watchdog:start()
+
+connect_wifi()