Log CC power data & send house totals
This applet is used 1) to log CurrentCost data to file on usb stick and 2) calculate house total load and generate xAP events for it (send respective message), latter again is configured to be posted on Pachube.
I have small Linux box as home server (for samba, mythtv, dlna/ps3ms) that is up occasionally; when up it will periodically copy files from livebox and bulk load to mysql. This data then can then be further analysed and visualized. I have used Google Vis tools and mc-goog-visualization for this.
Enjoy,
Aivo
CcPowerApplet.lua
require("xap")
module (...,package.seeall)
info = {version="1.0", description="Log CurrentCost power data & xAP send house totals"}
load = { } -- array of CurrentCost latest phase 1..3 values
temp = 0 -- Currentcost temperature
logtime = os.time() -- using this we decide if current second event is already being sent
logpath = "/mnt/usb/livebox/currentcost" -- folder on usb stick
oktolog = false -- set to true when load and temp values all get initialised
function init()
fp = xap.Filter()
fp:add("xap-header", "source", "dbzoo.livebox.CurrentCost:ch.*")
fp:callback(saveload)
ft = xap.Filter()
ft:add("xap-header", "source", "dbzoo.livebox.CurrentCost:temp")
-- ft:add("xap-header", "class", "xAPBSC.info")
ft:callback(savetemp)
xap.Timer(delaylogstart, 2):start()
end
-- Wait until all values initialized
function delaylogstart(self)
if table.getn(load) < 3 or temp == 0 then return end
oktolog = true
self:delete()
end
function saveload()
local source = xap.getValue("xap-header","source")
local ch = tonumber(source:sub(-1))
if ch == nil then
print('Type mismatch, cc chnum.')
return
end
load[ch] = xap.getValue("input.state","text")
-- print(string.format("%s,%s,%s,%s", os.date("%Y-%m-%d %X"), ch, xap.getValue("input.state","text"), temp))
if oktolog and os.time() ~= logtime then -- one log line/sum event for same second
logtime = os.time() -- delaying send for 1 second,
xap.Timer(logandsend, 1):start() -- other possible events from same second are saved until then
end
end
function savetemp()
temp = xap.getValue("input.state","text")
end
function logandsend(self)
local sumload = load[1] + load[2] + load[3]
local cmd = string.format("echo %s,%s,%s,%s,%s,%s>>%s/%s", os.date("%Y-%m-%d %X"), sumload, load[1], load[2], load[3], temp, logpath, os.date("%Y%m%d"))
os.execute(cmd)
-- print(cmd)
local msg = string.format([[xap-header
{
target=dbzoo.livebox.CurrentCost:script
class=xAPBSC.ccel
}
input.state
{
state=on
text=%s
displaytext=%s watts
}]], sumload, sumload)
xap.sendShort(msg)
-- print(msg)
self:delete()
end
OK what I've done is made a few minor tweaks to your code which I've summarized below.
We create the endpoint "dbzoo.livebox.CurrentCost:ch.total" which is a REAL BSC endpoint and will be the total of each of the ch.1,ch.2,ch.3 phases. Its in the same namespace as the CurrentCost program so as it make it look more natural.
require("xap.bsc")
local cctotal = bsc.Endpoint{source="dbzoo.livebox.CurrentCost:ch.total", direction=bsc.INPUT, type=bsc.STREAM}
The logic you had in place for reporting events remains but now we update and send event for this new BSC endpoint, instead of building our own xAP message.
cctotal:setText(sumload)
-- Damn I don't have?! cctotal:setDisplayText() -- I'll fix that.
cctotal.displaytext = string.format("%s Watts", sumload)
cctotal:sendEvent()
Now as this new endpoint adheres to xAPBSC you can easily access it from xAPFlash like this.
<button NAME="CC Total"> <gridX>2</gridX> <gridY>0</gridY> <xAP> <schema>xAPBSC</schema> <uid>*</uid> <source>dbzoo.livebox.CurrentCost:ch.total</source> </xAP> <mode>text</mode> </button>
You may need to replace the '*' with its UID if you find this is not working, the UID will be automatically computed and you can snoop the xAP message to find out what it is.
Hope this information puts your mind in the right place for thinking about how these sorts of things should be done.
I've not tested any of this code - so if its doesn't work first time don't be suprised, however it should be pretty close to what you should be doing.
Brett
Attachment | Size |
---|---|
ccpowerapplet.lua | 2.33 KB |
How about I modify xap-currentcost to include a ch.total endpoint that will automatically compute the SUM of ch.1 + ch.2 + ch.3 and expose itself as a BSC endpoint.
This will make your code much simplier as you can forget about all this summation logic and let xap-currentcost handle it.
I've added a new channel "ch.total" which is defered creation until a WATT reading is seen for at least two phases. Once created it will update summing the total power consumption over all the channels.
I've pushed up FIRMWARE release 292 with this in it so don't use my code above - but its still a nice example of how this could also be done in LUA.
Brett
Really? This is BAD I'll have to fix that I never noticed it when I tested. Thanks. I'll have to push another release now... grrr
Try release 293 :)
Avio, If 292 was working and 293 is not I can't see how that can be as I literally added 1 line of code between these revisions. And here is that line of code, which forces ch.total to UID 5
bscSetEndpointUID(5);
The endpoint mappings for the currentcost look like this:
- ch.1 is 01
- ch.2 is 02
- ch.3 is 03
- temp is 04
- ch.total is 05
- sensor.1 is 11
- ...
- sensor.9 is 20
As I have no CC to test with I was feeding in a text file to make sure it was working and it parsed this without any problem doing exactly as I would expect. Anybody else reporting CC issues with 293?
Brett
Hi Brett,
Here is an applet where I use class=xAPBSC.ccel and target=dbzoo.livebox.CurrentCost:script.
Regards,
Aivo