-
Notifications
You must be signed in to change notification settings - Fork 0
/
P1_Monitor-20.fqa
1 lines (1 loc) · 48.5 KB
/
P1_Monitor-20.fqa
1
{"name":"P1 Monitor","type":"com.fibaro.powerMeter","apiVersion":"1.2","initialProperties":{"viewLayout":{"$jason":{"body":{"header":{"style":{"height":"0"},"title":"quickApp_device_1553"},"sections":{"items":[{"components":[{"name":"label","style":{"weight":"1.2"},"text":"Label","type":"label","visible":true},{"style":{"weight":"0.5"},"type":"space"}],"style":{"weight":"1.2"},"type":"vertical"}]}},"head":{"title":"quickApp_device_1553"}}},"uiCallbacks":[],"quickAppVariables":[{"name":"IPaddress","type":"string","value":"192.168.1.120"},{"name":"waterMeter","type":"string","value":"false"},{"name":"language","type":"string","value":"en"},{"name":"interval","type":"string","value":"3"},{"name":"debugLevel","type":"string","value":"1"}],"typeTemplateInitialized":true},"files":[{"name":"main","isMain":true,"isOpen":false,"content":"-- Quickapp P1 Monitor main\n\n\nlocal function getChildVariable(child,varName)\n for _,v in ipairs(child.properties.quickAppVariables or {}) do\n if v.name==varName then return v.value end\n end\n return \"\"\nend\n\n\nfunction QuickApp:updateChildDevices()\n for id,child in pairs(self.childDevices) do -- Update Child Devices\n child:updateValue(data) \n end\nend\n\n\nfunction QuickApp:logging(level,text) -- Logging function for debug\n if tonumber(debugLevel) >= tonumber(level) then \n self:debug(text)\n end\nend\n\n\nfunction QuickApp:unitCheckWatt(measurement) -- Set the measurement and unit to Watt, Kilowatt, Megawatt or Gigawatt\n self:logging(3,\"unitCheckWatt() - Set the measurement and unit to Watt, Kilowatt, Megawatt or Gigawatt\")\n if measurement > 1000000000 then\n return string.format(\"%.2f\",measurement/1000000000),\"GW\"\n elseif measurement > 1000000 then\n return string.format(\"%.2f\",measurement/1000000),\"MW\"\n elseif measurement > 1000 then\n return string.format(\"%.2f\",measurement/1000),\"kW\"\n else\n return string.format(\"%.0f\",measurement),\"W\"\n end\nend\n\n\nfunction QuickApp:updateProperties() -- Update the properties\n self:logging(3,\"updateProperties() - Update the properties\")\n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.net_consumption)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.net_consumption)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", data.timestamp_local)\nend\n\n\nfunction QuickApp:updateLabels() -- Update the labels\n self:logging(3,\"updateLabels() - Update the labels\")\n local labelText = \"\"\n labelText = labelText ..translation[\"Consumption\"] ..\": \" ..data.consumption ..\" \" ..translation[\"Watt\"] ..\" (\" ..translation[\"Max\"] ..\" \" ..data.max_consumption ..\" \" ..data.max_consumption_unit ..\" \" ..translation[\"at\"] ..\" \" ..data.max_consumption_time ..\")\" ..\"\\n\" \n labelText = labelText ..translation[\"Production\"] ..\": \" ..data.production ..\" \" ..translation[\"Watt\"] ..\" (\" ..translation[\"Max\"] ..\" \" ..data.max_production ..\" \" ..data.max_production_unit ..\" \" ..translation[\"at\"] ..\" \" ..data.max_production_time ..\")\" ..\"\\n\"\n labelText = labelText ..translation[\"Waterflow\"] ..\": \" ..data.waterflow ..\" \" ..translation[\"L/min\"] ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Todays consumption\"] ..\": \" ..data.todays_consumption ..\" \" ..translation[\"kWh\"] ..\"\\n\"\n labelText = labelText ..translation[\"Todays production\"] ..\": \" ..data.todays_production ..\" \" ..translation[\"kWh\"] ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Totals\"] ..\": \" ..\"\\n\" \n labelText = labelText ..translation[\"Consumption high\"] ..\": \" ..data.consumption_high ..\" \" ..translation[\"kWh\"] ..\" (\" ..translation[\"Today\"] ..\" \" ..data.today_consumption_high ..\" \" ..translation[\"kWh\"] ..\")\" ..\"\\n\" \n labelText = labelText ..translation[\"Consumption low\"] ..\": \" ..data.consumption_low ..\" \" ..translation[\"kWh\"] ..\" (\" ..translation[\"Today\"] ..\" \" ..data.today_consumption_low ..\" \" ..translation[\"kWh\"] ..\")\" ..\"\\n\"\n labelText = labelText ..translation[\"Consumption\"] ..\": \" ..data.total_consumption ..\" \" ..translation[\"kWh\"] ..\"\\n\" \n labelText = labelText ..translation[\"Production high\"] ..\": \" ..data.production_high ..\" \" ..translation[\"kWh\"] ..\" (\" ..translation[\"Today\"] ..\" \" ..data.today_production_high ..\" \" ..translation[\"kWh\"] ..\")\" ..\"\\n\" \n labelText = labelText ..translation[\"Production low\"] ..\": \" ..data.production_low ..\" \" ..translation[\"kWh\"] ..\" (\" ..translation[\"Today\"] ..\" \" ..data.today_production_low ..\" \" ..translation[\"kWh\"] ..\")\" ..\"\\n\"\n labelText = labelText ..translation[\"Production\"] ..\": \" ..data.total_production ..\" \" ..translation[\"kWh\"] ..\"\\n\"\n labelText = labelText ..translation[\"Gas\"] ..\": \" ..data.gas ..\" m³ (\" ..translation[\"Today\"] ..\": \" ..data.today_gas ..\" m³\" ..\" / \" ..translation[\"Lasthour\"] ..\": \" ..data.lasthour_gas ..\" L)\" ..\"\\n\"\n labelText = labelText ..translation[\"Water\"] ..\": \" ..data.water ..\" m³\" ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Consumption\"] ..\":\" ..\"\\n\"\n labelText = labelText ..translation[\"L1\"] ..\": \" ..data.consumption_L1 ..\" - \" ..translation[\"L2\"] ..\": \" ..data.consumption_L2 ..\" - \" ..translation[\"L3\"] ..\": \" ..data.consumption_L3 ..\" \" ..translation[\"Watt\"] ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Production\"] ..\"\\n\"\n labelText = labelText ..translation[\"L1\"] ..\": \" ..data.production_L1 ..\" - \" ..translation[\"L2\"] ..\": \" ..data.production_L2 ..\" - \" ..translation[\"L3\"] ..\": \" ..data.production_L3 ..\" \" ..\"Watt\" ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Ampere\"] ..\":\" ..\"\\n\"\n labelText = labelText ..translation[\"L1\"] ..\": \" ..data.L1_A ..\" - \" ..translation[\"L2\"] ..\": \" ..data.L2_A ..\" - \" ..translation[\"L3\"] ..\": \" ..data.L3_A ..\" \" ..translation[\"Amp\"] ..\"\\n\\n\"\n \n labelText = labelText ..translation[\"Voltage\"] ..\":\" ..\"\\n\"\n labelText = labelText ..translation[\"L1\"] ..\": \" ..data.L1_V ..\" - \" ..translation[\"L2\"] ..\": \" ..data.L2_V ..\" - \" ..translation[\"L3\"] ..\": \" ..data.L3_V ..\" \" ..translation[\"Volt\"] ..\"\\n\\n\"\n\n labelText = labelText ..translation[\"Updated\"] ..\": \" ..data.timestamp_local ..\"\\n\"\n\n self:updateView(\"label\", \"text\", labelText)\n self:logging(2,labelText)\nend\n\n\nfunction QuickApp:valuesWatermeter(jsonTable) -- Get the values from json file Watermeter\n self:logging(3,\"valuesWatermeter() - Get the values from json file Watermeter\")\n data.waterflow = string.format(\"%.1f\",jsonTable[2].WATERMETER_CONSUMPTION_LITER) -- Use the seconds measurement, to get a stable value (not counting from 1 to n up to one minute)\n local waterflow_check = tonumber(jsonTable[1].WATERMETER_CONSUMPTION_LITER) \n data.water = string.format(\"%.3f\",jsonTable[1].WATERMETER_CONSUMPTION_TOTAL_M3)\n data.waterflow_timestamp = tonumber(jsonTable[1].TIMESTAMP_UTC)\n if waterflow_check > tonumber(data.waterflow) or waterflow_check == 0 then -- Check if current waterflow is higer than one minute ago or is zero\n data.waterflow = string.format(\"%.1f\",waterflow_check)\n end\n if os.time()-data.waterflow_timestamp > 70 and tonumber(data.waterflow) > 0 then -- If measurement (>0) is older than 70 seconds then change measurement to zero\n data.waterflow = \"0.0\"\n end\nend\n\n\nfunction QuickApp:valuesStatus(jsonTable) -- Get the values from json file Status\n self:logging(3,\"valuesStatus() - Get the values from json file Status\")\n data.consumption_L1 = string.format(\"%.1f\",tonumber(jsonTable[74].STATUS)*1000)\n data.consumption_L2 = string.format(\"%.1f\",tonumber(jsonTable[75].STATUS)*1000)\n data.consumption_L3 = string.format(\"%.1f\",tonumber(jsonTable[76].STATUS)*1000)\n data.production_L1 = string.format(\"%.1f\",tonumber(jsonTable[77].STATUS)*1000)\n data.production_L2 = string.format(\"%.1f\",tonumber(jsonTable[78].STATUS)*1000)\n data.production_L3 = string.format(\"%.1f\",tonumber(jsonTable[79].STATUS)*1000)\n data.L1_A = string.format(\"%.1f\",jsonTable[100].STATUS)\n data.L2_A = string.format(\"%.1f\",jsonTable[101].STATUS)\n data.L3_A = string.format(\"%.1f\",jsonTable[102].STATUS)\n data.L1_V = string.format(\"%.1f\",jsonTable[103].STATUS)\n data.L2_V = string.format(\"%.1f\",jsonTable[104].STATUS)\n data.L3_V = string.format(\"%.1f\",jsonTable[105].STATUS) \n data.max_consumption = string.format(\"%.0f\",tonumber(jsonTable[1].STATUS)*1000)\n data.max_production = string.format(\"%.0f\",tonumber(jsonTable[3].STATUS)*1000)\n data.max_consumption, data.max_consumption_unit = self:unitCheckWatt(tonumber(data.max_consumption)) -- Set measurement and unit to W, kW, MW or GW\n data.max_production, data.max_production_unit = self:unitCheckWatt(tonumber(data.max_production)) -- Set measurement and unit to W, kW, MW or GW\n data.max_consumption_time = jsonTable[2].STATUS\n data.max_production_time = jsonTable[4].STATUS\n data.today_consumption_low = string.format(\"%.3f\",jsonTable[8].STATUS)\n data.today_consumption_high = string.format(\"%.3f\",jsonTable[9].STATUS)\n data.today_production_low = string.format(\"%.3f\",jsonTable[10].STATUS)\n data.today_production_high = string.format(\"%.3f\",jsonTable[11].STATUS)\n data.todays_consumption = string.format(\"%.3f\",tonumber(data.today_consumption_low) + tonumber(data.today_consumption_high))\n data.todays_production = string.format(\"%.3f\",tonumber(data.today_production_low) + tonumber(data.today_production_high))\n data.today_gas = string.format(\"%.3f\",jsonTable[44].STATUS)\n data.lasthour_gas = string.format(\"%.0f\",tonumber(jsonTable[50].STATUS)*1000)\n\n local pattern = \"(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)\" -- Convert data.max_consumption_time and data.max_production_time to nice format\n local runyear, runmonth, runday, runhour, runminute, runseconds = data.max_consumption_time:match(pattern)\n local convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})\n data.max_consumption_time = os.date(\"%H:%M\", convertedTimestamp)\n runyear, runmonth, runday, runhour, runminute, runseconds = data.max_production_time:match(pattern)\n convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})\n data.max_production_time = os.date(\"%H:%M\", convertedTimestamp)\nend\n\n\nfunction QuickApp:valuesSmartmeter(jsonTable) -- Get the values from json file Smartmeter\n self:logging(3,\"valuesSmartmeter() - Get the values from json file Smartmeter\")\n data.consumption = string.format(\"%.1f\",jsonTable[1].CONSUMPTION_W)\n data.consumption_high = string.format(\"%.3f\",jsonTable[1].CONSUMPTION_KWH_HIGH)\n data.consumption_low = string.format(\"%.3f\",jsonTable[1].CONSUMPTION_KWH_LOW)\n data.production = string.format(\"%.1f\",jsonTable[1].PRODUCTION_W)\n data.production_high = string.format(\"%.3f\",jsonTable[1].PRODUCTION_KWH_HIGH)\n data.production_low = string.format(\"%.3f\",jsonTable[1].PRODUCTION_KWH_LOW)\n data.gas = string.format(\"%.3f\",jsonTable[1].CONSUMPTION_GAS_M3) \n data.net_consumption = string.format(\"%.1f\",jsonTable[1].CONSUMPTION_W - jsonTable[1].PRODUCTION_W)\n data.total_consumption = string.format(\"%.3f\",(jsonTable[1].CONSUMPTION_KWH_HIGH + jsonTable[1].CONSUMPTION_KWH_LOW))\n data.total_production = string.format(\"%.3f\",(jsonTable[1].PRODUCTION_KWH_HIGH + jsonTable[1].PRODUCTION_KWH_LOW))\n data.tarifcode = jsonTable[1].TARIFCODE\n data.timestamp_local = jsonTable[1].TIMESTAMP_lOCAL\n \n local pattern = \"(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)\" -- Convert timestamp_local to nice format\n local runyear, runmonth, runday, runhour, runminute, runseconds = data.timestamp_local:match(pattern)\n local convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})\n data.timestamp_local = os.date(\"%d-%m-%Y %H:%M:%S\", convertedTimestamp)\n\n if data.tarifcode == \"P\" then\n data.tarifcodeText = \"(\" ..translation[\"High\"] ..\")\"\n elseif data.tarifcode == \"D\" then\n data.tarifcodeText = \"(\" ..translation[\"Low\"] ..\")\"\n else\n data.tarifcodeText = \"\"\n end\n\nend\n\n\nfunction QuickApp:getData() -- Get data from P1 Monitor \n self:logging(3,\"getData() - Get data from P1 Monitor \")\n local url = \"http://\" ..IPaddress ..path\n self:logging(3,\"url: \" ..url)\n self.http:request(url, {\n options = {\n headers = {Accept = \"application/json\"}, method = 'GET'},\n success = function(response)\n self:logging(3,\"Response status: \" ..response.status)\n self:logging(3,\"Response data: \" ..response.data)\n local jsonTable = json.decode(response.data) -- Decode the json string from api to lua-table\n\n self:logging(3,\"Mode prev: \" ..mode)\n if mode == \"Smartmeter\" then\n self:valuesSmartmeter(jsonTable) -- Get the values from json file Smartmeter\n path = pathStatus -- Next path\n mode = \"Status\" -- Next mode\n elseif mode == \"Status\" then \n self:valuesStatus(jsonTable) -- Get the values from json file Status\n if waterMeter then\n path = pathWatermeter -- Next path\n mode = \"Watermeter\" -- Next mode\n else\n path = pathSmartmeter -- Next path\n mode = \"Smartmeter\" -- Next mode \n end\n elseif mode == \"Watermeter\" then\n self:valuesWatermeter(jsonTable) -- Get the values from json file Watermeter\n path = pathSmartmeter -- Next path\n mode = \"Smartmeter\" -- Next mode \n end\n self:logging(3,\"Mode next: \" ..mode)\n\n self:updateLabels() -- Update the labels\n self:updateProperties() -- Update the properties\n self:updateChildDevices() -- Update the Child Devices\n\n end,\n error = function(error)\n self:error(\"error: \" ..json.encode(error))\n self:updateProperty(\"log\", \"error: \" ..json.encode(error))\n end\n }) \n fibaro.setTimeout(interval, function() self:getData() end) -- Checks every [interval] seconds for new data (three loops: Smartmeter, Status and Watermeter)\nend \n\n\nfunction QuickApp:createVariables() -- Setup the global variables\n self:logging(2,\"createVariables() - Setup the global variables\")\n pathSmartmeter = \"/api/v1/smartmeter?limit=1&json=object\" -- Default path Smartmeter\n pathStatus = \"/api/v1/status?json=object\" -- Default path Status\n pathWatermeter = \"/api/v2/watermeter/minute?limit=2&sort=des&json=object\" -- Default path Watermeter\n path = pathSmartmeter -- Set initial value for path\n mode = \"Smartmeter\" -- Set initial value for mode\n translation = i18n:translation(string.lower(self:getVariable(\"language\"))) -- Initialise the translation\n\n data = {}\n data.consumption = \"0\"\n data.production = \"0\"\n data.total_consumption = \"\"\n data.total_production = \"\"\n data.tarifcode = \"\"\n data.tarifcodeText = \"\"\n data.consumption_L1 = \"0\" \n data.consumption_L2 = \"0\" \n data.consumption_L3 = \"0\" \n data.production_L1 = \"0\" \n data.production_L2 = \"0\" \n data.production_L3 = \"0\" \n data.consumption_high = \"0\"\n data.consumption_low = \"0\"\n data.production_high = \"0\"\n data.production_low = \"0\"\n data.L1_A = \"0\" \n data.L2_A = \"0\" \n data.L3_A = \"0\" \n data.L1_V = \"0\" \n data.L2_V = \"0\" \n data.L3_V = \"0\" \n data.waterflow = \"0\"\n data.waterflow_timestamp = 0\n data.water = \"0\"\n data.gas = \"0\"\n data.timestamp_local = \"\"\n data.max_consumption = \"0\"\n data.max_production = \"0\"\n data.max_consumption_unit =\"W\" \n data.max_production_unit = \"W\" \n data.max_consumption_time = \"\"\n data.max_production_time = \"\"\n data.todays_consumption = \"0\"\n data.todays_production = \"0\"\n data.today_consumption_low = \"0\"\n data.today_consumption_high = \"0\"\n data.today_production_low = \"0\"\n data.today_production_high = \"0\"\n data.today_gas = \"0\"\n data.lasthour_gas = \"0\"\nend\n\n\nfunction QuickApp:getQuickappVariables() -- Get all Quickapp Variables or create them\n IPaddress = self:getVariable(\"IPaddress\")\n waterMeter = string.lower(self:getVariable(\"waterMeter\"))\n local language = string.lower(self:getVariable(\"language\"))\n interval = tonumber(self:getVariable(\"interval\")) \n debugLevel = tonumber(self:getVariable(\"debugLevel\"))\n\n -- Check existence of the mandatory variables, if not, create them with default values \n if IPaddress == \"\" or IPaddress == nil then \n IPaddress = \"192.168.1.120\" -- Default IPaddress \n self:setVariable(\"IPaddress\", IPaddress)\n self:trace(\"Added QuickApp variable IPaddress\")\n end\n if waterMeter == \"\" or waterMeter == nil then \n waterMeter = \"false\" -- Default availability of waterMeter is \"false\"\n self:setVariable(\"waterMeter\",waterMeter)\n self:trace(\"Added QuickApp variable waterMeter\")\n end \n if language == \"\" or language == nil or (language ~= \"en\" and language ~= \"nl\" and language ~= \"fr\" and language ~= \"pl\") then\n language = \"en\" \n self:setVariable(\"language\",language)\n self:trace(\"Added QuickApp variable language\")\n end\n if interval == \"\" or interval == nil then\n interval = \"10\" -- Default interval in seconds (The P1 meter normally reads every 10 seconds)\n self:setVariable(\"interval\", interval)\n self:trace(\"Added QuickApp variable interval\")\n interval = tonumber(interval)\n end\n if debugLevel == \"\" or debugLevel == nil then\n debugLevel = \"1\" -- Default value for debugLevel response in seconds\n self:setVariable(\"debugLevel\",debugLevel)\n self:trace(\"Added QuickApp variable debugLevel\")\n debugLevel = tonumber(debugLevel)\n end\n if waterMeter == \"true\" then \n waterMeter = true \n else\n waterMeter = false\n end\n if waterMeter then\n interval = tonumber(string.format(\"%.0f\",(interval*1000/3)))\n else\n interval = tonumber(string.format(\"%.0f\",(interval*1000/2)))\n self:warning(\"No waterMeter to measure waterflow\")\n end\n self:logging(3,\"interval: \" ..interval)\nend\n\n\nfunction QuickApp:setupChildDevices() -- Setup Child Devices\n local cdevs = api.get(\"/devices?parentId=\"..self.id) or {} -- Pick up all Child Devices\n function self:initChildDevices() end -- Null function, else Fibaro calls it after onInit()...\n\n if #cdevs == 0 then -- If no Child Devices, create them\n local initChildData = { \n {className=\"consumption\", name=\"Consumption\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"production\", name=\"Production\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"todays_consumption\", name=\"Todays Consumption\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"todays_production\", name=\"Todays Production\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"waterflow\", name=\"Water Flow\", type=\"com.fibaro.waterMeter\", value=0},\n {className=\"consumption_high\", name=\"Consumption High\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"consumption_low\", name=\"Consumption Low\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"production_high\", name=\"Production High\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"production_low\", name=\"Production Low\", type=\"com.fibaro.energyMeter\", value=0},\n {className=\"consumption_L1\", name=\"Consumption L1\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"consumption_L2\", name=\"Consumption L2\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"consumption_L3\", name=\"Consumption L3\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"production_L1\", name=\"Production L1\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"production_L2\", name=\"Production L2\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"production_L3\", name=\"Production L3\", type=\"com.fibaro.powerMeter\", value=0},\n {className=\"L1_A\", name=\"Ampere L1\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"L2_A\", name=\"Ampere L2\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"L3_A\", name=\"Ampere L3\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"L1_V\", name=\"Voltage L1\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"L2_V\", name=\"Voltage L2\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"L3_V\", name=\"Voltage L3\", type=\"com.fibaro.electricMeter\", value=0},\n {className=\"water\", name=\"Water\", type=\"com.fibaro.waterMeter\", value=0},\n {className=\"gas\", name=\"Total Gas\", type=\"com.fibaro.gasMeter\", value=0},\n }\n for _,c in ipairs(initChildData) do\n local child = self:createChildDevice(\n {name = c.name,\n type=c.type,\n value=c.value,\n unit=c.unit,\n initialInterfaces = {},\n },\n _G[c.className] -- Fetch class constructor from class name\n )\n child:setVariable(\"className\",c.className) -- Save class name so we know when we load it next time\n end \n else \n for _,child in ipairs(cdevs) do\n local className = getChildVariable(child,\"className\") -- Fetch child class name\n local childObject = _G[className](child) -- Create child object from the constructor name\n self.childDevices[child.id]=childObject\n childObject.parent = self -- Setup parent link to device controller \n end\n end\nend\n\n\nfunction QuickApp:onInit()\n __TAG = fibaro.getName(plugin.mainDeviceId) ..\" ID:\" ..plugin.mainDeviceId\n self.http = net.HTTPClient({timeout=3000})\n self:debug(\"onInit\")\n self:setupChildDevices() -- Setup the Child Devices\n \n if not api.get(\"/devices/\"..self.id).enabled then\n self:warning(\"Device\", fibaro.getName(plugin.mainDeviceId), \"is disabled\")\n return\n end\n \n self:getQuickappVariables() -- Get Quickapp Variables or create them\n self:createVariables() -- Create Variables\n self:getData() -- Go to getData\nend\n\n-- EOF "},{"name":"i18n","isMain":false,"isOpen":false,"content":"-- Quickapp P1 Monitor i18n translation\n\n\nclass \"i18n\"\nfunction i18n:translation(language)\n translation = {\n en = {\n [\"Consumption\"] = \"Consumption\", \n [\"Production\"] = \"Production\", \n [\"Waterflow\"] = \"Waterflow\", \n [\"Todays consumption\"] = \"Todays consumption\", \n [\"Todays production\"] = \"Todays production\", \n [\"Totals\"] = \"Totals\", \n [\"Consumption high\"] = \"Consumption high\", \n [\"Consumption low\"] = \"Consumption low\", \n [\"Production high\"] = \"Production high\", \n [\"Production low\"] = \"Producton low\", \n [\"Gas\"] = \"Gas\", \n [\"Water\"] = \"Water\", \n [\"L1\"] = \"L1\", \n [\"L2\"] = \"L2\", \n [\"L3\"] = \"L3\", \n [\"Ampere\"] = \"Ampere\", \n [\"Voltage\"] = \"Voltage\", \n [\"Amp\"] = \"Amp\", \n [\"Volt\"] = \"Volt\", \n [\"Watt\"] = \"Watt\", \n [\"kWh\"] = \"kWh\", \n [\"Today\"] = \"Today\", \n [\"Max\"] = \"Max\", \n [\"at\"] = \"at\", \n [\"L/min\"] = \"L/min\", \n [\"High\"] = \"High\", \n [\"Low\"] = \"Low\", \n [\"Lasthour\"] = \"Lasthour\", \n [\"Updated\"] = \"Updated\"},\n nl = {\n [\"Consumption\"] = \"Consumptie\", \n [\"Production\"] = \"Productie\", \n [\"Waterflow\"] = \"Waterstroom\", \n [\"Todays consumption\"] = \"Consumptie vandaag\", \n [\"Todays production\"] = \"Productie vandaag\", \n [\"Totals\"] = \"Totalen\", \n [\"Consumption high\"] = \"Consumptie hoog\", \n [\"Consumption low\"] = \"Consumptie laag\", \n [\"Production high\"] = \"Productie hoog\", \n [\"Production low\"] = \"Productie laag\", \n [\"Gas\"] = \"Gas\", \n [\"Water\"] = \"Water\", \n [\"L1\"] = \"L1\", \n [\"L2\"] = \"L2\", \n [\"L3\"] = \"L3\", \n [\"Ampere\"] = \"Ampere\", \n [\"Voltage\"] = \"Voltage\", \n [\"Amp\"] = \"Amp\", \n [\"Volt\"] = \"Volt\", \n [\"Watt\"] = \"Watt\", \n [\"kWh\"] = \"kWh\", \n [\"Today\"] = \"Vandaag\", \n [\"Max\"] = \"Max\", \n [\"at\"] = \"op\", \n [\"L/min\"] = \"L/min\", \n [\"High\"] = \"Hoog\", \n [\"Low\"] = \"Laag\", \n [\"Lasthour\"] = \"Afgelopen uur\", \n [\"Updated\"] = \"Bijgewerkt\"},\n fr = {\n [\"Consumption\"] = \"Consommation\", \n [\"Production\"] = \"Production\", \n [\"Waterflow\"] = \"L'écoulement de l'eau\", \n [\"Todays consumption\"] = \"Consommation d'aujourd'hui\", \n [\"Todays production\"] = \"La production d'aujourd'hui\", \n [\"Totals\"] = \"Totaux\", \n [\"Consumption high\"] = \"Consommation élevée\", \n [\"Consumption low\"] = \"Consommation faible\", \n [\"Production high\"] = \"Production élevée\", \n [\"Production low\"] = \"Production faible\", \n [\"Gas\"] = \"Gaz\", \n [\"Water\"] = \"L'eau\", \n [\"L1\"] = \"L1\", \n [\"L2\"] = \"L2\", \n [\"L3\"] = \"L3\", \n [\"Ampere\"] = \"Ampère\", \n [\"Voltage\"] = \"Voltage\", \n [\"Amp\"] = \"Amp\", \n [\"Volt\"] = \"Volt\", \n [\"Watt\"] = \"Watt\", \n [\"kWh\"] = \"kWh\", \n [\"Today\"] = \"Aujourd'hui\", \n [\"Max\"] = \"Max\", \n [\"at\"] = \"à\", \n [\"L/min\"] = \"L/min\", \n [\"High\"] = \"Élevé\", \n [\"Low\"] = \"Faible\", \n [\"Lasthour\"] = \"Dernière heure\", \n [\"Updated\"] = \"Actualisé\"},\n pl = {\n [\"Consumption\"] = \"Konsumpcja\", \n [\"Production\"] = \"Produkcja\", \n [\"Waterflow\"] = \"Przepływ wody\", \n [\"Todays consumption\"] = \"Dzisiejsza konsumpcja\", \n [\"Todays production\"] = \"Dzisiejsza produkcja\", \n [\"Totals\"] = \"Sumy\", \n [\"Consumption high\"] = \"Konsumpcja wysoka\", \n [\"Consumption low\"] = \"Niskie zużycie\", \n [\"Production high\"] = \"Produkcja wysoka\", \n [\"Production low\"] = \"Produkcja niska\", \n [\"Gas\"] = \"Gaz\", \n [\"Water\"] = \"Woda\", \n [\"L1\"] = \"L1\", \n [\"L2\"] = \"L2\", \n [\"L3\"] = \"L3\", \n [\"Ampere\"] = \"Amper\", \n [\"Voltage\"] = \"Woltaż\", \n [\"Amp\"] = \"Amp\", \n [\"Volt\"] = \"Woltaż\", \n [\"Watt\"] = \"Watt\", \n [\"kWh\"] = \"kWh\", \n [\"Today\"] = \"Dziś\", \n [\"Max\"] = \"Max\", \n [\"at\"] = \"w\", \n [\"L/min\"] = \"L/min\", \n [\"High\"] = \"Wysoki\", \n [\"Low\"] = \"Niski\", \n [\"Lasthour\"] = \"Ostatnia godzina\", \n [\"Updated\"] = \"Zaktualizowano\"},\n } \n translation = translation[language] -- Shorten the table to only the current translation\n return translation\nend\n\n-- EOF"},{"name":"childs","isMain":false,"isOpen":false,"content":"-- Quickapp P1 Monitor childs\n\n\nclass 'consumption'(QuickAppChild)\nfunction consumption:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.consumption)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", translation[\"Max\"] ..\" \" ..data.max_consumption ..\" \" ..data.max_consumption_unit ..\" \" ..data.max_consumption_time)\nend\n\n\nclass 'production'(QuickAppChild)\nfunction production:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Todays Production child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.production)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", translation[\"Max\"] ..\" \" ..data.max_production ..\" \" ..data.max_production_unit ..\" \" ..data.max_production_time)\nend\n\n\nclass 'todays_consumption'(QuickAppChild)\nfunction todays_consumption:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction todays_consumption:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.todays_consumption)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'todays_production'(QuickAppChild)\nfunction todays_production:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Todays Production child device (\" ..self.id ..\") to production\")\n end\nend\nfunction todays_production:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.todays_production)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'waterflow'(QuickAppChild)\nfunction waterflow:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction waterflow:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.waterflow)))\n self:updateProperty(\"unit\", translation[\"L/min\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'consumption_L1'(QuickAppChild)\nfunction consumption_L1:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption_L1:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption_L1)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.consumption_L1)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'consumption_L2'(QuickAppChild)\nfunction consumption_L2:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption_L2:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption_L2)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.consumption_L2)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'consumption_L3'(QuickAppChild)\nfunction consumption_L3:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption_L3:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption_L3)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.consumption_L3)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L1'(QuickAppChild)\nfunction production_L1:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Todays Production child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production_L1:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production_L1)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.production_L1)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L2'(QuickAppChild)\nfunction production_L2:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Todays Production child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production_L2:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production_L2)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.production_L2)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L3'(QuickAppChild)\nfunction production_L3:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Todays Production child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production_L3:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production_L3)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.production_L3)))\n self:updateProperty(\"unit\", translation[\"Watt\"])\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'L1_A'(QuickAppChild)\nfunction L1_A:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L1_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L1_A)))\n self:updateProperty(\"unit\", translation[\"Amp\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L2_A'(QuickAppChild)\nfunction L2_A:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L2_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L2_A)))\n self:updateProperty(\"unit\", translation[\"Amp\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L3_A'(QuickAppChild)\nfunction L3_A:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L3_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L3_A)))\n self:updateProperty(\"unit\", translation[\"Amp\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L1_V'(QuickAppChild)\nfunction L1_V:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L1_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L1_V)))\n self:updateProperty(\"unit\", translation[\"Volt\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L2_V'(QuickAppChild)\nfunction L2_V:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L2_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L2_V)))\n self:updateProperty(\"unit\", translation[\"Volt\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L3_V'(QuickAppChild)\nfunction L3_V:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Todays Consumption child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction L3_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L3_V)))\n self:updateProperty(\"unit\", translation[\"Volt\"])\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'consumption_high'(QuickAppChild)\nfunction consumption_high:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Consumption High child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption_high:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption_high)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", translation[\"Today\"] ..\" \" ..data.today_consumption_high ..\" \" ..translation[\"kWh\"])\nend\n\n\nclass 'consumption_low'(QuickAppChild)\nfunction consumption_low:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"consumption\" then \n self:updateProperty(\"rateType\", \"consumption\")\n self:warning(\"Changed rateType interface of Consumption Low child device (\" ..self.id ..\") to consumption\")\n end\nend\nfunction consumption_low:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.consumption_low)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", translation[\"Today\"] ..\" \" ..data.today_consumption_low ..\" \" ..translation[\"kWh\"])\nend\n\n\nclass 'production_high'(QuickAppChild)\nfunction production_high:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Production High child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production_high:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production_high)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", translation[\"Today\"] ..\" \" ..data.today_production_high ..\" \" ..translation[\"kWh\"])\nend\n\n\nclass 'production_low'(QuickAppChild)\nfunction production_low:__init(dev)\n QuickAppChild.__init(self,dev)\n if fibaro.getValue(self.id, \"rateType\") ~= \"production\" then \n self:updateProperty(\"rateType\", \"production\")\n self:warning(\"Changed rateType interface of Production Low child device (\" ..self.id ..\") to production\")\n end\nend\nfunction production_low:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.production_low)))\n self:updateProperty(\"unit\", translation[\"kWh\"])\n self:updateProperty(\"log\", translation[\"Today\"] ..\" \" ..data.today_production_low ..\" \" ..translation[\"kWh\"])\nend\n\n\nclass 'water'(QuickAppChild)\nfunction water:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction water:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.water)))\n self:updateProperty(\"unit\", \"m³\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'gas'(QuickAppChild)\nfunction gas:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction gas:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.gas)))\n self:updateProperty(\"unit\", \"m³\")\n self:updateProperty(\"log\", translation[\"Today\"] ..\" \" ..data.today_gas ..\" m³\")\nend\n\n-- EOF"},{"name":"readme","isMain":false,"isOpen":false,"content":"--[[ Quickapp P1 Monitor readme\n\nThis Quickapp retrieves energy consumption, energy production, gas and water usage from the (P1 Monitor) energy, gas and water meter. \nThis Quickapp uses the software of ztatz.com to get the values from your smart energymeter. \nThe ztatz plug-and-play software can run on a Raspberry Pi or in a Docker container. \n\nThe Energy consumption and energy production are added to the HC3 energy panel. \nUse the child devices Todays Consumption and Todays Production to store energy data (kWh) in the Energy Panel. \nAnd use the child devices Consumption and Production for instantaneous power (Watt) in the Energy Panel calculations. \n\nChild Devices for: \n- Consumption (Watt) (input for instantaneous power in Energy Panel calculations)\n- Production (Watt) (input for instantaneous power in Energy Panel calculations)\n- Todays Consumption (kWh) (input for energy panel)\n- Todays Production (kWh) (input for energy panel)\n- Waterflow (Liter)\n- Consumption High (kWh)\n- Consumption Low (kWh)\n- Production High (kWh)\n- Production Low (kWh)\n- Consumption L1 (Watt)\n- Consumption L2 (Watt)\n- Consumption L3 (Watt)\n- Production L1 (Watt)\n- Production L2 (Watt)\n- Production L3 (Watt)\n- Ampere L1 (Amp)\n- Ampere L2 (Amp)\n- Ampere L3 (Amp)\n- Voltage L1 (Volt)\n- Voltage L2 (Volt)\n- Voltage L3 (Volt)\n- Total Gas (m³)\n- Total Waterflow (m³)\n\nInterval: \nIt is possible to process messages from the smart meter every second. Of course, this is only possible if the smart meter actually sends a message every second. This can be turned on via the ztatz software P1 port configuration page via the \"maximum processing speed\" option. Note that this gives a higher load on the Rpi (or Docker). It has been tested on the Rpi3/Rpi4 and works well on it. Older or other RPIs have not been tested.\n\nThe P1 Monitor QuickApp uses 2 API calls each cycle, and if you also use Waterflow, 3 API calls each cycle. With an interval setting of 10 seconds there is an API call every 5 seconds (and with Waterflow enabled, every 3.33 seconds). So the fastest interval setting will probably be 3 seconds with Waterflow and 2 seconds without Waterflow. \n\nZtatz software: \nhttps://www.ztatz.nl\nDocker container based on the ztatz.nl software: The container version has the same functionality as the full version for the Raspberry Pi. Docker container: https://hub.docker.com/r/mclaassen/p1mon\n\n\nVersion 2.0 (8th January 2023)\n- Changed child device types for optimal support of the Energy Panel: \n - kWh -> com.fibaro.energyMeter\n - ampere/voltage -> com.fibaro.electricMeter\n - Watt -> com.fibaro.powerMeter\n - gas -> com.fibaro.gasMeter\n - water -> com.fibaro.waterMeter\n- Removed Power device calculation\n- Removed child devices for gross consumption and device consumption\n- Changed code to multi file\n- Added for translations for English, French, Polish and Dutch\n\n\nVersion 1.6 (8th January 2022)\n- Changed the waterflow algoritme to show more stable and more acurate measurements\n- Small change in the code for checking existance of waterflow sensor\n- Changed the Waterflow unit from Liter to L/min\n- Added experimental net consumption to power \n- Added Lasthour gas to labels\n- Changed the API request for status to json output\n\nVersion 1.5 (4th September 2021)\n- Support of new Energy Panel: \n - Changed Child device Net Consumption to Main device with type com.fibaro.powerSensor (value can be positive or negative)\n - Added Child device Todays Consumption to show the daily energy consumption in kWh\n - Added Child device Todays Production to show the daily energy production in kWh\n - Changed Child device Consumption High and Low to com.fibaro.energyMeter (kWh in property \"value\"; \"rateType\" = consumption). These values will be shown in the new energy panel. \n - Changed Child device Production High and Low to com.fibaro.energyMeter (kWh in property \"value\"; \"rateType\" = production). These values will be shown in the new energy panel. \n - Added automaticaly change rateType interface of Child device Consumption High and Low to \"consumption\" and Production High and Low to \"production\"\n - Changed Child device Consumption and Production to type com.fibaro.powerSensor (Watt) to show power graphs\n - Changed Child device Consumption L1, L2 and L3 and Production L1, L2 and L3 to type com.fibaro.powerSensor (Watt) to show power graphs\n- Additional changes:\n - Added todays Maximum consumption and todays Maximum production and timestamp to the label text and Child device log text\n - Added todays Maximum consumption and todays Maximum production automatic format measurement to W, Kw, MW or GW\n - Added todays Consumption low and high (kWh) and todays Production low and high (kWh) to the label text and Child devices log text\n - Added todays Consumption of gas in the label text and Child device log text\n - Added Timestamp in format dd-mm-yyyy hh:mm:ss to log of Main device and labels\n - Placed production below consumption in the labels\n - Solved bug when Production is higher than Consumption with calculation of Gross Consumption (Gross Consumption = Net Consumption minus or plus Device Consumption)\n\nVersion 1.4 (11th April 2021)\n- Added Child Devices Waterflow and Total Waterflow\n\nVersion 1.3 (13th February 2021)\n- Added Child Devices for Voltage L1 L2 L3\n\nVersion 1.2 (6th February 2021)\n- Added a lot of Child Devices for Net Consumption, Consumption, Production, Gross Consumption, Device Consumption, Consumption High, Consumption Low, Production High, Production Low, Total Gas, Consumption L1 L2 L3, Ampere L1 L2 L3, Production L1 L2 and L3\n\nVersion 1.1 (18th January 2021)\n- Solved a bug when powerID = 0\n\nVersion 1.0 (15th Januari 2021)\n- Changed routine te get Energy Device ID's fast (no more maxNodeID needed)\n- Added \"Update Devicelist\" button to update the Energy devicelist\n- Added Tarifcode High and Low (and empty for flat fee)\n- Rounded Consumption and Production to zero digits Watt\n- Added Quickapp variable for debug level (1=some, 2=few, 3=all). Recommended default value is 1. \n- Re-aranged the labels\n- Cleaned up some code\n\nVersion 0.3 (16th August 2020)\n- Added Quickapp variables for easy configuration\n- Added Power Production\n- Changed method of adding QuickApp variables, so they can be edited\n\n\nVariables (mandatory and created automatically): \n- IPaddress = IP address of your P1 monitor\n- interval = Number in seconds, the P1 Monitor normally is updated every 10 seconds, sometimes even faster\n- debugLevel = Number (1=some, 2=few, 3=all) (default = 1)\n- waterMeter = Existance of watermeter true or false (default = false)\n- language = Preferred language (default = en) (supported languages are Engish (en), French (fr), Polish (pl) and Dutch (nl))\n\n\nTested on:\n- P1 Monitor version: 20221105 V2.1.0\n- Raspberry Pi model: Raspberry Pi 4 Model B Rev 1.1\n- Linux-5.15.74-v7l+-armv7l-with-glibc2.31\n- Python versie: 3.9.2\n\n\nI use a Smart Meter Cable Starter Kit:\n- Raspberry Pi 4 Model B Rev 1.1 2GB\n- 32GB Micro SDHC\n- Smart Meter cable\n- P1 Monitor software from: https://www.ztatz.nl\n- Water Flow Sensor (M18 8mm sensing DC 5V NPN NO LJ18A3-8-Z/BX-5V cylinder inductive proximity sensor switch work voltage 5VDC special for MCU)\n\n\nExample content Json table Smartmeter (without values for production):\n[{\"CONSUMPTION_GAS_M3\": 6635.825, \"CONSUMPTION_KWH_HIGH\": 9986.186, \"CONSUMPTION_KWH_LOW\": 9170.652, \"CONSUMPTION_W\": 692, \"PRODUCTION_KWH_HIGH\": 0.0, \"PRODUCTION_KWH_LOW\": 0.0, \"PRODUCTION_W\": 0, \"RECORD_IS_PROCESSED\": 0, \"TARIFCODE\": \"D\", \"TIMESTAMP_UTC\": 1601733693, \"TIMESTAMP_lOCAL\": \"2020-10-03 16:01:33\"}]\n \nExample content Json table Watermeter: \n[{\"TIMEPERIOD_ID\": 11, \"TIMESTAMP_UTC\": 1615713840, \"TIMESTAMP_lOCAL\": \"2021-03-14 10:24:00\", \"WATERMETER_CONSUMPTION_LITER\": 1.0, \"WATERMETER_CONSUMPTION_TOTAL_M3\": 3406.243, \"WATERMETER_PULS_COUNT\": 1.0}]\n\n]]"}]}