Log CC digital sensor data & send 1min totals

No replies
aivo
Offline
Tallinn, Estonia
Joined: 2 Mar 2011

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

Hardware Info