Polish Lua examples (#2846)

* Add missing globals from luacheck config

* Fix luacheck warnings in all lua files

* Re-enable luacheck in Travis

* Speed up Travis by using preinstalled LuaRocks

* Fix more luacheck warnings in httpserver lua module

* Fix DCC module and add appropriate definitions to luacheck config.

* Change inline comments from ignoring block to only ignore specific line

* Add Luacheck for Windows and enable it for both Windows and Linux

* Change luacheck exceptions and fix errors from 1st round of polishing

* Add retry and timeout params to wget
This commit is contained in:
galjonsfigur 2019-12-31 00:53:54 +01:00 committed by Marcel Stör
parent 36df8d009f
commit 6926c66b16
67 changed files with 897 additions and 710 deletions

View File

@ -20,6 +20,7 @@ addons:
packages: packages:
- python-serial - python-serial
- srecord - srecord
- luarocks
cache: cache:
- directories: - directories:
- cache - cache
@ -33,4 +34,5 @@ script:
- echo "checking:" - echo "checking:"
- find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo - find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
- find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 $LUACC -p - find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 $LUACC -p
# - if [ "$OS" = "linux" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck.sh || true ; fi - if [ "$OS" = "linux" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck-linux.sh; fi
- if [ "$OS" = "windows" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck-windows.sh; fi

View File

@ -1,43 +1,47 @@
-- --
-- Light sensor on ADC(0), RGB LED connected to gpio12(6) Green, gpio13(7) Blue & gpio15(8) Red. -- Light sensor on adc0(A0), RGB LED connected to gpio12(D6) Green, gpio13(D7) Blue & gpio15(D8) Red.
-- This works out of the box on the typical ESP8266 evaluation boards with Battery Holder -- This works out of the box on the typical ESP8266 evaluation boards with Battery Holder
-- --
-- It uses the input from the sensor to drive a "rainbow" effect on the RGB LED -- It uses the input from the sensor to drive a "rainbow" effect on the RGB LED
-- Includes a very "pseudoSin" function -- Includes a very "pseudoSin" function
-- --
-- Required C Modules: adc, tmr, pwm
function led(r,Sg,b) local redLed, greenLed, blueLed = 8, 6, 7
pwm.setduty(8,r)
pwm.setduty(6,g) local function setRGB(r,g,b)
pwm.setduty(7,b) pwm.setduty(redLed, r)
pwm.setduty(greenLed, g)
pwm.setduty(blueLed, b)
end end
-- this is perhaps the lightest weight sin function in existance -- this is perhaps the lightest weight sin function in existence
-- Given an integer from 0..128, 0..512 appximating 256 + 256 * sin(idx*Pi/256) -- Given an integer from 0..128, 0..512 approximating 256 + 256 * sin(idx*Pi/256)
-- This is first order square approximation of sin, it's accurate around 0 and any multiple of 128 (Pi/2), -- This is first order square approximation of sin, it's accurate around 0 and any multiple of 128 (Pi/2),
-- 92% accurate at 64 (Pi/4). -- 92% accurate at 64 (Pi/4).
function pseudoSin (idx) local function pseudoSin(idx)
idx = idx % 128 idx = idx % 128
lookUp = 32 - idx % 64 local lookUp = 32 - idx % 64
val = 256 - (lookUp * lookUp) / 4 local val = 256 - (lookUp * lookUp) / 4
if (idx > 64) then if (idx > 64) then
val = - val; val = - val;
end end
return 256+val return 256+val
end end
pwm.setup(6,500,512) do
pwm.setup(7,500,512) pwm.setup(redLed, 500, 512)
pwm.setup(8,500,512) pwm.setup(greenLed,500, 512)
pwm.start(6) pwm.setup(blueLed, 500, 512)
pwm.start(7) pwm.start(redLed)
pwm.start(8) pwm.start(greenLed)
pwm.start(blueLed)
tmr.alarm(1,20,1,function() tmr.create():alarm(20, tmr.ALARM_AUTO, function()
idx = 3 * adc.read(0) / 2 local idx = 3 * adc.read(0) / 2
r = pseudoSin(idx) local r = pseudoSin(idx)
g = pseudoSin(idx + 43) local g = pseudoSin(idx + 43) -- ~1/3rd of 128
b = pseudoSin(idx + 85) local b = pseudoSin(idx + 85) -- ~2/3rd of 128
led(r,g,b) setRGB(r,g,b)
idx = (idx + 1) % 128 end)
end) end

View File

@ -4,7 +4,7 @@ local PIN = 2 -- GPIO4
local addr = 0x12a local addr = 0x12a
CV = {[29]=0, local CV = {[29]=0,
[1]=bit.band(addr, 0x3f), --CV_ACCESSORY_DECODER_ADDRESS_LSB (6 bits) [1]=bit.band(addr, 0x3f), --CV_ACCESSORY_DECODER_ADDRESS_LSB (6 bits)
[9]=bit.band(bit.rshift(addr,6), 0x7) --CV_ACCESSORY_DECODER_ADDRESS_MSB (3 bits) [9]=bit.band(bit.rshift(addr,6), 0x7) --CV_ACCESSORY_DECODER_ADDRESS_MSB (3 bits)
} }
@ -37,18 +37,18 @@ end
local function DCC_command(cmd, params) local function DCC_command(cmd, params)
if not is_new(cmd, params) then return end if not is_new(cmd, params) then return end
if cmd == dcc.DCC_IDLE then if cmd == dcc.DCC_IDLE then
return return
elseif cmd == dcc.DCC_TURNOUT then elseif cmd == dcc.DCC_TURNOUT then
print("Turnout command") print("Turnout command")
elseif cmd == dcc.DCC_SPEED then elseif cmd == dcc.DCC_SPEED then
print("Speed command") print("Speed command")
elseif cmd == dcc.DCC_FUNC then elseif cmd == dcc.DCC_FUNC then
print("Function command") print("Function command")
else else
print("Other command", cmd) print("Other command", cmd)
end end
for i,j in pairs(params) do for i,j in pairs(params) do
print(i, j) print(i, j)
end end
@ -69,18 +69,21 @@ local function CV_callback(operation, param)
elseif operation == dcc.CV_VALID then elseif operation == dcc.CV_VALID then
oper = "Valid" oper = "Valid"
result = 1 result = 1
elseif operation == CV_RESET then elseif operation == dcc.CV_RESET then
oper = "Reset" oper = "Reset"
CV = {} CV = {}
end end
print(("[CV_callback] %s CV %d%s"):format(oper, param.CV, param.Value and "\tValue: "..param.Value or "\tValue: nil")) print(("[CV_callback] %s CV %d%s")
:format(oper, param.CV, param.Value and "\tValue: "..param.Value or "\tValue: nil"))
return result return result
end end
dcc.setup(PIN, dcc.setup(PIN,
DCC_command, DCC_command,
dcc.MAN_ID_DIY, 1, dcc.MAN_ID_DIY, 1,
--bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY), -- Accessories (turnouts) decoder -- Accessories (turnouts) decoder:
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT), -- Cab (train) decoder --bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY),
-- Cab (train) decoder
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT),
0, -- ??? 0, -- ???
CV_callback) CV_callback)

View File

@ -6,7 +6,7 @@
-- was tested with an AOL and Time Warner cable email accounts (GMail and other services who do -- was tested with an AOL and Time Warner cable email accounts (GMail and other services who do
-- not support no SSL access will not work). -- not support no SSL access will not work).
require("imap") local imap = require("imap")
local IMAP_USERNAME = "email@domain.com" local IMAP_USERNAME = "email@domain.com"
local IMAP_PASSWORD = "password" local IMAP_PASSWORD = "password"
@ -25,21 +25,13 @@ local SSID_PASSWORD = "password"
local count = 0 -- we will send several IMAP commands/requests, this variable helps keep track of which one to send local count = 0 -- we will send several IMAP commands/requests, this variable helps keep track of which one to send
local imap_socket, timer
-- configure the ESP8266 as a station
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID,SSID_PASSWORD)
wifi.sta.autoconnect(1)
-- create an unencrypted connection
local imap_socket = net.createConnection(net.TCP,0)
--- ---
-- @name setup -- @name setup
-- @description A call back function used to begin reading email -- @description A call back function used to begin reading email
-- upon sucessfull connection to the IMAP server -- upon sucessfull connection to the IMAP server
function setup(sck) local function setup(sck)
-- Set the email user name and password, IMAP tag, and if debugging output is needed -- Set the email user name and password, IMAP tag, and if debugging output is needed
imap.config(IMAP_USERNAME, imap.config(IMAP_USERNAME,
IMAP_PASSWORD, IMAP_PASSWORD,
@ -49,19 +41,16 @@ function setup(sck)
imap.login(sck) imap.login(sck)
end end
imap_socket:on("connection",setup) -- call setup() upon connection
imap_socket:connect(IMAP_PORT,IMAP_SERVER) -- connect to the IMAP server
local subject = "" local subject = ""
local from = "" local from = ""
local message = "" local body = ""
--- ---
-- @name do_next -- @name do_next
-- @description A call back function for a timer alarm used to check if the previous -- @description A call back function for a timer alarm used to check if the previous
-- IMAP command reply has been processed. If the IMAP reply has been processed -- IMAP command reply has been processed. If the IMAP reply has been processed
-- this function will call the next IMAP command function necessary to read the email -- this function will call the next IMAP command function necessary to read the email
function do_next() local function do_next()
-- Check if the IMAP reply was processed -- Check if the IMAP reply was processed
if(imap.response_processed() == true) then if(imap.response_processed() == true) then
@ -75,15 +64,18 @@ function do_next()
count = count + 1 count = count + 1
elseif (count == 1) then elseif (count == 1) then
-- After examining/selecting the INBOX folder we can begin to retrieve emails. -- After examining/selecting the INBOX folder we can begin to retrieve emails.
imap.fetch_header(imap_socket,imap.get_most_recent_num(),"SUBJECT") -- Retrieve the SUBJECT of the first/newest email -- Retrieve the SUBJECT of the first/newest email
imap.fetch_header(imap_socket,imap.get_most_recent_num(),"SUBJECT")
count = count + 1 count = count + 1
elseif (count == 2) then elseif (count == 2) then
subject = imap.get_header() -- store the SUBJECT response in subject subject = imap.get_header() -- store the SUBJECT response in subject
imap.fetch_header(imap_socket,imap.get_most_recent_num(),"FROM") -- Retrieve the FROM of the first/newest email -- Retrieve the FROM of the first/newest email
imap.fetch_header(imap_socket,imap.get_most_recent_num(),"FROM")
count = count + 1 count = count + 1
elseif (count == 3) then elseif (count == 3) then
from = imap.get_header() -- store the FROM response in from from = imap.get_header() -- store the FROM response in from
imap.fetch_body_plain_text(imap_socket,imap.get_most_recent_num()) -- Retrieve the BODY of the first/newest email -- Retrieve the BODY of the first/newest email
imap.fetch_body_plain_text(imap_socket,imap.get_most_recent_num())
count = count + 1 count = count + 1
elseif (count == 4) then elseif (count == 4) then
body = imap.get_body() -- store the BODY response in body body = imap.get_body() -- store the BODY response in body
@ -92,9 +84,9 @@ function do_next()
else else
-- display the email contents -- display the email contents
-- create patterns to strip away IMAP protocl text from actual message -- create patterns to strip away IMAP protocol text from actual message
pattern1 = "(\*.+\}\r\n)" -- to remove "* n command (BODY[n] {n}" local pattern1 = "%*.*}\n" -- to remove "* n command (BODY[n] {n}"
pattern2 = "(%)\r\n.+)" -- to remove ") t1 OK command completed" local pattern2 = "%)\n.+" -- to remove ") t1 OK command completed"
from = string.gsub(from,pattern1,"") from = string.gsub(from,pattern1,"")
from = string.gsub(from,pattern2,"") from = string.gsub(from,pattern2,"")
@ -108,7 +100,7 @@ function do_next()
body = string.gsub(body,pattern2,"") body = string.gsub(body,pattern2,"")
print("Message: " .. body) print("Message: " .. body)
tmr.stop(0) -- Stop the timer alarm timer:stop() -- Stop the timer alarm
imap_socket:close() -- close the IMAP socket imap_socket:close() -- close the IMAP socket
collectgarbage() -- clean up collectgarbage() -- clean up
end end
@ -116,5 +108,18 @@ function do_next()
end end
-- A timer alarm is sued to check if an IMAP reply has been processed do
tmr.alarm(0,1000,1, do_next) -- configure the ESP8266 as a station
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID,SSID_PASSWORD)
wifi.sta.autoconnect(1)
-- create an unencrypted connection
imap_socket = net.createConnection(net.TCP,0)
imap_socket:on("connection",setup) -- call setup() upon connection
imap_socket:connect(IMAP_PORT,IMAP_SERVER) -- connect to the IMAP server
-- A timer alarm is sued to check if an IMAP reply has been processed
timer = tmr.create()
timer:alarm(1000, tmr.ALARM_AUTO, do_next)
end

View File

@ -1,16 +1,17 @@
--- ---
-- Working Example: https://www.youtube.com/watch?v=CcRbFIJ8aeU -- Working Example: https://www.youtube.com/watch?v=CcRbFIJ8aeU
-- @description a basic SMTP email example. You must use an account which can provide unencrypted authenticated access. -- @description a basic SMTP email example. You must use an account which can
-- This example was tested with an AOL and Time Warner email accounts. GMail does not offer unecrypted authenticated access. -- provide unencrypted authenticated access.
-- This example was tested with an AOL and Time Warner email accounts.
-- GMail does not offer unencrypted authenticated access.
-- To obtain your email's SMTP server and port simply Google it e.g. [my email domain] SMTP settings -- To obtain your email's SMTP server and port simply Google it e.g. [my email domain] SMTP settings
-- For example for timewarner you'll get to this page http://www.timewarnercable.com/en/support/faqs/faqs-internet/e-mailacco/incoming-outgoing-server-addresses.html -- For example for timewarner you'll get to this page
-- http://www.timewarnercable.com/en/support/faqs/faqs-internet/e-mailacco/incoming-outgoing-server-addresses.html
-- To Learn more about SMTP email visit: -- To Learn more about SMTP email visit:
-- SMTP Commands Reference - http://www.samlogic.net/articles/smtp-commands-reference.htm -- SMTP Commands Reference - http://www.samlogic.net/articles/smtp-commands-reference.htm
-- See "SMTP transport example" in this page http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol -- See "SMTP transport example" in this page http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
-- @author Miguel -- @author Miguel
require("base64")
-- The email and password from the account you want to send emails from -- The email and password from the account you want to send emails from
local MY_EMAIL = "esp8266@domain.com" local MY_EMAIL = "esp8266@domain.com"
local EMAIL_PASSWORD = "123456" local EMAIL_PASSWORD = "123456"
@ -37,18 +38,18 @@ wifi.sta.autoconnect(1)
local email_subject = "" local email_subject = ""
local email_body = "" local email_body = ""
local count = 0 local count = 0
local timer
local smtp_socket = nil -- will be used as socket to email server local smtp_socket = nil -- will be used as socket to email server
-- The display() function will be used to print the SMTP server's response -- The display() function will be used to print the SMTP server's response
function display(sck,response) local function display(sck, response) -- luacheck: no unused
print(response) print(response)
end end
-- The do_next() function is used to send the SMTP commands to the SMTP server in the required sequence. -- The do_next() function is used to send the SMTP commands to the SMTP server in the required sequence.
-- I was going to use socket callbacks but the code would not run callbacks after the first 3. -- I was going to use socket callbacks but the code would not run callbacks after the first 3.
function do_next() local function do_next()
if(count == 0)then if(count == 0)then
count = count+1 count = count+1
local IP_ADDRESS = wifi.sta.getip() local IP_ADDRESS = wifi.sta.getip()
@ -58,10 +59,10 @@ function do_next()
smtp_socket:send("AUTH LOGIN\r\n") smtp_socket:send("AUTH LOGIN\r\n")
elseif(count == 2) then elseif(count == 2) then
count = count + 1 count = count + 1
smtp_socket:send(base64.enc(MY_EMAIL).."\r\n") smtp_socket:send(encoder.toBase64(MY_EMAIL).."\r\n")
elseif(count == 3) then elseif(count == 3) then
count = count + 1 count = count + 1
smtp_socket:send(base64.enc(EMAIL_PASSWORD).."\r\n") smtp_socket:send(encoder.toBase64(EMAIL_PASSWORD).."\r\n")
elseif(count==4) then elseif(count==4) then
count = count+1 count = count+1
smtp_socket:send("MAIL FROM:<" .. MY_EMAIL .. ">\r\n") smtp_socket:send("MAIL FROM:<" .. MY_EMAIL .. ">\r\n")
@ -82,26 +83,27 @@ function do_next()
smtp_socket:send(message.."\r\n.\r\n") smtp_socket:send(message.."\r\n.\r\n")
elseif(count==8) then elseif(count==8) then
count = count+1 count = count+1
tmr.stop(0) timer:stop()
smtp_socket:send("QUIT\r\n") smtp_socket:send("QUIT\r\n")
else else
smtp_socket:close() smtp_socket:close()
end end
end end
-- The connectted() function is executed when the SMTP socket is connected to the SMTP server. -- The connected() function is executed when the SMTP socket is connected to the SMTP server.
-- This function will create a timer to call the do_next function which will send the SMTP commands -- This function will create a timer to call the do_next function which will send the SMTP commands
-- in sequence, one by one, every 5000 seconds. -- in sequence, one by one, every 5000 seconds.
-- You can change the time to be smaller if that works for you, I used 5000ms just because. -- You can change the time to be smaller if that works for you, I used 5000ms just because.
function connected(sck) local function connected()
tmr.alarm(0,5000,1,do_next) timer = tmr.create()
timer:alarm(5000, tmr.ALARM_AUTO, do_next)
end end
-- @name send_email -- @name send_email
-- @description Will initiated a socket connection to the SMTP server and trigger the connected() function -- @description Will initiated a socket connection to the SMTP server and trigger the connected() function
-- @param subject The email's subject -- @param subject The email's subject
-- @param body The email's body -- @param body The email's body
function send_email(subject,body) local function send_email(subject,body)
count = 0 count = 0
email_subject = subject email_subject = subject
email_body = body email_body = body
@ -111,19 +113,13 @@ function send_email(subject,body)
smtp_socket:connect(SMTP_PORT,SMTP_SERVER) smtp_socket:connect(SMTP_PORT,SMTP_SERVER)
end end
-- Send an email do
send_email( -- Send an email
"ESP8266", send_email(
[[Hi, "ESP8266",
How are your IoT projects coming along? [[Hi,
Best Wishes, How are your IoT projects coming along?
ESP8266]]) Best Wishes,
ESP8266]]
)
end

View File

@ -10,6 +10,7 @@
local M local M
do do
-- const -- const
-- luacheck: push no unused
local NEC_PULSE_US = 1000000 / 38000 local NEC_PULSE_US = 1000000 / 38000
local NEC_HDR_MARK = 9000 local NEC_HDR_MARK = 9000
local NEC_HDR_SPACE = 4500 local NEC_HDR_SPACE = 4500
@ -17,6 +18,7 @@ do
local NEC_ONE_SPACE = 1600 local NEC_ONE_SPACE = 1600
local NEC_ZERO_SPACE = 560 local NEC_ZERO_SPACE = 560
local NEC_RPT_SPACE = 2250 local NEC_RPT_SPACE = 2250
-- luacheck: pop
-- cache -- cache
local gpio, bit = gpio, bit local gpio, bit = gpio, bit
local mode, write = gpio.mode, gpio.write local mode, write = gpio.mode, gpio.write

View File

@ -10,7 +10,7 @@ local host, dir, image = ...
local doRequest, firstRec, subsRec, finalise local doRequest, firstRec, subsRec, finalise
local n, total, size = 0, 0 local n, total, size = 0, 0
doRequest = function(sk,hostIP) doRequest = function(socket, hostIP) -- luacheck: no unused
if hostIP then if hostIP then
local con = net.createConnection(net.TCP,0) local con = net.createConnection(net.TCP,0)
con:connect(80,hostIP) con:connect(80,hostIP)

View File

@ -46,7 +46,7 @@ local lfs_t = {
end end
end, end,
__newindex = function(_, name, value) __newindex = function(_, name, value) -- luacheck: no unused
error("LFS is readonly. Invalid write to LFS." .. name, 2) error("LFS is readonly. Invalid write to LFS." .. name, 2)
end, end,

View File

@ -24,8 +24,10 @@ end
This will exclude any strings already in the ROM table, so the output is the list This will exclude any strings already in the ROM table, so the output is the list
of putative strings that you should consider adding to LFS ROM table. of putative strings that you should consider adding to LFS ROM table.
---------------------------------------------------------------------------------]] ---------------------------------------------------------------------------------
]]--
-- luacheck: ignore
local preload = "?.lc;?.lua", "/\n;\n?\n!\n-", "@init.lua", "_G", "_LOADED", local preload = "?.lc;?.lua", "/\n;\n?\n!\n-", "@init.lua", "_G", "_LOADED",
"_LOADLIB", "__add", "__call", "__concat", "__div", "__eq", "__gc", "__index", "_LOADLIB", "__add", "__call", "__concat", "__div", "__eq", "__gc", "__index",
"__le", "__len", "__lt", "__mod", "__mode", "__mul", "__newindex", "__pow", "__le", "__len", "__lt", "__mod", "__mode", "__mul", "__newindex", "__pow",

