Log CC digital sensor data & send 1min totals
This applet is used to log CurrentCost sensor data and generate events for their minute totals. Latter again can be configured to to posted on Pachube.
Using CurrentCost digital development boards and some TTL logic++ it is possible to count pulses from gas and water meters.
Enjoy,
Aivo
CcSensorsApplet.lua
require("xap")
module (...,package.seeall)
 
info = {version="1.0", description="Log CurrentCost sensor data & xAP send their 1min sums"}
senstates = { }      -- array holding sensor last states; these and next are reset after each send
sensums = { }        -- .. sensor pulse count sums
senlogtimes = { }    -- .. last log times
senofftimes = { }    -- .. last off times
senclasses = { "cdgas", "cdwat" }     -- events generated are with class=xAPBSC.cdgas and similar
senfactors = { 10, 8 }                    -- gas L: 10 * imp -- gas wh: 10 * 1.079723 * 33.7 / 3.6 -- water L: 8 * imp
logpath = '/mnt/usb/livebox/ccsensors'    -- folder on usb stick
period = 60            -- period in seconds we are counting for / send interval
function init()
    fs = xap.Filter()
    fs:add("xap-header", "source", "dbzoo.livebox.CurrentCost:sensor.*")
    fs:callback(savesensor)
    xap.Timer(sendcountsum, period):start()
end
function savesensor()
    local source = xap.getValue("xap-header","source")
    local sensor = tonumber(source:sub(-1))
    if sensor == nil then
        print('Type mismatch, cc sensor.')
        return
    end
    local state = xap.getValue("input.state","state")
    if state == "on" then
        if sensums[sensor] == nil then
            sensums[sensor] = 1
        else
            sensums[sensor] = sensums[sensor] + 1
        end
    end
--    print(sensor, senstates[sensor], state, os.date("%X", senlogtimes[sensor]), os.date("%X", senofftimes[sensor]), os.date("%X"))
    if state == "on" or state ~= senstates[sensor] then
        -- logged are "on" and "on"<->"off"
        -- for "off"->"on" also last "off" before "on" is logged (if not logged yet)
        if senstates[sensor] == "off" and senlogtimes[sensor] ~= senofftimes[sensor] then
            logdataoff(sensor)
        end
        senstates[sensor] = state
        logdata(sensor)
    end
    if state == "off" then
        senstates[sensor] = state
        senofftimes[sensor] = os.time()
    end
end
function logdataoff(sensor)
--    print("logdataoff")
    if senlogtimes[sensor] == nil or senofftimes[sensor] == nil then return end
    local cmd = string.format('echo %s,%s,%s,%s>>%s/%s', os.date("%Y-%m-%d %X", senofftimes[sensor]), sensor, "off", senofftimes[sensor] - senlogtimes[sensor], logpath, os.date("%Y%m%d"))
    os.execute(cmd)
--    print(cmd)
end
function logdata(sensor)
    if senlogtimes[sensor] == nil then senlogtimes[sensor] = 0 end
    local timediff = os.difftime(os.time(), senlogtimes[sensor])
    local cmd = string.format('echo %s,%s,%s,%s>>%s/%s', os.date("%Y-%m-%d %X"), sensor, senstates[sensor], timediff, logpath, os.date("%Y%m%d"))
    os.execute(cmd)
    senlogtimes[sensor] = os.time()
--    print(cmd)
end
function sendcountsum()
    for i = 1, table.getn(senclasses) do
        local sumtosend = 0
        if sensums[i] ~= nil then sumtosend = sensums[i] end
        local sumtosendextra = sumtosend * senfactors[i]
--        print(senclasses[i], sumtosend, sumtosendextra, os.time())
        local msg = string.format([[xap-header
{
target=dbzoo.livebox.CurrentCost:script
class=xAPBSC.%s
}
input.state
{
state=on
text=%s
extra=%s
}]], senclasses[i], sumtosend, sumtosendextra)
        xap.sendShort(msg)
--        print(msg)
    end
    sensums = { }
end
