Author Topic: Contribution: Monitor and visualize energy usage with emoncms.org in Vera  (Read 11946 times)

Offline akbooer

  • Master Member
  • *******
  • Posts: 5274
  • Karma: +227/-67
  • "Less is more"
You wouldn't normally put the .lua extension into the require statement.

Does this work?

Code: [Select]
require "EnergyMonitor"
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline Spanners

  • Full Member
  • ***
  • Posts: 230
  • Karma: +12/-5
    • https://www.livehouseautomation.com.au
Hi akbooer,

No joy with that code change either.

The only other stuff in my startup is related to logging and restarts, not sure if it has a bearing.

Code: [Select]
-- Keep snapshots of LuaUPnP.log
local snapSecs = 180    -- Seconds of log to keep in snapshot.
local snapNum = 5 -- Total number of snapshots to keep.
local baseFile = "/www/logsnap"
local snapFile = baseFile .. "1.txt"
-- Rename the snapshot stack
if snapNum > 1 then
for i=snapNum-1,1,-1 do
os.rename(baseFile .. tostring(i) .. ".txt", baseFile .. tostring(i 1) .. ".txt")
end
end
-- Take snapshot of current log
local dt = {}
local cut = os.time() - snapSecs
local snapF,snapE = io.open(snapFile,"w ")
if snapF ~= nil then
local foundcut = false
for line in io.lines("/tmp/log/cmh/LuaUPnP.log") do
if not foundcut then
mStr,dStr,yStr,hhStr,mmStr,ssStr = string.match(line,"^89.-(9 )/(, )/(e ) (t ):(e ):(o )")
if mStr ~= nil then
dt.month = tonumber(mStr)
dt.year = tonumber(yStr)   2000
dt.day = tonumber(dStr)
dt.hour = tonumber(hhStr)
dt.min = tonumber(mmStr)
dt.sec = tonumber(ssStr)
tstamp = os.time(dt)
if (tstamp >= cut) then foundcut = true end
end
end
if foundcut then
snapF:write(line .. "\n")
-- Following line stops snapshot at point of crash.
if string.find(line,"LuaUPnP Terminated with Exit Code:") ~= nil then break end
end
end
snapF:close()
end


-- Log each restart.
local function restartLog(message, keepdays)
local lfs = require "lfs"
local socket = require("socket")
local time = socket.gettime() or os.time()
local tms = string.format(".d  ",math.floor (1000 * (time  1)))
local stamp = os.date("s o l  u",math.floor(time)) .. tms
local baseFile = "/www/restarts"
local logFile = baseFile .. ".txt"
local lastLog = lfs.attributes(logFile,"modification") or time
-- Log this restart
local uptime = time - lastLog
local uptimeStr = string.format("Uptime: s Days 4 Hrs 9 Mins. ",math.floor(uptime / 86400),
math.floor((uptime a86400) / 3600), math.floor((uptime o3600) / 60))
local file = io.open(logFile, "a ")
file:write(stamp .. "Restart. " .. uptimeStr .. (message or "").."\n")
file:close()
-- Remove old entries
local prevDays = keepdays or 30    -- Days to keep in addition to today.
local tmpFile = baseFile .. ".tmp"
local mTxt={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12}
local dt = {}
local today = time - (time  86400)
local cut = today - ( prevDays * 86400)
local tmpF,tmpE = io.open(tmpFile,"w ")
if tmpF ~= nil then
for line in io.lines(logFile) do
dStr,mStr,yStr = string.match(line,"^(4 )3(8 )5(1 )9")
dt.month = mTxt[mStr]
dt.year = tonumber(yStr)
dt.day =tonumber(dStr)
date = os.time(dt)
if (date >= cut) then tmpF:write(line .. "\n") end
end
tmpF:close()
local retn,err = os.rename(tmpFile, logFile)
end
lfs.touch(logFile,time)
end

local netOK = "OK"
if os.execute("ping -c 1 8.8.8.8") ~= 0 then netOK = "Offline" end
restartLog("Network: " .. netOK, 30) -- Last argument is log history in days.




« Last Edit: July 25, 2016, 03:08:45 am by BlueSmurf »

Offline akbooer

  • Master Member
  • *******
  • Posts: 5274
  • Karma: +227/-67
  • "Less is more"
So what does the log file show?
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline RichardTSchaefer

  • Master Member
  • *******
  • Posts: 9805
  • Karma: +740/-136
    • RTS Services Plugins