View File

@ -5,8 +5,8 @@
-- then enter the following commands interactively through the UART: -- then enter the following commands interactively through the UART:
-- --
do do
local _,ma,fa=node.flashindex() local sa, ma, fa = node.flashindex()
for n,v in pairs{LFS_MAPPED=ma, LFS_BASE=fa, SPIFFS_BASE=sa} do for n,v in pairs{LFS_MAPPED = ma, LFS_BASE = fa, SPIFFS_BASE = sa} do
print(('export %s=""0x%x"'):format(n, v)) print(('export %s=""0x%x"'):format(n, v))
end end
end end
@ -60,7 +60,5 @@ local initTimer = tmr.create()
initTimer:register(1000, tmr.ALARM_SINGLE, initTimer:register(1000, tmr.ALARM_SINGLE,
function() function()
local fi=node.flashindex; return pcall(fi and fi'_init') local fi=node.flashindex; return pcall(fi and fi'_init')
end end)
)
initTimer:start() initTimer:start()

View File

@ -1,3 +1,4 @@
-- luacheck: globals self
if (self.timer) then self.timer:stop() end--SAFETRIM if (self.timer) then self.timer:stop() end--SAFETRIM
-- function _doTick(self) -- function _doTick(self)

View File

@ -2,7 +2,7 @@
-- function _provision(self,socket,first_rec) -- function _provision(self,socket,first_rec)
local self, socket, first_rec = ... local self, socket, first_rec = ...
local crypto, file, json, node, table = crypto, file, sjson, node, table local crypto, file, json, node, table = crypto, file, sjson, node, table
local stripdebug, gc = node.stripdebug, collectgarbage local stripdebug, gc = node.stripdebug, collectgarbage
local buf = {} local buf = {}
@ -13,11 +13,10 @@ local function getbuf() -- upval: buf, table
end end
-- Process a provisioning request record -- Process a provisioning request record
local function receiveRec(socket, rec) -- upval: self, buf, crypto local function receiveRec(sck, rec) -- upval: self, buf, crypto
-- Note that for 2nd and subsequent responses, we assme that the service has -- Note that for 2nd and subsequent responses, we assume that the service has
-- "authenticated" itself, so any protocol errors are fatal and lkely to -- "authenticated" itself, so any protocol errors are fatal and likely to
-- cause a repeating boot, throw any protocol errors are thrown. -- cause a repeating boot, throw any protocol errors are thrown.
local config, file, log = self.config, file, self.log
local cmdlen = (rec:find('\n',1, true) or 0) - 1 local cmdlen = (rec:find('\n',1, true) or 0) - 1
local cmd,hash = rec:sub(1,cmdlen-6), rec:sub(cmdlen-5,cmdlen) local cmd,hash = rec:sub(1,cmdlen-6), rec:sub(cmdlen-5,cmdlen)
if cmdlen < 16 or if cmdlen < 16 or
@ -25,7 +24,9 @@ local function receiveRec(socket, rec) -- upval: self, buf, crypto
return error("Invalid command signature") return error("Invalid command signature")
end end
local s; s, cmd = pcall(json.decode, cmd) local s
s, cmd = pcall(json.decode, cmd)
if not s then error("JSON decode error") end
local action,resp = cmd.a, {s = "OK"} local action,resp = cmd.a, {s = "OK"}
local chunk local chunk
@ -59,15 +60,15 @@ local function receiveRec(socket, rec) -- upval: self, buf, crypto
if not msg then if not msg then
gc(); gc() gc(); gc()
local code, name = string.dump(lcf), cmd.name:sub(1,-5) .. ".lc" local code, name = string.dump(lcf), cmd.name:sub(1,-5) .. ".lc"
local s = file.open(name, "w+") local f = file.open(name, "w+")
if s then if f then
for i = 1, #code, 1024 do for i = 1, #code, 1024 do
s = s and file.write(code:sub(i, ((i+1023)>#code) and i+1023 or #code)) f = f and file.write(code:sub(i, ((i+1023)>#code) and i+1023 or #code))
end end
file.close() file.close()
if not s then file.remove(name) end if not f then file.remove(name) end
end end
if s then if f then
resp.lcsize=#code resp.lcsize=#code
print("Updated ".. name) print("Updated ".. name)
else else
@ -80,15 +81,15 @@ local function receiveRec(socket, rec) -- upval: self, buf, crypto
buf = {} buf = {}
elseif action == "dl" then elseif action == "dl" then
local s = file.open(cmd.name, "w+") local dlFile = file.open(cmd.name, "w+")
if s then if dlFile then
for i = 1, #buf do for i = 1, #buf do
s = s and file.write(buf[i]) dlFile = dlFile and file.write(buf[i])
end end
file.close() file.close()
end end
if s then if dlFile then
print("Updated ".. cmd.name) print("Updated ".. cmd.name)
else else
file.remove(cmd.name) file.remove(cmd.name)
@ -109,13 +110,13 @@ local function receiveRec(socket, rec) -- upval: self, buf, crypto
file.open(self.prefix.."config.json", "w+") file.open(self.prefix.."config.json", "w+")
file.writeline(json.encode(cmd)) file.writeline(json.encode(cmd))
file.close() file.close()
socket:close() sck:close()
print("Restarting to load new application") print("Restarting to load new application")
node.restart() -- reboot just schedules a restart node.restart() -- reboot just schedules a restart
return return
end end
end end
self.socket_send(socket, resp, chunk) self.socket_send(sck, resp, chunk)
gc() gc()
end end

View File

@ -9,14 +9,13 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- upvals -- upvals
local crypto, file, json, net, node, table, wifi = local crypto, json, node, wifi =
crypto, file, sjson, net, node, table, wifi crypto, sjson, node, wifi
local error, pcall = error, pcall local error = error
local loadfile, gc = loadfile, collectgarbage local loadfile, gc = loadfile, collectgarbage
local concat, unpack = table.concat, unpack or table.unpack
local self = {post = node.task.post, prefix = "luaOTA/", conf = {}} local self = {post = node.task.post, prefix = "luaOTA/", conf = {}}
-- luacheck: globals DEBUG
self.log = (DEBUG == true) and print or function() end self.log = (DEBUG == true) and print or function() end
self.modname = ... self.modname = ...
self.timer = tmr.create() self.timer = tmr.create()
@ -27,15 +26,15 @@ end
-------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------
-- Utility Functions -- Utility Functions
setmetatable( self, {__index=function(self, func) --upval: loadfile setmetatable( self, {__index=function(obj, func) --upval: loadfile
-- The only __index calls in in LuaOTA are dynamically loaded functions. -- The only __index calls in in LuaOTA are dynamically loaded functions.
-- The convention is that functions starting with "_" are treated as -- The convention is that functions starting with "_" are treated as
-- call-once / ephemeral; the rest are registered in self -- call-once / ephemeral; the rest are registered in self
func = self.prefix .. func func = obj.prefix .. func
local f,msg = loadfile( func..".lc") local f,msg = loadfile( func..".lc")
if msg then f, msg = loadfile(func..".lua") end if msg then f, msg = loadfile(func..".lua") end
if msg then error (msg,2) end if msg then error (msg,2) end
if func:sub(8,8) ~= "_" then self[func] = f end if func:sub(8,8) ~= "_" then obj[func] = f end
return f return f
end} ) end} )

View File

@ -1,5 +1,4 @@
-- -- luacheck: globals DEBUG
local function enum(t,log) for k,v in pairs(t)do log(k,v) end end
return {entry = function(msg) return {entry = function(msg)
package.loaded["luaOTA.default"]=nil package.loaded["luaOTA.default"]=nil
local gc=collectgarbage; gc(); gc() local gc=collectgarbage; gc(); gc()

View File

@ -17,6 +17,8 @@
]] ]]
-- luacheck: std max
local socket = require "socket" local socket = require "socket"
local lfs = require "lfs" local lfs = require "lfs"
local md5 = require "md5" local md5 = require "md5"
@ -31,7 +33,6 @@ local receive_and_parse -- function(esp)
local provision -- function(esp, config, files, inventory, fingerprint) local provision -- function(esp, config, files, inventory, fingerprint)
local read_file -- function(fname) local read_file -- function(fname)
local save_file -- function(fname, data) local save_file -- function(fname, data)
local compress_lua -- function(lua_file)
local hmac -- function(data) local hmac -- function(data)
-- Function-wide locals (can be upvalues) -- Function-wide locals (can be upvalues)
@ -164,6 +165,7 @@ receive_and_parse = function(esp)
local packed_cmd, sig = line:sub(1,#line-6),line:sub(-6) local packed_cmd, sig = line:sub(1,#line-6),line:sub(-6)
-- print("reply:", packed_cmd, sig) -- print("reply:", packed_cmd, sig)
local status, cmd = pcall(json.decode, packed_cmd) local status, cmd = pcall(json.decode, packed_cmd)
if not status then error("JSON decode error") end
if not hmac or hmac(packed_cmd):sub(-6) == sig then if not hmac or hmac(packed_cmd):sub(-6) == sig then
if cmd and cmd.data == "number" then if cmd and cmd.data == "number" then
local data = esp:receive(cmd.data) local data = esp:receive(cmd.data)
@ -183,7 +185,7 @@ provision = function(esp, config, inventory, fingerprint)
local name, size, mtime, content = f.name, f.size, f.mtime, f.content local name, size, mtime, content = f.name, f.size, f.mtime, f.content
if not cf[name] or cf[name] ~= mtime then if not cf[name] or cf[name] ~= mtime then
-- Send the file -- Send the file
local func, action, cmd, buf local action, cmd, buf
if f.name:sub(-4) == ".lua" then if f.name:sub(-4) == ".lua" then
assert(load(content, f.name)) -- check that the contents can compile assert(load(content, f.name)) -- check that the contents can compile
if content:find("--SAFETRIM\n",1,true) then if content:find("--SAFETRIM\n",1,true) then
@ -241,12 +243,11 @@ end
-- Save contents to the given file -- Save contents to the given file
---------------------------------- ----------------------------------
save_file = function(fname, data) save_file = function(fname, data) -- luacheck: ignore
local file = io.open(fname, "wb") local file = io.open(fname, "wb")
file:write(data) file:write(data)
file:close() file:close()
end end
-------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------
main() -- now that all functions have been bound to locals, we can start the show :-) main() -- now that all functions have been bound to locals, we can start the show :-)

View File

