openwrt: adapt repository structure to simplify build environment setup
This commit is contained in:
parent
bf0c4948df
commit
93582b14fe
1486 changed files with 42 additions and 20 deletions
44
openwrt/package/flukso/Makefile
Normal file
44
openwrt/package/flukso/Makefile
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) 2008 jokamajo.org
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=flukso
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/flukso
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
DEPENDS:=+liblua-xmlrpc +ntpclient
|
||||
TITLE:=Flukso - community metering
|
||||
endef
|
||||
|
||||
define Package/flukso/description
|
||||
This package contains the necessary openwrt files for the Flukso [www.flukso.net] community metering application.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/flukso/install
|
||||
$(INSTALL_DIR) $(1)/usr/share/lua/flukso/
|
||||
$(CP) $(PKG_BUILD_DIR)/flukso.lua $(1)/usr/share/lua/flukso/
|
||||
$(CP) $(PKG_BUILD_DIR)/data.lua $(1)/usr/share/lua/flukso/
|
||||
$(CP) $(PKG_BUILD_DIR)/dbg.lua $(1)/usr/share/lua/flukso/
|
||||
$(CP) $(PKG_BUILD_DIR)/auth.lua $(1)/usr/share/lua/flukso/
|
||||
$(CP) $(PKG_BUILD_DIR)/heartbeat.lua $(1)/usr/share/lua/flukso/
|
||||
$(INSTALL_DIR) $(1)/etc/init.d/
|
||||
$(CP) $(PKG_BUILD_DIR)/flukso.init $(1)/etc/init.d/flukso
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,flukso))
|
||||
73
openwrt/package/flukso/src/auth.lua
Normal file
73
openwrt/package/flukso/src/auth.lua
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
--
|
||||
-- auth.lua: property and methods for generating hmac-sha1 authentication
|
||||
-- Copyright (c) 2009 jokamajo.org
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- as published by the Free Software Foundation; either version 2
|
||||
-- of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
|
||||
require 'luci.model.uci'
|
||||
require 'lxyssl'
|
||||
|
||||
local string, table, os, luci, lxyssl =
|
||||
string, table, os, luci, lxyssl
|
||||
|
||||
local getfenv, setmetatable, type, pairs, tostring =
|
||||
getfenv, setmetatable, type, pairs, tostring
|
||||
|
||||
module(...)
|
||||
local modenv = getfenv()
|
||||
|
||||
function new()
|
||||
return setmetatable({}, {__index = modenv})
|
||||
end
|
||||
|
||||
function load(T)
|
||||
local uci = luci.model.uci.cursor()
|
||||
uci:foreach ('system', 'system',
|
||||
function(section)
|
||||
T.device, T.key, T.version = section.device, section.key, section.version
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
function hmac(T, M, timestamp)
|
||||
function string.hex(x)
|
||||
local t={}
|
||||
for c in x:gmatch('(.)') do t[#t+1]=string.format('%02x', c:byte()) end
|
||||
return table.concat(t,'')
|
||||
end
|
||||
|
||||
function serialise(M)
|
||||
if type(M) == 'table' then
|
||||
local sequence = ''
|
||||
for k, v in pairs(M) do
|
||||
if v ~= nil then
|
||||
sequence = sequence..tostring(k)..serialise(v)
|
||||
end
|
||||
end
|
||||
return sequence
|
||||
else
|
||||
return tostring(M)
|
||||
end
|
||||
end
|
||||
|
||||
T.timestamp = timestamp or os.time()
|
||||
T.message = T.timestamp..':'..serialise(M)..':'..T.key
|
||||
T.signature = lxyssl.hash('hmac-sha1', T.key):digest(T.message):hex()
|
||||
|
||||
T.message, T.key, T.version = nil, nil, nil
|
||||
end
|
||||
62
openwrt/package/flukso/src/data.lua
Normal file
62
openwrt/package/flukso/src/data.lua
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
--
|
||||
-- data.lua: property and methods for manipulating incoming measurements
|
||||
-- Copyright (c) 2009 jokamajo.org
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- as published by the Free Software Foundation; either version 2
|
||||
-- of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
|
||||
local os, math, table =
|
||||
os, math, table
|
||||
|
||||
local getfenv, setmetatable, pairs =
|
||||
getfenv, setmetatable, pairs
|
||||
|
||||
module (...)
|
||||
local modenv = getfenv() -- module environment
|
||||
|
||||
function new()
|
||||
return setmetatable({}, {__index = modenv})
|
||||
end
|
||||
|
||||
function add(M, meter, timestamp, value)
|
||||
if not M[meter] then M[meter] = {} end
|
||||
M[meter][timestamp] = value
|
||||
end
|
||||
|
||||
function clear(M)
|
||||
for meter in pairs(M) do
|
||||
M[meter] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function filter(M, span, offset)
|
||||
for meter, T in pairs(M) do
|
||||
local H = {} -- helper table, an indexed array containing all the measurement's timestamps
|
||||
for timestamp in pairs(T) do H[#H+1] = timestamp end
|
||||
table.sort(H) -- sort in ascending order, oldest timestamps will be treated first
|
||||
|
||||
local i = 2
|
||||
while not (H[i+1] == nil or H[i] > os.time()-offset) do
|
||||
if math.floor(H[i-1]/span) == math.floor(H[i]/span) and math.floor(H[i]/span) == math.floor(H[i+1]/span) then
|
||||
T[H[i]] = nil
|
||||
table.remove(H, i)
|
||||
else
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
50
openwrt/package/flukso/src/dbg.lua
Normal file
50
openwrt/package/flukso/src/dbg.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
--
|
||||
-- dbg.lua: library for debugging with vardump in Lua
|
||||
-- Lua Programming Gems Chapter 3
|
||||
-- Vardump: The Power of Seeing What's Behind
|
||||
-- Copyright 2008 by Tobias Sülzenbrück and Christoph Beckmann
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
|
||||
local getfenv, getmetatable, print, pairs, type, tostring = getfenv, getmetatable, print, pairs, type, tostring
|
||||
|
||||
module(...)
|
||||
local modenv = getfenv() -- module environment
|
||||
|
||||
function vardump(value, depth, key)
|
||||
local linePrefix = ""
|
||||
local spaces = ""
|
||||
|
||||
if key ~= nil then
|
||||
linePrefix = "["..key.."] = "
|
||||
end
|
||||
|
||||
if depth == nil then
|
||||
depth = 0
|
||||
else
|
||||
depth = depth + 1
|
||||
for i = 1,depth do spaces = spaces.." " end
|
||||
end
|
||||
|
||||
if type(value) == 'table' then
|
||||
-- mTable = getmetatable(value)
|
||||
-- if mTable == nil then
|
||||
print(spaces..linePrefix.."(table) ")
|
||||
-- else
|
||||
-- print(spaces.."(metatable) ")
|
||||
-- value = mTable
|
||||
-- end
|
||||
for tableKey, tableValue in pairs(value) do
|
||||
vardump(tableValue, depth, tableKey)
|
||||
end
|
||||
elseif type(value) == 'function'
|
||||
or type(value) == 'thread'
|
||||
or type(value) == 'userdata'
|
||||
or value == nil
|
||||
then
|
||||
print(spaces..tostring(value))
|
||||
else
|
||||
print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
|
||||
end
|
||||
end
|
||||
17
openwrt/package/flukso/src/flukso.init
Executable file
17
openwrt/package/flukso/src/flukso.init
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (c) 2008-2009 jokamajo.org
|
||||
# $Id$
|
||||
|
||||
START=98
|
||||
|
||||
start() {
|
||||
stty 4800 < /dev/ttyS0
|
||||
/usr/share/lua/flukso/flukso.lua >&- 2>&- <&- &
|
||||
/usr/share/lua/flukso/heartbeat.lua 1 >&- 2>&- <&-
|
||||
echo -e "$(date '+%M') * * * * /usr/share/lua/flukso/heartbeat.lua 0\n"'*/15 * * * * [ -z "$(ps | grep '\'flukso.lu[a]\'')" ] && reboot' | crontab -
|
||||
}
|
||||
|
||||
stop() {
|
||||
crontab -r
|
||||
kill -SIGKILL $(ps | grep 'flukso.lu[a]' | awk '{print $1}')
|
||||
}
|
||||
154
openwrt/package/flukso/src/flukso.lua
Executable file
154
openwrt/package/flukso/src/flukso.lua
Executable file
|
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
--
|
||||
-- flukso.lua: flukso deamon running on openwrt
|
||||
-- Copyright (c) 2008-2009 jokamajo.org
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- as published by the Free Software Foundation; either version 2
|
||||
-- of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
|
||||
require 'posix'
|
||||
require 'xmlrpc.http'
|
||||
|
||||
data = require 'flukso.data'
|
||||
auth = require 'flukso.auth'
|
||||
dbg = require 'flukso.dbg'
|
||||
|
||||
local param = {xmlrpcaddress = 'http://logger.flukso.net/xmlrpc',
|
||||
xmlrpcversion = '1',
|
||||
xmlrpcmethod = 'logger.measurementAdd',
|
||||
device = '/dev/ttyS0',
|
||||
interval = 300}
|
||||
|
||||
function receive(device)
|
||||
return coroutine.wrap(function()
|
||||
-- open the connection to the syslog deamon, specifying our identity
|
||||
posix.openlog('flukso')
|
||||
posix.syslog(30, 'starting the flukso deamon')
|
||||
posix.syslog(30, 'listening for pulses on '..device..'...')
|
||||
|
||||
for line in io.lines(device) do
|
||||
if line:sub(1, 3) == 'pls' and line:len() == 47 and line:find(':') == 37 then -- user data + additional data integrity checks
|
||||
posix.syslog(30, 'received pulse from '..device..': '..line:sub(5))
|
||||
|
||||
-- flash the power led for 50ms
|
||||
os.execute('gpioctl clear 4')
|
||||
socket.select(nil, nil, 0.05)
|
||||
os.execute('gpioctl set 4')
|
||||
|
||||
local meter, value = line:sub(5, 36), tonumber(line:sub(38))
|
||||
coroutine.yield(meter, os.time(), value)
|
||||
elseif line:sub(1, 3) == 'msg' then -- control data
|
||||
posix.syslog(31, 'received message from '..device..': '..line:sub(5))
|
||||
else
|
||||
posix.syslog(27, 'input error on '..device..': '..line)
|
||||
end
|
||||
end
|
||||
|
||||
posix.syslog(30, 'closing down the flukso deamon')
|
||||
os.exit()
|
||||
end)
|
||||
end
|
||||
|
||||
function buffer(source, interval)
|
||||
return coroutine.wrap(function()
|
||||
local measurements = data.new()
|
||||
local threshold = os.time() + interval
|
||||
|
||||
while true do
|
||||
local meter, timestamp, value = source()
|
||||
if meter ~= nil and timestamp > 1234567890 then measurements:add(meter, timestamp, value) end
|
||||
if timestamp > threshold and next(measurements) then --checking whether table is not empty
|
||||
coroutine.yield(measurements)
|
||||
threshold = timestamp + interval
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function filter(source, span, offset)
|
||||
return coroutine.wrap(function()
|
||||
while true do
|
||||
local measurements = source()
|
||||
measurements:filter(span, offset)
|
||||
coroutine.yield(measurements)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function send(source, address, version, method)
|
||||
return coroutine.wrap(function()
|
||||
while true do
|
||||
local measurements = source()
|
||||
local auth = auth.new()
|
||||
auth:load()
|
||||
auth:hmac(measurements)
|
||||
|
||||
local status, ret_or_err, res = pcall(xmlrpc.http.call,
|
||||
address..'/'..version,
|
||||
method,
|
||||
auth,
|
||||
measurements)
|
||||
|
||||
if status then
|
||||
posix.syslog(30, tostring(res))
|
||||
if ret_or_err then --successful xmlrpc call
|
||||
measurements:clear()
|
||||
end
|
||||
else
|
||||
posix.syslog(27, tostring(ret_or_err)..' '..address..' '..tostring(res))
|
||||
end
|
||||
coroutine.yield(measurements)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function gc(source)
|
||||
return coroutine.wrap(function()
|
||||
while true do
|
||||
local measurements = source()
|
||||
posix.syslog(31, tostring(collectgarbage('count')*1024)..' bytes of memory used by Lua before garbage collection cycle')
|
||||
collectgarbage() -- force a complete garbage collection cycle
|
||||
posix.syslog(31, tostring(collectgarbage('count')*1024)..' bytes of memory used by Lua after garbage collection cycle')
|
||||
coroutine.yield(measurements)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- receive: listen to the serial port for incoming pulses
|
||||
-- buffer: buffer the pulses in a measurement object
|
||||
-- filter: sweep recursively to filter all redundant entries
|
||||
-- send: report the measurements to the server via xmlrpc
|
||||
-- gc: perform a full garbage collection cycle
|
||||
|
||||
local aggregator = gc(
|
||||
send(
|
||||
filter(
|
||||
filter(
|
||||
filter(
|
||||
buffer(
|
||||
receive(param.device)
|
||||
, param.interval)
|
||||
, 60, 0)
|
||||
, 900, 7200)
|
||||
, 86400, 172800)
|
||||
, param.xmlrpcaddress, param.xmlrpcversion, param.xmlrpcmethod)
|
||||
)
|
||||
|
||||
while true do
|
||||
dbg.vardump(aggregator())
|
||||
end
|
||||
90
openwrt/package/flukso/src/heartbeat.lua
Executable file
90
openwrt/package/flukso/src/heartbeat.lua
Executable file
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
--
|
||||
-- Lua 5.1 heartbeat script running on openwrt
|
||||
-- Copyright (c) 2008-2009 jokamajo.org
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- as published by the Free Software Foundation; either version 2
|
||||
-- of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
--
|
||||
-- $Id$
|
||||
--
|
||||
|
||||
if not arg[1] then
|
||||
print ('Please pass the reset argument as a boolean to the script.')
|
||||
else
|
||||
-- load libraries
|
||||
require 'posix'
|
||||
require 'xmlrpc.http'
|
||||
require 'luci.sys'
|
||||
|
||||
auth = require 'flukso.auth'
|
||||
dbg = require 'flukso.dbg'
|
||||
|
||||
-- config parameters
|
||||
local param = {server = 'logger.flukso.net',
|
||||
xmlrpcaddress = 'http://logger.flukso.net/xmlrpc',
|
||||
xmlrpcversion = '1',
|
||||
xmlrpcmethod = 'logger.heartbeat'}
|
||||
|
||||
local monitor = {reset = tonumber(arg[1])}
|
||||
|
||||
-- open the connection to the syslog deamon, specifying our identity
|
||||
posix.openlog('heartbeat')
|
||||
|
||||
-- calculate hmac and collect relevant monitoring points
|
||||
local auth = auth.new()
|
||||
auth:load()
|
||||
monitor.version = tonumber(auth.version)
|
||||
|
||||
monitor.uptime = math.floor(luci.sys.uptime())
|
||||
monitor.uart_oe = string.match(luci.sys.exec('cat /proc/tty/driver/serial'), 'oe:(%d+)') or 0
|
||||
system, model, monitor.memtotal, monitor.memcached, monitor.membuffers, monitor.memfree = luci.sys.sysinfo()
|
||||
|
||||
auth:hmac(monitor)
|
||||
|
||||
dbg.vardump(auth)
|
||||
dbg.vardump(monitor)
|
||||
|
||||
-- send a heartbeat method call
|
||||
local pcall_ok, return_or_err, pong = pcall(xmlrpc.http.call,
|
||||
param.xmlrpcaddress..'/'..param.xmlrpcversion,
|
||||
param.xmlrpcmethod,
|
||||
auth,
|
||||
monitor)
|
||||
|
||||
dbg.vardump(pong)
|
||||
|
||||
if pcall_ok and return_or_err then
|
||||
auth:load()
|
||||
auth:hmac(pong.upgrade, pong.timestamp)
|
||||
|
||||
if auth.signature == pong.signature and pong.timestamp > os.time() - 300 then
|
||||
posix.syslog(31, 'successful heartbeat authentication')
|
||||
|
||||
if tonumber(pong.upgrade) == monitor.version then --reset device
|
||||
os.execute('reboot')
|
||||
elseif tonumber(pong.upgrade) > monitor.version then -- upgrade device to specified version
|
||||
os.execute('wget -P /tmp http://'..param.server..'/files/upgrade/upgrade.'..pong.upgrade)
|
||||
os.execute('chmod a+x /tmp/upgrade.'..pong.upgrade)
|
||||
os.execute('/tmp/upgrade.'..pong.upgrade)
|
||||
os.execute('rm /tmp/upgrade.'..pong.upgrade)
|
||||
end
|
||||
end
|
||||
else
|
||||
posix.syslog(11, tostring(return_or_err))
|
||||
end
|
||||
-- close the connection to the syslog deamon
|
||||
posix.closelog()
|
||||
end
|
||||
14
openwrt/package/flukso/src/load.lua
Executable file
14
openwrt/package/flukso/src/load.lua
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#! /usr/bin/env lua
|
||||
|
||||
require 'socket'
|
||||
|
||||
local fd = assert(io.open('/dev/ttyUSB0', 'w'))
|
||||
|
||||
for i = tonumber(arg[1]), tonumber(arg[2]) do
|
||||
local data = 'pls ' .. arg[3] .. ':' .. string.sub(string.rep('0', 10) .. i, -10, -1) .. '\n'
|
||||
fd:write(data)
|
||||
socket.select(nil, nil, 0.001)
|
||||
|
||||
end
|
||||
|
||||
fd:close()
|
||||
Loading…
Add table
Add a link
Reference in a new issue