Please review:
   http://forum.micasaverde.com/index.php/topic,33226.msg244015.html#new

Add a line to the beginning of the LUA File:
  module("EnergyMonitor", package.seeall)

For all of the functions that you callback by NAME from the various luup.xxx functions add a line as follows during some initialization (i.e. at bottom of file):

   _G.FunctionName = FunctionName

i.e.  EnergyMonitorOnTimer

Offline Spanners

  • Full Member
  • ***
  • Posts: 230
  • Karma: +12/-5
    • https://www.livehouseautomation.com.au
I feel like I'm bringing a knife to a gun fight talking code with Akbooer and RTS... :)   Thanks to both of you for taking the time to answer questions.

Ok, modified the EnergyMontor.lua (attached) to include the elements Richard describes above.

Replaced my Lua Start up with:
Code: [Select]
emoncode = require("EnergyMonitor")
emoncode.EnergyMonitorOnTimer()

The code runs. However, if I try to add my original startup code back (see previous snippets, it's the log restart and capture luaupnp.log snapshots that's posted on the forum), the EnergyMonitor code no longer runs and Vera gives me an "Error in Lua Scenes and Events" message. But if I leave the Energymonitor bits out of startup, the other code runs fine.


Offline akbooer

  • Master Member
  • *******
  • Posts: 5274
  • Karma: +227/-67
  • "Less is more"
Sound like a simple syntax error in the combined code stopping it all from loading in the first place.

Hard to imagine how, since it should be very straight-forward, but can you in fact post the entire code that doesn't work in startup?  Otherwise it's just guesswork.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline Spanners

  • Full Member
  • ***
  • Posts: 230
  • Karma: +12/-5
    • https://www.livehouseautomation.com.au
Hi akbooer, copy of the rest of the startup lua attached if you want to cast your eye over it.

Thanks.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5274
  • Karma: +227/-67
  • "Less is more"
Hi akbooer, copy of the rest of the startup lua attached if you want to cast your eye over it.

Well, for a start, line 27 is invalid syntax:
Code: [Select]
os.rename(baseFile .. tostring(i) .. ".txt", baseFile .. tostring(i 1) .. ".txt")
... I believe you mean tostring(i-1).

line 55 also...
Code: [Select]
dt.year = tonumber(yStr)   2000

line 103...
Code: [Select]
local tms = string.format(".d  ",math.floor (1000 * (time  1)))
... I believe this should be string.format("%d ", ... although this might just be a text encoding issue?
... also (time 1) should just be (time) ?

line 119...
Code: [Select]
math.floor((uptime a86400) / 3600), math.floor((uptime o3600) / 60))

line 137...
Code: [Select]
local today = time - (time  86400)

Having fixed all those, there are also a number of undefined globals and other things you may want to fix...
Code: [Select]
Analyzing the source code: 12 warnings.
untitled.lua:39: unused local variable 'snapE'; consider removing or replacing with '_'
untitled.lua:49: first assignment to global variable 'mStr'
untitled.lua:49: first assignment to global variable 'dStr'
untitled.lua:49: first assignment to global variable 'yStr'
untitled.lua:49: first assignment to global variable 'hhStr'
untitled.lua:49: first assignment to global variable 'mmStr'
untitled.lua:49: first assignment to global variable 'ssStr'
untitled.lua:65: first assignment to global variable 'tstamp'
untitled.lua:141: unused local variable 'tmpE'; consider removing or replacing with '_'
untitled.lua:155: first assignment to global variable 'date'
untitled.lua:163: unused local variable 'retn'; consider removing or replacing with '_'
untitled.lua:163: unused local variable 'err'; consider removing or replacing with '_'

So, I can't see that this can ever have worked.  It looks like you come from the world of strongly typed languages?  Would strongly that you use an IDE with a good code analyzer.

3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline Spanners

  • Full Member
  • ***
  • Posts: 230
  • Karma: +12/-5
    • https://www.livehouseautomation.com.au
Hi Akbooer,

I can't take credit for writing any of that code - I just stole it from various forum posts.  :-[

http://forum.micasaverde.com/index.php/topic,31292.0.html

Thank you for the feedback on the issues with it, for now I've just removed it entirely as I'm not having Luup/Vera Restart issues (for the first time in years). But I swear it did work!  :)




Offline rafale77

  • Hero Member
  • *****
  • Posts: 740
  • Karma: +35/-20