@ -29,10 +29,12 @@ local TWILIO_ACCOUNT_SID = "xxxxxx"
local TWILIO_TOKEN = "xxxxxx" local TWILIO_TOKEN = "xxxxxx"
local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service
-- Please be sure to understand the security issues of using this relay app and use at your own risk. -- Please be sure to understand the security issues of using this relay app and use at your own risk.
local URI = "/twilio/Calls.json" local URI = "/twilio/Calls.json"
function build_post_request(host, uri, data_table) local wifiTimer = tmr.create()
local function build_post_request(host, uri, data_table)
local data = "" local data = ""
@ -40,7 +42,7 @@ function build_post_request(host, uri, data_table)
data = data .. param.."="..value.."&" data = data .. param.."="..value.."&"
end end
request = "POST "..uri.." HTTP/1.1\r\n".. local request = "POST "..uri.." HTTP/1.1\r\n"..
"Host: "..host.."\r\n".. "Host: "..host.."\r\n"..
"Connection: close\r\n".. "Connection: close\r\n"..
"Content-Type: application/x-www-form-urlencoded\r\n".. "Content-Type: application/x-www-form-urlencoded\r\n"..
@ -53,7 +55,7 @@ function build_post_request(host, uri, data_table)
return request return request
end end
local function display(sck,response) local function display(socket, response) -- luacheck: no unused
print(response) print(response)
end end
@ -69,7 +71,7 @@ local function make_call(from,to,body)
To = to To = to
} }
socket = net.createConnection(net.TCP,0) local socket = net.createConnection(net.TCP,0)
socket:on("receive",display) socket:on("receive",display)
socket:connect(80,HOST) socket:connect(80,HOST)
@ -80,13 +82,13 @@ local function make_call(from,to,body)
end) end)
end end
function check_wifi() local function check_wifi()
local ip = wifi.sta.getip() local ip = wifi.sta.getip()
if(ip==nil) then if(ip==nil) then
print("Connecting...") print("Connecting...")
else else
tmr.stop(0) wifiTimer:stop()
print("Connected to AP!") print("Connected to AP!")
print(ip) print(ip)
-- make a call with a voice message "your house is on fire" -- make a call with a voice message "your house is on fire"
@ -95,4 +97,4 @@ function check_wifi()
end end
tmr.alarm(0,2000,1,check_wifi) wifiTimer:alarm(2000, tmr.ALARM_AUTO, check_wifi)

View File

@ -14,23 +14,17 @@
-- Website: http://AllAboutEE.com -- Website: http://AllAboutEE.com
--------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------
require ("mcp23008") local mcp23008 = require ("mcp23008")
-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware -- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
gpio0, gpio2 = 3, 4 local gpio0, gpio2 = 3, 4
-- Setup the MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0xff)
mcp23008.writeGPPU(0xff)
--- ---
-- @name showButtons -- @name showButtons
-- @description Shows the state of each GPIO pin -- @description Shows the state of each GPIO pin
-- @return void -- @return void
--------------------------------------------------------- ---------------------------------------------------------
function showButtons() local function showButtons()
local gpio = mcp23008.readGPIO() -- read the GPIO/buttons states local gpio = mcp23008.readGPIO() -- read the GPIO/buttons states
@ -51,7 +45,13 @@ function showButtons()
print("\r\n") print("\r\n")
end end
tmr.alarm(0,2000,1,showButtons) -- run showButtons() every 2 seconds do
-- Setup the MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0xff)
mcp23008.writeGPPU(0xff)
tmr.create():alarm(2000, tmr.ALARM_AUTO, showButtons) -- run showButtons() every 2 seconds
end

View File

@ -13,26 +13,17 @@
-- Website: http://AllAboutEE.com -- Website: http://AllAboutEE.com
--------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------
require ("mcp23008") local mcp23008 = require ("mcp23008")
-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware -- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
gpio0, gpio2 = 3, 4 local gpio0, gpio2 = 3, 4
-- Setup MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0x00) -- make all GPIO pins as outputs
mcp23008.writeGPIO(0x00) -- make all GIPO pins off/low
--- ---
-- @name count() -- @name count()
-- @description Reads the value from the GPIO register, increases the read value by 1 -- @description Reads the value from the GPIO register, increases the read value by 1
-- and writes it back so the LEDs will display a binary count up to 255 or 0xFF in hex. -- and writes it back so the LEDs will display a binary count up to 255 or 0xFF in hex.
local function count() local function count()
local gpio = mcp23008.readGPIO()
local gpio = 0x00
gpio = mcp23008.readGPIO()
if(gpio<0xff) then if(gpio<0xff) then
mcp23008.writeGPIO(gpio+1) mcp23008.writeGPIO(gpio+1)
@ -41,5 +32,15 @@ local function count()
end end
end end
-- Run count() every 100ms
tmr.alarm(0,100,1,count) do
-- Setup MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0x00) -- make all GPIO pins as outputs
mcp23008.writeGPIO(0x00) -- make all GIPO pins off/low
-- Run count() every 100ms
tmr.create():alarm(100, tmr.ALARM_AUTO, count)
end

View File

@ -1,33 +1,41 @@
-- test with cloudmqtt.com -- test with cloudmqtt.com
m_dis={} local m_dis = {}
function dispatch(m,t,pl)
if pl~=nil and m_dis[t] then local function dispatch(m,t,pl)
m_dis[t](m,pl) if pl~=nil and m_dis[t] then
end m_dis[t](m,pl)
end
end end
function topic1func(m,pl)
print("get1: "..pl) local function topic1func(_,pl)
print("get1: "..pl)
end end
function topic2func(m,pl)
print("get2: "..pl) local function topic2func(_,pl)
print("get2: "..pl)
end end
m_dis["/topic1"]=topic1func
m_dis["/topic2"]=topic2func do
-- Lua: mqtt.Client(clientid, keepalive, user, pass) m_dis["/topic1"] = topic1func
m=mqtt.Client("nodemcu1",60,"test","test123") m_dis["/topic2"] = topic2func
m:on("connect",function(m) -- Lua: mqtt.Client(clientid, keepalive, user, pass)
print("connection "..node.heap()) local m = mqtt.Client("nodemcu1", 60, "test", "test123")
m:subscribe("/topic1",0,function(m) print("sub done") end) m:on("connect",function(client)
m:subscribe("/topic2",0,function(m) print("sub done") end) print("connection "..node.heap())
m:publish("/topic1","hello",0,0) m:publish("/topic2","world",0,0) client:subscribe("/topic1",0,function() print("sub done") end)
end ) client:subscribe("/topic2",0,function() print("sub done") end)
m:on("offline", function(conn) client:publish("/topic1","hello",0,0)
client:publish("/topic2","world",0,0)
end)
m:on("offline", function()
print("disconnect to broker...") print("disconnect to broker...")
print(node.heap()) print(node.heap())
end) end)
m:on("message",dispatch ) m:on("message",dispatch )
-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) -- Lua: mqtt:connect( host, port, secure, function(client) )
m:connect("m11.cloudmqtt.com",11214,0,1) m:connect("m11.cloudmqtt.com",11214,0)
tmr.alarm(0,10000,1,function() local pl = "time: "..tmr.time() tmr.create():alarm(10000, tmr.ALARM_AUTO, function()
m:publish("/topic1",pl,0,0) local pl = "time: "..tmr.time()
end) m:publish("/topic1",pl,0,0)
end)
end

View File

@ -1,22 +1,23 @@
-- test transfer files over mqtt. -- test transfer files over mqtt.
m_dis={} local m_dis = {}
function dispatch(m,t,pl)
if pl~=nil and m_dis[t] then local function dispatch(m, t, pl)
if pl ~= nil and m_dis[t] then
m_dis[t](m,pl) m_dis[t](m,pl)
end end
end end
function pubfile(m,filename) local function pubfile(m,filename)
file.close() file.close()
file.open(filename) file.open(filename)
repeat repeat
local pl=file.read(1024) local pl = file.read(1024)
if pl then m:publish("/topic2",pl,0,0) end if pl then m:publish("/topic2", pl, 0, 0) end
until not pl until not pl
file.close() file.close()
end end
-- payload(json): {"cmd":xxx,"content":xxx} -- payload(json): {"cmd":xxx,"content":xxx}
function topic1func(m,pl) local function topic1func(m,pl)
print("get1: "..pl) print("get1: "..pl)
local pack = sjson.decode(pl) local pack = sjson.decode(pl)
if pack.content then if pack.content then
@ -30,21 +31,22 @@ function topic1func(m,pl)
end end
end end
m_dis["/topic1"]=topic1func do
-- Lua: mqtt.Client(clientid, keepalive, user, pass) m_dis["/topic1"]=topic1func
m=mqtt.Client() -- Lua: mqtt.Client(clientid, keepalive, user, pass)
m:on("connect",function(m) local m = mqtt.Client()
print("connection "..node.heap()) m:on("connect",function(client)
m:subscribe("/topic1",0,function(m) print("sub done") end) print("connection "..node.heap())
end ) client:subscribe("/topic1", 0, function() print("sub done") end)
m:on("offline", function(conn) end)
print("disconnect to broker...") m:on("offline", function()
print(node.heap()) print("disconnect to broker...")
end) print(node.heap())
m:on("message",dispatch ) end)
-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) ) m:on("message",dispatch )
m:connect("192.168.18.88",1883,0,1) -- Lua: mqtt:connect( host, port, secure, function(client) )
m:connect("192.168.18.88",1883,0)
end
-- usage: -- usage:
-- another client(pc) subscribe to /topic2, will receive the test.lua content. -- another client(pc) subscribe to /topic2, will receive the test.lua content.
-- and publish below message to /topic1 -- and publish below message to /topic1

View File

@ -6,7 +6,7 @@
-- **************************************************************************** -- ****************************************************************************
function cb_drained(d) local function cb_drained()
print("drained "..node.heap()) print("drained "..node.heap())
file.seek("set", 0) file.seek("set", 0)
@ -14,27 +14,29 @@ function cb_drained(d)
--d:play(pcm.RATE_8K) --d:play(pcm.RATE_8K)
end end
function cb_stopped(d) local function cb_stopped()
print("playback stopped") print("playback stopped")
file.seek("set", 0) file.seek("set", 0)
end end
function cb_paused(d) local function cb_paused()
print("playback paused") print("playback paused")
end end
file.open("jump_8k.u8", "r") do
file.open("jump_8k.u8", "r")
drv = pcm.new(pcm.SD, 1) local drv = pcm.new(pcm.SD, 1)
-- fetch data in chunks of FILE_READ_CHUNK (1024) from file -- fetch data in chunks of FILE_READ_CHUNK (1024) from file
drv:on("data", function(drv) return file.read() end) drv:on("data", function(driver) return file.read() end) -- luacheck: no unused
-- get called back when all samples were read from the file -- get called back when all samples were read from the file
drv:on("drained", cb_drained) drv:on("drained", cb_drained)
drv:on("stopped", cb_stopped) drv:on("stopped", cb_stopped)
drv:on("paused", cb_paused) drv:on("paused", cb_paused)
-- start playback -- start playback
drv:play(pcm.RATE_8K) drv:play(pcm.RATE_8K)
end

View File

@ -29,10 +29,12 @@ local TWILIO_ACCOUNT_SID = "xxxxxx"
local TWILIO_TOKEN = "xxxxxx" local TWILIO_TOKEN = "xxxxxx"
local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service
-- Please be sure to understand the security issues of using this relay app and use at your own risk. -- Please be sure to understand the security issues of using this relay app and use at your own risk.
local URI = "/twilio/Messages.json" local URI = "/twilio/Messages.json"
function build_post_request(host, uri, data_table) local wifiTimer = tmr.create()
local function build_post_request(host, uri, data_table)
local data = "" local data = ""
@ -40,7 +42,7 @@ function build_post_request(host, uri, data_table)
data = data .. param.."="..value.."&" data = data .. param.."="..value.."&"
end end
request = "POST "..uri.." HTTP/1.1\r\n".. local request = "POST "..uri.." HTTP/1.1\r\n"..
"Host: "..host.."\r\n".. "Host: "..host.."\r\n"..
"Connection: close\r\n".. "Connection: close\r\n"..
"Content-Type: application/x-www-form-urlencoded\r\n".. "Content-Type: application/x-www-form-urlencoded\r\n"..
@ -53,7 +55,7 @@ function build_post_request(host, uri, data_table)
return request return request
end end
local function display(sck,response) local function display(socket, response) -- luacheck: no unused
print(response) print(response)
end end
@ -69,7 +71,7 @@ local function send_sms(from,to,body)
To = to To = to
} }
socket = net.createConnection(net.TCP,0) local socket = net.createConnection(net.TCP,0)
socket:on("receive",display) socket:on("receive",display)
socket:connect(80,HOST) socket:connect(80,HOST)
@ -80,13 +82,13 @@ local function send_sms(from,to,body)
end) end)
end end
function check_wifi() local function check_wifi()
local ip = wifi.sta.getip() local ip = wifi.sta.getip()
if(ip==nil) then if(ip==nil) then
print("Connecting...") print("Connecting...")
else else
tmr.stop(0) wifiTimer.stop()
print("Connected to AP!") print("Connected to AP!")
print(ip) print(ip)
-- send a text message with the text "Hello from your esp8266" -- send a text message with the text "Hello from your esp8266"
@ -95,4 +97,4 @@ function check_wifi()
end end
tmr.alarm(0,7000,1,check_wifi) wifiTimer.alarm(7000, tmr.ALARM_AUTO, check_wifi)

View File

