CREATIVE CHAOS   ▋ blog

Home Temperature Monitoring with Grafana

PUBLISHED ON 30/11/2017 — EDITED ON 11/12/2023 — PROJECTS

Intro

From nothing to full fledged monitoring with stuff laying around.

HWG-STE push HWG-STE plus

Fake routing for PUSH hostname

First challenge was to send push data to my own server. Unfortunately the devices have hardcoded push URL string set up. But that is a small bump in the road for us. We will fake DNS resolving of the sensdesk.com hostname and route all requests to our server.

I have an ASUS router with alternative FW called Merlin, that can do that. Most advanced routers have this option, so search for the solution for your specific hardware.

echo "address=/sensdesk.com/176.31.162.150" > /jffs/configs/dnsmasq.conf.add && service restart_dnsmasq

Source

Intercept the PUSH on the server

Source

As devices are sending HTTP POST requests, we can direct the request to fake apache site (virtual host) at our server.

Create one and enable it, for ServerName, set sensdesk.com.

There is no documentation on POST so I have intercepted the request and extracted it like this:

a2enmod security2
 # Enable the module.
    SecRuleEngine On
    SecAuditEngine on

    # Setup logging in a dedicated file.
    SecAuditLog /var/log/apache2/website-audit.log
    # Allow it to access requests body.
    SecRequestBodyAccess on
    SecAuditLogParts ABIFHZ

    # Setup default action.
    SecDefaultAction "nolog,noauditlog,allow,phase:2"

    # Define the rule that will log the content of POST requests.
    SecRule REQUEST_METHOD "^POST$" "chain,allow,phase:2,id:123"
    SecRule REQUEST_URI ".*" "auditlog"

This is what we got:

--ed1d9e24-A--
[22/Nov/2017:17:26:27 +0100] WhWlM7AfopYAAG7LN5sAAAAM 84.52.146.140 4807 176.31.162.150 80
--ed1d9e24-B--
POST /portal.php? HTTP/1.1
Host: sensdesk.com
User-Agent: HWg-STE Px Version 2.0.7
Content-type: text/xml
Transfer-Encoding: chunked
Authorization: Basic ZGVuaTpFWGhjbmE=

--ed1d9e24-C--
<?xml version="1.0" encoding="utf-8"?><Root><Agent><Version>2.0.7</Version><XmlVer>4.02</XmlVer><Model>52</Model><vendor_id>0</vendor_id><MAC>00:0A:59:02:14:F4</MAC></Agent><Network><IPAddr>192.168.1.149</IPAddr><Submask>255.255.255.0</Submask><Gateway>192.168.1.1</Gateway><HttpPort>80</HttpPort></Network><Time><TimeZone>1</TimeZone><SummerTime>1</SummerTime><Timestamp>1511367985</Timestamp><UpTime>125610</UpTime></Time><Portal><DeviceName>HWg-STE Push</DeviceName><PushSource>0</PushSource><Retransmit>1</Retransmit><PushPeriod>900</PushPeriod><LogPeriod>300</LogPeriod><APLimit>30</APLimit><APSourceID>0</APSourceID><ServerAddress>http://sensdesk.com/portal.php</ServerAddress><PortalPort>80</PortalPort></Portal><Sensors><Entry><ID>4684</ID><Name>RH IN</Name><Units>%RH</Units><Exp>-1</Exp><ValueLog><Value>501;501;501;501;501;501;501;501;501;501</Value><TimeOffset>-655;-505;-480;-450;-355;-341;-330;-300;-55;0</TimeOffset><Status>1;1;1;1;1;1;1;1;1;1</Status></ValueLog><Value>501</Value></Entry><Entry><ID>45505</ID><Name>T IN</Name><Units>C</Units><Exp>-1</Exp><ValueLog><Value>215;215;215;215;215;216;216;216;216;217</Value><TimeOffset>-655;-505;-480;-450;-355;-341;-330;-300;-55;0</TimeOffset><Status>1;1;1;1;1;1;1;1;1;1</Status></ValueLog><Value>217</Value></Entry></Sensors><Inputs></Inputs></Root>
--ed1d9e24-F--
HTTP/1.1 403 Forbidden
Content-Length: 219
Content-Type: text/html; charset=iso-8859-1