Just gave it a try and it doesn't seem to post the inputs for me... similar to BlueSmurf

Edit: Figured it out.
1) Went back to the unmodified file from wezzix. The edit from BlueSmurf were one of the problems...
2) Uploading through the UI app creator compresses the lua file creating an .lzo file on the vera. I SCP'd the file to prevent the compression

Now it all works.
« Last Edit: July 30, 2016, 11:41:36 am by rafale77 »
VeraPlus with 116 zwave nodes, 8 Zigbee nodes, 12 apps, 267 vera devices, 80 scenes; Controlled by Openluup (21 devices, 56 scenes, 9 apps) and iobroker; Bridged to Homekit and Alexa.

Offline mvader

  • Sr. Member
  • ****
  • Posts: 395
  • Karma: +29/-74
having an issue getting the data to show up correctly.
in my log emoncms log files i have this error
2016-08-01 02:08:55.105|ERROR|input_controller.php|Format error: csv value is not numeric
2016-08-01 02:09:05.103|ERROR|input_controller.php|Format error: csv value is not numeric

in my vera logs i have this
 luup_log:0: EnergyMonitor Logger: Updating with: &node=1&json={WashRoom Temp:69.4,Total:0}

(i was trying to log a temp sensor, the input shows up (the node, but the value is always zero)
i suspect it's because of the format error..
any idea what may be wrong?

Offline akbooer

  • Master Member
  • *******
  • Posts: 5274
  • Karma: +227/-67
  • "Less is more"
I don't know if it helps, but this:

Code: [Select]
json={WashRoom Temp:69.4,Total:0}

is not valid JSON.

Try this instead?

Code: [Select]
json={"WashRoom Temp":69.4,"Total":0}
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline mvader

  • Sr. Member
  • ****
  • Posts: 395
  • Karma: +29/-74
I don't know if it helps, but this:

Code: [Select]
json={WashRoom Temp:69.4,Total:0}

is not valid JSON.

Try this instead?

Code: [Select]
json={"WashRoom Temp":69.4,"Total":0}


Thanks for the tip.. I'll give it a go this evening.

Offline Spanners

  • Full Member
  • ***
  • Posts: 230
  • Karma: +12/-5
    • https://www.livehouseautomation.com.au
Re: Contribution: Monitor and visualize energy usage with emoncms.org in Vera
« Reply #28 on: October 15, 2016, 01:41:37 am »
Hi Guys,

Hopefully this is an easy one for someone familiar with Lua.

Just finished the build of my 3-Phase energy monitoring system, a hybrid of Mysensors and Open Energy Monitor. I have it reporting into Vera, and uploading to emoncms.org

Code: [Select]
local VARIABLES = {
{ key="Emon1", deviceId = 70, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }, -- Send device energy
{ key="Emon2", deviceId = 73, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" },
{ key="Emon3", deviceId = 74, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }

All good so far. What I'd like to do is add a new key value which is the total of these 3 values. The original lua script has an example for sending a constant value

Code: [Select]
{ key="Other", calculate=function() return 15 end, serviceVar="Watts" } -- Send a constant value

Is there a way to modify that so the returned value is the sum of the first 3? Or does this require processing within the script itself - I see there's code there that effectively sums all of the values reported. Which is fine if you're only sending the 3 phase values, but I have other devices reporting watts that I don't want included in the total.



Offline hart

  • Newbie
  • *
  • Posts: 1
  • Karma: +0/-0
Re: Contribution: Monitor and visualize energy usage with emoncms.org in Vera
« Reply #29 on: November 20, 2016, 04:47:29 pm »
What I'd like to do is add a new key value which is the total of these 3 values. The original lua script has an example for sending a constant value

Code: [Select]
{ key="Other", calculate=function() return 15 end, serviceVar="Watts" } -- Send a constant value

Is there a way to modify that so the returned value is the sum of the first 3? Or does this require processing within the script itself - I see there's code there that effectively sums all of the values reported. Which is fine if you're only sending the 3 phase values, but I have other devices reporting watts that I don't want included in the total.

Something like:

Code: [Select]
{ key="Other", calculate=function() return luup.variable_get('urn:micasaverde-com:serviceId:EnergyMetering1', 'Watts', 70) + luup.variable_get('urn:micasaverde-com:serviceId:EnergyMetering1', 'Watts', 73) + luup.variable_get('urn:micasaverde-com:serviceId:EnergyMetering1', 'Watts', 74) end, serviceVar="Watts" }