@ -1,11 +1,18 @@
-- Test sjson and GitHub API -- Test sjson and GitHub API
local s = tls.createConnection() local s = tls.createConnection()
s:on("connection", function(sck, c) s:on("connection", function(sck)
sck:send("GET /repos/nodemcu/nodemcu-firmware/git/trees/master HTTP/1.0\r\nUser-agent: nodemcu/0.1\r\nHost: api.github.com\r\nConnection: close\r\nAccept: application/json\r\n\r\n") sck:send(
[[GET /repos/nodemcu/nodemcu-firmware/git/trees/master HTTP/1.0
User-agent: nodemcu/0.1
Host: api.github.com
Connection: close
Accept: application/json
]])
end) end)
function startswith(String, Start) local function startswith(String, Start)
return string.sub(String, 1, string.len(Start)) == Start return string.sub(String, 1, string.len(Start)) == Start
end end
@ -23,13 +30,13 @@ local decoder = sjson.decoder({
end end
} }
}) })
local function handledata(s) local function handledata(sck)
decoder:write(s) decoder:write(sck)
end end
-- The receive callback is somewhat gnarly as it has to deal with find the end of the header -- The receive callback is somewhat gnarly as it has to deal with find the end of the header
-- and having the newline sequence split across packets -- and having the newline sequence split across packets
s:on("receive", function(sck, c) s:on("receive", function(socket, c) -- luacheck: no unused
if partial then if partial then
c = partial .. c c = partial .. c
partial = nil partial = nil
@ -45,8 +52,8 @@ s:on("receive", function(sck, c)
handledata(c) handledata(c)
return return
end end
local s, e = c:find("\r\n") local str, e = c:find("\r\n")
if s then if str then
-- Throw away line -- Throw away line
c = c:sub(e + 1) c = c:sub(e + 1)
else else

View File

@ -1,17 +1,20 @@
-- Somfy module example (beside somfy module requires also SJSON module) -- Somfy module example (beside somfy module requires also SJSON module)
-- The rolling code number is stored in the file somfy.cfg. A cached write of the somfy.cfg file is implemented in order to reduce the number of write to the EEPROM memory. Together with the logic of the file module it should allow long lasting operation. -- The rolling code number is stored in the file somfy.cfg.
-- A cached write of the somfy.cfg file is implemented in order to reduce
-- the number of write to the EEPROM memory. Together with the logic of the
-- file module it should allow long lasting operation.
config_file = "somfy." local config_file = "somfy."
local config, config_saved
-- somfy.cfg looks like -- somfy.cfg looks like
-- {"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}} -- {"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}
local tmr_cache = tmr.create() local tmr_cache = tmr.create()
local tmr_delay = tmr.create() local tmr_delay = tmr.create()
pin = 4 local pin = 4
gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP)
function deepcopy(orig) local function deepcopy(orig)
local orig_type = type(orig) local orig_type = type(orig)
local copy local copy
if orig_type == 'table' then if orig_type == 'table' then
@ -26,8 +29,8 @@ function deepcopy(orig)
return copy return copy
end end
function readconfig() local function readconfig()
local cfg, ok, ln local ln
if file.exists(config_file.."cfg") then if file.exists(config_file.."cfg") then
print("Reading config from "..config_file.."cfg") print("Reading config from "..config_file.."cfg")
file.open(config_file.."cfg", "r+") file.open(config_file.."cfg", "r+")
@ -47,7 +50,7 @@ function readconfig()
config_saved = deepcopy(config) config_saved = deepcopy(config)
end end
function writeconfighard() local function writeconfighard()
print("Saving config") print("Saving config")
file.remove(config_file.."bak") file.remove(config_file.."bak")
file.rename(config_file.."cfg", config_file.."bak") file.rename(config_file.."cfg", config_file.."bak")
@ -63,8 +66,8 @@ function writeconfighard()
config_saved = deepcopy(config) config_saved = deepcopy(config)
end end
function writeconfig() local function writeconfig()
tmr.stop(tmr_cache) tmr_cache:stop()
local savenow = false local savenow = false
local savelater = false local savelater = false
@ -87,12 +90,18 @@ function writeconfig()
end end
if savelater then if savelater then
print("Saving config later") print("Saving config later")
tmr.alarm(tmr_cache, 65000, tmr.ALARM_SINGLE, writeconfighard) tmr_cache:alarm(65000, tmr.ALARM_SINGLE, writeconfighard)
end end
end end
--======================================================================================================-- --======================================================================================================--
function down(remote, cb, par) local function wait(ms, cb, par)
par = par or {}
print("wait: ".. ms)
if cb then tmr_delay:alarm(ms, tmr.ALARM_SINGLE, function () cb(unpack(par)) end) end
end
local function down(remote, cb, par)
par = par or {} par = par or {}
print("down: ".. remote) print("down: ".. remote)
config[remote].rc=config[remote].rc+1 config[remote].rc=config[remote].rc+1
@ -100,7 +109,7 @@ function down(remote, cb, par)
writeconfig() writeconfig()
end end
function up(remote, cb, par) local function up(remote, cb, par)
par = par or {} par = par or {}
print("up: ".. remote) print("up: ".. remote)
config[remote].rc=config[remote].rc+1 config[remote].rc=config[remote].rc+1
@ -108,7 +117,7 @@ function up(remote, cb, par)
writeconfig() writeconfig()
end end
function downStep(remote, cb, par) local function downStep(remote, cb, par)
par = par or {} par = par or {}
print("downStep: ".. remote) print("downStep: ".. remote)
config[remote].rc=config[remote].rc+1 config[remote].rc=config[remote].rc+1
@ -116,7 +125,7 @@ function downStep(remote, cb, par)
writeconfig() writeconfig()
end end
function upStep(remote, cb, par) local function upStep(remote, cb, par) -- luacheck: ignore
par = par or {} par = par or {}
print("upStep: ".. remote) print("upStep: ".. remote)
config[remote].rc=config[remote].rc+1 config[remote].rc=config[remote].rc+1
@ -124,14 +133,9 @@ function upStep(remote, cb, par)
writeconfig() writeconfig()
end end
function wait(ms, cb, par)
par = par or {}
print("wait: ".. ms)
if cb then tmr.alarm(tmr_delay, ms, tmr.ALARM_SINGLE, function () cb(unpack(par)) end) end
end
--======================================================================================================-- --======================================================================================================--
gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP)
if not config then readconfig() end if not config then readconfig() end
if #config == 0 then -- somfy.cfg does not exist if #config == 0 then -- somfy.cfg does not exist
config = sjson.decode([[{"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}]]) config = sjson.decode([[{"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}]])
@ -141,5 +145,11 @@ down('window1',
wait, {60000, wait, {60000,
up, {'window1', up, {'window1',
wait, {9000, wait, {9000,
downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1' downStep, {'window1',
downStep, {'window1',
downStep, {'window1',
downStep, {'window1',
downStep, {'window1',
downStep, {'window1',
downStep, {'window1'
}}}}}}}}}}) }}}}}}}}}})

View File

@ -1,16 +1,18 @@
uart.setup(0,9600,8,0,1,0) do
sv=net.createServer(net.TCP, 60) uart.setup(0, 9600, 8, 0, 1, 0)
global_c = nil local sv = net.createServer(net.TCP, 60)
sv:listen(9999, function(c) local global_c = nil
if global_c~=nil then sv:listen(9999, function(c)
global_c:close() if global_c~=nil then
end global_c:close()
global_c=c end
c:on("receive",function(sck,pl) uart.write(0,pl) end) global_c = c
end) c:on("receive",function(_, pl) uart.write(0, pl) end)
end)
uart.on("data",4, function(data) uart.on("data", 4, function(data)
if global_c~=nil then if global_c ~= nil then
global_c:send(data) global_c:send(data)
end end
end, 0) end, 0)
end

View File

@ -27,7 +27,7 @@ function M.getzones()
return result return result
end end
function load(t) local function load(t)
local z = file.open(thezone .. ".zone", "r") local z = file.open(thezone .. ".zone", "r")
local hdr = z:read(20) local hdr = z:read(20)
@ -35,7 +35,8 @@ function load(t)
if magic == "TZif" then if magic == "TZif" then
local lens = z:read(24) local lens = z:read(24)
local ttisgmt_count, ttisdstcnt, leapcnt, timecnt, typecnt, charcnt = struct.unpack("> LLLLLL", lens) local ttisgmt_count, ttisdstcnt, leapcnt, timecnt, typecnt, charcnt -- luacheck: no unused
= struct.unpack("> LLLLLL", lens)
local times = z:read(4 * timecnt) local times = z:read(4 * timecnt)
local typeindex = z:read(timecnt) local typeindex = z:read(timecnt)

View File

