-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sensor_Community-1.fqa
1 lines (1 loc) · 27.3 KB
/
Sensor_Community-1.fqa
1
{"name":"Sensor Community","type":"com.fibaro.genericDevice","apiVersion":"1.2","initialProperties":{"viewLayout":{"$jason":{"body":{"header":{"style":{"height":"0"},"title":"quickApp_device_473"},"sections":{"items":[{"components":[{"name":"label1","style":{"weight":"1.2"},"text":"Label1","type":"label"},{"style":{"weight":"0.5"},"type":"space"}],"style":{"weight":"1.2"},"type":"vertical"},{"components":[{"name":"button1","style":{"weight":"1.2"},"text":"Refresh","type":"button"},{"style":{"weight":"0.5"},"type":"space"}],"style":{"weight":"1.2"},"type":"vertical"}]}},"head":{"title":"quickApp_device_473"}}},"uiCallbacks":[{"callback":"button1Event","eventType":"onReleased","name":"button1"}],"quickAppVariables":[{"name":"sensorID1","value":"13463"},{"name":"sensorID2","value":"13464"},{"name":"interval","value":"146"},{"name":"httpTimeout","value":"60"},{"name":"userID","value":"0"},{"name":"debugLevel","value":"1"},{"name":"icon","value":"0"}],"typeTemplateInitialized":true},"files":[{"name":"main","isMain":true,"isOpen":true,"content":"-- QuickApp SENSOR.COMMUNITY \n\n-- This QuickApp reads the PM2.5, PM10, Temperature, Humidity and Airpressure values directly from a sensor somewhere in this world\n-- That sensor doesn't have to be your own sensor, any sensor can be used, just find one in your neighborhood \n-- For locating the sensor(ID's) in your neighborhood see: https://sensor.community/en/\n-- Select two (!) SensorID's, one for PM2.5 and PM10 values and one for Temperature, Humidity and Airpressure values\n\n-- The PM2.5, PM10, Temperature, Humidity, Absolute Humidity and Airpressure readings are stored in the value of six (child) devices, so you can read the value from your own scenes\n-- This QuickApp will send notifications when PM2.5 or PM10 readings reach a breakpoint (if userID ~= 0)\n\n-- Absolute humidity is the measure of water vapor (moisture) in the air, regardless of temperature. It is expressed as grams of moisture per cubic meter of air (g/m3) \n\n\n-- Version 1.0 (7th February 2021)\n-- Added Child Devices for Temperature, Humidity, Absolute Humidity and Airpressure\n-- Changed the quickapp variable SensorID to two variables, one for PM values and one for Temperature, Humidity and Airpressure values\n-- Added Quickapp variable for debug level (1=some, 2=few, 3=all). Recommended default value is 1.\n-- Added QuickApp Variable for user defined icon master device-- Added Airpressure Text in log of Airpressure Child Device\n-- Removed QuickApp Variable address, there was no need to change it by user\n-- Added values for Temperature, Humidity, Absolute Humidity and Airpressure to the lables\n-- Added values for Country, Latitude and Longitude to the labels\n-- Added Sensor ID to the log below the value\n-- Added \"Refresh\" button\n-- Added extra check for empty data return from Sensor Community\n\n\n-- Version 0.4 (19th August 2020)\n-- Added child devices for PM2.5 and PM10\n-- Added time of measurement, adjusted to your timezone\n-- Added timeout QuickApp variable with high http timeout value to prevent errors\n-- Error message instead off debug message in case of an error\n-- Changed method of adding QuickApp variables, so they can be edited\n\n\n-- See also https://luftdaten.info\n-- See also for CVS files: https://archive.luftdaten.info\n-- See also https://github.com/opendata-stuttgart/\n-- API documentation: https://github.com/opendata-stuttgart/meta/wiki/EN-APIs\n\n\n-- Variables (mandatory): \n-- sensorID1 = [number] SensorID for PM2.5 and PM10 values, your own sensor or from someone else, 13463 is an example\n-- sensorID2 = [number] SensorID for Temperature, Humidity and Airpressure values, your own sensor or from someone else, 13464 is an example\n-- interval = [number] in seconds time to get the sensor data from sensor.community\n-- timeout = [number] in seconds for http timeout\n-- userID = [number] userID to notify of PM2.5 / PM10 breakpoints\n-- debugLevel = [number] Debug logging (1=some, 2=few, 3=all) (default = 1)\n-- icon = [numbber] User defined icon number (add the icon via an other device and lookup the number)\n\n\n-- PM2.5 breakpoints\n-- 0 - 30 GOOD (Minimal)\n-- 31 - 60 SATISFACTORY (Minor breathing discomfort to sensitive people)\n-- 61 - 90 MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\n-- 91 - 120 POOR (Breathing discomfort to all)\n-- 121 - 250 VERY POOR (Respiratory illness on prolonged exposure)\n-- 250+ SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\n\n-- PM10 breakpoints\n-- 0 - 50 GOOD (Minimal)p\n-- 51 - 100 SATISFACTORY (Minor breathing discomport to sensitive people)\n-- 101 - 250 MODERATELY POLLUTED Breathing discomfoort to asthma patients, elderly and children\n-- 251 - 350 POOR (Breathing discomfort to all)\n-- 351 - 430 VERY POOR (Respiratory illness on prolonged exposure)\n-- 430+ SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\n\n\n-- No editing of this code is needed \n\n\nclass 'PolutionSensorTemp'(QuickAppChild)\nfunction PolutionSensorTemp:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"Air Quality Temperature sensor initiated, deviceId:\",self.id)\nend\nfunction PolutionSensorTemp:updateValue(data,userID) \n --self:debug(\"Temperature: \",data.temperature)\n self:updateProperty(\"value\",tonumber(data.temperature))\nend\n\nclass 'PolutionSensorHumid'(QuickAppChild)\nfunction PolutionSensorHumid:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"Air Quality Humidity sensor initiated, deviceId:\",self.id)\nend\nfunction PolutionSensorHumid:updateValue(data,userID) \n self:updateProperty(\"value\",tonumber(data.humidity)) \nend\n\nclass 'PolutionSensorHumidAbs'(QuickAppChild)\nfunction PolutionSensorHumidAbs:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"Air Quality Absolute Humidity sensor initiated, deviceId:\",self.id)\nend\nfunction PolutionSensorHumidAbs:updateValue(data,userID) \n self:updateProperty(\"value\",tonumber(data.humidityabsolute)) \n self:updateProperty(\"unit\", \"g/m³\")\nend\n\nclass 'PolutionSensorPressure'(QuickAppChild)\nfunction PolutionSensorPressure:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"Air Quality Airpressure sensor initiated, deviceId:\",self.id)\nend\nfunction PolutionSensorPressure:updateValue(data,userID) \n self:updateProperty(\"value\",tonumber(data.airpressure)) \n self:updateProperty(\"unit\", \"hPa\")\n self:updateProperty(\"log\", data.airpressuretext)\nend\n\nclass 'PolutionSensorPM25'(QuickAppChild)\nfunction PolutionSensorPM25:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"PM2.5 sensor initiated, deviceId:\",self.id)\nend\n\nfunction PolutionSensorPM25:updateValue(data,userID) \n\n local pm25,pm25prev = data.pm25,data.pm25prev\n\n -- Send notifications when PM2.5 level reach breakpoints \n -- PM2.5 breakpoint 0 - 30 GOOD (Minimal)\n if (tonumber(pm25) > 0 and tonumber(pm25) <= 30) then\n pm25Text = \"GOOD\"\n if (pm25prev > 30) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level GOOD (Minimal)\")\n self:debug(\"PM2.5 level GOOD (Minimal)\",pm25 ..\" µg/m³\")\n end\n end\n -- PM2.5 breakpoint 31 - 60 SATISFACTORY (Minor breathing discomfort to sensitive people)\n if (tonumber(pm25) >= 31 and tonumber(pm25) <= 60) then\n pm25Text = \"SATISFACTORY\"\n if (pm25prev < 31 or pm25prev > 60) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level SATISFACTORY (Minor breathing discomfort to sensitive people)\")\n self:debug(\"PM2.5 level SATISFACTORY (Minor breathing discomfort to sensitive people)\",pm25 ..\" µg/m³\")\n end\n end\n -- PM2.5 breakpoint 61 - 90 MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\n if (tonumber(pm25) >= 61 and tonumber(pm25) <= 90) then\n pm25Text = \"MODERATELY POLLUTED\"\n if (pm25prev < 61 or pm25prev > 90) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\")\n self:debug(\"PM2.5 level MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\",pm25 ..\" µg/m³\")\n end \n end\n -- PM2.5 breakpoint 91 - 120 POOR (Breathing discomfort to all)\n if (tonumber(pm25) >= 91 and tonumber(pm25) <= 120) then\n pm25Text = \"POOR\"\n if (pm25prev < 91 or pm25prev > 120) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level POOR (Breathing discomfort to all)\")\n self:debug(\"PM2.5 level POOR (Breathing discomfort to all)\",pm25 ..\" µg/m³\")\n end\n end\n -- PM2.5 breakpoint 120 - 250 VERY POOR (Respiratory illness on prolonged exposure)\n if (tonumber(pm25) >= 120 and tonumber(pm25) <= 250) then\n pm25Text = \"VERY POOR\"\n if (pm25prev < 121 or pm25prev > 250) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level VERY POOR (Respiratory illness on prolonged exposure)\")\n self:debug(\"PM2.5 level VERY POOR (Respiratory illness on prolonged exposure)\",pm25 ..\" µg/m³\")\n end\n end\n -- PM2.5 breakpoint 250+ SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\n if (tonumber(pm25) >= 250 ) then\n pm25Text = \"SEVERE\"\n if (pm25prev < 250) then\n fibaro.alert(\"push\", {userID}, \"PM2.5 \"..pm25 ..\" µg/m³\" ..\" level SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\")\n self:debug(\"PM2.5 level SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\",pm25 ..\" µg/m³\")\n end\n end\n\n if tonumber(pm25) > tonumber(pm25prev) then\n pm25Trend = \" ↑\"\n elseif tonumber(pm25) < tonumber(pm25prev) then\n pm25Trend = \" ↓\"\n else\n pm25Trend = \" =\"\n end \n\n -- Update properties for PM2.5 sensor\n self:updateProperty(\"value\", tonumber(pm25)) \n self:updateProperty(\"unit\", \"㎍/㎥\")\n self:updateProperty(\"log\", pm25Text ..pm25Trend)\nend\n\nclass 'PolutionSensorPM10'(QuickAppChild)\nfunction PolutionSensorPM10:__init(dev)\n QuickAppChild.__init(self,dev)\n --self:trace(\"PM10 sensor initiated, deviceId:\",self.id)\nend\n\nfunction PolutionSensorPM10:updateValue(data,userID) \n local pm10,pm10prev = data.pm10,data.pm10prev\n\n -- Send notifications when PM10 level reach breakpoints \n -- PM10 breakpoint 0 - 50 GOOD (Minimal)\n if (tonumber(pm10) > 0 and tonumber(pm10) <= 50) then\n pm10Text = \"GOOD\"\n if (pm10prev > 50) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level GOOD (Minimal)\")\n self:debug(\"PM10 level GOOD (Minimal)\",pm10 ..\" µg/m³\")\n end\n end\n -- PM10 breakpoint 51 - 100 SATISFACTORY (Minor breathing discomfort to sensitive people)\n if (tonumber(pm10) >= 51 and tonumber(pm10) <= 100) then\n pm10Text = \"SATISFACTORY\"\n if (pm10prev < 51 or pm10prev > 100) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level SATISFACTORY (Minor breathing discomfort to sensitive people)\")\n self:debug(\"PM10 level SATISFACTORY (Minor breathing discomfort to sensitive people)\",pm10 ..\" µg/m³\")\n end\n end\n -- PM10 breakpoint 101 - 250 MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\n if (tonumber(pm10) >= 101 and tonumber(pm10) <= 250) then\n pm10Text = \"MODERATELY POLLUTED\"\n if (pm10prev < 101 or pm10prev > 250) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\")\n self:debug(\"PM10 level MODERATELY POLLUTED Breathing discomfort to asthma patients, elderly and children\",pm10 ..\" µg/m³\")\n end\n end\n -- PM10 breakpoint 251 - 350 POOR (Breathing discomfort to all)\n if (tonumber(pm10) >= 251 and tonumber(pm10) <= 350) then\n pm10Text = \"POOR\"\n if (pm10prev < 251 or pm10prev > 350) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level POOR (Breathing discomfort to all)\")\n self:debug(\"PM10 level POOR (Breathing discomfort to all)\",pm10 ..\" µg/m³\")\n end\n end\n -- PM10 breakpoint 351 - 430 VERY POOR (Respiratory illness on prolonged exposure)\n if (tonumber(pm10) >= 351 and tonumber(pm10) <= 439) then\n pm10Text = \"VERY POOR\"\n if (pm10prev < 351 or pm10prev > 430) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level VERY POOR (Respiratory illness on prolonged exposure)\")\n self:debug(\"PM10 level VERY POOR (Respiratory illness on prolonged exposure)\",pm10 ..\" µg/m³\")\n end\n end\n -- PM10 breakpoint 430+ SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\n if (tonumber(pm10) >= 439 ) then\n pm10Text = \"SEVERE\"\n if (pm10prev < 430) then\n fibaro.alert(\"push\", {userID}, \"PM10 \"..pm10 ..\" µg/m³\" ..\" level SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\")\n self:debug(\"PM10 level SEVERE (Health impact even on light physical work. Serious impact on people with heart/lung disease)\",pm10 ..\" µg/m³\")\n end\n end\n\n if tonumber(pm10) > tonumber(pm10prev) then\n pm10Trend = \" ↑\"\n elseif tonumber(pm10) < tonumber(pm10prev) then\n pm10Trend = \" ↓\"\n else\n pm10Trend = \" =\"\n end\n\n -- Update properties for PM10 sensor\n self:updateProperty(\"value\",tonumber(pm10)) \n self:updateProperty(\"unit\", \"㎍/㎥\")\n self:updateProperty(\"log\", pm10Text ..pm10Trend)\nend\n\n\n-- QuickApp functions\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: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:setPressuretext(text) -- Setup for airpressuretext\n press = tonumber(text)\n if press < 974 then \n return \"Thunderstorms\"\n elseif press < 990 then\n return \"Stormy\"\n elseif press < 1002 then\n return \"Rain\"\n elseif press < 1010 then\n return \"Cloudy\"\n elseif press < 1022 then\n return \"Unstable\"\n elseif press < 1035 then\n return \"Stable\"\n else\n return \"Very dry\"\n end\nend\n\n\nfunction QuickApp:button1Event()\n self:updateView(\"button1\", \"text\", \"Please wait...\")\n self:getData()\n fibaro.setTimeout(5000, function() -- Pause for [timeout] seconds (default 5 seconds)\n self:updateView(\"button1\", \"text\", \"Refresh\")\n end)\nend\n\n\n-- Calculate Absolute Humidity (based on Temperature, Relative Humidity and Airpressure)\nfunction QuickApp:getHumidityAbs(hum,temp,press) -- Source from muhmuh at Fibaro forum\n local EXP = 2.71828182845904523536028747135266249775724709369995\n local humidityAbs = 0.622 * hum/100 * (1.01325 * 10^(5.426651 - 2005.1 / (temp + 273.15) + 0.00013869 * ((temp + 273.15) * (temp + 273.15) - 293700) / (temp + 273.15) * (10^(0.000000000011965 * ((temp + 273.15) * (temp + 273.15) - 293700) * ((temp + 273.15) * (temp + 273.15) - 293700)) - 1) - 0.0044 * 10^((-0.0057148 * (374.11 - temp)^1.25))) + (((temp + 273.15) / 647.3) - 0.422) * (0.577 - ((temp + 273.15) / 647.3)) * EXP^(0.000000000011965 * ((temp + 273.15) * (temp + 273.15) - 293700) * ((temp + 273.15) * (temp + 273.15) - 293700)) * 0.00980665) / (press/1000 - hum/100 * (1.01325 * 10^(5.426651 - 2005.1 / (temp + 273.15) + 0.00013869 * ((temp + 273.15) * (temp + 273.15) - 293700) / (temp + 273.15) * (10^(0.000000000011965 * ((temp + 273.15) * (temp + 273.15) - 293700) * ((temp + 273.15) * (temp + 273.15) - 293700)) - 1) - 0.0044 * 10^((-0.0057148 * (374.11 - temp)^1.25))) + (((temp + 273.15) / 647.3) - 0.422) * (0.577 - ((temp + 273.15) / 647.3)) * EXP^(0.000000000011965 * ((temp + 273.15) * (temp + 273.15) - 293700) * ((temp + 273.15) * (temp + 273.15) - 293700)) * 0.00980665)) * press/1000 * 100000000 / ((temp + 273.15) * 287.1)\n self:logging(3,\"Absolute humidty: \" ..string.format(\"%.2f\",humidityAbs))\n return string.format(\"%.2f\",humidityAbs)\nend\n\n\nfunction QuickApp:updateProperties() --Update properties\n self:logging(3,\"updateProperties\")\n self:updateProperty(\"log\", newtimestamp ..\"\\n\" ..\"Sensor ID: \" ..sensorID)\nend\n\n\nfunction QuickApp:updateLabels() -- Update labels\n self:logging(3,\"updateLabels\")\n local labelText = \"PM2.5: \" ..data.pm25 ..\" µg/m³\" ..\"\\n\"\n labelText = labelText ..\"PM10: \" ..data.pm10 ..\" µg/m³\" ..\"\\n\"\n labelText = labelText ..\"Temperature: \" ..data.temperature ..\" °C\" ..\"\\n\"\n labelText = labelText ..\"Humidity: \" ..data.humidity ..\" %\" ..\"\\n\"\n labelText = labelText ..\"Absolute Humidity: \" ..data.humidityabsolute ..\" g/m³\" ..\"\\n\" \n labelText = labelText ..\"Airpressure: \" ..data.airpressure ..\" hPa (\" ..data.airpressuretext ..\")\" ..\"\\n\\n\" \n --labelText = labelText ..\"Airpressure: \" ..data.airpressure ..\" hPa\" ..\"\\n\\n\" \n labelText = labelText ..\"Sensor ID: \" ..sensorID1 ..\" / \" ..sensorID2 ..\" (\" ..data.country ..\" \" ..data.latitude ..\" / \" ..data.longitude ..\")\" ..\"\\n\\n\"\n labelText = labelText ..\"Measurement: \" ..newtimestamp\n self:logging(2,\"labelText: \" ..labelText)\n self:updateView(\"label1\", \"text\", labelText) \nend\n\n\nfunction QuickApp:getValues() -- Get the values\n self:logging(3,\"getValues\")\n local n = \"\"\n self:logging(3,\"Sensor type: \" ..jsonTable[1].sensor.sensor_type.name) \n if jsonTable[1].sensor.sensor_type.name == \"SDS011\" or jsonTable[1].sensor.sensor_type.name == \"DHT22\" then\n n = 2\n elseif jsonTable[1].sensor.sensor_type.name == \"BME280\" then\n n = 3\n else\n self:warning(\"Unknown type sensor\")\n n = 2\n end\n for i=1,n do\n if jsonTable[1].sensordatavalues[i].value_type == \"P1\" then\n data.pm10 = jsonTable[1].sensordatavalues[i].value\n elseif jsonTable[1].sensordatavalues[i].value_type == \"P2\" then\n data.pm25 = jsonTable[1].sensordatavalues[i].value\n elseif jsonTable[1].sensordatavalues[i].value_type == \"temperature\" then\n data.temperature = jsonTable[1].sensordatavalues[i].value\n elseif jsonTable[1].sensordatavalues[i].value_type == \"pressure\" then\n data.airpressure = string.format(\"%.0f\",tonumber(jsonTable[1].sensordatavalues[i].value)/100)\n elseif jsonTable[1].sensordatavalues[i].value_type == \"humidity\" then\n data.humidity = string.format(\"%.0f\",tonumber(jsonTable[1].sensordatavalues[i].value))\n else\n self:warning(\"Unknown measurement value\")\n end\n end\n if data.pm10 == \"\" or data.pm10 == nil then\n data.pm10 = \"0\" -- Temporarily value\n end\n if data.pm25 == \"\" or data.pm25 == nil then\n data.pm25 = \"0\" -- Temporarily value\n end\n if data.temperature == \"\" or data.temperature == nil then\n data.temperature = \"21\" -- Temporarily value\n end\n if data.humidity == \"\" or data.humidity == nil then\n data.humidity = \"50\" -- Temporarily value\n end\n if data.airpressure == \"\" or data.airpressure == nil then\n data.airpressure = \"1013\" -- Temporarily value\n end\n\n self:logging(3,\"Values: PM10: \" ..data.pm10 ..\" PM25: \" ..data.pm25 ..\" Temp: \" ..data.temperature ..\" Hum: \" ..data.humidity ..\" Press: \" ..data.airpressure)\n\n data.timestamp = jsonTable[1].timestamp \n data.country = jsonTable[1].location.country\n data.latitude = jsonTable[1].location.latitude\n data.longitude = jsonTable[1].location.longitude\n data.humidityabsolute = self:getHumidityAbs(data.humidity,data.temperature,data.airpressure) -- Calculate Absolute Humidity\n data.airpressuretext = self:setPressuretext(data.airpressure) -- Setup Airpressure Text\n self:logging(3,\"airpressuretext: \" ..data.airpressuretext)\n\n -- Check timezone and daylight saving time\n local timezone = os.difftime(os.time(), os.time(os.date(\"!*t\",os.time())))/3600\n if os.date(\"*t\").isdst then -- Check daylight saving time \n timezone = timezone + 1\n end\n self:logging(3,\"Timezone + dst: \" ..timezone)\n\n -- Convert time of measurement to local timezone\n local pattern = \"(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)\"\n local runyear, runmonth, runday, runhour, runminute, runseconds = data.timestamp:match(pattern)\n local convertedTimestamp = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})\n --local newtimestamp = os.date(\"%d-%m-%Y %X\", convertedTimestamp +(timezone*3600)) \n newtimestamp = os.date(\"%d-%m-%Y %X\", convertedTimestamp +(timezone*3600))\n self:logging(3,\"newtimestamp: \" ..newtimestamp)\nend\n\n\nfunction QuickApp:getData()\n self:logging(3,\"Start getData\")\n self:logging(2,\"URL: \" ..address ..sensorID ..\"/\")\n http:request(address ..sensorID ..\"/\", {\n options={headers = {Accept = \"application/json\"},method = 'GET'}, \n success = function(response)\n self:logging(3,\"response status: \" ..response.status)\n self:logging(3,\"headers: \" ..response.headers[\"Content-Type\"])\n self:logging(2,\"Response data: \" ..response.data)\n\n if response.data == nil or response.data == \"\" or response.data == \"[]\" then -- Check for empty result\n self:warning(\"Temporarily no data from Sensor Community\")\n self:logging(3,\"SetTimeout \" ..interval ..\" seconds\")\n fibaro.setTimeout(interval*1000, function() \n self:getdata()\n end)\n end\n\n jsonTable = json.decode(response.data) -- JSON decode from api to lua-table\n\n self:getValues()\n self:updateLabels()\n self:updateProperties()\n\n data.pm25prev=pm25prev\n data.pm10prev=pm10prev\n\n for id,child in pairs(self.childDevices) do \n child:updateValue(data,userID) \n end\n\n pm25prev = tonumber(data.pm25)\n pm10prev = tonumber(data.pm10)\n \n self:logging(2,\"sensorID former: \" ..sensorID)\n if sensorID == sensorID1 then -- Change the sensorID form first to second and back\n sensorID = sensorID2\n else\n sensorID = sensorID1\n end\n self:logging(2,\"sensorID next: \" ..sensorID)\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\n self:logging(3,\"SetTimeout \" ..interval ..\" seconds\")\n fibaro.setTimeout((interval/2)*1000, function() \n self:getData()\n end)\nend\n\n\nfunction QuickApp:getQuickAppVariables() -- Get all variables \n address = \"http://data.sensor.community/airrohr/v1/sensor/\"\n sensorID = \"\"\n sensorID1 = self:getVariable(\"sensorID1\")\n sensorID2 = self:getVariable(\"sensorID2\")\n interval = tonumber(self:getVariable(\"interval\")) \n httpTimeout = tonumber(self:getVariable(\"httpTimeout\")) \n userID = tonumber(self:getVariable(\"userID\")) \n debugLevel = tonumber(self:getVariable(\"debugLevel\"))\n local icon = tonumber(self:getVariable(\"icon\")) \n\n if sensorID1 ==\"\" or sensorID1 == nil then\n sensorID1 = \"13463\" -- Default sensorID is 13463 (just random sensor)\n self:setVariable(\"sensorID1\",sensorID1)\n self:trace(\"Added QuickApp variable sensorID1\")\n end\n if sensorID2 ==\"\" or sensorID2 == nil then\n sensorID2 = \"13464\" -- Default sensorID is 13463 (just random sensor)\n self:setVariable(\"sensorID2\",sensorID2)\n self:trace(\"Added QuickApp variable sensorID2\")\n end\n if interval == \"\" or interval == nil then\n interval = \"146\" -- Default interval is 73 because values needs 2 cyclus, normally the sensor renews its readings every 145 seconds \n self:setVariable(\"interval\",interval)\n self:trace(\"Added QuickApp variable interval\")\n interval = tonumber(interval)\n end \n if httpTimeout == \"\" or httpTimeout == nil then\n httpTimeout = \"60\" -- Default timeout is 120 (higher than normal to prevent errors)\n self:setVariable(\"httpTimeout\",httpTimeout)\n self:trace(\"Added QuickApp variable httpTimeout\")\n httpTimeout = tonumber(httpTimeout)\n end\n if userID == \"\" or userID == nil then \n userID = \"0\" -- Default userID\n self:setVariable(\"userID\",userID)\n self:trace(\"Added QuickApp variable userID\")\n userID = tonumber(userID)\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 icon == \"\" or icon == nil then \n icon = \"0\" -- Default icon\n self:setVariable(\"icon\",icon)\n self:trace(\"Added QuickApp variable icon\")\n icon = tonumber(icon)\n end\n if icon ~= 0 then \n self:updateProperty(\"deviceIcon\", icon) -- set user defined icon \n end\n sensorID = sensorID1 -- Set the sensorID to the first SensorID\nend\n\n\nfunction QuickApp:setupChildDevices()\n local cdevs = api.get(\"/devices?parentId=\"..self.id) or {} -- Pick up all my children \n function self:initChildDevices() end -- Null function, else Fibaro calls it after onInit()...\n\n if #cdevs==0 then -- No children, create children\n local initChildData = { \n {className=\"PolutionSensorTemp\", name=\"Temperature\", type=\"com.fibaro.temperatureSensor\", value=0, unit=\"°C\"},\n {className=\"PolutionSensorHumid\", name=\"Humidity\", type=\"com.fibaro.humiditySensor\", value=0, unit=\"%\"},\n {className=\"PolutionSensorHumidAbs\", name=\"Absolute Humidity\", type=\"com.fibaro.multilevelSensor\", value=0, unit=\"g/m³\"},\n {className=\"PolutionSensorPressure\", name=\"Airpressure\", type=\"com.fibaro.multilevelSensor\", value=0, unit=\"hPa\"},\n {className=\"PolutionSensorPM25\", name=\"PM2.5\", type=\"com.fibaro.multilevelSensor\", value=0, unit=\"µg/m³\"},\n {className=\"PolutionSensorPM10\", name=\"PM10\", type=\"com.fibaro.multilevelSensor\", value=0, unit=\"µg/m³\"},\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 = {}, -- Add interfaces if you need\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:debug(\"onInit\") \n self:setupChildDevices()\n self:getQuickAppVariables() \n http = net.HTTPClient({timeout=httpTimeout*1000})\n pm25prev,pm10prev = 0,0\n pm10Text,pm25Text,pm25Trend,pm10Trend = \"\",\"\",\"\",\"\"\n data = {}\n self:getData()\nend\n\n--EOF"}]}