Contribution: Monitor and visualize energy usage with emoncms.org in Vera

Can someone tell me what is wrong with this code? I can get the inputs to post to emoncms but the variables all post “0”. Where is my mistake?

Notes: I have setup the startup Lua code as directed. Both of my deviceId’s match the two Aeon sensors I have (the main device, not the CT clamps).

[code]module(“EnergyMonitor”, package.seeall)

– Setup your account at http://emoncms.org/
– See API documentation at Emoncms - input api

– API Key
local API_KEY = “REMOVED FOR SECURITY REASONS”

– Setup your devices here. You can use a function to calculate the power as illustrated in the sample.
– For device logging, use: key, deviceId, serviceId, serviceVar
– For function based logging, use: key, calculate, serviceVar

local VARIABLES = {
{ key=“HEM”, deviceId = 155, serviceId=‘urn:schemas-micasaverde-com:device:PowerMeter:1’, serviceVar=“Watts” },
{ key=“HEM”, deviceId = 155, serviceId=‘urn:schemas-micasaverde-com:device:PowerMeter:1’, serviceVar=“CurrentLevel” },
{ key=“kilnwelder”, deviceId = 135, serviceId=‘urn:schemas-micasaverde-com:device:PowerMeter:1’, serviceVar=“Watts” },
{ key=“kilnwelder”, deviceId = 135, serviceId=‘urn:schemas-micasaverde-com:device:PowerMeter:1’, serviceVar=“CurrentLevel” },
{ key=‘TestVar’, calculate=function() return 15 end, serviceVar=“dsmtest” } – Send a constant value
}

– Add the following to your Vera’s Startup Lua (without the preceding dashes) to run the logging on every Vera restart
– emoncode = require(“EnergyMonitor”)
– emoncode.EnergyMonitorOnTimer()

local NODE_ID = 10
local TOTAL_KEY = ‘Total’

– Upload Frequency in seconds ORIGINALLY 60
local updateInterval = 10

– Log debug messages
local DEBUG = true

– You shouldn’t need to change anything below this line –

local http = require(‘socket.http’)
http.TIMEOUT = 3