@ -9,8 +9,13 @@
-- --
-- *************************************************************************** -- ***************************************************************************
-- display object
local disp
local draw_state, loop_tmr = 0, tmr.create()
-- setup I2c and connect display -- setup I2c and connect display
function init_i2c_display() local function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs -- SDA and SCL can be assigned freely to available GPIOs
local sda = 5 -- GPIO14 local sda = 5 -- GPIO14
local scl = 6 -- GPIO12 local scl = 6 -- GPIO12
@ -18,9 +23,8 @@ function init_i2c_display()
i2c.setup(0, sda, scl, i2c.SLOW) i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g2.ssd1306_i2c_128x64_noname(0, sla) disp = u8g2.ssd1306_i2c_128x64_noname(0, sla)
end end
-- setup SPI and connect display -- setup SPI and connect display
function init_spi_display() local function init_spi_display() -- luacheck: no unused
-- Hardware SPI CLK = GPIO14 -- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
@ -37,8 +41,7 @@ function init_spi_display()
disp = u8g2.ssd1306_128x64_noname(1, cs, dc, res) disp = u8g2.ssd1306_128x64_noname(1, cs, dc, res)
end end
local function u8g2_prepare()
function u8g2_prepare()
disp:setFont(u8g2.font_6x10_tf) disp:setFont(u8g2.font_6x10_tf)
disp:setFontRefHeightExtendedText() disp:setFontRefHeightExtendedText()
disp:setDrawColor(1) disp:setDrawColor(1)
@ -47,7 +50,7 @@ function u8g2_prepare()
end end
function u8g2_box_frame(a) local function u8g2_box_frame(a)
disp:drawStr( 0, 0, "drawBox") disp:drawStr( 0, 0, "drawBox")
disp:drawBox(5,10,20,10) disp:drawBox(5,10,20,10)
disp:drawBox(10+a,15,30,7) disp:drawBox(10+a,15,30,7)
@ -56,7 +59,7 @@ function u8g2_box_frame(a)
disp:drawFrame(10+a,15+30,30,7) disp:drawFrame(10+a,15+30,30,7)
end end
function u8g2_disc_circle(a) local function u8g2_disc_circle(a)
disp:drawStr( 0, 0, "drawDisc") disp:drawStr( 0, 0, "drawDisc")
disp:drawDisc(10,18,9) disp:drawDisc(10,18,9)
disp:drawDisc(24+a,16,7) disp:drawDisc(24+a,16,7)
@ -65,13 +68,13 @@ function u8g2_disc_circle(a)
disp:drawCircle(24+a,16+30,7) disp:drawCircle(24+a,16+30,7)
end end
function u8g2_r_frame(a) local function u8g2_r_frame(a)
disp:drawStr( 0, 0, "drawRFrame/Box") disp:drawStr( 0, 0, "drawRFrame/Box")
disp:drawRFrame(5, 10,40,30, a+1) disp:drawRFrame(5, 10,40,30, a+1)
disp:drawRBox(50, 10,25,40, a+1) disp:drawRBox(50, 10,25,40, a+1)
end end
function u8g2_string(a) local function u8g2_string(a)
disp:setFontDirection(0) disp:setFontDirection(0)
disp:drawStr(30+a,31, " 0") disp:drawStr(30+a,31, " 0")
disp:setFontDirection(1) disp:setFontDirection(1)
@ -82,7 +85,7 @@ function u8g2_string(a)
disp:drawStr(30,31-a, " 270") disp:drawStr(30,31-a, " 270")
end end
function u8g2_line(a) local function u8g2_line(a)
disp:drawStr( 0, 0, "drawLine") disp:drawStr( 0, 0, "drawLine")
disp:drawLine(7+a, 10, 40, 55) disp:drawLine(7+a, 10, 40, 55)
disp:drawLine(7+a*2, 10, 60, 55) disp:drawLine(7+a*2, 10, 60, 55)
@ -90,7 +93,7 @@ function u8g2_line(a)
disp:drawLine(7+a*4, 10, 100, 55) disp:drawLine(7+a*4, 10, 100, 55)
end end
function u8g2_triangle(a) local function u8g2_triangle(a)
local offset = a local offset = a
disp:drawStr( 0, 0, "drawTriangle") disp:drawStr( 0, 0, "drawTriangle")
disp:drawTriangle(14,7, 45,30, 10,40) disp:drawTriangle(14,7, 45,30, 10,40)
@ -99,7 +102,7 @@ function u8g2_triangle(a)
disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset) disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset)
end end
function u8g2_ascii_1() local function u8g2_ascii_1()
disp:drawStr( 0, 0, "ASCII page 1") disp:drawStr( 0, 0, "ASCII page 1")
for y = 0, 5 do for y = 0, 5 do
for x = 0, 15 do for x = 0, 15 do
@ -108,7 +111,7 @@ function u8g2_ascii_1()
end end
end end
function u8g2_ascii_2() local function u8g2_ascii_2()
disp:drawStr( 0, 0, "ASCII page 2") disp:drawStr( 0, 0, "ASCII page 2")
for y = 0, 5 do for y = 0, 5 do
for x = 0, 15 do for x = 0, 15 do
@ -117,7 +120,7 @@ function u8g2_ascii_2()
end end
end end
function u8g2_extra_page(a) local function u8g2_extra_page(a)
disp:drawStr( 0, 0, "Unicode") disp:drawStr( 0, 0, "Unicode")
disp:setFont(u8g2.font_unifont_t_symbols) disp:setFont(u8g2.font_unifont_t_symbols)
disp:setFontPosTop() disp:setFontPosTop()
@ -129,9 +132,9 @@ function u8g2_extra_page(a)
end end
end end
cross_width = 24 local cross_width = 24
cross_height = 24 local cross_height = 24
cross_bits = string.char( local cross_bits = string.char(
0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00, 0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00,
0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80, 0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80,
@ -139,24 +142,25 @@ cross_bits = string.char(
0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00,
0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00) 0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00)
cross_fill_width = 24 -- luacheck: push no unused
cross_fill_height = 24 local cross_fill_width = 24
cross_fill_bits = string.char( local cross_fill_height = 24
local cross_fill_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x64, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x64, 0x00, 0x26,
0x84, 0x00, 0x21, 0x08, 0x81, 0x10, 0x08, 0x42, 0x10, 0x10, 0x3C, 0x08, 0x84, 0x00, 0x21, 0x08, 0x81, 0x10, 0x08, 0x42, 0x10, 0x10, 0x3C, 0x08,
0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x80, 0x18, 0x01, 0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x80, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0x00, 0x01, 0x40, 0x00, 0x02, 0x20, 0x00, 0x04, 0x80, 0x18, 0x01, 0x80, 0x00, 0x01, 0x40, 0x00, 0x02, 0x20, 0x00, 0x04,
0x10, 0x3C, 0x08, 0x08, 0x42, 0x10, 0x08, 0x81, 0x10, 0x84, 0x00, 0x21, 0x10, 0x3C, 0x08, 0x08, 0x42, 0x10, 0x08, 0x81, 0x10, 0x84, 0x00, 0x21,
0x64, 0x00, 0x26, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 0x64, 0x00, 0x26, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-- luacheck: pop
cross_block_width = 14 local cross_block_width = 14
cross_block_height = 14 local cross_block_height = 14
cross_block_bits = string.char( local cross_block_bits = string.char(
0xFF, 0x3F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xFF, 0x3F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0xC1, 0x20, 0xC1, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xC1, 0x20, 0xC1, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
0x01, 0x20, 0xFF, 0x3F) 0x01, 0x20, 0xFF, 0x3F)
function u8g2_bitmap_overlay(a) local function u8g2_bitmap_overlay(a)
local frame_size = 28 local frame_size = 28
disp:drawStr(0, 0, "Bitmap overlay") disp:drawStr(0, 0, "Bitmap overlay")
@ -177,7 +181,7 @@ function u8g2_bitmap_overlay(a)
end end
end end
function u8g2_bitmap_modes(transparent) local function u8g2_bitmap_modes(transparent)
local frame_size = 24 local frame_size = 24
disp:drawBox(0, frame_size * 0.5, frame_size * 5, frame_size) disp:drawBox(0, frame_size * 0.5, frame_size * 5, frame_size)
@ -201,7 +205,7 @@ function u8g2_bitmap_modes(transparent)
end end
function draw() local function draw()
u8g2_prepare() u8g2_prepare()
local d3 = bit.rshift(draw_state, 3) local d3 = bit.rshift(draw_state, 3)
@ -235,7 +239,7 @@ function draw()
end end
function loop() local function loop()
-- picture loop -- picture loop
disp:clearBuffer() disp:clearBuffer()
draw() draw()
@ -251,13 +255,12 @@ function loop()
loop_tmr:start() loop_tmr:start()
end end
do
loop_tmr:register(100, tmr.ALARM_SEMI, loop)
draw_state = 0 init_i2c_display()
loop_tmr = tmr.create() --init_spi_display()
loop_tmr:register(100, tmr.ALARM_SEMI, loop)
init_i2c_display() print("--- Starting Graphics Test ---")
--init_spi_display() loop_tmr:start()
end
print("--- Starting Graphics Test ---")
loop_tmr:start()

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M
@ -7,10 +8,7 @@ function M.run()
print("Running component color_test...") print("Running component color_test...")
local mx
local c, x local c, x
mx = disp:getWidth() / 2
--my = disp:getHeight() / 2
disp:setColor(0, 0, 0, 0) disp:setColor(0, 0, 0, 0)
disp:drawBox(0, 0, disp:getWidth(), disp:getHeight()) disp:drawBox(0, 0, disp:getWidth(), disp:getHeight())

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,3 +1,4 @@
-- luacheck: globals T r disp millis lcg_rnd
local M, module = {}, ... local M, module = {}, ...
_G[module] = M _G[module] = M

View File

@ -1,5 +1,23 @@
-- luacheck: new globals z T r disp lcg_rnd millis
z = 127 -- start value
T = 1000
r = 0
disp = nil
local loop_idx = 0
function lcg_rnd()
z = bit.band(65 * z + 17, 255)
return z
end
function millis()
local usec = tmr.now()
return usec/1000
end
-- setup SPI and connect display -- setup SPI and connect display
function init_spi_display() local function init_spi_display()
-- Hardware SPI CLK = GPIO14 -- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
@ -20,11 +38,8 @@ function init_spi_display()
disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res) disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
end end
-- switch statement http://lua-users.org/wiki/SwitchStatement -- switch statement http://lua-users.org/wiki/SwitchStatement
function switch(c) local function switch(c)
local swtbl = { local swtbl = {
casevar = c, casevar = c,
caseof = function (self, code) caseof = function (self, code)
@ -46,20 +61,7 @@ function switch(c)
return swtbl return swtbl
end end
local function set_clip_range()
z = 127 -- start value
function lcg_rnd()
z = bit.band(65 * z + 17, 255)
return z
end
function millis()
local usec = tmr.now()
return usec/1000
end
function set_clip_range()
local x, y, w, h local x, y, w, h
w = bit.band(lcg_rnd(), 31) w = bit.band(lcg_rnd(), 31)
h = bit.band(lcg_rnd(), 31) h = bit.band(lcg_rnd(), 31)
@ -71,7 +73,7 @@ function set_clip_range()
disp:setClipRange(x, y, w, h) disp:setClipRange(x, y, w, h)
end end
function loop() local function loop()
if (loop_idx == 0) then if (loop_idx == 0) then
switch(bit.band(r, 3)) : caseof { switch(bit.band(r, 3)) : caseof {
@ -112,18 +114,12 @@ function loop()
print("Heap: " .. node.heap()) print("Heap: " .. node.heap())
end end
do
init_spi_display()
T = 1000 disp:begin(ucg.FONT_MODE_TRANSPARENT)
disp:setFont(ucg.font_ncenR14_hr)
disp:clearScreen()
r = 0 tmr.create():alarm(3000, tmr.ALARM_AUTO, function() loop() end)
loop_idx = 0 end
init_spi_display()
disp:begin(ucg.FONT_MODE_TRANSPARENT)
disp:setFont(ucg.font_ncenR14_hr)
disp:clearScreen()
tmr.register(0, 3000, tmr.ALARM_AUTO, function() loop() end)
tmr.start(0)

View File

@ -1,5 +1,7 @@
local disp
-- setup SPI and connect display -- setup SPI and connect display
function init_spi_display() local function init_spi_display()
-- Hardware SPI CLK = GPIO14 -- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
@ -20,17 +22,17 @@ function init_spi_display()
disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res) disp = ucg.st7735_18x128x160_hw_spi(bus, cs, dc, res)
end end
do
init_spi_display()
disp:begin(ucg.FONT_MODE_TRANSPARENT)
disp:clearScreen()
disp:setFont(ucg.font_ncenR12_tr);
disp:setColor(255, 255, 255);
disp:setColor(1, 255, 0,0);
init_spi_display() disp:setPrintPos(0, 25)
disp:print("Hello World!")
disp:begin(ucg.FONT_MODE_TRANSPARENT) end
disp:clearScreen()
disp:setFont(ucg.font_ncenR12_tr);
disp:setColor(255, 255, 255);
disp:setColor(1, 255, 0,0);
disp:setPrintPos(0, 25)
disp:print("Hello World!")

View File

@ -1,5 +1,7 @@
local disp
-- setup SPI and connect display -- setup SPI and connect display
function init_spi_display() local function init_spi_display()
-- Hardware SPI CLK = GPIO14 -- Hardware SPI CLK = GPIO14
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
@ -21,7 +23,7 @@ function init_spi_display()
end end
function upper_pin(x, y) local function upper_pin(x, y)
local w = 7 local w = 7
local h = 6 local h = 6
disp:setColor(0, 212, 212, 212) disp:setColor(0, 212, 212, 212)
@ -36,7 +38,7 @@ function upper_pin(x, y)
disp:drawGradientLine(x+w, y, h, 1) disp:drawGradientLine(x+w, y, h, 1)
end end
function lower_pin(x, y) local function lower_pin(x, y)
local w = 7 local w = 7
local h = 5 local h = 5
disp:setColor(0, 212, 212, 212) disp:setColor(0, 212, 212, 212)
@ -56,7 +58,7 @@ function lower_pin(x, y)
disp:drawPixel(x+w, y+h) disp:drawPixel(x+w, y+h)
end end
function ic_body(x, y) local function ic_body(x, y)
local w = 4*14+4 local w = 4*14+4
local h = 31 local h = 31
disp:setColor(0, 60, 60, 60) disp:setColor(0, 60, 60, 60)
@ -77,7 +79,7 @@ function ic_body(x, y)
disp:drawDisc(x+w-1, y+h/2+1, 7, bit.bor(ucg.DRAW_UPPER_LEFT, ucg.DRAW_LOWER_LEFT)) disp:drawDisc(x+w-1, y+h/2+1, 7, bit.bor(ucg.DRAW_UPPER_LEFT, ucg.DRAW_LOWER_LEFT))
end end
function draw_ucg_logo() local function draw_ucg_logo()
local a, b local a, b
--ucg_Init(ucg, ucg_sdl_dev_cb, ucg_ext_none, (ucg_com_fnptr)0) --ucg_Init(ucg, ucg_sdl_dev_cb, ucg_ext_none, (ucg_com_fnptr)0)
@ -156,12 +158,12 @@ function draw_ucg_logo()
--disp:drawString(1, 61, 0, "code.google.com/p/ucglib/") --disp:drawString(1, 61, 0, "code.google.com/p/ucglib/")
end end
do
init_spi_display()
init_spi_display() disp:begin(ucg.FONT_MODE_TRANSPARENT)
disp:clearScreen()
disp:begin(ucg.FONT_MODE_TRANSPARENT) disp:setRotate180()
disp:clearScreen() draw_ucg_logo()
end
disp:setRotate180()
draw_ucg_logo()

View File

@ -1,21 +1,24 @@
do
wifi.setmode(wifi.SOFTAP) wifi.setmode(wifi.SOFTAP)
wifi.ap.config({ ssid = "test", pwd = "12345678" }) wifi.ap.config({ ssid = "test", pwd = "12345678" })
gpio.mode(1, gpio.OUTPUT) gpio.mode(1, gpio.OUTPUT)
srv = net.createServer(net.TCP) local srv = net.createServer(net.TCP)
srv:listen(80, function(conn) srv:listen(80, function(conn)
conn:on("receive", function(client, request) conn:on("receive", function(client, request)
local buf = "" local buf = ""
local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") -- luacheck: no unused
if (method == nil) then if (method == nil) then
_, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") -- luacheck: no unused
end end
local _GET = {} local _GET = {}
if (vars ~= nil) then if (vars ~= nil) then
for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
_GET[k] = v _GET[k] = v
end end
end end
buf = buf .. "<!DOCTYPE html><html><body><h1>Hello, this is NodeMCU.</h1><form src=\"/\">Turn PIN1 <select name=\"pin\" onchange=\"form.submit()\">" buf = buf .. "<!DOCTYPE html><html><body><h1>Hello, this is NodeMCU.</h1>"
.. "<form src=\"/\">Turn PIN1 <select name=\"pin\" onchange=\"form.submit()\">"
local _on, _off = "", "" local _on, _off = "", ""
if (_GET.pin == "ON") then if (_GET.pin == "ON") then
_on = " selected=true" _on = " selected=true"
@ -29,3 +32,4 @@ srv:listen(80, function(conn)
end) end)
conn:on("sent", function(c) c:close() end) conn:on("sent", function(c) c:close() end)
end) end)
end

View File

@ -33,14 +33,14 @@ local function read_data(ADDR, commands, length)
i2c.start(id) i2c.start(id)
i2c.address(id, ADDR,i2c.RECEIVER) i2c.address(id, ADDR,i2c.RECEIVER)
tmr.delay(200000) tmr.delay(200000)
c = i2c.read(id, length) local c = i2c.read(id, length)
i2c.stop(id) i2c.stop(id)
return c return c
end end
local function read_lux() local function read_lux()
dataT = read_data(GY_30_address, CMD, 2) local dataT = read_data(GY_30_address, CMD, 2)
--Make it more faster --Make it more faster
UT = dataT:byte(1) * 256 + dataT:byte(2) local UT = dataT:byte(1) * 256 + dataT:byte(2)
l = (UT*1000/12) l = (UT*1000/12)
return(l) return(l)
end end

View File

@ -6,19 +6,17 @@
-- --
-- MIT license, http://opensource.org/licenses/MIT -- MIT license, http://opensource.org/licenses/MIT
-- *************************************************************************** -- ***************************************************************************
tmr.alarm(0, 10000, 1, function() local bh1750 = require("bh1750")
SDA_PIN = 6 -- sda pin, GPIO12 local sda = 6 -- sda pin, GPIO12
SCL_PIN = 5 -- scl pin, GPIO14 local scl = 5 -- scl pin, GPIO14
bh1750 = require("bh1750") do
bh1750.init(SDA_PIN, SCL_PIN) bh1750.init(sda, scl)
bh1750.read(OSS)
l = bh1750.getlux()
print("lux: "..(l / 100).."."..(l % 100).." lx")
-- release module tmr.create():alarm(10000, tmr.ALARM_AUTO, function()
bh1750 = nil bh1750.read()
package.loaded["bh1750"]=nil local l = bh1750.getlux()
print("lux: "..(l / 100).."."..(l % 100).." lx")
end) end)
end

View File

@ -10,42 +10,42 @@
--Ps 需要改动的地方LW_GATEWAY乐联的设备标示USERKEY乐联userkey --Ps 需要改动的地方LW_GATEWAY乐联的设备标示USERKEY乐联userkey
--Ps You nees to rewrite the LW_GATEWAYLelian's Device IDUSERKEYLelian's userkey --Ps You nees to rewrite the LW_GATEWAYLelian's Device IDUSERKEYLelian's userkey
local bh1750 = require("bh1750")
tmr.alarm(0, 60000, 1, function() local sda = 6 -- sda pin, GPIO12
SDA_PIN = 6 -- sda pin, GPIO12 local scl = 5 -- scl pin, GPIO14
SCL_PIN = 5 -- scl pin, GPIO14 local ServerIP
BH1750 = require("BH1750") do
BH1750.init(SDA_PIN, SCL_PIN) bh1750.init(sda, scl)
BH1750.read(OSS)
l = BH1750.getlux()
--定义数据变量格式 Define the veriables formate tmr.create():alarm(60000, tmr.ALARM_AUTO, function()
PostData = "[{\"Name\":\"T\",\"Value\":\"" ..(l / 100).."."..(l % 100).."\"}]" bh1750.read()
--创建一个TCP连接 Create a TCP Connection local l = bh1750.getlux()
socket=net.createConnection(net.TCP, 0) --定义数据变量格式 Define the veriables formate
--域名解析IP地址并赋值 DNS...it local PostData = "[{\"Name\":\"T\",\"Value\":\"" ..(l / 100).."."..(l % 100).."\"}]"
socket:dns("www.lewei50.com", function(conn, ip) --创建一个TCP连接 Create a TCP Connection
ServerIP = ip local socket = net.createConnection(net.TCP, 0)
print("Connection IP:" .. ServerIP) --域名解析IP地址并赋值 DNS...it
end) socket:dns("www.lewei50.com", function(_, ip)
ServerIP = ip
--开始连接服务器 Connect the sever print("Connection IP:" .. ServerIP)
socket:connect(80, ServerIP) end)
socket:on("connection", function(sck) end)
--HTTP请求头定义 HTTP Head
socket:send("POST /api/V1/gateway/UpdateSensors/LW_GATEWAY HTTP/1.1\r\n" ..
"Host: www.lewei50.com\r\n" ..
"Content-Length: " .. string.len(PostData) .. "\r\n" ..
"userkey: USERKEY\r\n\r\n" ..
PostData .. "\r\n")
--HTTP响应内容 Print the HTTP response
socket:on("receive", function(sck, response)
print(response)
end)
end)
--开始连接服务器 Connect the sever
socket:connect(80, ServerIP)
socket:on("connection", function() end)
--HTTP请求头定义 HTTP Head
socket:send("POST /api/V1/gateway/UpdateSensors/LW_GATEWAY HTTP/1.1\r\n" ..
"Host: www.lewei50.com\r\n" ..
"Content-Length: " .. string.len(PostData) .. "\r\n" ..
"userkey: USERKEY\r\n\r\n" ..
PostData .. "\r\n")
--HTTP响应内容 Print the HTTP response
socket:on("receive", function(sck, response) -- luacheck: no unused
print(response)
end)
end)
end

View File

@ -1,14 +1,17 @@
t = require("ds18b20") local t = require("ds18b20")
pin = 3 -- gpio0 = 3, gpio2 = 4 local pin = 3 -- gpio0 = 3, gpio2 = 4
local function readout(temp) local function readout(temps)
if t.sens then if t.sens then
print("Total number of DS18B20 sensors: ".. #t.sens) print("Total number of DS18B20 sensors: ".. #t.sens)
for i, s in ipairs(t.sens) do for i, s in ipairs(t.sens) do
print(string.format(" sensor #%d address: %s%s", i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or "")) print(string.format(" sensor #%d address: %s%s", i,
('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)),
s:byte(9) == 1 and " (parasite)" or ""))
end end
end end
for addr, temp in pairs(temp) do
for addr, temp in pairs(temps) do
print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp)) print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
end end
@ -17,36 +20,35 @@ local function readout(temp)
--package.loaded["ds18b20"]=nil --package.loaded["ds18b20"]=nil
end end
t:enable_debug() do
file.remove("ds18b20_save.lc") -- remove saved addresses t:enable_debug()
print("=============================================", node.heap()) file.remove("ds18b20_save.lc") -- remove saved addresses
print("first call, no addresses in flash, search is performed") print("=============================================", node.heap())
t:read_temp(readout, pin, t.C) print("first call, no addresses in flash, search is performed")
t:read_temp(readout, pin, t.C)
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function() tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
print("=============================================", node.heap()) print("=============================================", node.heap())
print("second readout, no new search, found addresses are used") print("second readout, no new search, found addresses are used")
t:read_temp(readout, pin) t:read_temp(readout, pin)
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function() tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
print("=============================================", node.heap()) print("=============================================", node.heap())
print("force search again") print("force search again")
t:read_temp(readout, pin, nil, true) t:read_temp(readout, pin, nil, true)
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function() tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
print("=============================================", node.heap()) print("=============================================", node.heap())
print("save search results") print("save search results")
t:read_temp(readout, pin, nil, false, true) t:read_temp(readout, pin, nil, false, true)
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function() tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
print("=============================================", node.heap()) print("=============================================", node.heap())
print("use saved addresses") print("use saved addresses")
t.sens={} t.sens={}
t:read_temp(readout, pin) t:read_temp(readout, pin)
end) end)
end)
end) end)
end)
end) end
end)

View File

