diff --git a/P1_Monitor-16.fqa b/P1_Monitor-16.fqa new file mode 100644 index 0000000..de26af9 --- /dev/null +++ b/P1_Monitor-16.fqa @@ -0,0 +1 @@ +{"name":"P1 Monitor","type":"com.fibaro.powerSensor","apiVersion":"1.2","initialProperties":{"viewLayout":{"$jason":{"body":{"header":{"style":{"height":"0"},"title":"quickApp_device_969"},"sections":{"items":[{"components":[{"name":"label1","style":{"weight":"1.2"},"text":"Label1","type":"label","visible":true},{"style":{"weight":"0.5"},"type":"space"}],"style":{"weight":"1.2"},"type":"vertical"},{"components":[{"name":"button1","style":{"weight":"1.2"},"text":"Update Devicelist","type":"button","visible":true},{"style":{"weight":"0.5"},"type":"space"}],"style":{"weight":"1.2"},"type":"vertical"}]}},"head":{"title":"quickApp_device_969"}}},"uiCallbacks":[{"callback":"button1Event","eventType":"onReleased","name":"button1"}],"quickAppVariables":[{"name":"IPaddress","type":"string","value":"192.168.1.120"},{"name":"debugLevel","type":"string","value":"1"},{"name":"powerID","value":"0"},{"name":"waterMeter","value":"false"},{"name":"Interval","value":"10"}],"typeTemplateInitialized":true},"files":[{"name":"main","isMain":true,"isOpen":true,"content":"-- QUICKAPP P1 MONITOR \n\n-- This Quickapp retrieves energy consumption, energy production, gas and water usage from the (P1 Monitor) energy, gas and water meter \n\n-- Child Devices for Consumption (Watt), Production (Watt), Todays Consumption (kWh), Todays Production (kWh), Gross Consumption (Watt), Device Consumption (Watt), Waterflow (Liter), Consumption High (kWh), Consumption Low (kWh), Production High (kWh), Production Low (kWh), Consumption L1 L2 L3 (Watt), Production L1 L2 and L3 (Watt), Ampere L1 L2 L3 (Amp), Voltage L1 L2 L3 (Volt), Total Gas (m³) and Total Waterflow (m³)\n\n-- Energy consumption and energy production is added to the (new) HC3 energy panel\n\n-- All power consumption of all HomeCenter devices is summarized\n-- The difference between the total power consumption and the power consumption of the HomeCenter devices is put in a unused device (unless the powerID = 0 or empty)\n\n-- The Child device Todays Consumption can be selected in the Generals Settings as \"Main energy meter\". Doing so, the summary consumption will be from this device. If not, the consumption will come from the Child device Consumption High, the Child device Consumption Low and all your energy registering Z-wave devices and there values will be counted twice unless you change the Energy panel setting of each energy registering Z-wave device. \n\n\n-- ToDo as soon as Yubii Mobile App supports all device types:\n-- water -> com.fibaro.waterMeter \n-- ampere/voltage -> com.fibaro.electricMeter\n-- gas -> com.fibaro.gasMeter\n-- devices with power values (Watt) --> com.fibaro.powerMeter\n\n\n-- Version 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\n\n-- Version 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\n-- Version 1.4 (11th April 2021)\n-- Added Child Devices Waterflow and Total Waterflow\n\n-- Version 1.3 (13th February 2021)\n-- Added Child Devices for Voltage L1 L2 L3\n\n-- Version 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\n-- Version 1.1 (18th January 2021)\n-- Solved a bug when powerID = 0\n\n-- Version 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\n-- Version 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\n-- Variables (mandatory): \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-- powerID = ID of the device where you want to capture the 'delta' power, use 0 if you don't want to store the delta energy consumption\n-- debugLevel = Number (1=some, 2=few, 3=all) (default = 1)\n-- waterMeter = Existance of watermeter true or false (default = false)\n\n\n-- Tested on:\n-- P1 Monitor version: 20210618 V1.3.1\n-- Raspberry Pi model: Raspberry Pi 4 Model B Rev 1.1\n-- Linux-5.10.17-v7l+-armv7l-with-debian-10.9\n-- Python versie: 3.7.3\n\n\n-- I use a Smart Meter Cable Starter Kit:\n -- Raspberry Pi 4 Model B Rev 1.1 2GB\n -- 8GB Micro SDHC\n -- Original Raspberry Pi 4B Enclosure\n -- Original Raspberry Pi USB-C 3A power supply\n -- Smart Meter cable\n -- P1 Monitor software from: https://www.ztatz.nl\n\n\n-- Example 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 \n-- Example 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 \n-- No editing of this code is needed \n\n\nclass 'consumption'(QuickAppChild)\nfunction consumption:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"consumption QuickappChild initiated, deviceId:\",self.id)\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\", \"Watt\")\n self:updateProperty(\"log\", \"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)\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\", \"Watt\")\n self:updateProperty(\"log\", \"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\", \"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\", \"kWh\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'gross_consumption'(QuickAppChild)\nfunction gross_consumption:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction gross_consumption:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.gross_consumption)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.gross_consumption)))\n self:updateProperty(\"unit\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'device_consumption'(QuickAppChild)\nfunction device_consumption:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction device_consumption:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.3f\",data.device_consumption)))\n self:updateProperty(\"power\", tonumber(string.format(\"%.3f\",data.device_consumption)))\n self:updateProperty(\"unit\", \"Watt\")\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\", \"L/min\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'consumption_L1'(QuickAppChild)\nfunction consumption_L1:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'consumption_L2'(QuickAppChild)\nfunction consumption_L2:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'consumption_L3'(QuickAppChild)\nfunction consumption_L3:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L1'(QuickAppChild)\nfunction production_L1:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L2'(QuickAppChild)\nfunction production_L2:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'production_L3'(QuickAppChild)\nfunction production_L3:__init(dev)\n QuickAppChild.__init(self,dev)\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\", \"Watt\")\n self:updateProperty(\"log\", \" \")\nend\n\n\nclass 'L1_A'(QuickAppChild)\nfunction L1_A:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L1_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L1_A)))\n self:updateProperty(\"unit\", \"Amp\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L2_A'(QuickAppChild)\nfunction L2_A:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L2_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L2_A)))\n self:updateProperty(\"unit\", \"Amp\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L3_A'(QuickAppChild)\nfunction L3_A:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L3_A:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.1f\",data.L3_A)))\n self:updateProperty(\"unit\", \"Amp\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L1_V'(QuickAppChild)\nfunction L1_V:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L1_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L1_V)))\n self:updateProperty(\"unit\", \"Volt\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L2_V'(QuickAppChild)\nfunction L2_V:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L2_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L2_V)))\n self:updateProperty(\"unit\", \"Volt\")\n self:updateProperty(\"log\", \"\")\nend\n\n\nclass 'L3_V'(QuickAppChild)\nfunction L3_V:__init(dev)\n QuickAppChild.__init(self,dev)\nend\nfunction L3_V:updateValue(data) \n self:updateProperty(\"value\", tonumber(string.format(\"%.0f\",data.L3_V)))\n self:updateProperty(\"unit\", \"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\", \"kWh\")\n self:updateProperty(\"log\", \"Today \" ..data.today_consumption_high ..\" 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\", \"kWh\")\n self:updateProperty(\"log\", \"Today \" ..data.today_consumption_low ..\" 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\", \"kWh\")\n self:updateProperty(\"log\", \"Today \" ..data.today_production_high ..\" 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\", \"kWh\")\n self:updateProperty(\"log\", \"Today \" ..data.today_production_low ..\" 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\", \"Today \" ..data.today_gas ..\" m³\")\nend\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\n-- QuickApp Functions\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:button1Event() -- Refresh button event\n self:updateView(\"button1\", \"text\", \"Please wait...\")\n self:eDevices() -- Get all Energy Devices\n fibaro.setTimeout(5000, function()\n self:updateView(\"button1\", \"text\", \"Update Devicelist\")\n end)\nend\n\n\nfunction QuickApp:unitCheckWatt(measurement) -- Set the measurement and unit to Watt, Kilowatt, Megawatt or Gigawatt\n self:logging(3,\"Start unitCheckWatt\")\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:consumption() -- Update the energy consumption of all energy devices\n self:logging(3,\"QuickApp:consumption\")\n local deviceValue = 0\n local id = 1\n data.device_consumption = 0\n data.gross_consumption = 0\n for key, id in pairs(eDevices) do\n if fibaro.getValue(id, \"power\") and id~=powerID then\n deviceValue = fibaro.getValue(id, \"power\")\n data.device_consumption = data.device_consumption + deviceValue\n end\n end\n \n if tonumber(data.net_consumption) < 0 then -- Measured power usage minus power usage from all devices\n data.gross_consumption = tonumber(data.net_consumption) + data.device_consumption -- Production is higher than consumption (negative net consumption)\n else\n data.gross_consumption = tonumber(data.net_consumption) - data.device_consumption \n end\n\n if powerID ~= 0 and powerID == nil then\n api.put(\"/devices/\"..powerID, {[\"properties\"]={[\"power\"]=data.gross_consumption}}) -- Put gross_consumption into device with powerID\n end\nend\n\n\nfunction QuickApp:updateProperties() -- Update the properties\n self:logging(3,\"QuickApp:updateProperties\")\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\", \"Watt\")\n self:updateProperty(\"log\", data.timestamp_local)\nend\n\n\nfunction QuickApp:updateLabels() -- Update the labels\n self:logging(3,\"QuickApp:updateLabels\")\n local labelText = \"\"\n labelText = labelText ..\"Consumption: \" ..data.consumption ..\" Watt (Max \" ..data.max_consumption ..\" \" ..data.max_consumption_unit ..\" at \" ..data.max_consumption_time ..\")\" ..\"\\n\" \n labelText = labelText ..\"Production: \" ..data.production ..\" Watt (Max \" ..data.max_production ..\" \" ..data.max_production_unit ..\" at \" ..data.max_production_time ..\")\" ..\"\\n\"\n labelText = labelText ..\"Waterflow: \" ..data.waterflow ..\" L/min\" ..\"\\n\\n\"\n \n labelText = labelText ..\"Todays consumption: \" ..data.todays_consumption ..\" kWh\" ..\"\\n\"\n labelText = labelText ..\"Todays production: \" ..data.todays_production ..\" kWh\" ..\"\\n\"\n labelText = labelText ..\"Gross consumption: \" ..data.gross_consumption ..\" Watt\" ..\"\\n\"\n labelText = labelText ..\"Device consumption: \" ..data.device_consumption ..\" Watt\" ..\"\\n\\n\"\n \n labelText = labelText ..\"Totals:\" ..\"\\n\" \n labelText = labelText ..\"Consumption high: \" ..data.consumption_high ..\" kWh (Today \" ..data.today_consumption_high ..\" kWh)\" ..\"\\n\" \n labelText = labelText ..\"Consumption low: \" ..data.consumption_low ..\" kWh (Today \" ..data.today_consumption_low ..\" kWh)\" ..\"\\n\"\n labelText = labelText ..\"Consumption: \" ..data.total_consumption ..\" kWh\" ..\"\\n\" \n labelText = labelText ..\"Production high: \" ..data.production_high ..\" kWh (Today \" ..data.today_production_high ..\" kWh)\" ..\"\\n\" \n labelText = labelText ..\"Producton low: \" ..data.production_low ..\" kWh (Today \" ..data.today_production_low ..\" kWh)\" ..\"\\n\"\n labelText = labelText ..\"Production: \" ..data.total_production ..\" kWh\" ..\"\\n\"\n labelText = labelText ..\"Gas: \" ..data.gas ..\" m³ (Today: \" ..data.today_gas ..\" m³\" ..\" / Lasthour: \" ..data.lasthour_gas ..\" L)\" ..\"\\n\"\n labelText = labelText ..\"Water: \" ..data.water ..\" m³\" ..\"\\n\\n\"\n \n labelText = labelText ..\"Consumption:\" ..\"\\n\"\n labelText = labelText ..\"L1: \" ..data.consumption_L1 ..\" - L2: \" ..data.consumption_L2 ..\" - L3: \" ..data.consumption_L3 ..\" Watt \" ..\"\\n\\n\"\n \n labelText = labelText ..\"Production\" ..\"\\n\"\n labelText = labelText ..\"L1: \" ..data.production_L1 ..\" - L2: \" ..data.production_L2 ..\" - L3: \" ..data.production_L3 ..\" Watt \" ..\"\\n\\n\"\n \n labelText = labelText ..\"Ampere:\" ..\"\\n\"\n labelText = labelText ..\"L1: \" ..data.L1_A ..\" - L2: \" ..data.L2_A ..\" - L3: \" ..data.L3_A ..\" Amp \" ..\"\\n\\n\"\n \n labelText = labelText ..\"Voltage:\" ..\"\\n\"\n labelText = labelText ..\"L1: \" ..data.L1_V ..\" - L2: \" ..data.L2_V ..\" - L3: \" ..data.L3_V ..\" Volt \" ..\"\\n\\n\"\n\n labelText = labelText ..\"Updated: \" ..data.timestamp_local ..\"\\n\"\n\n self:updateView(\"label1\", \"text\", labelText)\n self:logging(2,labelText)\nend\n\n\nfunction QuickApp:valuesWatermeter() -- Get the values from json file Watermeter\n self:logging(3,\"QuickApp:valuesWatermeter\")\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() -- Get the values from json file Status\n self:logging(3,\"QuickApp:valuesStatus\")\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() -- Get the values from json file Smartmeter\n self:logging(3,\"QuickApp:valuesSmartmeter\")\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 = \"(High)\"\n elseif data.tarifcode == \"D\" then\n data.tarifcodeText = \"(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\")\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\n local apiResult = response.data \n jsonTable = json.decode(apiResult) -- 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() -- Get the values from json file Smartmeter\n self:consumption() -- Store net consumption in unused device \n Path = pathStatus -- Next path\n Mode = \"Status\" -- Next mode\n elseif Mode == \"Status\" then \n self:valuesStatus() -- 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() -- 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:eDevices() -- Get all Device IDs which measure Energy Consumption\n eDevices = {}\n local devices, status = api.get(\"/devices?interface=energy\")\n self:trace(\"Updated devicelist devices with energy consumption\")\n for k in pairs(devices) do\n table.insert(eDevices,devices[k].id)\n end\n self:logging(2,\"Energy Devices: \" ..json.encode(eDevices))\nend\n\n\nfunction QuickApp:createVariables() -- Get all Quickapp Variables or create them\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 \n data = {}\n \n data.consumption = \"0\"\n data.production = \"0\"\n \n data.device_consumption = 0\n data.gross_consumption = 0 \n data.total_consumption = \"\"\n data.total_production = \"\"\n data.tarifcode = \"\"\n data.tarifcodeText = \"\"\n \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 \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 \n data.waterflow = \"0\"\n data.waterflow_timestamp = 0\n data.water = \"0\"\n data.gas = \"0\"\n \n data.timestamp_local = \"\"\n \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\"\n \nend\n\n\nfunction QuickApp:getQuickappVariables() -- Get all Quickapp Variables or create them\n IPaddress = self:getVariable(\"IPaddress\")\n powerID = tonumber(self:getVariable(\"powerID\"))\n waterMeter = string.lower(self:getVariable(\"waterMeter\"))\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 powerID == \"\" or powerID == nil then \n powerID = \"0\" -- ID of the device where you want to capture the 'delta' power, use 0 if you don't want to store the energy consumption\n self:setVariable(\"powerID\", powerID)\n self:trace(\"Added QuickApp variable powerID\")\n powerID = tonumber(powerID)\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 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 powerID == 0 or powerID == nil then\n self:warning(\"No powerID to store net power consumption\")\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.powerSensor\", value=0},\n {className=\"production\", name=\"Production\", type=\"com.fibaro.powerSensor\", 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=\"gross_consumption\", name=\"Gross Consumption\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"device_consumption\", name=\"Device Consumption\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"waterflow\", name=\"Water Flow\", type=\"com.fibaro.multilevelSensor\", 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.powerSensor\", value=0},\n {className=\"consumption_L2\", name=\"Consumption L2\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"consumption_L3\", name=\"Consumption L3\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"production_L1\", name=\"Production L1\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"production_L2\", name=\"Production L2\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"production_L3\", name=\"Production L3\", type=\"com.fibaro.powerSensor\", value=0},\n {className=\"L1_A\", name=\"Ampere L1\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"L2_A\", name=\"Ampere L2\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"L3_A\", name=\"Ampere L3\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"L1_V\", name=\"Voltage L1\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"L2_V\", name=\"Voltage L2\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"L3_V\", name=\"Voltage L3\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"water\", name=\"Water\", type=\"com.fibaro.multilevelSensor\", value=0},\n {className=\"gas\", name=\"Total Gas\", type=\"com.fibaro.multilevelSensor\", 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:eDevices() -- Get all Energy Devices\n self:getData() -- Go to getData\nend\n\n-- EOF "}]} \ No newline at end of file