Plugin file
Plugin configuration file
{
"name": "dragino-lht65n",
"version": "1.0.0",
"description": "Remote LoRaWAN temperature and humidity sensor",
"author": "Thinger.io",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/thinger-io/plugins.git",
"directory": "dragino-lht65n"
},
"metadata": {
"name": "Dragino LHT65N",
"description": "Remote LoRaWAN temperature and humidity sensor",
"category": "devices",
"image": "assets/dragino-lht65n.png"
},
"resources": {
"products": [
{
"enabled": true,
"name": "Dragino LHT65N",
"product": "LHT65N",
"profile": {
"api": {
"downlink": {
"enabled": true,
"handle_connectivity": false,
"request": {
"data": {
"path": "/downlink",
"payload": "{\r\n \"data\" : \"{{payload.data=\"\"}}\",\r\n \"port\" : {{payload.port=2}},\r\n \"priority\": {{payload.priority=3}},\r\n \"confirmed\" : {{payload.confirmed=false}},\r\n \"uplink\" : {{property.uplink}} \r\n}",
"payload_function": "",
"payload_type": "",
"plugin": "{{property.uplink.source}}",
"target": "plugin_endpoint"
}
},
"response": {
"data": {}
}
},
"uplink": {
"device_id_resolver": "",
"enabled": true,
"handle_connectivity": true,
"request": {
"data": {
"payload": "{{payload}}",
"payload_function": "",
"payload_type": "source_payload",
"target": "resource_stream"
}
},
"response": {
"data": {}
}
}
},
"autoprovisions": {
"device_autoprovisioning": {
"config": {
"mode": "pattern",
"pattern": "dragino-lht65n-.*"
},
"enabled": true
}
},
"buckets": {
"lht65n_data": {
"backend": "mongodb",
"data": {
"payload": "{{payload}}",
"payload_function": "getDataBucket",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"enabled": true,
"retention": {
"period": 3,
"unit": "months"
},
"tags": []
}
},
"code": {
"code": "/**\r\n * Thinger.io decoder for Dragino LHT65N\r\n */\r\n\r\nfunction getBAT(payload) {\r\n return payload.BAT;\r\n}\r\n\r\nfunction getFirmwareVersion(payload) {\r\n return payload.FIRMWARE_VERSION;\r\n}\r\n\r\nfunction getFrequency_Band(payload) {\r\n return payload.FREQUENCY_BAND;\r\n}\r\n\r\nfunction getSub_Band(payload) {\r\n return payload.SUB_BAND;\r\n}\r\n\r\nfunction getSENSOR_MODEL(payload) {\r\n return payload.SENSOR_MODEL;\r\n}\r\n\r\nfunction decode_Uplink(input) {\r\n var hexString = input.payload;\r\n var bytes = [];\r\n \r\n // Transform hex string to bytes array\r\n for (var i = 0; i < hexString.length; i += 2) {\r\n bytes.push(parseInt(hexString.substr(i, 2), 16));\r\n }\r\n\r\n\r\n try {\r\n // If port not exist use port2 as default\r\n var port = input.fPort || 2;\r\n \r\n // Call Dragino decoder\r\n var decoded = Decoder(bytes, port);\r\n \r\n return decoded;\r\n\r\n\r\n } catch (error) {\r\n return {\r\n error: \"Decoding error: \" + error.message,\r\n raw_payload: hexString,\r\n bytes_length: bytes.length,\r\n fPort: input.fPort || 2\r\n };\r\n }\r\n}\r\n\r\n\r\nfunction getDataBucket(payload) {\r\n return payload;\r\n}\r\n\r\n\r\n/** \r\n * Dragino decoder\r\n*/\r\nfunction Str1(str2){\r\n var str3 =\"\";\r\n for (var i=0;i<str2.length;i++){\r\n if (str2[i]<=0x0f){\r\n str2[i]=\"0\"+str2[i].toString(16)+\"\";\r\n }\r\n str3+= str2[i].toString(16)+\"\";}\r\n return str3;\r\n}\r\nfunction str_pad(byte){\r\n var zero = '00';\r\n var hex= byte.toString(16); \r\n var tmp = 2-hex.length;\r\n return zero.substr(0,tmp) + hex + \" \";\r\n}\r\n\r\nfunction datalog(i,bytes){\r\n var Ext= bytes[6]&0x0F;\r\n var bb;\r\n \tif((Ext=='1')||(Ext=='9'))\r\n{\r\n\tbb=parseFloat(((bytes[0+i]<<24>>16 | bytes[1+i])/100).toFixed(2));\r\n}\r\n \telse if((Ext=='2')||(Ext=='10'))\r\n{\r\n\tbb=parseFloat(((bytes[0+i]<<24>>16 | bytes[1+i])/100).toFixed(2));\r\n}\r\n\telse if(Ext=='4')\r\n{\r\n\tvar Exti_pin_level=bytes[0+i] ? \"High\":\"Low\"; \r\n var Exti_status=bytes[1+i] ? \"True\":\"False\";\r\n bb=Exti_pin_level+Exti_status;\r\n}\r\n\telse if(Ext=='5')\r\n{\r\n\tbb=bytes[0+i]<<8 | bytes[1+i];\r\n}\r\n\telse if(Ext=='6')\r\n{\r\n\tbb=(bytes[0+i]<<8 | bytes[1+i])/1000;\r\n}\r\n\telse if(Ext=='7')\r\n{\r\n\tbb=bytes[0+i]<<8 | bytes[1+i];\r\n}\r\n\telse if((Ext=='8')||(Ext=='14'))\r\n{\r\n\tbb=bytes[0+i]<<8 | bytes[1+i];\r\n}\r\nelse if((Ext=='11')||(Ext=='12'))\r\n{\r\n bb=parseFloat(((bytes[0+i]<<24>>16 | bytes[1+i])/100).toFixed(2)); \r\n}\r\n var cc= parseFloat(((bytes[2+i]<<24>>16 | bytes[3+i])/100).toFixed(2));\r\n var dd= parseFloat((((bytes[4+i]<<8 | bytes[5+i])&0xFFF)/10).toFixed(1));\r\n var ee= getMyDate((bytes[7+i]<<24 | bytes[8+i]<<16 | bytes[9+i]<<8 | bytes[10+i]).toString(10));\r\n var string='['+bb+','+cc+','+dd+','+ee+']'+','; \r\n \r\n return string;\r\n}\r\n\r\nfunction getzf(c_num){ \r\n if(parseInt(c_num) < 10)\r\n c_num = '0' + c_num; \r\n\r\n return c_num; \r\n}\r\n\r\nfunction getMyDate(str){ \r\n var c_Date;\r\n if(str > 9999999999)\r\n c_Date = new Date(parseInt(str));\r\n else \r\n c_Date = new Date(parseInt(str) * 1000);\r\n \r\n var c_Year = c_Date.getFullYear(), \r\n c_Month = c_Date.getMonth()+1, \r\n c_Day = c_Date.getDate(),\r\n c_Hour = c_Date.getHours(), \r\n c_Min = c_Date.getMinutes(), \r\n c_Sen = c_Date.getSeconds();\r\n var c_Time = c_Year +'-'+ getzf(c_Month) +'-'+ getzf(c_Day) +' '+ getzf(c_Hour) +':'+ getzf(c_Min) +':'+getzf(c_Sen); \r\n \r\n return c_Time;\r\n}\r\n\r\nfunction Decoder(bytes, port) {\r\nvar Ext= bytes[6];\r\nvar button = bytes[6]&0x10;\r\nvar poll_message_status=((bytes[6]>>6)&0x03);\r\n\r\nvar Connect=(bytes[6]&0x80)>>7;\r\nvar decode = {};\r\nvar data = {};\r\nif((port==3)&&((bytes[2]==0x01)||(bytes[2]==0x02)||(bytes[2]==0x03)||(bytes[2]==0x04))){\r\n\tvar array1=[]\r\n\tvar bytes1=\"0x\"\r\n\tvar str1=Str1(bytes)\r\n\tvar str2=str1.substring(0,6)\r\n\tvar str3=str1.substring(6,)\r\n var reg=/.{4}/g;\r\n\tvar rs=str3.match(reg);\r\n\trs.push(str3.substring(rs.join('').length));\r\n\trs.pop()\r\n\tvar new_arr = [...rs]\r\n\tvar data1=new_arr\r\n\tdecode.Node_type=\"LHT65N\";\r\n\tdecode.bat=parseInt(bytes1+str2.substring(0,4)& 0x3FFF)\r\n\tif (parseInt(bytes1+str2.substring(4,))==1){\r\n\t\tdecode.sensor=\"ds18b20\"\r\n\t}\r\n\telse if(parseInt(bytes1+str2.substring(4,))==2){\r\n\t decode.sensor=\"tmp117\"\r\n\t}\r\n\telse if(parseInt(bytes1+str2.substring(4,))==3){\r\n\t\tdecode.sensor=\"gxht30\"\r\n\t}\r\n\telse if(parseInt(bytes1+str2.substring(4,))==4){\r\n\t\tdecode.sensor=\"sht31\"\r\n\t}\t\r\n\tfor (var i=0;i<data1.length;i++){\r\n var temp=(parseInt(bytes1+data1[i].substring(0,4)))/100\r\n array1[i]=temp\r\n}\r\n\tdecode.Temp=array1\r\n\t{\r\n return decode;\r\n }\r\n}\t\r\nelse if(port==5)\r\n{\r\n var sub_band;\r\n var freq_band;\r\n var sensor;\r\n \r\n if(bytes[0]==0x0B)\r\n sensor= \"LHT65N\";\r\n else if(bytes[0]==0x1A)\r\n sensor= \"LHT65N-PIR\";\r\n \r\n if(bytes[4]==0xff)\r\n sub_band=\"NULL\";\r\n else\r\n sub_band=bytes[4];\r\n \r\n if(bytes[3]==0x01)\r\n freq_band=\"EU868\";\r\n else if(bytes[3]==0x02)\r\n freq_band=\"US915\";\r\n else if(bytes[3]==0x03)\r\n freq_band=\"IN865\";\r\n else if(bytes[3]==0x04)\r\n freq_band=\"AU915\";\r\n else if(bytes[3]==0x05)\r\n freq_band=\"KZ865\";\r\n else if(bytes[3]==0x06)\r\n freq_band=\"RU864\";\r\n else if(bytes[3]==0x07)\r\n freq_band=\"AS923\";\r\n else if(bytes[3]==0x08)\r\n freq_band=\"AS923_1\";\r\n else if(bytes[3]==0x09)\r\n freq_band=\"AS923_2\";\r\n else if(bytes[3]==0x0A)\r\n freq_band=\"AS923_3\";\r\n else if(bytes[3]==0x0B)\r\n freq_band=\"CN470\";\r\n else if(bytes[3]==0x0C)\r\n freq_band=\"EU433\";\r\n else if(bytes[3]==0x0D)\r\n freq_band=\"KR920\";\r\n else if(bytes[3]==0x0E)\r\n freq_band=\"MA869\";\r\n \r\n var firm_ver= (bytes[1]&0x0f)+'.'+(bytes[2]>>4&0x0f)+'.'+(bytes[2]&0x0f);\r\n var bat= (bytes[5]<<8 | bytes[6])/1000;\r\n \r\n return {\r\n SENSOR_MODEL:sensor,\r\n FIRMWARE_VERSION:firm_ver,\r\n FREQUENCY_BAND:freq_band,\r\n SUB_BAND:sub_band,\r\n BAT:bat,\r\n };\r\n}\r\n\r\nswitch (poll_message_status) {\t\t\r\ncase 0:\t\r\n{ \r\nif(Ext==0x09)\r\n{\r\n decode.TempC_DS=parseFloat(((bytes[0]<<24>>16 | bytes[1])/100).toFixed(2));\r\n decode.Bat_status=bytes[4]>>6;\r\n}\r\nelse if(Ext==0x0A)\r\n{\r\n decode.TempC_TMP117=parseFloat(((bytes[0]<<24>>16 | bytes[1])/100).toFixed(2));\r\n decode.Bat_status=bytes[4]>>6; \r\n}\r\nelse\r\n{\r\n decode.BatV= ((bytes[0]<<8 | bytes[1]) & 0x3FFF)/1000;\r\n var Bat_status=bytes[0]>>6;\r\n if (Bat_status == 3)\r\n decode.Bat_status=\"Good\"\r\n else if(Bat_status == 2)\r\n decode.Bat_status=\"OK\"\r\n else if(Bat_status == 1)\r\n decode.Bat_status=\"Low\"\r\n else if(Bat_status == 0)\r\n decode.Bat_status=\"Ultra Low\"\r\n}\r\n\r\nif((Ext!=0x0f)&&(Ext!=0x10)&&(Ext!=0x20)&&(Ext!=0x0E))\r\n{\r\n decode.TempC_SHT=parseFloat(((bytes[2]<<24>>16 | bytes[3])/100).toFixed(2));\r\n decode.Hum_SHT=parseFloat((((bytes[4]<<8 | bytes[5])&0xFFF)/10).toFixed(1));\r\n}\r\nif(Connect=='1')\r\n{\r\n decode.No_connect=\"Sensor no connection\";\r\n}\r\n\r\nif(Ext=='0')\r\n{\r\n decode.Ext_sensor =\"No external sensor\";\r\n}\r\nelse if(Ext=='1')\r\n{\r\n decode.Ext_sensor =\"Temperature Sensor\";\r\n decode.TempC_DS=parseFloat(((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2));\r\n}\r\nelse if(Ext=='2')\r\n{\r\n decode.Ext_sensor =\"Temperature Sensor\";\r\n decode.TempC_TMP117=parseFloat(((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2));\r\n}\r\nelse if(Ext=='4')\r\n{\r\n decode.Work_mode=\"Interrupt Sensor send\";\r\n decode.Exti_pin_level=bytes[7] ? \"High\":\"Low\"; \r\n decode.Exti_status=bytes[8] ? \"True\":\"False\";\r\n \r\n}\r\nelse if(Ext=='5')\r\n{\r\n decode.Work_mode=\"Illumination Sensor\";\r\n decode.ILL_lx=bytes[7]<<8 | bytes[8];\r\n}\r\nelse if(Ext=='6')\r\n{\r\n decode.Work_mode=\"ADC Sensor\";\r\n decode.ADC_V=(bytes[7]<<8 | bytes[8])/1000;\r\n}\r\nelse if(Ext=='7')\r\n{\r\n decode.Work_mode=\"Interrupt Sensor count\";\r\n decode.Exit_count=bytes[7]<<8 | bytes[8];\r\n}\r\nelse if(Ext=='8')\r\n{\r\n decode.Work_mode=\"Interrupt Sensor count\";\r\n decode.Exit_count=bytes[7]<<24 | bytes[8]<<16 | bytes[9]<<8 | bytes[10];\r\n}\r\nelse if(Ext=='9')\r\n{\r\n decode.Work_mode=\"DS18B20 & timestamp\";\r\n decode.Systimestamp=(bytes[7]<<24 | bytes[8]<<16 | bytes[9]<<8 | bytes[10] );\r\n}\r\nelse if(Ext==0x0A)\r\n{\r\n decode.Work_mode=\"TMP117 & timestamp\";\r\n decode.Systimestamp=(bytes[7]<<24 | bytes[8]<<16 | bytes[9]<<8 | bytes[10] ); \r\n}\r\nelse if(Ext=='11')\r\n{\r\n decode.Work_mode=\"SHT31 Sensor\";\r\n decode.Ext_TempC_SHT=parseFloat(((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2));\r\n decode.Ext_Hum_SHT=parseFloat((((bytes[9]<<8 | bytes[10])&0xFFF)/10).toFixed(1)); \r\n}\r\nelse if(Ext==0x10)\r\n{\r\n decode.Work_mode=\"SHT31ID\";\r\n decode.ID=str_pad(bytes[2])+str_pad(bytes[3])+str_pad(bytes[4])+str_pad(bytes[5]);\r\n decode.Ext_TempC_SHT=parseFloat(((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2));\r\n decode.Ext_Hum_SHT=parseFloat((((bytes[9]<<8 | bytes[10])&0xFFF)/10).toFixed(1)); \r\n}\r\nelse if(Ext==0x20)\r\n{\r\n decode.Work_mode=\"NE117ID\";\r\n decode.ID=str_pad(bytes[2])+str_pad(bytes[3])+str_pad(bytes[4])+str_pad(bytes[5])+str_pad(bytes[9])+str_pad(bytes[10]);\r\n decode.TempC_TMP117=parseFloat(((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2)); \r\n}\r\nelse if(Ext=='15')\r\n{\r\n decode.Work_mode=\"DS18B20ID\";\r\n decode.ID=str_pad(bytes[2])+str_pad(bytes[3])+str_pad(bytes[4])+str_pad(bytes[5])+str_pad(bytes[7])+str_pad(bytes[8])+str_pad(bytes[9])+str_pad(bytes[10]);\r\n}\r\n}\r\n decode.Node_type=\"LHT65N\";\r\n if((bytes.length==11)||(bytes.length==15))\r\n {\r\n return decode;\r\n }\r\nbreak;\r\n\r\ncase 1:\r\n {\r\n for(var i=0;i<bytes.length;i=i+11)\r\n {\r\n var da= datalog(i,bytes);\r\n if(i=='0')\r\n decode.DATALOG=da;\r\n else\r\n decode.DATALOG+=da;\r\n }\r\ndecode.Node_type=\"LHT65N\";\r\n}\r\n{\r\nreturn decode;\r\n}\r\nbreak;\r\n\r\ncase 2:\r\n {\r\n for(var i=0;i<bytes.length;i=i+11)\r\n {\r\n var da= datalog(i,bytes);\r\n if(i=='0')\r\n data.DATALOG=da;\r\n else\r\n data.DATALOG+=da;\r\n }\r\n\tdata.Node_type=\"LHT65N\";\r\n}\r\n{\r\nreturn{\r\n data:data,\r\n retransmission_Status:\"retransmission_Status\",\r\n };\r\n}\r\nbreak;\r\n\r\n\r\ndefault:\r\n return {\r\n errors: [\"unknown\"]\r\n }\r\n}\r\n}",
"environment": "javascript",
"storage": "",
"version": "1.0"
},
"flows": {
"lht65n_decoder_flow": {
"data": {
"payload": "{{payload}}",
"payload_function": "decode_Uplink",
"payload_type": "source_payload",
"resource": "uplink",
"source": "resource",
"update": "events"
},
"enabled": true,
"sink": {
"payload": "{{payload}}",
"payload_function": "",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"target": "resource_stream"
},
"split_data": false
}
},
"properties": {
"lht65n_bat": {
"data": {
"payload": "{{payload}}",
"payload_function": "getBAT",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"default": {
"source": "value"
},
"enabled": true
},
"lht65n_firmware_version": {
"data": {
"payload": "{{payload}}",
"payload_function": "getFirmwareVersion",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"default": {
"source": "value"
},
"enabled": true
},
"lht65n_frequency_band": {
"data": {
"payload": "{{payload}}",
"payload_function": "getFrequency_Band",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"default": {
"source": "value"
},
"enabled": true
},
"lht65n_sensor_model": {
"data": {
"payload": "{{payload}}",
"payload_function": "getSENSOR_MODEL",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"default": {
"source": "value"
},
"enabled": true
},
"lht65n_sub_band": {
"data": {
"payload": "{{payload}}",
"payload_function": "getSub_Band",
"payload_type": "source_payload",
"resource_stream": "uplink_decoded",
"source": "resource_stream"
},
"default": {
"source": "value"
},
"enabled": true
},
"uplink": {
"data": {
"payload": "{{payload}}",
"payload_function": "",
"payload_type": "source_payload",
"resource": "uplink",
"source": "resource",
"update": "events"
},
"default": {
"source": "value"
},
"description": "Last raw uplink recieved",
"enabled": true
}
}
},
"_resources": {
"properties": [
{
"property": "dashboard",
"value": {
"properties": {
"template": true
},
"tabs": [
{
"icon": "fas fa-tachometer-alt",
"widgets": [
{
"layout": {
"col": 3,
"row": 12,
"sizeX": 1,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Humidity"
},
"properties": {
"color": "#0000ff",
"max": 100,
"min": 0,
"unit": "%Rh"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "Hum_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#1abc9c",
"name": "Source 1",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 3,
"row": 6,
"sizeX": 1,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "External Temperature"
},
"properties": {
"color": "#ff0000",
"max": 100,
"min": 0,
"unit": "ºC"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_DS",
"tags": {
"device": [],
"group": []
}
},
"color": "#1abc9c",
"name": "Source 1",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 3,
"row": 0,
"sizeX": 1,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Internal Temperature"
},
"properties": {
"color": "#ff0000",
"max": 100,
"min": 0,
"unit": "ºC"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#1abc9c",
"name": "Source 1",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 4,
"row": 0,
"sizeX": 2,
"sizeY": 12
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Last recorded information"
},
"properties": {
"source": "code",
"template": "<div style=\"width:100%; height:100%; overflow-y:auto\">\r\n <table class=\"table table-striped table-condensed\">\r\n <thead>\r\n <tr>\r\n <th>Date</th>\r\n <th>Internal Temperature (°C)</th>\r\n <th>Humidity (%RH)</th>\r\n <th>External Temperature (°C)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr ng-repeat=\"entry in value\">\r\n <td>{{ entry.ts | date:'medium' }}</td>\r\n <td>{{ entry.TempC_SHT || entry.temperature || '—' }}</td>\r\n <td>{{ entry.Hum_SHT || entry.humidity || '—' }}</td>\r\n <td>{{ entry.TempC_DS || entry.external_temp || '—' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n</div>\r\n"
},
"sources": [
{
"aggregation": {},
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "ts",
"tags": {
"device": [],
"group": []
}
},
"color": "#1abc9c",
"name": "ts",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
},
{
"aggregation": {},
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#ff0000",
"name": "internal temperature",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
},
{
"aggregation": {},
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "Hum_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#3498db",
"name": "humidity",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
},
{
"aggregation": {},
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_DS",
"tags": {
"device": [],
"group": []
}
},
"color": "#9b59b6",
"name": "external Temperature",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
}
],
"type": "html_time"
},
{
"layout": {
"col": 0,
"row": 12,
"sizeX": 3,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Historic Humidity"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": true
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "Hum_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#0000ff",
"name": "Humidity",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
}
],
"type": "chart"
},
{
"layout": {
"col": 0,
"row": 0,
"sizeX": 3,
"sizeY": 12
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Historic Temperature"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": true
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_SHT",
"tags": {
"device": [],
"group": []
}
},
"color": "#ff0000",
"name": "Internal Temperature",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
},
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "TempC_DS",
"tags": {
"device": [],
"group": []
}
},
"color": "#e39f0d",
"name": "External Temperature",
"source": "bucket",
"timespan": {
"magnitude": "hour",
"mode": "relative",
"period": "latest",
"value": 24
}
}
],
"type": "chart"
},
{
"layout": {
"col": 4,
"row": 12,
"sizeX": 2,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Battery"
},
"properties": {
"color": "#f0e924",
"max": 4,
"min": 3,
"unit": "V"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "lht65n_data",
"mapping": "BatV",
"tags": {
"device": [],
"group": []
}
},
"color": "#1abc9c",
"name": "Source 1",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
}
]
}
]
}
}
]
}
}
]
}
}