Virtual meter
Smart meters only measure net electricity consumption/production, i.e. Electricity consumption - Electricity production. This script subtracts electricity production from smart meter readings to get electricity consumption. It's triggered each time the smart meter or PV meter update.
Create virtual meter
- Create dummy hardware and device
- If no Dummy Hardware already available, go to Setup -> Hardware. Else go to step 3
- Name: anything, e.g. "Virtual Devices" (this name is only used internally)
- Type: "Dummy (does nothing, use for virtual switches only)"
- Click on 'Add'
- Click on 'Create Virtual Sensors' from the table of hardware above
- Name: anything, e.g. "Power Consumption" (this name is displayed on the dashboard etc.)
- Sensor type: "Electric (Instant+Counter)"
- Click 'Ok'
- If no Dummy Hardware already available, go to Setup -> Hardware. Else go to step 3
- Get name/id of relevant sensors
- Note down the name of your smart meter and solar meter devices (not hardware)
- Note the name and ID of your virtual sensor
- Update and copy the script below
- Update meter / sensor names
- Go to Setup -> More Options -> Events
- Enter name (e.g. PowerConsumption), Select 'Lua' and 'Device'
- Toggle event active, save
- Update utility/dashboard accordingly
Lua script
-- Power consumption device script - SunnyBoy 20180523
--
-- Smart meters only measure net electricity consumption/production, i.e.
-- Electricity consumption - Electricity production. This script subtracts
-- electricity production from smart meter readings to get electricity
-- consumption. It's triggered each time the smart meter or PV meter update.
--
-- 1. Create dummy hardware and device
-- 1.1 Go to Setup -> Hardware
-- Name: anything, e.g. "Ele_Consumption" (this name is only used internally)
-- Type: "Dummy (does nothing, use for virtual switches only)"
-- 1.2 Click on 'Add'
-- 1.3 Click on 'Create Virtual Sensors' from the table of hardware above
-- Name: anything, e.g. "Power Consumption" (this name is displayed on the dashboard etc.)
-- Sensor type: "Electric (Instant+Counter)"
-- 1.4 Click 'Ok'
-- 2. Get name/id of relevant sensors
-- 2.1. Note down the name of your smart meter and solar meter devices (not hardware)
-- 2.2. Note the name and ID of your virtual sensor
-- 3. Update and copy the script below
-- 3.1. Update meter / sensor names
-- 3.2. Go to Setup -> More Options -> Events
-- 3.3. Enter name (e.g. PowerConsumption), Select 'Lua' and 'Device'
-- 3.4. Toggle event active, save
-- 4. Update utility/dashboard accordingly
commandArray = {}
debug = false
-- for debugging, use this file
if (debug) then
file = io.open("/home/pi/lua_test.log", "a") -- append
end
-- Update these lines before use
smartmeter = "Power (net)" -- name of smart meter device
solarmeter = "Solar Power" -- name of solar meter device
dummymeter = "Power Consumption" -- name of virtual sensor
dummymeter_id = 20 -- ID of virtual sensor
dummymeter_trigger = solarmeter -- name of the meter to trigger the dummy meter update. Use the slowest meter here: if your smart meter updates every 10 sec and PV every 100 sec, you get 9 values using potentially outdated PV data. In my case cloudy days gave negative consumption because of this.
-- debug to check what devices are named (but better use 'Show current states' in
-- online editor)
if (debug) then
file:write('other devices states:\n')
for i, v in pairs(otherdevices) do file:write(i, v) end
file:write("\n")
file:write('other devices svalues:\n')
for i, v in pairs(otherdevices_svalues) do file:write(i, v) end
file:write("\n")
end
-- loop through all the changed devices, only update during day if solar meter
-- is triggered, or during the night if smart meter is triggered.
for deviceName,deviceValue in pairs(devicechanged) do
if (debug) then
file:write("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'\n");
end
-- Looks like: Device based event fired on 'Power (net)', value '2058750;1175597;790812;1911744;251;0'
-- Syntax: USAGE1;USAGE2;RETURN1;RETURN2;CONS;PROD https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Electricity_P1_smart_meter
-- Counter: T1: 2058.750, T2: 1175.671
-- Counter Return: R1: 790.812, R2: 1911.744
-- Or: Device based event fired on 'Solar Power', value '0.000;3755165.000'
-- Counter: 3755.165
-- Time of script consumption counter: 2058.750 + 1175.671 + 3755.165 - 790.812 - 1911.744
if (deviceName == solarmeter and timeofday['Daytime']) or (deviceName == smartmeter and timeofday['Nighttime']) then
-- Smart meter: Match six integers separated by semicolum
-- first four are energy meters, last two are power meters?
smart_e1, smart_e2, smart_e3, smart_e4, smart_p1, smart_p2 = otherdevices_svalues[smartmeter]:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")
-- Solar meter power;counter: 0.000;3755165.000
solar_p, solar_e = otherdevices_svalues[solarmeter]:match("([^;]+);([^;]+)")
-- Calculate power consumption and update dummy device. Consumption is
-- always positive, so we add our solar power to the smart meter power
-- if solar generates 1kW, smart meter shows -0.5kW, real consumption is 0.5kW (=solar - return)
-- if solar generates 1kW, smart meter shows 0.5kW, real consumption is 1.5kW (=solar + consumption)
consumption_p = smart_p1 + solar_p - smart_p2
consumption_e = smart_e1 + smart_e2 + solar_e - smart_e3 - smart_e4
-- Populate commandArray with update command
commandArray[1] = {['UpdateDevice'] = dummymeter_id .. "|0|" .. consumption_p .. ";" .. consumption_e}
if (debug) then
file:write("Update device".. dummymeter_id .. "|0|" .. consumption_p .. ";" .. consumption_e .. "\n");
end
end
end
if (debug) then
file:close()
end
return commandArray