Skip to content

Commit

Permalink
Merge pull request #167 from konnected-io/add-zones
Browse files Browse the repository at this point in the history
Add configuration by zone, bump sw version to 3.1.0
  • Loading branch information
heythisisnate authored Aug 12, 2022
2 parents 90f181b + f8866b5 commit b1b8d89
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 46 deletions.
15 changes: 14 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build

on: [push, pull_request]
on: pull_request

jobs:
build-upload:
Expand All @@ -19,5 +19,18 @@ jobs:
sudo apt-get update
sudo apt-get -y install libusb-1.0-0 cmake srecord
pip install -U pyserial
- name: Build
env:
PR_NUMBER: ${{ github.event.number }}
run: ./scripts/build-firmware

- uses: keithweaver/[email protected]
name: Copy PR bin to AWS
with:
command: cp
source: build/konnected-esp8266-PR-${{ github.event.number }}.bin
destination: s3://konnected-io/builds/
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_region: us-east-2
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ private

# NodeMCU
nodemcu-firmware

# IDE's
.vscode
8 changes: 6 additions & 2 deletions scripts/build-firmware
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ function usage() {
set -e

if ! git describe --exact-match --tags &> /dev/null; then
BRANCH="$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')"
if [[ -z "${PR_NUMBER}" ]]; then
BRANCH="$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')"
else
BRANCH="PR-"${PR_NUMBER}
fi
else
BRANCH="$(git describe --exact-match --tags $(git log -n1 --pretty='%h'))"
BRANCH="$(git describe --exact-match --tags $(git log -n1 --pretty='%h'))"
fi

FW_TAG="3.0.0-release_20210201"
Expand Down
85 changes: 64 additions & 21 deletions src/lfs/application.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,62 @@ local actuators = require("actuators")
local settings = require("settings")
local ds18b20 = require("ds18b20")
local sensorTimer = tmr.create()
local zoneToPin = require("zone_to_pin")

-- globals
sensorPut = {}
actuatorGet = {}

local function getDevicePin(device)
if device.zone ~= nil then
return zoneToPin(device.zone)
else
return device.pin
end
end

-- initialize binary sensors
for i, sensor in pairs(sensors) do
print("Heap:", node.heap(), "Initializing sensor pin:", sensor.pin)
gpio.mode(sensor.pin, gpio.INPUT, gpio.PULLUP)
local pin = getDevicePin(sensor)
if sensor.zone ~= nil then
print("Heap:", node.heap(), "Initializing sensor zone:", sensor.zone)
else
print("Heap:", node.heap(), "Initializing sensor pin:", pin)
end

gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
end

-- initialize actuators
for i, actuator in pairs(actuators) do
local pin = getDevicePin(actuator)
local initialState = actuator.trigger == gpio.LOW and gpio.HIGH or gpio.LOW
print("Heap:", node.heap(), "Initializing actuator pin:", actuator.pin, "on:", actuator.trigger or gpio.HIGH, "off:", initialState)
gpio.write(actuator.pin, initialState)
gpio.mode(actuator.pin, gpio.OUTPUT)
if actuator.zone ~= nil then
print("Heap:", node.heap(), "Initializing actuator zone:", actuator.zone, "on:", actuator.trigger or gpio.HIGH, "off:", initialState)
else
print("Heap:", node.heap(), "Initializing actuator pin:", pin, "on:", actuator.trigger or gpio.HIGH, "off:", initialState)
end

gpio.write(pin, initialState)
gpio.mode(pin, gpio.OUTPUT)
table.insert(actuatorGet, actuator)
end

-- initialize DHT sensors
if #dht_sensors > 0 then
require("dht")

local function readDht(pin)
local status, temp, humi, temp_dec, humi_dec = dht.read(pin)
local function readDht(sensor)
local status, temp, humi, temp_dec, humi_dec = dht.read(getDevicePin(sensor))
if status == dht.OK then
local temperature_string = temp .. "." .. math.abs(temp_dec)
local humidity_string = humi .. "." .. humi_dec
print("Heap:", node.heap(), "Temperature:", temperature_string, "Humidity:", humidity_string)
table.insert(sensorPut, { pin = pin, temp = temperature_string, humi = humidity_string })
if sensor.zone ~= nil then
table.insert(sensorPut, { zone = sensor.zone, temp = temperature_string, humi = humidity_string })
else
table.insert(sensorPut, { pin = sensor.pin, temp = temperature_string, humi = humidity_string })
end
else
print("Heap:", node.heap(), "DHT Status:", status)
end
Expand All @@ -45,42 +70,60 @@ if #dht_sensors > 0 then
for i, sensor in pairs(dht_sensors) do
local pollInterval = tonumber(sensor.poll_interval) or 0
pollInterval = (pollInterval > 0 and pollInterval or 3) * 60 * 1000
print("Heap:", node.heap(), "Polling DHT on pin " .. sensor.pin .. " every " .. pollInterval .. "ms")
tmr.create():alarm(pollInterval, tmr.ALARM_AUTO, function() readDht(sensor.pin) end)
readDht(sensor.pin)
if sensor.zone ~= nil then
print("Heap:", node.heap(), "Polling DHT on zone " .. sensor.zone .. " every " .. pollInterval .. "ms")
else
print("Heap:", node.heap(), "Polling DHT on pin " .. sensor.pin .. " every " .. pollInterval .. "ms")
end
tmr.create():alarm(pollInterval, tmr.ALARM_AUTO, function() readDht(sensor) end)
readDht(sensor)
end
end

-- initialize ds18b20 temp sensors
if #ds18b20_sensors > 0 then

local function ds18b20Callback(pin)
local function ds18b20Callback(sensor)
local callbackFn = function(temps)
for addr,value in pairs(temps) do
print("Heap:", node.heap(), "Temperature:", value)
table.insert(sensorPut, { pin = pin, temp = value,
addr = string.format(('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)))})
local addrStr = string.format(('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)))
if sensor.zone ~= nil then
table.insert(sensorPut, { zone = sensor.zone, temp = value, addr = addrStr })
else
table.insert(sensorPut, { pin = sensor.pin, temp = value, addr = addrStr })
end
end
end
return callbackFn
end

for i, sensor in pairs(ds18b20_sensors) do
local pin = getDevicePin(sensor)
local pollInterval = tonumber(sensor.poll_interval) or 0
pollInterval = (pollInterval > 0 and pollInterval or 3) * 60 * 1000
print("Heap:", node.heap(), "Polling DS18b20 on pin " .. sensor.pin .. " every " .. pollInterval .. "ms")
local callbackFn = ds18b20Callback(sensor.pin)
tmr.create():alarm(pollInterval, tmr.ALARM_AUTO, function() ds18b20:read_temp(callbackFn, sensor.pin, ds18b20.C) end)
ds18b20:read_temp(callbackFn, sensor.pin, ds18b20.C)
if sensor.zone ~= nil then
print("Heap:", node.heap(), "Polling DS18b20 on zone " .. sensor.zone .. " every " .. pollInterval .. "ms")
else
print("Heap:", node.heap(), "Polling DS18b20 on pin " .. pin .. " every " .. pollInterval .. "ms")
end

local callbackFn = ds18b20Callback(sensor)
tmr.create():alarm(pollInterval, tmr.ALARM_AUTO, function() ds18b20:read_temp(callbackFn, pin, ds18b20.C) end)
ds18b20:read_temp(callbackFn, pin, ds18b20.C)
end
end

-- Poll every configured binary sensor and insert into the request queue when changed
sensorTimer:alarm(200, tmr.ALARM_AUTO, function(t)
for i, sensor in pairs(sensors) do
if sensor.state ~= gpio.read(sensor.pin) then
sensor.state = gpio.read(sensor.pin)
table.insert(sensorPut, { pin = sensor.pin, state = sensor.state })
if sensor.state ~= gpio.read(getDevicePin(sensor)) then
sensor.state = gpio.read(getDevicePin(sensor))
if sensor.zone ~= nil then
table.insert(sensorPut, { zone = sensor.zone, state = sensor.state })
else
table.insert(sensorPut, { pin = sensor.pin, state = sensor.state })
end
end
end
end)
Expand Down
10 changes: 9 additions & 1 deletion src/lfs/aws_iot.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local module = ...

local mqtt = require('mqtt_ws')
local settings = require('settings')
local zoneToPin = require("zone_to_pin")
local device_id = wifi.sta.getmac():lower():gsub(':','')
local c = mqtt.Client(settings.aws)
local topics = settings.aws.topics
Expand Down Expand Up @@ -103,6 +104,9 @@ c:on('message', function(_, topic, message)
local revertIn = (payload.momentary + pause) * times - pause
tmr.create():alarm(revertIn, tmr.ALARM_SINGLE, function()
local revertState = { pin = endState.pin, state = endState.state == 0 and 1 or 0}
if endState.zone ~= nil then
revertState = { zone = endState.zone, state = endState.state == 0 and 1 or 0}
end
table.insert(sensorPut, revertState)
end)
end
Expand All @@ -116,7 +120,11 @@ c:on('connect', function()

-- update current state of actuators upon boot
for i, actuator in pairs(actuatorGet) do
table.insert(sensorPut, { pin = actuator.pin, state = gpio.read(actuator.pin) })
if actuator.zone ~= nil then
table.insert(sensorPut, { zone = actuator.zone, state = gpio.read(zoneToPin(actuator.zone)) })
else
table.insert(sensorPut, { pin = actuator.pin, state = gpio.read(actuator.pin) })
end
end

heartbeat:start()
Expand Down
2 changes: 1 addition & 1 deletion src/lfs/device.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local me = {
id = "uuid:8f655392-a778-4fee-97b9-4825918" .. string.format("%x", node.chipid()),
name = "Konnected",
hwVersion = "3.0.0",
swVersion = "3.0.1",
swVersion = "3.1.0",
http_port = math.floor(node.chipid()/1000) + 8000,
urn = "urn:schemas-konnected-io:device:Security:1"
}
Expand Down
38 changes: 29 additions & 9 deletions src/lfs/rest_endpoint.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
local module = ...

local zoneToPin = require("zone_to_pin")

-- print HTTP status line
local function printHttpResponse(code, data)
local a = { "Heap:", node.heap(), "HTTP Call:", code }
Expand Down Expand Up @@ -27,28 +29,46 @@ local function startLoop(settings)
local actuator = actuatorGet[1]
timeout:start()

http.get(table.concat({ settings.endpoint, "/device/", dni, '?pin=', actuator.pin }),
table.concat({ "Authorization: Bearer ", settings.token, "\r\nAccept: application/json\r\n" }),
local req = nil
if actuator.zone ~= nil then
req = table.concat({ settings.endpoint, "/device/", dni, '?zone=', actuator.zone })
else
req = table.concat({ settings.endpoint, "/device/", dni, '?pin=', actuator.pin })
end

http.get(req, table.concat({ "Authorization: Bearer ", settings.token, "\r\nAccept: application/json\r\n" }),
function(code, response)
timeout:stop()
local pin, state, json_response, status
local zone, pin, state, json_response, status
if response and code >= 200 and code < 300 then
status, json_response = pcall(function() return sjson.decode(response) end)
if status then
zone = json_response.zone
pin = tonumber(json_response.pin)
state = tonumber(json_response.state)
end
end
printHttpResponse(code, {pin = pin, state = state})

gpio.mode(actuator.pin, gpio.OUTPUT)
if pin == tonumber(actuator.pin) and code >= 200 and code < 300 and state then
gpio.write(actuator.pin, state)
if zone ~= nil then
printHttpResponse(code, {zone = zone, state = state})
pin = zoneToPin(actuator.zone)
else
printHttpResponse(code, {pin = pin, state = state})
end

gpio.mode(pin, gpio.OUTPUT)
if pin == tonumber(actuator.pin) or zone == actuator.zone and code >= 200 and code < 300 and state then
gpio.write(pin, state)
else
state = actuator.trigger == gpio.LOW and gpio.HIGH or gpio.LOW
gpio.write(actuator.pin, state)
gpio.write(pin, state)
end

if zone ~= nil then
print("Heap:", node.heap(), "Initialized actuator Zone:", actuator.zone, "Trigger:", actuator.trigger, "Initial state:", state)
else
print("Heap:", node.heap(), "Initialized actuator Pin:", actuator.pin, "Trigger:", actuator.trigger, "Initial state:", state)
end
print("Heap:", node.heap(), "Initialized actuator Pin:", actuator.pin, "Trigger:", actuator.trigger, "Initial state:", state)

table.remove(actuatorGet, 1)
blinktimer:start()
Expand Down
16 changes: 13 additions & 3 deletions src/lfs/server_device.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@ local function process(request)
if request.method == "GET" then
if request.query then
request.query.pin = request.query.pin or "all"
request.query.zone = request.query.zone or "all"
end
local body = {}
if request.query.pin == "all" then
if request.query.pin == "all" or request.query.zone == "all" then
local sensors = require("sensors")
for i, sensor in pairs(sensors) do
table.insert(body, { pin = sensor.pin, state = sensor.state })
if sensor.pin ~= nil then
table.insert(body, { pin = sensor.pin, state = sensor.state })
else
table.insert(body, { zone = sensor.zone, state = sensor.state })
end
end
else
elseif request.query.pin then
body = { {
pin = request.query.pin,
state = gpio.read(request.query.pin)
} }
else
body = { {
zone = request.query.zone,
state = gpio.read(require("zone_to_pin")(request.query.zone))
} }
end
return sjson.encode(body)
end
Expand Down
Loading

0 comments on commit b1b8d89

Please sign in to comment.