From 937040944ffdf7819b7ce7bee23a3d346718c0e4 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 19 Nov 2015 19:33:05 +0100 Subject: Major refactoring, splitting stuff into separate files. --- Makefile | 3 + README.md | 3 + diller/README.md | 11 ++++ diller/cfg.lua | 36 ++++++++++++ diller/init.lua | 60 ++++++++++++++++++++ diller/inter.lua | 2 +- diller/main.lua | 151 ++----------------------------------------------- diller/manual_init.lua | 10 +--- diller/mq.lua | 74 +++++++++++++----------- diller/on_cmd.lua | 137 ++++++++++++++++++++++++++++++++++++++++++++ diller/property.lua | 0 upload.sh | 15 +++-- 12 files changed, 311 insertions(+), 191 deletions(-) create mode 100644 diller/cfg.lua create mode 100644 diller/init.lua create mode 100644 diller/on_cmd.lua create mode 100644 diller/property.lua diff --git a/Makefile b/Makefile index 0471eae..c23a003 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,9 @@ all: compile-%: @$(MAKE) -j 8 $(patsubst %.lua,%.lc,$(wildcard $(patsubst compile-%,%,$@)/*.lua)) +clean-%: + rm -f $(wildcard $(patsubst clean-%,%,$@)/*.lc) + upload-%: @$(MAKE) $(patsubst upload-%,compile-%,$@) ./upload.sh $(patsubst upload-%,%,$@) diff --git a/README.md b/README.md index 54134a8..28b0e84 100644 --- a/README.md +++ b/README.md @@ -93,3 +93,6 @@ Open screen and paste this code: # References * [Lua API](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en) + * + * + * http://blog.3mdeb.com/2015/01/25/esp-12-upgrade-to-esp-iot-sdk-v0-dot-9-5-using-esp-open-sdk-toolchain/ diff --git a/diller/README.md b/diller/README.md index b454862..e042f94 100644 --- a/diller/README.md +++ b/diller/README.md @@ -47,6 +47,17 @@ The command will always return the current values. ok ssid=.. +## List properties + +Request: + + list-properties + +Response: + + ok count= + property key=.. [name=..] [description=..] + ## Set property value TODO: Implement description? A longer string describing the property. diff --git a/diller/cfg.lua b/diller/cfg.lua new file mode 100644 index 0000000..2a8472c --- /dev/null +++ b/diller/cfg.lua @@ -0,0 +1,36 @@ +function info(msg) + print("info msg="..msg) +end + +function read_cfg(name, required) + local filename = "cfg-"..name + if not file.open(filename, "r") then + if required then + panic("Could not read configuration file: "..filename) + else + return nil + end + end + local value = file.readline() + file.close() + if value == nil or #value == 0 then + if required then + panic("Empty configuration file: "..filename) + else + return nil + end + end + return string.sub(value, 1, -2) +end + +function write_cfg(name, value) + local filename = "cfg-"..name + local ok + ok = file.open(filename, "w+") + if ok then + ok = file.writeline(value) + file.flush() + file.close() + end + return ok +end diff --git a/diller/init.lua b/diller/init.lua new file mode 100644 index 0000000..c842898 --- /dev/null +++ b/diller/init.lua @@ -0,0 +1,60 @@ +-- l = file.list(); for k,v in pairs(l) do print("name: "..k..", size: "..v) end +function go() + compile = true + x = function(name) + compile = true + compiled = name:gsub('lua$','lc') + if compile then + local ok = file.open(name) + if not ok then + print('already compiled '..name) + return + end + + print('Compiling '..name) + node.compile(name) + + ok = file.open(compiled) + if ok then + print('success, removing '..name) + file.remove(name) + end + else + print('removing compiled version of '..name) + file.remove(compiled) + end + end + ext = 'lua' + if compile then + ext = 'lc' + end + + x('main.lua') + x('cfg.lua') + x('on_cmd.lua') + x('inter.lua') + x('mq.lua') + x('property.lua') + x = nil + + print("network"); + print("wlan"); + print("set-property id=temp-0 value=12.3 type=temperature name=Water"); + + print("heap.."..node.heap()) + mq = require('mq') + print("heap.."..node.heap()) + inter = require('inter') + print("heap.."..node.heap()) + dofile('on_cmd.'..ext) + print("heap.."..node.heap()) + dofile('cfg.'..ext) + print("heap.."..node.heap()) + dofile('main.'..ext) + print("heap.."..node.heap()) + + -- leave no trace behind! + compile = nil + go = nil + main() +end diff --git a/diller/inter.lua b/diller/inter.lua index a0aee5b..2e6014e 100644 --- a/diller/inter.lua +++ b/diller/inter.lua @@ -53,7 +53,7 @@ end local cb function inter_on_line(line) --- info("line:"..line) + info("line:"..line) local cmd, args = P.parse(line) if not cmd then diff --git a/diller/main.lua b/diller/main.lua index 3450bec..98e28b0 100644 --- a/diller/main.lua +++ b/diller/main.lua @@ -4,53 +4,16 @@ function panic(reason) node.restart() end -info = function(msg) - print("info "..msg) -end - -local P = {} - local inter = require('inter') local mq = require('mq') -local properties = {} - -local function read_cfg(name, required) - local filename = "cfg-"..name - if not file.open(filename, "r") then - if required then - panic("Could not read configuration file: "..filename) - else - return nil - end - end - local value = file.readline() - file.close() - if value == nil or #value == 0 then - if required then - panic("Empty configuration file: "..filename) - else - return nil - end - end - return string.sub(value, 1, -2) -end - -local function write_cfg(name, value) - local filename = "cfg-"..name - file.open(filename, "w+") - local ok = file.writeline(value) - file.flush() - file.close() - return ok -end - -local function configure_wlan() +function configure_wlan() local wlan_ssid = read_cfg("wlan-ssid", false) local wlan_password = read_cfg("wlan-password", false) if not wlan_ssid or not wlan_password then info("Missing SSID and/or password configuration, use 'wlan' to configure") + wifi.sta.config('', '') return end @@ -59,99 +22,12 @@ local function configure_wlan() wifi.sta.config(wlan_ssid, wlan_password) end -local function on_cmd(cmd, args) - if not cmd then - return - end - - info("on_cmd: '"..cmd.."', #args="..tostring(table.getn(args))) - for k, v in pairs(args) do - info(k.."="..tostring(v)) - end - - if cmd == "reset" then - print("ok reset") - panic("Reset requested") - elseif cmd == "wlan" then - local ssid = args.ssid password = args.password - - local reconfigured = false - if args.ssid then - write_cfg("wlan-ssid", args.ssid) - end - if args.password then - write_cfg("wlan-password", args.password) - end - if args.ssid and args.password then - configure_wlan() - end - ssid, password, bssid_set, bssid = wifi.sta.getconfig() - print("ok ssid="..(ssid or '')) - elseif cmd == "network" then - local ip = args.ip nm = args.netmask gw = args.gateway - - if args.ip then - wifi.sta.setip({ip=ip, netmask=nm, gateway=gw}) - end - - ip, nm, gw = wifi.sta.getip() - print("ok ip="..(ip or '').." netmask="..(nm or '').." gateway="..(gw or '')) - elseif cmd == "set-property" then - local id = args.id - if not id then - print("fail status=missing-id") - else - property = properties[id] - - local value_path = "property/"..id.."/value" - local name_path = "property/"..id.."/name" - local description_path = "property/"..id.."/description" - - if not property then - info("new property: "..id) - property = {} - properties[id] = property - mq.subscribe(name_path, function() info('message on '..path) end) - mq.subscribe(description_path, function() info('message on '..path) end) - end - - if args.value then - mq.publish(value_path, args.value) - end - if args.name and property.name ~= args.name then - info("publishing name") - mq.publish(name_path, args.name) - property.name = args.name - end - if args.description and property.description ~= args.description then - info("publishing description") - mq.publish(description_path, args.description) - property.description = args.description - end - end - elseif cmd == "publish" then --- print("Publishing, topic="..tostring(cmd.topic)..", payload="..tostring(cmd.payload)) - ok, msg = mq.publish(cmd.topic, cmd.payload) - if ok then - print("ok status="..msg) - else - print("failed status="..msg) - end - else - print("failed status=unknown-command") - end -end - local function print_status() ip, nm, gw = wifi.sta.getip() print("status uptime="..tmr.time().." heap-left="..node.heap().." ip="..tostring(ip).." netmask="..tostring(nm).." gateway="..tostring(gw)) end --- uart.setup(id, baud, databits, parity, stopbits, echo) --- uart.setup(0, 115200, 8, 0, 1, 0) --- uart.setup(0, 9600, 8, 0, 1, 0) - -function P.main() +function main() local timers = { status = 0, inter = 1, @@ -166,23 +42,8 @@ function P.main() inter.init(on_cmd) - tmr.alarm(timers.status, 10 * 1000, 1, print_status) - --- local majorVer, minorVer, devVer, chipId, flashId, flashSize, flashMode, flashSpeed, buildDate = node.info() --- payload = '{"version": "'..majorVer..'.'..minorVer..'.'..devVer..'", "chipId":'..chipId..', "flashId":'..flashId..', "flashSize":'..flashSize..', "flashMode":'..flashMode..', "flashSpeed":'..flashSpeed --- --- if buildDate then --- payload = payload..', "buildDate": "'..buildDate..'"' --- end --- --- if node.info_versions then --- major, minor, dev, buildDate, sdkVersion = node.info_versions() --- payload = payload..'", versions": {"major": '..major..', "minor": '..minor..', "dev": '..dev..', "buildDate": "'..buildDate..'", "sdk": "'..sdkVersion..'"}' --- end --- payload = payload.."}" --- P.publish("firmware", payload) - + load_properties() info("init done") -end -return P + tmr.alarm(timers.status, 10 * 1000, 1, print_status) +end diff --git a/diller/manual_init.lua b/diller/manual_init.lua index 2bf5c9e..2f12a45 100644 --- a/diller/manual_init.lua +++ b/diller/manual_init.lua @@ -1,9 +1 @@ -node.compile('inter.lua'); -node.compile('mq.lua'); --- node.compile('main.lua'); - -print("network"); -print("wlan"); -print("set-property id=temp-0 value=12.3 type=temperature name=Water"); -require('main').main(); - +tmr.delay(1000000) diff --git a/diller/mq.lua b/diller/mq.lua index f3136d6..524bff2 100644 --- a/diller/mq.lua +++ b/diller/mq.lua @@ -1,33 +1,44 @@ local P = {} -local m, topic, cid +local m, topic, cid, connected local subscriptions = {} local function mq_client_connected(con) info("mqtt: connected") + connected = true end local function subscribed() info("mqtt: subscribed") end -local function disconnect() - info("mqtt: Lost wifi connection, disconnecting") - m:close() - m = nil +local function offline() + info("mqtt: disconnected") + connected = false +-- m:close() +-- m = nil end local function on_message(client, topic, message) -- p("mqtt: on_message: topic="..topic..", message="..message) - local _, _, new_property_name = string.find(topic, '/property/([%a%d-]+)/name$') - if new_property_name then - print("msg cmd=new-property-name id="..new_property_name..", name="..message) - return; + local _, _, key = string.find(topic, '/property/([%a%d-]+)/name$') + if key then + local filename = 'property-'..key..'-name' + local old = read_cfg(filename, false) + if old ~= message then + write_cfg(filename, message) + end + print("msg cmd=new-property-name key="..key..", name=\""..message.."\"") end - local _, _, new_description_name = string.find(topic, '/property/([%a%d-]+)/description$') - if new_description_name then - print("msg cmd=new-property-description id="..new_description_name..", description="..message) + local _, _, key = string.find(topic, '/property/([%a%d-]+)/description$') + if key then + local filename = 'property-'..key..'-description' + local old = read_cfg(filename, false) + if old ~= message then + write_cfg(filename, message) + end + print("msg cmd=new-property-description key="..key..", description=\""..message.."\"") end end @@ -36,26 +47,16 @@ function mq_on_timer() -- local status = wifi.sta.status() -- p("mqtt: checking status, status="..status) - local status = wifi.sta.getip() - - if status and status ~= "0.0.0.0" then - if not m then - info("mqtt: connecting") + info("mqtt: connecting") - -- client id, keepalive, username, password - m = mqtt.Client(cid, 120) - -- m:on("connect", mq_connected) - m:on("offline", function() m:close(); m = nil end) - m:on("message", on_message) + -- client id, keepalive, username, password + m = mqtt.Client(cid, 120) + -- m:on("connect", mq_connected) + m:on("offline", offline) + m:on("message", on_message) - -- host, port, secure, auto_reconnect, function(client), ssl=8883 - m:connect("trygvis.io", 1883, 0, 0, mq_client_connected) - end - else - if m then - disconnect() - end - end + -- host, port, secure, auto_reconnect, function(client), ssl=8883 + m:connect("trygvis.io", 1883, 0, 1, mq_client_connected) end function P.init(timer_id, device_id, client_id) @@ -63,7 +64,8 @@ function P.init(timer_id, device_id, client_id) topic = "/diller/"..device_id - tmr.alarm(timer_id, 4 * 1000, 1, mq_on_timer) + -- Wait a bit to get a connection first + tmr.alarm(timer_id, 5 * 1000, 0, mq_on_timer) end function P.subscribe(path) @@ -88,10 +90,18 @@ function P.publish(path, payload) end path = topic.."/"..path - info("mqtt: path="..path) + -- info("mqtt: path="..path) m:publish(path, payload, 0, 0) return true, 'ok' end +function P.status() + if connected then + return 'connected' + else + return 'disconnected' + end +end + return P diff --git a/diller/on_cmd.lua b/diller/on_cmd.lua new file mode 100644 index 0000000..0050e4b --- /dev/null +++ b/diller/on_cmd.lua @@ -0,0 +1,137 @@ +local inter = require('inter') +local mq = require('mq') +local properties = {} + +function load_properties() + local l = file.list() + info("loading properties") + + for k, v in pairs(l) do + local key = string.match(k, '^cfg%-property%-(.+)%-key$') + if key then +-- info('property..'..key) + + local name = read_cfg('property-'..key..'-name') + local description = read_cfg('property-'..key..'-description') + + local property = { + key = key, + name = name, + description = description + } + properties[key] = property + else +-- info('bad name: '..k) + end + end + + if true then return end; +-- load_properties = nil +end + +function on_cmd(cmd, args) + if not cmd then + return + end + + info("on_cmd: '"..cmd.."', #args="..tostring(table.getn(args))) + for k, v in pairs(args) do + info(k.."="..tostring(v)) + end + + if cmd == "reset" then + print("ok reset") + panic("Reset requested") + elseif cmd == "wlan" then + local ssid = args.ssid password = args.password + + local reconfigured = false + if args.ssid then + write_cfg("wlan-ssid", args.ssid) + end + if args.password then + write_cfg("wlan-password", args.password) + end + if args.ssid and args.password then + configure_wlan() + end + ssid, password, bssid_set, bssid = wifi.sta.getconfig() + print("ok ssid="..(ssid or '')) + elseif cmd == "network" then + local ip = args.ip nm = args.netmask gw = args.gateway + + if args.ip then + wifi.sta.setip({ip=ip, netmask=nm, gateway=gw}) + end + + ip, nm, gw = wifi.sta.getip() + print("ok ip="..(ip or '').." netmask="..(nm or '').." gateway="..(gw or '')) + elseif cmd == "mqtt" then + local status = mq.status() + print("ok status="..(status or '')) + elseif cmd == "list-properties" then + print("ok count="..tostring(table.getn(properties))) + for key, property in pairs(properties) do + line = "property key="..key + + if property.name then + line = line..' name="'..property.name..'"' + end + + if property.description then + line = line..' description="'..property.description..'"' + end + print(line) + end + elseif cmd == "set-property" then + local key = args.key + + -- Compatability + if not key then + key = args.id + end + + if not key then + print("fail status=missing-key") + else + property = properties[key] + + local value_path = "property/"..key.."/value" + local name_path = "property/"..key.."/name" + local description_path = "property/"..key.."/description" + + if not property then + write_cfg('property-'..key..'-key', key) + info("new property: "..key) + property = {key = key} + properties[key] = property + mq.subscribe(name_path, function() info('message on '..path) end) + mq.subscribe(description_path, function() info('message on '..path) end) + end + + if args.value then + mq.publish(value_path, args.value) + end + if args.name and property.name ~= args.name then + info("publishing name") + mq.publish(name_path, args.name) + property.name = args.name + end + if args.description and property.description ~= args.description then + info("publishing description") + mq.publish(description_path, args.description) + property.description = args.description + end + end + elseif cmd == "publish" then +-- print("Publishing, topic="..tostring(cmd.topic)..", payload="..tostring(cmd.payload)) + ok, msg = mq.publish(cmd.topic, cmd.payload) + if ok then + print("ok status="..msg) + else + print("failed status="..msg) + end + else + print("failed status=unknown-command") + end +end diff --git a/diller/property.lua b/diller/property.lua new file mode 100644 index 0000000..e69de29 diff --git a/upload.sh b/upload.sh index 65005bf..981cec3 100755 --- a/upload.sh +++ b/upload.sh @@ -7,8 +7,15 @@ basedir=$(pwd) cookie=$(cd $dir; echo $(pwd)/.cookie) cmd=() paths=() +port=() -for path in $(ls "$dir"/cfg-* "$dir"/*.lua 2>/dev/null) +if [[ $NODEMCU_PORT != '' ]] +then + port+=(--port) + port+=("$NODEMCU_PORT") +fi + +for path in $(ls "$dir"/cfg-* "$dir"/*.lua |grep -v manual_init.lua 2>/dev/null) do if [[ $path -nt "$cookie" ]] then @@ -20,12 +27,12 @@ done if [[ ${#cmd[@]} -gt 0 ]] then - "$basedir/nodemcu-uploader/nodemcu-uploader.py" upload "${cmd[@]}" + "$basedir/nodemcu-uploader/nodemcu-uploader.py" "${port[@]}" upload "${cmd[@]}" fi touch "$cookie" if [[ -r "$dir/manual_init.lua" ]] then - cat "$dir/manual_init.lua" - "$basedir/nodemcu-uploader/nodemcu-uploader.py" exec "$dir/manual_init.lua" +# cat "$dir/manual_init.lua" + "$basedir/nodemcu-uploader/nodemcu-uploader.py" "${port[@]}" exec "$dir/manual_init.lua" fi -- cgit v1.2.3