local BASE_URL = “http://emoncms.org/input/post.json?apikey=” … API_KEY
local Log = function (text) luup.log('EnergyMonitor Logger: ’ … (text or “empty”)) end
local lastFullUpload = 0

local items = {} – contains items: { time, deviceId, value }

local function StartCallbackTimer(interval)
luup.call_delay(“EnergyMonitorOnTimer”, interval or updateInterval, nil)
end

local function InitWatch()
StartCallbackTimer(1)
end

local function AddKeyValuePair(key, value)
local item = string.format(“%s:%s”, key, tostring(value))
items[#items + 1] = item
end

local function SerializeData()
local dataText = “{” … table.concat(items, “,”) … “}”
return dataText
end

local function ResetData()
items = {}
end

local function SendData()
local data = SerializeData()
ResetData()

local parameters = "&node=" .. tostring(NODE_ID) .. "&json=" .. data
local url = BASE_URL .. parameters
if (DEBUG) then Log("Updating with: " .. parameters) end
http.request(url)

end

local function AddAllVariablesAndTotal()
local total = 0
for i, v in ipairs(VARIABLES) do
local value
if v.deviceId then
value = luup.variable_get(v.serviceId, v.serviceVar, v.deviceId)
elseif v.calculate then
value = v.calculate()
end
value = tonumber(value) or 0
if v.serviceVar == “Watts” then
total = total + value
end
AddKeyValuePair(v.key, value)
end
AddKeyValuePair(TOTAL_KEY, total)
end

function EnergyMonitorOnTimer()
StartCallbackTimer()
AddAllVariablesAndTotal()
SendData()
end

_G.EnergyMonitorOnTimer = EnergyMonitorOnTimer
InitWatch()
[/code]

Here is my code if it can help in finding the error.

Cheers!

[quote=“jamac, post:31, topic:190754”]I followed RTS’s instructions and added the following to the start of the EnergyMonitor.lua file

module("EnergyMonitor", package.seeall)

This to the end of the file:

_G.EnergyMonitorOnTimer = EnergyMonitorOnTimer

And, this in the Edit Startup Lua window:

emoncode = require("EnergyMonitor") emoncode.EnergyMonitorOnTimer()[/quote]

I don’t think that all three things are necessary. The first two should do the job. When I add emoncode.EnergyMonitorOnTimer() in start up lua, I can see two consecutive post requests in the log. Removing that line still keeps the script working.

I have a VeraPlus. EmonBase, EmonTxV3 with 4 CTs, temp sensor, etc. From what I see here, the code posts from the Vera TO EmonCMS. Is that correct?

I would like to read my CTs, VRMS, Power, Temp, etc. FROM EmonCMS and use them in the Vera for Scenes. Has anyone done this?

Rearden

The plugin SiteSensor provides functionality to query a url and retrieve json values.

[quote=“rearden, post:44, topic:190754”]I have a VeraPlus. EmonBase, EmonTxV3 with 4 CTs, temp sensor, etc. From what I see here, the code posts from the Vera TO EmonCMS. Is that correct?

I would like to read my CTs, VRMS, Power, Temp, etc. FROM EmonCMS and use them in the Vera for Scenes. Has anyone done this?

Rearden[/quote]

Could someone help me out with my Lua file? I think i’ve missed configured it somehow because no data is reported on emoncms.

[code]-- API Key
local API_KEY = “xxxx”

– Setup your devices here. You can use a function to calculate the power as illustrated in the sample.
– For device logging, use: key, deviceId, serviceId, serviceVar
– For function based logging, use: key, calculate, serviceVar
local VARIABLES = {
{ key=“Emon1”, deviceId = 223, serviceId=‘urn:micasaverde-com:serviceId:EnergyMetering1’, serviceVar=“Watts” }, – Send device energy
{ key=“Emon2”, deviceId = 224, serviceId=‘urn:micasaverde-com:serviceId:EnergyMetering1’, serviceVar=“Watts” },
{ key=‘Emon3’, deviceId = 225, serviceId=“urn:micasaverde-com:serviceId:EnergyMetering1”, serviceVar=“Watts”}, – Send switch status
}

local NODE_ID = 10
local TOTAL_KEY = ‘Total’[/code]

Try removing the comma after the last entry in the variable list.

I missed that. Thanks!

I also double checked the API write key but still no reading end up in emoncms. Is there something else i can check prior to finding out on how to get the logs out of the Vera?

It’s not the comma. That’s perfectly valid Lua syntax.

What am i looking for in the logs?

Something like this?

06 03/14/18 21:40:50.131 Device_Variable::m_szValue_set device: 227 service: urn:upnp-org:serviceId:altui1 variable: Version was: v2.16 now: v2.16 #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x73db2520> 06 03/14/18 21:40:50.673 Device_Variable::m_szValue_set device: 227 service: urn:upnp-org:serviceId:altui1 variable: DataStorageProviders was: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "default": 1, "type": "number", "key": "nodeid", "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "default": "vera_data_published", "type": "text", "key": "eventname", "label": "Hook Event Name" } ] } } now: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "key": "nodeid", "type": "number", "default": 1, "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "key": "eventname", "type": "text", "default": "vera_data_published", "label": "Hook Event Name" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] } } #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:0 <0x73db2520> 06 03/14/18 21:40:50.715 Device_Variable::m_szValue_set device: 227 service: urn:upnp-org:serviceId:altui1 variable: DataStorageProviders was: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "key": "nodeid", "type": "number", "default": 1, "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "key": "eventname", "type": "text", "default": "vera_data_published", "label": "Hook Event Name" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] } } now: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "default": 1, "type": "number", "key": "nodeid", "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "key": "eventname", "type": "text", "default": "vera_data_published", "label": "Hook Event Name" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] } } #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:0 <0x73db2520> 06 03/14/18 21:40:50.748 Device_Variable::m_szValue_set device: 227 service: urn:upnp-org:serviceId:altui1 variable: DataStorageProviders was: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "default": 1, "type": "number", "key": "nodeid", "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "key": "eventname", "type": "text", "default": "vera_data_published", "label": "Hook Event Name" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] } } now: { "emoncms": { "url": "", "callback": "sendValueToStorage_emoncms", "parameters": [ { "default": 1, "type": "number", "key": "nodeid", "label": "Node ID" }, { "type": "number", "key": "feedid", "label": "Feed ID" }, { "type": "text", "key": "inputkey", "label": "Input Key name" }, { "type": "text", "key": "readwritekey", "label": "Read/Write API Key" }, { "type": "url", "key": "graphicurl", "label": "Graphic Url", "ifheight": 460, "default": "http://emoncms.org/vis/realtime?feedid={1}&embed=1&apikey={3}" } ] }, "IFTTT": { "url": "", "callback": "sendValueToStorage_ifttt", "parameters": [ { "type": "text", "key": "webhookkey", "label": "Web Hook Key" }, { "default": "vera_data_published", "type": "text", "key": "eventname", "label": "Hook Event Name" } ] }, "thingspeak": { "url": "", "callback": "sendValueToStorage_thingspeak", "parameters": [ { "type": "number", "key": "channelid", "label": "Channel ID" }, { "type": "text", "key": "readkey", "label": "Read API Key" }, { "type": "text", "key": "writekey", "label": "Write API Key" }, { "default": 1, "type": "number", "key": "fieldnum", "label": "Field Number" }, { "default": "//api.thingspeak.com/channels/{0}/charts/{3}?key={1}&width=450&height=260&results=60&dynamic=true", "type": "url", "key": "graphicurl", "label": "Graphic Url" } ] } } #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:0 <0x73db2520> 06 03/14/18 21:40:50.749 Device_Variable::m_szValue_set device: 227 service: urn:upnp-org:serviceId:altui1 variable: VariablesToSend was: now: #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x73db2520> 06

I tried to run the EnergyMonitor.lua in the Test Luup code section and now it pushed to emoncms. All zero’s that is :slight_smile: and thats not correct.

I changed Watts to KWH in my Lua file and now its actually displaying values :slight_smile:

Im sort of there but not…

I dont code so im just trying to decypher what everyone has done on this thread and have no idea what Im doing.

Ive managed to get the lua file into my VE and put

emoncode = require(“EnergyMonitor”)
emoncode.EnergyMonitorOnTimer()

into startup lua

Should I be using the “read API” or the “read & write API” key?

I used the read and write API and eventually Emoncms populated, however it only did it once, and never updated again despite the feed saying updated (in 30+min increments)

And could some kind soul take a look at my lua file and tell me if there are any syntax issues

[code]-- Setup your account at http://emoncms.org/
– See API documentation at Emoncms - input api

module(“EnergyMonitor”, package.seeall)

– API Key
local API_KEY = “e89…d6e8f82”

– Setup your devices here. You can use a function to calculate the power as illustrated in the sample.
– For device logging, use: key, deviceId, serviceId, serviceVar
– For function based logging, use: key, calculate, serviceVar
local VARIABLES = {
{ key=“Test”, deviceId = 37, serviceId=‘urn:micasaverde-com:serviceId:EnergyMetering1’, serviceVar=“Watts” }, – Send device energy
{ key=‘Other1’, calculate=function() return 15 end, serviceVar=“Watts” } – Send a constant value
}

local NODE_ID = 10
local TOTAL_KEY = ‘Total’

– Upload Frequency in seconds
local updateInterval = 10

– Log debug messages
local DEBUG = true

– You shouldn’t need to change anything below this line –

local http = require(‘socket.http’)
http.TIMEOUT = 3

local BASE_URL = “http://emoncms.org/input/post.json?apikey=” … API_KEY
local Log = function (text) luup.log('EnergyMonitor Logger: ’ … (text or “empty”)) end
local lastFullUpload = 0

local items = {} – contains items: { time, deviceId, value }

local function StartCallbackTimer(interval)
luup.call_delay(“EnergyMonitorOnTimer”, interval or updateInterval, nil)
end

local function InitWatch()
StartCallbackTimer(1)
end

local function AddKeyValuePair(key, value)
local item = string.format(“%s:%s”, key, tostring(value))
items[#items + 1] = item
end

local function SerializeData()
local dataText = “{” … table.concat(items, “,”) … “}”
return dataText
end

local function ResetData()
items = {}
end

local function SendData()
local data = SerializeData()
ResetData()

local parameters = "&node=" .. tostring(NODE_ID) .. "&json=" .. data
local url = BASE_URL .. parameters
if (DEBUG) then Log("Updating with: " .. parameters) end
http.request(url)

end

local function AddAllVariablesAndTotal()
local total = 0
for i, v in ipairs(VARIABLES) do
local value
if v.deviceId then
value = luup.variable_get(v.serviceId, v.serviceVar, v.deviceId)
elseif v.calculate then
value = v.calculate()
end
value = tonumber(value) or 0
if v.serviceVar == “Watts” then
total = total + value
end
AddKeyValuePair(v.key, value)
end
AddKeyValuePair(TOTAL_KEY, total)
end

function EnergyMonitorOnTimer()
StartCallbackTimer()
AddAllVariablesAndTotal()
SendData()
end

– Added by RTS
_G.FunctionName = FunctionName

InitWatch()

[/code]

any help would be greatly appreciated

OK,
I posted some other posts here just now in frustration and have subsequently deleted them.

What I will do though is point people in a direction that ABSOLUTELY worked for me.

Follow the instructions in the link ive posted (im not related in any way to this company nor do I know them)

All you have to do is change your devices AND read/write API key, put this in startup.lua

emoncode = require(“EnergyMonitor”)
emoncode.EnergyMonitorOnTimer()

and bingo you have energy monitoring.

Heres the link:
https://www.livehouseautomation.com.au/blogs/news/using-emoncms-to-log-power-use

Thank you to “livehouseautomation.com.au” for this step by step.

I was about to reply in detail to your Lua syntax issue, but I’m glad you don’t need the response, now.

Also pleased to see that you are up and running and have shared your solutions with others here. That’s indeed what the forum is all about.

[quote=“wezzix, post:4, topic:190754”]I found an error in the code and just uploaded a fixed file (deviceId was missing from VARIABLES).

I also made “Total” exclude any variables but Watts. That means that you can easily do arbitrary logging of switches, light level, battery level etc.
I included an example for a switch also:
Set up the feed as in my first post (first feed), that is, use the “Log to feed” processing. You can simply check on your feed by clicking on the “eye”-icon in the feed list. Attached is a sample of how my switch looks really zoomed in (zoom in by click and select in the graph). Not sure if that fits your needs. You can always export the feed data as CSV.

-- Setup your devices here. You can use a function to calculate the power as illustrated in the sample. -- For device logging, use: key, deviceId, serviceId, serviceVar -- For function based logging, use: key, calculate, serviceVar local VARIABLES = { { key="Livingroom", deviceId = 12, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }, -- Send device energy { key="Kitchen", deviceId = 13, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }, { key='KitchenSwitch', deviceId=13, serviceId="urn:upnp-org:serviceId:SwitchPower1", serviceVar="Status"}, -- Send switch status { key='Computer', calculate=function() return (IsComputerPingSensorTripped() and 38 or 1) end, serviceVar="Watts" }, -- Send variable value { key='Other', calculate=function() return 15 end, serviceVar="Watts" } -- Send a constant value }[/quote]

Where is the attachment?

[quote=“wezzix, post:4, topic:190754”]I found an error in the code and just uploaded a fixed file (deviceId was missing from VARIABLES).

I also made “Total” exclude any variables but Watts. That means that you can easily do arbitrary logging of switches, light level, battery level etc.
I included an example for a switch also:
Set up the feed as in my first post (first feed), that is, use the “Log to feed” processing. You can simply check on your feed by clicking on the “eye”-icon in the feed list. Attached is a sample of how my switch looks really zoomed in (zoom in by click and select in the graph). Not sure if that fits your needs. You can always export the feed data as CSV.

-- Setup your devices here. You can use a function to calculate the power as illustrated in the sample. -- For device logging, use: key, deviceId, serviceId, serviceVar -- For function based logging, use: key, calculate, serviceVar local VARIABLES = { { key="Livingroom", deviceId = 12, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }, -- Send device energy { key="Kitchen", deviceId = 13, serviceId='urn:micasaverde-com:serviceId:EnergyMetering1', serviceVar="Watts" }, { key='KitchenSwitch', deviceId=13, serviceId="urn:upnp-org:serviceId:SwitchPower1", serviceVar="Status"}, -- Send switch status { key='Computer', calculate=function() return (IsComputerPingSensorTripped() and 38 or 1) end, serviceVar="Watts" }, -- Send variable value { key='Other', calculate=function() return 15 end, serviceVar="Watts" } -- Send a constant value }[/quote]

Where is the attachment? I’m looking for your fixed lua file. Thanks!

Ah! That’s where that lua code came from.
Added credits here HundredGraphs, visualize and smarten up your IoT data

where can I download the file you attached? EnergyMonitor.lua

Do you have login access to the old forum the file is on there.

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

Here it is EnergyMonitor.zip (1.3 KB)

1 Like