Some PHP magic to parse the data

I have minimal experience with PHP and I have come up with this, name the file portal.php and put it in DocumentRoot:

<?php
$post = file_get_contents("php://input");
$xml=simplexml_load_string($post) or die("Error: Cannot create object");

# echo $xml->Agent->Version . "<br>";
# echo $xml->Agent->XmlVer . "<br>";
# echo $xml->Agent->Model . "<br>";
# echo $xml->Agent->vendor_id . "<br>";
# echo $xml->Agent->MAC . "<br>";

#$IPAddr = $xml->Network->IPAddr;
#echo $xml->Network->Submask;
#echo $xml->Network->Gateway;
#echo $xml->Network->HttpPort;

# echo $xml->Time->TimeZone;
# echo $xml->Time->SummerTime;
# echo $xml->Time->Timestamp;
$UpTime = $xml->Time->UpTime;


$DeviceName = $xml->Portal->DeviceName;
# echo $xml->Portal->PushSource;
# echo $xml->Portal->Retransmit;
# echo $xml->Portal->PushPeriod;
# echo $xml->Portal->LogPeriod;
# echo $xml->Portal->APLimit;
# echo $xml->Portal->APSourceID;
# echo $xml->Portal->ServerAddress;
# echo $xml->Portal->PortalPort;


# echo $xml->Sensors->Entry[0]->ID;
#$Name1 = $xml->Sensors->Entry[0]->Name;
# echo $xml->Sensors->Entry[0]->Units;
# echo $xml->Sensors->Entry[0]->Exp;
# echo $xml->Sensors->Entry[0]->ValueLog->Value;
# echo $xml->Sensors->Entry[0]->ValueLog->TimeOffset;
# echo $xml->Sensors->Entry[0]->ValueLog->Status;
$Value1 = $xml->Sensors->Entry[0]->Value;

# echo $xml->Sensors->Entry[1]->ID;
#$Name2 = $xml->Sensors->Entry[1]->Name;
# echo $xml->Sensors->Entry[1]->Units;
# echo $xml->Sensors->Entry[1]->Exp;
# echo $xml->Sensors->Entry[1]->ValueLog->Value;
# echo $xml->Sensors->Entry[1]->ValueLog->TimeOffset;
# echo $xml->Sensors->Entry[1]->ValueLog->Status;
$Value2 = $xml->Sensors->Entry[1]->Value;



# echo $xml->Inputs->Entry[0]->ID;
# echo $xml->Inputs->Entry[0]->Name;
# echo $xml->Inputs->Entry[0]->ValueLog->Value;
# echo $xml->Inputs->Entry[0]->ValueLog->TimeOffset;
# echo $xml->Inputs->Entry[0]->Value;


# echo $xml->Inputs->Entry[1]->ID;
# echo $xml->Inputs->Entry[1]->Name;
# echo $xml->Inputs->Entry[1]->ValueLog->Value;
# echo $xml->Inputs->Entry[1]->ValueLog->TimeOffset;
# echo $xml->Inputs->Entry[1]->Value;


$out = "hwg,geohash=u24mcvhtmbyk,name=".$DeviceName." uptime=".$UpTime.",rh=".$Value1.",temp=".$Value2."\n";


file_put_contents($DeviceName, $out);

?>

There is a lot of variables I don’t use, but I still went the whole way of configuring them if I decide that I want them in the future.

Telegraf.conf

# Read metrics from one or more commands that can output to stdout
[[inputs.exec]]
  ## Commands array
  commands = [
    "cat /var/www/sensdesk.com/ZP17-IN",
    "cat /var/www/sensdesk.com/ZP17-OUT",
  ]

  ## Timeout for each command to complete.
  timeout = "5s"

  ## measurement name suffix (for separating different commands)
  name_suffix = "_info"

  ## Data format to consume.
  ## Each data format has its own unique set of configuration options, read
  ## more about them here:
  ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
  data_format = "influx"

See Also