aboutsummaryrefslogtreecommitdiff
path: root/diller
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-10-15 18:34:07 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2015-10-15 18:34:07 +0200
commit6d04ada06ce29868338face2fbbec8ab72c48dd2 (patch)
tree537ea335a906f7b8ef177ac435433a40b3731b50 /diller
parentd9da54abcc784ecca5e1c0c415820a32e68c2296 (diff)
downloadesp-playground-6d04ada06ce29868338face2fbbec8ab72c48dd2.tar.gz
esp-playground-6d04ada06ce29868338face2fbbec8ab72c48dd2.tar.bz2
esp-playground-6d04ada06ce29868338face2fbbec8ab72c48dd2.tar.xz
esp-playground-6d04ada06ce29868338face2fbbec8ab72c48dd2.zip
wip
Diffstat (limited to 'diller')
-rw-r--r--diller/README.md53
-rw-r--r--diller/inter.lua3
-rw-r--r--diller/main.lua13
-rw-r--r--diller/mq.lua58
4 files changed, 87 insertions, 40 deletions
diff --git a/diller/README.md b/diller/README.md
index 322ec45..72d5778 100644
--- a/diller/README.md
+++ b/diller/README.md
@@ -14,69 +14,60 @@ Is registration required? Can't the firmware just send an update without a value
/name (retained)
/description (retained)
/type TODO: remove?
+ /status TODO: remove? type specified what the message looks like
/firmware For updating the device's firmware
-## Device registration flow
-
- sub: /registration/<random id>
- pub: /registration {}
-
# Diller serial API
## Network settings
Request:
-Update network settings. If no paramters are given, no changes are done.
+Update or query network settings. If no paramters are given, no changes are done. If ip is set to a blank string, it will use DHCP.
- network [ip=..] [gateway=..] [ssid=..]
+ network [ip=..] [gateway=..] [netmask=..]
Response:
-The command will always return the current values. If the ssid was recently set, the ip, gateway and netmask fields may be missing.
+The command will always return the current values.
- ok ip=.. gateway=.. netmask=.. ssid=..
+ ok ip=.. gateway=.. netmask=.. netmask=..
-## Register property
+## Wlan settings
Request:
- register-property id=.. type=.. name=.. description=..
+Update or query wlan settings. If no paramters are given, no changes are done.
-Type examples:
-
-* `temperature`
-* `switch` - boolean switches
-* `humidity`
-* `rtc`
+ wlan [ssid=..] [password=..]
Response:
- ok
-
-## Publish property value
-
-Request:
-
- set-property id=.. [value=..] [name=..] [description=..]
+The command will always return the current values.
+
+ ok ssid=..
-Response:
+## Set property value
- ok
+TODO: Implement description? A longer string describing the sensor.
-The value might not be updated directly, but may be buffered on the device if it is not yet connected.
+Request:
-## Publish raw MQTT message
+ set-property id=.. [value=..] [name=..]
-Request:
+Type examples:
- publish topic=.. [qos=..] [retain=..]
- <next lines are payload. Double EOL completes payload>
+* `temperature`
+* `switch` - boolean switches
+* `humidity`
+* `rtc`
Response:
ok
+The value might not be updated directly, but may be buffered on the device if it is not yet connected.
+
## Reset the device
Request:
diff --git a/diller/inter.lua b/diller/inter.lua
index 725edbd..e10e1df 100644
--- a/diller/inter.lua
+++ b/diller/inter.lua
@@ -4,7 +4,8 @@ function P.parse(line)
-- print("inter_parse: line="..line)
line = string.sub(line, 1, string.find(line, "\r"))
- line = line:gsub("%s+", "")
+ line = line:gsub("^%s+", "")
+ line = line:gsub("%s+$", "")
local args = {}
local i = string.find(line, " ")
diff --git a/diller/main.lua b/diller/main.lua
index 112284c..eca88a9 100644
--- a/diller/main.lua
+++ b/diller/main.lua
@@ -44,14 +44,21 @@ local function on_cmd(cmd, args)
if not id then
print("fail status=missing-id")
else
+ local name_path = id.."/name"
+ mq.subscribe(name_path, function() print('message on '..path) end)
+
+ local description_path = id.."/description"
+ mq.subscribe(description_path, function() print('message on '..path) end)
+
if args.value then
- mq.publish(args.id.."/value", args.value)
+ local path = id.."/value"
+ mq.publish(path, args.value)
end
if args.name then
- mq.publish(args.id.."/name", args.name)
+ mq.publish(name_path, args.name)
end
if args.description then
- mq.publish(args.id.."/description", args.description)
+ mq.publish(description_path, args.description)
end
end
elseif cmd == "publish" then
diff --git a/diller/mq.lua b/diller/mq.lua
index 0b4a884..74f3ef8 100644
--- a/diller/mq.lua
+++ b/diller/mq.lua
@@ -1,12 +1,48 @@
local P = {}
local m, topic, cid
+local active_subscriptions = {}
+local pending_subscriptions = {}
+local pending_subcsription
local function p(msg)
print("MQTT: "..msg)
end
+-- Subscribe to all registered subscriptions
+-- TODO: subscriptions that are not successfull will remain in state = 1. Might not be a real problem if it happens, the server probably disallowed the subscription.
+local function create_subscriptions()
+ print("create_subscriptions, pending count "..table.getn(pending_subscriptions)..", pending: "..tostring(pending_subscription))
+
+ if (pending_subscription) then
+ return
+ end
+
+ pending_subcsription = table.remove(pending_subscriptions)
+
+ -- The API claims that the callback has this signature: function(client, topic, message)
+ -- but that doesn't seems right from the source code. The code doesn't
+ -- remember the topics that is being subscribed to.
+ m:subscribe(pending_subcsription, 0, function(client)
+ print("success: "..pending_subcsription)
+ table.insert(active_subscriptions, pending_subscription)
+ pending_subscription = nil
+ create_subscriptions()
+ end)
+end
+
local function mq_client_connected(con)
p("connected")
+
+ create_subscriptions()
+end
+
+local function disconnect()
+ p("Lost wifi connection, disconnecting")
+ m:close()
+ m = nil
+
+ -- append active_subscriptions to pending_subscriptions
+ active_subscriptions = {}
end
function mq_on_timer()
@@ -30,9 +66,7 @@ function mq_on_timer()
end
else
if m then
- p("Lost wifi connection, disconnecting")
- m:close()
- m = nil
+ disconnect()
end
end
end
@@ -45,17 +79,31 @@ function P.init(timer_id, client_id)
tmr.alarm(timer_id, 3 * 1000, 1, mq_on_timer)
end
+function P.subscribe(path, cb)
+ subscription = subscriptions[path]
+ if subscription then
+ print("subscription on "..path.." already registered, state="..tostring(subscription.state))
+ return
+ end
+
+ print("Registering subscription on "..path)
+
+ pending_subscriptions[path] = true
+
+ create_subscriptions()
+end
+
function P.publish(path, payload)
if not m then
print("Not connected, dropping message to "..path)
- return
+ return false, 'not connected'
end
path = topic.."/"..path
print("path="..path)
m:publish(path, payload, 0, 0)
- return true, "yo?"
+ return true, 'ok'
end
return P