@ -1,35 +1,37 @@
t = require('ds18b20') local t = require('ds18b20')
port = 80 local port = 80
pin = 3 -- gpio0 = 3, gpio2 = 4 local pin = 3 -- gpio0 = 3, gpio2 = 4
gconn = {} -- global variable for connection local gconn = {} -- local variable for connection
function readout(temp) local function readout(temps)
local resp = "HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" .. local resp = "HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" ..
"<!DOCTYPE HTML>" .. "<!DOCTYPE HTML>" ..
"<html><body>" .. "<html><body>" ..
"<b>ESP8266</b></br>" "<b>ESP8266</b></br>"
for addr, temp in pairs(temp) do for addr, temp in pairs(temps) do
resp = resp .. string.format("Sensor %s: %s &#8451</br>", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8)), temp) resp = resp .. string.format("Sensor %s: %s &#8451</br>",
('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8)), temp)
end end
resp = resp .. resp = resp ..
"Node ChipID: " .. node.chipid() .. "<br>" .. "Node ChipID: " .. node.chipid() .. "<br>" ..
"Node MAC: " .. wifi.sta.getmac() .. "<br>" .. "Node MAC: " .. wifi.sta.getmac() .. "<br>" ..
"Node Heap: " .. node.heap() .. "<br>" .. "Node Heap: " .. node.heap() .. "<br>" ..
"Timer Ticks: " .. tmr.now() .. "<br>" .. "Timer Ticks: " .. tmr.now() .. "<br>" ..
"</html></body>" "</html></body>"
gconn:send(resp) gconn:send(resp)
gconn:on("sent",function(conn) conn:close() end) gconn:on("sent",function(conn) conn:close() end)
end end
srv=net.createServer(net.TCP) do
srv:listen(port, local srv = net.createServer(net.TCP)
function(conn) srv:listen(port,
gconn = conn function(conn)
-- t:read_temp(readout) -- default pin value is 3 gconn = conn
t:read_temp(readout, pin) -- t:read_temp(readout) -- default pin value is 3
end t:read_temp(readout, pin)
) end)
end

View File

@ -3,23 +3,25 @@
-- NODEMCU TEAM -- NODEMCU TEAM
-- LICENCE: http://opensource.org/licenses/MIT -- LICENCE: http://opensource.org/licenses/MIT
-- @voborsky, @devsaurus, TerryE 26 Mar 2017 -- @voborsky, @devsaurus, TerryE 26 Mar 2017
---------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local modname = ... local modname = ...
-- Used modules and functions -- Used modules and functions
local table, string, ow, tmr, print, type, tostring, pcall, ipairs = local type, tostring, pcall, ipairs =
table, string, ow, tmr, print, type, tostring, pcall, ipairs type, tostring, pcall, ipairs
-- Local functions -- Local functions
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8, ow_reset, ow_reset_search, ow_skip, ow_depower = local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8,
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8, ow.reset, ow.reset_search, ow.skip, ow.depower ow_reset, ow_reset_search, ow_skip, ow_depower =
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8,
ow.reset, ow.reset_search, ow.skip, ow.depower
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
local string_char, string_dump = string.char, string.dump local string_char, string_dump = string.char, string.dump
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
local table_sort, table_concat = table.sort, table.concat local table_sort, table_concat = table.sort, table.concat
local math_floor = math.floor local math_floor = math.floor
local file_open = file.open local file_open = file.open
local conversion
table, string, tmr, ow = nil, nil, nil, nil
local DS18B20FAMILY = 0x28 local DS18B20FAMILY = 0x28
local DS1920FAMILY = 0x10 -- and DS18S20 series local DS1920FAMILY = 0x10 -- and DS18S20 series
@ -50,8 +52,6 @@ local function to_string(addr, esc)
end end
end end
local conversion
local function readout(self) local function readout(self)
local next = false local next = false
local sens = self.sens local sens = self.sens
@ -62,7 +62,7 @@ local function readout(self)
local addr = s:sub(1,8) local addr = s:sub(1,8)
ow_select(pin, addr) -- select the sensor ow_select(pin, addr) -- select the sensor
ow_write(pin, READ_SCRATCHPAD, MODE) ow_write(pin, READ_SCRATCHPAD, MODE)
data = ow_read_bytes(pin, 9) local data = ow_read_bytes(pin, 9)
local t=(data:byte(1)+data:byte(2)*256) local t=(data:byte(1)+data:byte(2)*256)
-- t is actually signed so process the sign bit and adjust for fractional bits -- t is actually signed so process the sign bit and adjust for fractional bits
@ -116,7 +116,7 @@ local function readout(self)
end end
end end
conversion = function (self) conversion = (function (self)
local sens = self.sens local sens = self.sens
local powered_only = true local powered_only = true
for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
@ -125,7 +125,7 @@ conversion = function (self)
ow_reset(pin) ow_reset(pin)
ow_skip(pin) -- select the sensor ow_skip(pin) -- select the sensor
ow_write(pin, CONVERT_T, MODE) -- and start conversion ow_write(pin, CONVERT_T, MODE) -- and start conversion
for i, s in ipairs(sens) do status[i] = 1 end for i, _ in ipairs(sens) do status[i] = 1 end
else else
for i, s in ipairs(sens) do for i, s in ipairs(sens) do
if status[i] == 0 then if status[i] == 0 then
@ -140,12 +140,11 @@ conversion = function (self)
end end
end end
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end) tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
end end)
local function _search(self, lcb, lpin, search, save) local function _search(self, lcb, lpin, search, save)
self.temp = {} self.temp = {}
if search then self.sens = {}; status = {} end if search then self.sens = {}; status = {} end
local temp = self.temp
local sens = self.sens local sens = self.sens
pin = lpin or pin pin = lpin or pin
@ -167,7 +166,7 @@ local function _search(self, lcb, lpin, search, save)
-- search the first device -- search the first device
addr = ow_search(pin) addr = ow_search(pin)
else else
for i, s in ipairs(sens) do status[i] = 0 end for i, _ in ipairs(sens) do status[i] = 0 end
end end
local function cycle() local function cycle()
debugPrint("cycle") debugPrint("cycle")

View File

@ -1,15 +1,17 @@
local ds3231 = require("ds3231")
-- ESP-01 GPIO Mapping -- ESP-01 GPIO Mapping
gpio0, gpio2 = 3, 4 local gpio0, gpio2 = 3, 4
i2c.setup(gpio0, gpio2, scl, i2c.SLOW) -- call i2c.setup() only once
require("ds3231") do
i2c.setup(0, gpio0, gpio2, i2c.SLOW) -- call i2c.setup() only once
second, minute, hour, day, date, month, year = ds3231.getTime(); local second, minute, hour, day, date, month, year = ds3231.getTime(); -- luacheck: no unused
-- Get current time -- Get current time
print(string.format("Time & Date: %s:%s:%s %s/%s/%s", hour, minute, second, date, month, year)) print(string.format("Time & Date: %s:%s:%s %s/%s/%s", hour, minute, second, date, month, year))
-- Don't forget to release it after use -- Don't forget to release it after use
ds3231 = nil ds3231 = nil -- luacheck: no unused
package.loaded["ds3231"]=nil package.loaded["ds3231"] = nil
end

View File

@ -1,54 +1,53 @@
local ds3231 = require('ds3231')
-- ESP-01 GPIO Mapping -- ESP-01 GPIO Mapping
gpio0, gpio2 = 3, 4 local gpio0, gpio2 = 3, 4
i2c.setup(gpio0, gpio2, scl, i2c.SLOW) -- call i2c.setup() only once local port = 80
local days = {
require('ds3231') [1] = "Sunday",
[2] = "Monday",
port = 80 [3] = "Tuesday",
[4] = "Wednesday",
days = { [5] = "Thursday",
[1] = "Sunday", [6] = "Friday",
[2] = "Monday", [7] = "Saturday"
[3] = "Tuesday",
[4] = "Wednesday",
[5] = "Thursday",
[6] = "Friday",
[7] = "Saturday"
} }
months = { local months = {
[1] = "January", [1] = "January",
[2] = "Febuary", [2] = "Febuary",
[3] = "March", [3] = "March",
[4] = "April", [4] = "April",
[5] = "May", [5] = "May",
[6] = "June", [6] = "June",
[7] = "July", [7] = "July",
[8] = "August", [8] = "August",
[9] = "September", [9] = "September",
[10] = "October", [10] = "October",
[11] = "November", [11] = "November",
[12] = "December" [12] = "December"
} }
srv=net.createServer(net.TCP) do
srv:listen(port, i2c.setup(0, gpio0, gpio2, i2c.SLOW) -- call i2c.setup() only once
function(conn)
second, minute, hour, day, date, month, year = ds3231.getTime() local srv = net.createServer(net.TCP)
prettyTime = string.format("%s, %s %s %s %s:%s:%s", days[day], date, months[month], year, hour, minute, second) srv:listen(port, function(conn)
local second, minute, hour, day, date, month, year = ds3231.getTime()
local prettyTime = string.format("%s, %s %s %s %s:%s:%s",
days[day], date, months[month], year, hour, minute, second)
conn:send("HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" .. conn:send("HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" ..
"<!DOCTYPE HTML>" .. "<!DOCTYPE HTML>" ..
"<html><body>" .. "<html><body>" ..
"<b>ESP8266</b></br>" .. "<b>ESP8266</b></br>" ..
"Time and Date: " .. prettyTime .. "<br>" .. "Time and Date: " .. prettyTime .. "<br>" ..
"Node ChipID : " .. node.chipid() .. "<br>" .. "Node ChipID : " .. node.chipid() .. "<br>" ..
"Node MAC : " .. wifi.sta.getmac() .. "<br>" .. "Node MAC : " .. wifi.sta.getmac() .. "<br>" ..
"Node Heap : " .. node.heap() .. "<br>" .. "Node Heap : " .. node.heap() .. "<br>" ..
"Timer Ticks : " .. tmr.now() .. "<br>" .. "Timer Ticks : " .. tmr.now() .. "<br>" ..
"</html></body>") "</html></body>")
conn:on("sent",function(conn) conn:close() end)
end conn:on("sent",function(sck) sck:close() end)
) end)
end

View File

@ -114,7 +114,7 @@ function M.reloadAlarms ()
i2c.write(id, 0x0F) i2c.write(id, 0x0F)
i2c.write(id, d) i2c.write(id, d)
i2c.stop(id) i2c.stop(id)
print('[LOG] Alarm '..almId..' reloaded') print('[LOG] Alarms reloaded')
end end
-- Enable alarmId bit. Let it to be triggered -- Enable alarmId bit. Let it to be triggered

View File

@ -22,8 +22,6 @@ _G[moduleName] = M
local USERNAME = "" local USERNAME = ""
local PASSWORD = "" local PASSWORD = ""
local SERVER = ""
local PORT = ""
local TAG = "" local TAG = ""
local DEBUG = false local DEBUG = false
@ -45,10 +43,10 @@ end
--- ---
-- @name display -- @name display
-- @description A generic IMAP response processing function. -- @description A generic IMAP response processing function.
-- Can disply the IMAP response if DEBUG is set to true. -- Can display the IMAP response if DEBUG is set to true.
-- Sets the reponse processed variable to true when the string "complete" -- Sets the response processed variable to true when the string "complete"
-- is found in the IMAP reply/response -- is found in the IMAP reply/response
local function display(socket, response) local function display(socket, response) -- luacheck: no unused
-- If debuggins is enabled print the IMAP response -- If debuggins is enabled print the IMAP response
if(DEBUG) then if(DEBUG) then
@ -67,7 +65,7 @@ end
--- ---
-- @name config -- @name config
-- @description Initiates the IMAP settings -- @description Initiates the IMAP settings
function M.config(username,password,tag,debug) function M.config(username, password, tag, debug)
USERNAME = username USERNAME = username
PASSWORD = password PASSWORD = password
TAG = tag TAG = tag
@ -96,13 +94,13 @@ end
-- @description Gets the most recent email number from the EXAMINE command. -- @description Gets the most recent email number from the EXAMINE command.
-- i.e. if EXAMINE returns "* 4 EXISTS" this means that there are 4 emails, -- i.e. if EXAMINE returns "* 4 EXISTS" this means that there are 4 emails,
-- so the latest/newest will be identified by the number 4 -- so the latest/newest will be identified by the number 4
local function set_most_recent_num(socket,response) local function set_most_recent_num(socket, response) -- luacheck: no unused
if(DEBUG) then if(DEBUG) then
print(response) print(response)
end end
local _, _, num = string.find(response,"([0-9]+) EXISTS(\.)") -- the _ and _ keep the index of the string found local _, _, num = string.find(response,"([0-9]+) EXISTS") -- the _ and _ keep the index of the string found
-- but we don't care about that. -- but we don't care about that.
if(num~=nil) then if(num~=nil) then
@ -117,7 +115,7 @@ end
--- ---
-- @name examine -- @name examine
-- @description IMAP examines the given mailbox/folder. Sends the IMAP EXAMINE command -- @description IMAP examines the given mailbox/folder. Sends the IMAP EXAMINE command
function M.examine(socket,mailbox) function M.examine(socket, mailbox)
response_processed = false response_processed = false
socket:send(TAG .. " EXAMINE " .. mailbox .. "\r\n") socket:send(TAG .. " EXAMINE " .. mailbox .. "\r\n")
@ -135,7 +133,7 @@ end
-- @name set_header -- @name set_header
-- @description Records the IMAP header field response in a variable -- @description Records the IMAP header field response in a variable
-- so that it may be read later -- so that it may be read later
local function set_header(socket,response) local function set_header(socket, response) -- luacheck: no unused
if(DEBUG) then if(DEBUG) then
print(response) print(response)
end end
@ -152,7 +150,7 @@ end
-- @param socket The IMAP socket to use -- @param socket The IMAP socket to use
-- @param msg_number The email number to read e.g. 1 will read fetch the latest/newest email -- @param msg_number The email number to read e.g. 1 will read fetch the latest/newest email
-- @param field A header field such as SUBJECT, FROM, or DATE -- @param field A header field such as SUBJECT, FROM, or DATE
function M.fetch_header(socket,msg_number,field) function M.fetch_header(socket, msg_number, field)
header = "" -- we are getting a new header so clear this variable header = "" -- we are getting a new header so clear this variable
response_processed = false response_processed = false
socket:send(TAG .. " FETCH " .. msg_number .. " BODY[HEADER.FIELDS (" .. field .. ")]\r\n") socket:send(TAG .. " FETCH " .. msg_number .. " BODY[HEADER.FIELDS (" .. field .. ")]\r\n")
@ -171,7 +169,7 @@ end
-- @name set_body -- @name set_body
-- @description Records the IMAP body response in a variable -- @description Records the IMAP body response in a variable
-- so that it may be read later -- so that it may be read later
local function set_body(socket,response) local function set_body(_, response)
if(DEBUG) then if(DEBUG) then
print(response) print(response)
@ -188,7 +186,7 @@ end
-- @description Sends the IMAP command to fetch a plain text version of the email's body -- @description Sends the IMAP command to fetch a plain text version of the email's body
-- @param socket The IMAP socket to use -- @param socket The IMAP socket to use
-- @param msg_number The email number to obtain e.g. 1 will obtain the latest email -- @param msg_number The email number to obtain e.g. 1 will obtain the latest email
function M.fetch_body_plain_text(socket,msg_number) function M.fetch_body_plain_text(socket, msg_number)
response_processed = false response_processed = false
body = "" -- clear the body variable since we'll be fetching a new email body = "" -- clear the body variable since we'll be fetching a new email
socket:send(TAG .. " FETCH " .. msg_number .. " BODY[1]\r\n") socket:send(TAG .. " FETCH " .. msg_number .. " BODY[1]\r\n")

View File

@ -11,7 +11,7 @@ local vprint = (verbose > 0) and print or function() end
-- Mock up enough of the nodemcu tmr structure, but pretend that nothing -- Mock up enough of the nodemcu tmr structure, but pretend that nothing
-- happens between ticks. This won't exercise the optimistic corking logic, -- happens between ticks. This won't exercise the optimistic corking logic,
-- but that's probably fine. -- but that's probably fine.
-- -- luacheck: push ignore
tmr = {} tmr = {}
tmr.ALARM_SINGLE = 0 tmr.ALARM_SINGLE = 0
function tmr.create() function tmr.create()
@ -19,6 +19,7 @@ function tmr.create()
function r:alarm(_i, _t, cb) vprint("TMR") cb() end function r:alarm(_i, _t, cb) vprint("TMR") cb() end
return r return r
end end
-- luacheck: pop
-- --
-- Mock up enough of the nodemcu net.socket type; have it log all the sends -- Mock up enough of the nodemcu net.socket type; have it log all the sends
@ -28,7 +29,7 @@ local outs = {}
local fakesock = { local fakesock = {
cb = nil, cb = nil,
on = function(this, _, cb) this.cb = cb end, on = function(this, _, cb) this.cb = cb end,
send = function(this, s) vprint("SEND", (verbose > 1) and s) table.insert(outs, s) end, send = function(this, s) vprint("SEND", (verbose > 1) and s) table.insert(outs, s) end -- luacheck: no unused
} }
local function sent() vprint("SENT") fakesock.cb() end local function sent() vprint("SENT") fakesock.cb() end
@ -68,25 +69,25 @@ sent() ; fchecke()
-- Hit default FSMALLLIM while building up -- Hit default FSMALLLIM while building up
fsendc("abracadabra lots small") fsendc("abracadabra lots small")
for i = 1, 32 do fsend("a") end for i = 1, 32 do fsend("a") end -- luacheck: no unused
nocoal() nocoal()
for i = 1, 4 do fsend("a") end for i = 1, 4 do fsend("a") end -- luacheck: no unused
sent() ; fcheck(string.rep("a", 32)) sent() ; fcheck(string.rep("a", 32))
sent() ; fcheck(string.rep("a", 4)) sent() ; fcheck(string.rep("a", 4))
sent() ; fchecke() sent() ; fchecke()
-- Hit string length while building up -- Hit string length while building up
fsendc("abracadabra overlong") fsendc("abracadabra overlong")
for i = 1, 10 do fsend(string.rep("a",32)) end for i = 1, 10 do fsend(string.rep("a",32)) end -- luacheck: no unused
sent() ; fcheck(string.rep("a", 320)) sent() ; fcheck(string.rep("a", 320))
sent() ; fchecke() sent() ; fchecke()
-- Hit neither before sending a big string -- Hit neither before sending a big string
fsendc("abracadabra mid long") fsendc("abracadabra mid long")
for i = 1, 6 do fsend(string.rep("a",32)) end for i = 1, 6 do fsend(string.rep("a",32)) end -- luacheck: no unused
fsend(string.rep("b", 256)) fsend(string.rep("b", 256))
nocoal() nocoal()
for i = 1, 6 do fsend(string.rep("c",32)) end for i = 1, 6 do fsend(string.rep("c",32)) end -- luacheck: no unused
sent() ; fcheck(string.rep("a", 192) .. string.rep("b", 256)) sent() ; fcheck(string.rep("a", 192) .. string.rep("b", 256))
sent() ; fcheck(string.rep("c", 192)) sent() ; fcheck(string.rep("c", 192))
sent() ; fchecke() sent() ; fchecke()
@ -109,33 +110,36 @@ sent() ; fcheck(string.rep("c",512))
sent() ; fchecke() sent() ; fchecke()
-- test a lazy generator -- test a lazy generator
local ix = 0 do
local function gen() vprint("GEN", ix); ix = ix + 1; return ("a" .. ix), ix < 3 and gen end local ix = 0
fsend(gen) local function gen() vprint("GEN", ix); ix = ix + 1; return ("a" .. ix), ix < 3 and gen end
fsend("b") fsend(gen)
fcheck("a1") fsend("b")
sent() ; fcheck("a2") fcheck("a1")
sent() ; fcheck("a3") sent() ; fcheck("a2")
sent() ; fcheck("b") sent() ; fcheck("a3")
sent() ; fchecke() sent() ; fcheck("b")
sent() ; fchecke()
end
-- test a completion-like callback that does send text -- test a completion-like callback that does send text
local ix = 0 do
local function gen() vprint("GEN"); ix = 1; return "efgh", nil end local ix = 0
fsend("abcd"); fsend(gen); fsend("ijkl") local function gen() vprint("GEN"); ix = 1; return "efgh", nil end
assert (ix == 0) fsend("abcd"); fsend(gen); fsend("ijkl")
fcheck("abcd"); assert (ix == 0) assert (ix == 0)
sent() ; fcheck("efgh"); assert (ix == 1); ix = 0 fcheck("abcd"); assert (ix == 0)
sent() ; fcheck("ijkl"); assert (ix == 0) sent() ; fcheck("efgh"); assert (ix == 1); ix = 0
sent() ; fchecke() sent() ; fcheck("ijkl"); assert (ix == 0)
sent() ; fchecke()
end
-- and one that doesn't -- and one that doesn't
local ix = 0 do
local function gen() vprint("GEN"); ix = 1; return nil, nil end local ix = 0
fsend("abcd"); fsend(gen); fsend("ijkl") local function gen() vprint("GEN"); ix = 1; return nil, nil end
assert (ix == 0) fsend("abcd"); fsend(gen); fsend("ijkl")
fcheck("abcd"); assert (ix == 0) assert (ix == 0)
sent() ; fcheck("ijkl"); assert (ix == 1); ix = 0 fcheck("abcd"); assert (ix == 0)
sent() ; fchecke() ; assert (ix == 0) sent() ; fcheck("ijkl"); assert (ix == 1); ix = 0
sent() ; fchecke() ; assert (ix == 0)
end
print("All tests OK") print("All tests OK")

View File

@ -19,8 +19,8 @@
Note that FTP also exposes a number of really private properties (which Note that FTP also exposes a number of really private properties (which
could be stores in local / upvals) as FTP properties for debug purposes. could be stores in local / upvals) as FTP properties for debug purposes.
]] ]]
local file,net,wifi,node,string,table,tmr,pairs,print,pcall, tostring = local file, net, wifi, node, table, tmr, pairs, print, pcall, tostring =
file,net,wifi,node,string,table,tmr,pairs,print,pcall, tostring file, net, wifi, node, table, tmr, pairs, print, pcall, tostring
local post = node.task.post local post = node.task.post
local FTP, cnt = {client = {}}, 0 local FTP, cnt = {client = {}}, 0
@ -90,18 +90,18 @@ function FTP.createServer(user, pass, dbgFlag) -- upval: FTP (, debug, tostring
-- debug("Sending: %s", rec) -- debug("Sending: %s", rec)
return CNX.cmdSocket:send(rec.."\r\n", cb) return CNX.cmdSocket:send(rec.."\r\n", cb)
end, --- send() end, --- send()
close = function(sock) -- upval: client, CNX (,debug, pcall, type) close = function(socket) -- upval: client, CNX (,debug, pcall, type)
-- debug("Closing CNX.socket=%s, sock=%s", tostring(CNX.socket), tostring(sock)) -- debug("Closing CNX.socket=%s, sock=%s", tostring(CNX.socket), tostring(sock))
for _,s in ipairs{'cmdSocket', 'dataServer', 'dataSocket'} do for _,s in ipairs{'cmdSocket', 'dataServer', 'dataSocket'} do
local sck; sck,CNX[s] = CNX[s], nil local sck; sck,CNX[s] = CNX[s], nil
-- debug("closing CNX.%s=%s", s, tostring(sck)) -- debug("closing CNX.%s=%s", s, tostring(sck))
if type(sck)=='userdata' then pcall(sck.close, sck) end if type(sck)=='userdata' then pcall(sck.close, sck) end
end end
client[sock] = nil client[socket] = nil
end -- CNX.close() end -- CNX.close()
} }
local function validateUser(sock, data) -- upval: CNX, FTP (, debug, processCommand) local function validateUser(socket, data) -- upval: CNX, FTP (, debug, processCommand)
-- validate the logon and if then switch to processing commands -- validate the logon and if then switch to processing commands
-- debug("Authorising: %s", data) -- debug("Authorising: %s", data)
@ -118,8 +118,8 @@ function FTP.createServer(user, pass, dbgFlag) -- upval: FTP (, debug, tostring
elseif CNX.validUser and cmd == 'PASS' then elseif CNX.validUser and cmd == 'PASS' then
if arg == FTP.pass then if arg == FTP.pass then
CNX.cwd = '/' CNX.cwd = '/'
sock:on("receive", function(sock,data) socket:on("receive", function(socketObj, dataObj)
processCommand(CNX,sock,data) processCommand(CNX,socketObj, dataObj)
end) -- logged on so switch to command mode end) -- logged on so switch to command mode
msg = "230 Login successful. Username & password correct; proceed." msg = "230 Login successful. Username & password correct; proceed."
else else
@ -134,8 +134,8 @@ function FTP.createServer(user, pass, dbgFlag) -- upval: FTP (, debug, tostring
return CNX.send(msg) return CNX.send(msg)
end end
local port,ip = sock:getpeer() local port,ip = sock:getpeer() -- luacheck: no unused
-- debug("Connection accepted: (userdata) %s client %s:%u", tostring(sock), ip, port) --debug("Connection accepted: (userdata) %s client %s:%u", tostring(sock), ip, port)
sock:on("receive", validateUser) sock:on("receive", validateUser)
sock:on("disconnection", CNX.close) sock:on("disconnection", CNX.close)
FTP.client[sock]=CNX FTP.client[sock]=CNX
@ -177,8 +177,8 @@ end -- FTP.close()
-- --
-- Find strings are used do this lookup and minimise long if chains. -- Find strings are used do this lookup and minimise long if chains.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
processCommand = function(cxt, sock, data) -- upvals: (, debug, processBareCmds, processSimpleCmds, processDataCmds) -- upvals: (, debug, processBareCmds, processSimpleCmds, processDataCmds)
processCommand = function(cxt, socket, data) -- luacheck: no unused
debug("Command: %s", data) debug("Command: %s", data)
data = data:gsub('[\r\n]+$', '') -- chomp trailing CRLF data = data:gsub('[\r\n]+$', '') -- chomp trailing CRLF
local cmd, arg = data:match('([a-zA-Z]+) *(.*)') local cmd, arg = data:match('([a-zA-Z]+) *(.*)')
@ -331,7 +331,7 @@ processDataCmds = function(cxt, cmd, arg) -- upval: FTP (, pairs, file, tostrin
pattern = arg:gsub('*','[^/%%.]*') pattern = arg:gsub('*','[^/%%.]*')
end end
for k,v in pairs(fileSize) do for k, _ in pairs(fileSize) do
if k:match(pattern) then if k:match(pattern) then
nameList[#nameList+1] = k nameList[#nameList+1] = k
else else
@ -341,8 +341,8 @@ processDataCmds = function(cxt, cmd, arg) -- upval: FTP (, pairs, file, tostrin
table.sort(nameList) table.sort(nameList)
function cxt.getData() -- upval: cmd, fileSize, nameList (, table) function cxt.getData() -- upval: cmd, fileSize, nameList (, table)
local list, user, v = {}, FTP.user local list, user = {}, FTP.user
for i = 1,10 do for i = 1,10 do -- luacheck: no unused
if #nameList == 0 then break end if #nameList == 0 then break end
local f = table.remove(nameList, 1) local f = table.remove(nameList, 1)
list[#list+1] = (cmd == "LIST") and list[#list+1] = (cmd == "LIST") and
@ -395,9 +395,9 @@ end -- processDataCmds(cmd, arg, send)
-- --
---------------- Open a new data server and port --------------------------- ---------------- Open a new data server and port ---------------------------
dataServer = function(cxt, n) -- upval: (pcall, net, ftpDataOpen, debug, tostring) dataServer = function(cxt, n) -- upval: (pcall, net, ftpDataOpen, debug, tostring)
local dataServer = cxt.dataServer local dataSrv = cxt.dataServer
if dataServer then -- close any existing listener if dataSrv then -- close any existing listener
pcall(dataServer.close, dataServer) pcall(dataSrv.close, dataSrv)
end end
if n then if n then
-- Open a new listener if needed. Note that this is only used to establish -- Open a new listener if needed. Note that this is only used to establish
@ -425,10 +425,11 @@ ftpDataOpen = function(cxt, dataSocket) -- upval: (debug, tostring, post, pcall)
cxt.dataServer = nil cxt.dataServer = nil
local function cleardown(skt,type) -- upval: cxt (, debug, tostring, post, pcall) local function cleardown(skt,type) -- upval: cxt (, debug, tostring, post, pcall)
-- luacheck: push no unused
type = type==1 and "disconnection" or "reconnection" type = type==1 and "disconnection" or "reconnection"
local which = cxt.setData and "setData" or (cxt.getData and cxt.getData or "neither") local which = cxt.setData and "setData" or (cxt.getData and cxt.getData or "neither")
-- debug("Cleardown entered from %s with %s", type, which) --debug("Cleardown entered from %s with %s", type, which)
-- luacheck: pop
if cxt.setData then if cxt.setData then
cxt.fileClose() cxt.fileClose()
cxt.setData = nil cxt.setData = nil
@ -446,8 +447,9 @@ ftpDataOpen = function(cxt, dataSocket) -- upval: (debug, tostring, post, pcall)
local on_hold = false local on_hold = false
dataSocket:on("receive", function(skt, rec) --upval: cxt, on_hold (, debug, tstring, post, node, pcall) dataSocket:on("receive", function(skt, rec) --upval: cxt, on_hold (, debug, tstring, post, node, pcall)
local which = cxt.setData and "setData" or (cxt.getData and cxt.getData or "neither")
-- debug("Received %u data bytes with %s", #rec, which) local which = cxt.setData and "setData" or (cxt.getData and cxt.getData or "neither")-- luacheck: no unused
--debug("Received %u data bytes with %s", #rec, which)
if not cxt.setData then return end if not cxt.setData then return end
@ -476,7 +478,8 @@ ftpDataOpen = function(cxt, dataSocket) -- upval: (debug, tostring, post, pcall)
function cxt.sender(skt) -- upval: cxt (, debug) function cxt.sender(skt) -- upval: cxt (, debug)
debug ("entering sender") debug ("entering sender")
if not cxt.getData then return end if not cxt.getData then return end
local rec, skt = cxt.getData(), cxt.dataSocket skt = skt or cxt.dataSocket
local rec = cxt.getData()
if rec and #rec > 0 then if rec and #rec > 0 then
-- debug("Sending %u data bytes", #rec) -- debug("Sending %u data bytes", #rec)
skt:send(rec) skt:send(rec)

View File

@ -1,14 +1,17 @@
HDC1000 = require("HDC1000") local HDC1000 = require("HDC1000")
sda = 1 local sda, scl = 1, 2
scl = 2 local drdyn = false
drdyn = false
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once do
HDC1000.setup(drdyn) i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
HDC1000.config() -- default values are used if called with no arguments. prototype is config(address, resolution, heater) HDC1000.setup(drdyn)
-- prototype is config(address, resolution, heater)
HDC1000.config() -- default values are used if called with no arguments.
print(string.format("Temperature: %.2f °C\nHumidity: %.2f %%", HDC1000.getTemp(), HDC1000.getHumi())) print(string.format("Temperature: %.2f °C\nHumidity: %.2f %%", HDC1000.getTemp(), HDC1000.getHumi()))
HDC1000 = nil -- Don't forget to release it after use
package.loaded["HDC1000"]=nil HDC1000 = nil -- luacheck: no unused
package.loaded["HDC1000"] = nil
end

View File

@ -40,9 +40,9 @@ local HDC1000_TEMP_HUMI_14BIT = 0x00
local function read16() local function read16()
i2c.start(id) i2c.start(id)
i2c.address(id, HDC1000_ADDR, i2c.RECEIVER) i2c.address(id, HDC1000_ADDR, i2c.RECEIVER)
data_temp = i2c.read(0, 2) local data_temp = i2c.read(0, 2)
i2c.stop(id) i2c.stop(id)
data = bit.lshift(string.byte(data_temp, 1, 1), 8) + string.byte(data_temp, 2, 2) local data = bit.lshift(string.byte(data_temp, 1, 1), 8) + string.byte(data_temp, 2, 2)
return data return data
end end

View File

@ -8,7 +8,7 @@ require("httpserver").createServer(80, function(req, res)
-- analyse method and url -- analyse method and url
print("+R", req.method, req.url, node.heap()) print("+R", req.method, req.url, node.heap())
-- setup handler of headers, if any -- setup handler of headers, if any
req.onheader = function(self, name, value) req.onheader = function(self, name, value) -- luacheck: ignore
print("+H", name, value) print("+H", name, value)
-- E.g. look for "content-type" header, -- E.g. look for "content-type" header,
-- setup body parser to particular format -- setup body parser to particular format
@ -21,7 +21,7 @@ require("httpserver").createServer(80, function(req, res)
-- end -- end
end end
-- setup handler of body, if any -- setup handler of body, if any
req.ondata = function(self, chunk) req.ondata = function(self, chunk) -- luacheck: ignore
print("+B", chunk and #chunk, node.heap()) print("+B", chunk and #chunk, node.heap())
if not chunk then if not chunk then
-- reply -- reply

View File

@ -48,7 +48,7 @@ do
csend("\r\n") csend("\r\n")
end end
end end
local send_header = function(self, name, value) local send_header = function(self, name, value) -- luacheck: ignore
-- NB: quite a naive implementation -- NB: quite a naive implementation
csend(name) csend(name)
csend(": ") csend(": ")
@ -88,13 +88,13 @@ do
local req, res local req, res
local buf = "" local buf = ""
local method, url local method, url
local ondisconnect = function(conn) local ondisconnect = function(connection)
conn:on("sent", nil) connection.on("sent", nil)
collectgarbage("collect") collectgarbage("collect")
end end
-- header parser -- header parser
local cnt_len = 0 local cnt_len = 0
local onheader = function(conn, k, v) local onheader = function(connection, k, v) -- luacheck: ignore
-- TODO: look for Content-Type: header -- TODO: look for Content-Type: header
-- to help parse body -- to help parse body
-- parse content length to know body length -- parse content length to know body length
@ -111,19 +111,19 @@ do
end end
-- body data handler -- body data handler
local body_len = 0 local body_len = 0
local ondata = function(conn, chunk) local ondata = function(connection, chunk) -- luacheck: ignore
-- feed request data to request handler -- feed request data to request handler
if not req or not req.ondata then return end if not req or not req.ondata then return end
req:ondata(chunk) req:ondata(chunk)
-- NB: once length of seen chunks equals Content-Length: -- NB: once length of seen chunks equals Content-Length:
-- ondata(conn) is called -- ondata(conn) is called
body_len = body_len + #chunk body_len = body_len + #chunk
-- print("-B", #chunk, body_len, cnt_len, node.heap()) -- print("-B", #chunk, body_len, cnt_len, node.heap())
if body_len >= cnt_len then if body_len >= cnt_len then
req:ondata() req:ondata()
end end
end end
local onreceive = function(conn, chunk) local onreceive = function(connection, chunk)
-- merge chunks in buffer -- merge chunks in buffer
if buf then if buf then
buf = buf .. chunk buf = buf .. chunk
@ -139,12 +139,12 @@ do
buf = buf:sub(e + 2) buf = buf:sub(e + 2)
-- method, url? -- method, url?
if not method then if not method then
local i local i, _ -- luacheck: ignore
-- NB: just version 1.1 assumed -- NB: just version 1.1 assumed
_, i, method, url = line:find("^([A-Z]+) (.-) HTTP/1.1$") _, i, method, url = line:find("^([A-Z]+) (.-) HTTP/1.1$")
if method then if method then
-- make request and response objects -- make request and response objects
req = make_req(conn, method, url) req = make_req(connection, method, url)
res = make_res(csend, cfini) res = make_res(csend, cfini)
end end
-- spawn request handler -- spawn request handler
@ -156,17 +156,17 @@ do
-- header seems ok? -- header seems ok?
if k then if k then
k = k:lower() k = k:lower()
onheader(conn, k, v) onheader(connection, k, v)
end end
-- headers end -- headers end
else else
-- NB: we feed the rest of the buffer as starting chunk of body -- NB: we feed the rest of the buffer as starting chunk of body
ondata(conn, buf) ondata(connection, buf)
-- buffer no longer needed -- buffer no longer needed
buf = nil buf = nil
-- NB: we explicitly reassign receive handler so that -- NB: we explicitly reassign receive handler so that
-- next received chunks go directly to body handler -- next received chunks go directly to body handler
conn:on("receive", ondata) connection:on("receive", ondata)
-- parser done -- parser done
break break
end end

View File

@ -24,7 +24,6 @@ local address = 0
local function read_reg(reg_addr, len) local function read_reg(reg_addr, len)
local ret={} local ret={}
local c local c
local x
i2c.start(id) i2c.start(id)
i2c.address(id, address ,i2c.TRANSMITTER) i2c.address(id, address ,i2c.TRANSMITTER)
i2c.write(id,reg_addr) i2c.write(id,reg_addr)
@ -32,9 +31,9 @@ local function read_reg(reg_addr, len)
i2c.start(id) i2c.start(id)
i2c.address(id, address,i2c.RECEIVER) i2c.address(id, address,i2c.RECEIVER)
c=i2c.read(id,len) c=i2c.read(id,len)
for x=1,len,1 do for x = 1, len, 1 do
tc=string.byte(c,x) local tc = string.byte(c, x)
table.insert(ret,tc) table.insert(ret, tc)
end end
i2c.stop(id) i2c.stop(id)
return ret return ret
@ -64,7 +63,7 @@ function M.setup(a)
if (a ~= nil) and (a >= 0x48) and (a <= 0x4b ) then if (a ~= nil) and (a >= 0x48) and (a <= 0x4b ) then
address = a address = a
i2c.start(id) i2c.start(id)
res = i2c.address(id, address, i2c.TRANSMITTER) --verify that the address is valid local res = i2c.address(id, address, i2c.TRANSMITTER) --verify that the address is valid
i2c.stop(id) i2c.stop(id)
if (res == false) then if (res == false) then
print("device not found") print("device not found")

View File

@ -17,6 +17,7 @@ _G[moduleName] = M
local MCP23008_ADDRESS = 0x20 local MCP23008_ADDRESS = 0x20
-- Registers' address as defined in the MCP23008's datashseet -- Registers' address as defined in the MCP23008's datashseet
-- luacheck: push no unused
local MCP23008_IODIR = 0x00 local MCP23008_IODIR = 0x00
local MCP23008_IPOL = 0x01 local MCP23008_IPOL = 0x01
local MCP23008_GPINTEN = 0x02 local MCP23008_GPINTEN = 0x02
@ -28,7 +29,7 @@ local MCP23008_INTF = 0x07
local MCP23008_INTCAP = 0x08 local MCP23008_INTCAP = 0x08
local MCP23008_GPIO = 0x09 local MCP23008_GPIO = 0x09
local MCP23008_OLAT = 0x0A local MCP23008_OLAT = 0x0A
-- luacheck: pop
-- Default value for i2c communication -- Default value for i2c communication
local id = 0 local id = 0
@ -75,8 +76,7 @@ local function read(registerAddress)
i2c.start(id) i2c.start(id)
-- Read the data form the register -- Read the data form the register
i2c.address(id,MCP23008_ADDRESS,i2c.RECEIVER) -- send the MCP's address and read bit i2c.address(id,MCP23008_ADDRESS,i2c.RECEIVER) -- send the MCP's address and read bit
local data = 0x00 local data = i2c.read(id,1) -- we expect only one byte of data
data = i2c.read(id,1) -- we expect only one byte of data
i2c.stop(id) i2c.stop(id)
return string.byte(data) -- i2c.read returns a string so we convert to it's int value return string.byte(data) -- i2c.read returns a string so we convert to it's int value

View File

@ -55,7 +55,7 @@ do
-- FIXME: this suddenly occurs. timeout? -- FIXME: this suddenly occurs. timeout?
--print("-FD") --print("-FD")
end) end)
_fd:on("receive", function(fd, s) _fd:on("receive", function(fd, s) --luacheck: no unused
--print("IN", s) --print("IN", s)
-- TODO: subscription to all channels -- TODO: subscription to all channels
-- lookup message pattern to determine channel and payload -- lookup message pattern to determine channel and payload

View File

@ -10,13 +10,13 @@
wifi.setmode(wifi.STATION) --Step1: Connect to Wifi wifi.setmode(wifi.STATION) --Step1: Connect to Wifi
wifi.sta.config("SSID","Password") wifi.sta.config("SSID","Password")
dht = require("dht_lib") --Step2: "Require" the libs local dht = require("dht_lib") --Step2: "Require" the libs
yeelink = require("yeelink_lib") local yeelink = require("yeelink_lib")
yeelink.init(23333,23333,"You api-key",function() --Step3: Register the callback function yeelink.init(23333,23333,"You api-key",function() --Step3: Register the callback function
print("Yeelink Init OK...") print("Yeelink Init OK...")
tmr.alarm(1,60000,1,function() --Step4: Have fun~ (Update your data) tmr.create():alarm(60000, tmr.ALARM_AUTO, function() --Step4: Have fun~ (Update your data)
dht.read(4) dht.read(4)
yeelink.update(dht.getTemperature()) yeelink.update(dht.getTemperature())

View File

@ -22,7 +22,7 @@ local apikey = ""
--================================ --================================
local debug = true --<<<<<<<<<<<<< Don't forget to "false" it before using local debug = true --<<<<<<<<<<<<< Don't forget to "false" it before using
--================================ --================================
local sk=net.createConnection(net.TCP, 0) local sk = net.createConnection(net.TCP, 0)
local datapoint = 0 local datapoint = 0
@ -31,10 +31,11 @@ local datapoint = 0
if wifi.sta.getip() == nil then if wifi.sta.getip() == nil then
print("Please Connect WIFI First") print("Please Connect WIFI First")
tmr.alarm(1,1000,1,function () local wifiTimer = tmr.create()
wifiTimer:alarm(1000, tmr.ALARM_AUTO,function ()
if wifi.sta.getip() ~= nil then if wifi.sta.getip() ~= nil then
tmr.stop(1) wifiTimer:stop()
sk:dns("api.yeelink.net",function(conn,ip) sk:dns("api.yeelink.net",function(_,ip)
dns=ip dns=ip
print("DNS YEELINK OK... IP: "..dns) print("DNS YEELINK OK... IP: "..dns)
end) end)
@ -42,12 +43,9 @@ if wifi.sta.getip() == nil then
end) end)
end end
sk:dns("api.yeelink.net",function(conn,ip) sk:dns("api.yeelink.net",function(conn, ip) -- luacheck: no unused
dns = ip
dns=ip print("DNS YEELINK OK... IP: "..dns)
print("DNS YEELINK OK... IP: "..dns)
end) end)
--========Set the init function=========== --========Set the init function===========
@ -61,12 +59,12 @@ function M.init(_device, _sensor, _apikey)
sensor = tostring(_sensor) sensor = tostring(_sensor)
apikey = _apikey apikey = _apikey
if dns == "0.0.0.0" then if dns == "0.0.0.0" then
tmr.alarm(2,5000,1,function () tmr.create():alarm(5000,tmr.ALARM_AUTO,function ()
if dns == "0.0.0.0" then if dns == "0.0.0.0" then
print("Waiting for DNS...") print("Waiting for DNS...")
end end
end) end)
return false return false
else else
return dns return dns
end end
@ -96,7 +94,7 @@ function M.update(_datapoint)
datapoint = tostring(_datapoint) datapoint = tostring(_datapoint)
sk:on("connection", function(conn) sk:on("connection", function()
print("connect OK...") print("connect OK...")
@ -116,7 +114,7 @@ function M.update(_datapoint)
end) end)
sk:on("receive", function(sck, content) sk:on("receive", function(conn, content) -- luacheck: no unused
if debug then if debug then
print("\r\n"..content.."\r\n") print("\r\n"..content.."\r\n")

View File

@ -173,6 +173,32 @@ stds.nodemcu_libs = {
toHex = empty toHex = empty
} }
}, },
dcc = {
fields = {
CV_READ = empty,
CV_RESET = empty,
CV_VALID = empty,
CV_WRITE = empty,
DCC_ACCESSORY = empty,
DCC_FUNC = empty,
DCC_IDLE = empty,
DCC_RAW = empty,
DCC_RESET = empty,
DCC_SERVICEMODE = empty,
DCC_SPEED = empty,
DCC_SPEED_RAW = empty,
DCC_TURNOUT = empty,
FLAGS_AUTO_FACTORY_DEFAULT = empty,
FLAGS_DCC_ACCESSORY_DECODER = empty,
FLAGS_MY_ADDRESS_ONLY = empty,
FLAGS_OUTPUT_ADDRESS_MODE = empty,
MAN_ID_DIY = empty,
MAN_ID_JMRI = empty,
MAN_ID_SILICON_RAILWAY = empty,
close = empty,
setup = empty
}
},
dht = { dht = {
fields = { fields = {
ERROR_CHECKSUM = empty, ERROR_CHECKSUM = empty,
@ -200,12 +226,17 @@ stds.nodemcu_libs = {
}, },
file = { file = {
fields = { fields = {
chdir = empty,
close = empty, close = empty,
exists = empty, exists = empty,
flush = empty, flush = empty,
format = empty,
fscfg = empty,
fsinfo = empty, fsinfo = empty,
getcontents = empty, getcontents = empty,
list = empty, list = empty,
mount = empty,
n = empty,
on = empty, on = empty,
open = empty, open = empty,
putcontents = empty, putcontents = empty,
@ -393,7 +424,10 @@ stds.nodemcu_libs = {
}, },
task = { task = {
fields = { fields = {
post = empty post = empty,
LOW_PRIORITY = empty,
MEDIUM_PRIORITY = empty,
HIGH_PRIORITY = empty
} }
} }
} }
@ -576,6 +610,13 @@ stds.nodemcu_libs = {
transaction = empty transaction = empty
} }
}, },
struct = {
fields = {
pack = empty,
size = empty,
unpack = empty
}
},
switec = { switec = {
fields = { fields = {
close = empty, close = empty,
@ -876,7 +917,8 @@ stds.nodemcu_libs = {
}, },
pack = empty, pack = empty,
unpack = empty, unpack = empty,
size = empty size = empty,
package = {fields = {seeall = read_write}}
} }
} }

View File

@ -114,6 +114,12 @@ local function printTables(fileName)
if not findBegin then if not findBegin then
findBegin, _, field = string.find(line, "LROT_TABENTRY%(%s?(%g+),") findBegin, _, field = string.find(line, "LROT_TABENTRY%(%s?(%g+),")
end end
if not findBegin then
findBegin, _, field = string.find(line, "LROT_FUNCENTRY_S%(%s?(%g+),")
end
if not findBegin then
findBegin, _, field = string.find(line, "LROT_FUNCENTRY_F%(%s?(%g+),")
end
if findBegin then if findBegin then
if not string.find(field, "__") then if not string.find(field, "__") then

View File

@ -0,0 +1,72 @@
#!/bin/bash
set -e
exists() {
if command -v "$1" >/dev/null 2>&1
then
return 0
else
return 1
fi
}
usage() {
echo "
usage: bash tools/travis/run-luacheck.sh [-s]
Avarible options are:
-s: Standalone mode: Lua, LuaRocks and luacheck
will be installed in nodemcu-firmare/cache folder.
By default script will use luarocks installed in host system.
"
}
install_tools() {
if ! exists luarocks; then
echo "LuaRocks not found!"
exit 1
fi
eval "`luarocks path --bin`" #Set PATH for luacheck
#In Travis Path it's not changed by LuaRocks for some unknown reason
if [ "${TRAVIS}" = "true" ]; then
export PATH=$PATH:/home/travis/.luarocks/bin
fi
if ! exists luacheck; then
echo "Installing luacheck"
luarocks install --local luacheck || exit
fi
}
install_tools_standalone() {
if ! [ -x cache/localua/bin/luarocks ]; then
echo "Installing Lua 5.3 and LuaRocks"
bash tools/travis/localua.sh cache/localua || exit
fi
if ! [ -x cache/localua/bin/luacheck ]; then
echo "Installing luacheck"
cache/localua/bin/luarocks install luacheck || exit
fi
}
if [[ $1 == "" ]]; then
install_tools
else
while getopts "s" opt
do
case $opt in
(s) install_tools_standalone ;;
(*) usage; exit 1 ;;
esac
done
fi
echo "Static analysys of"
find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
(find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 luacheck --config tools/luacheck_config.lua) || exit

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -e
#Download luacheck binary if nessesary
if ! [ -x "cache/luacheck.exe" ]; then
wget --tries=5 --timeout=10 --waitretry=10 --read-timeout=10 --retry-connrefused -O cache/luacheck.exe https://github.com/mpeterv/luacheck/releases/download/0.23.0/luacheck.exe
fi
echo "Static analysys of"
find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
(find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 cache/luacheck.exe --config tools/luacheck_config.lua) || exit

View File

@ -1,17 +0,0 @@
#!/bin/bash
set -e
echo "Installing Lua 5.3, LuaRocks and Luacheck"
(
cd "$TRAVIS_BUILD_DIR" || exit
bash tools/travis/localua.sh cache/localua || exit
cache/localua/bin/luarocks install luacheck || exit
)
(
echo "Static analysys of:"
find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
)
(find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 cache/localua/bin/luacheck --config tools/luacheck_config.lua) || exit