Weatherstation WH2600

Others (MiLight, Hue, Toon etc...)
Post Reply
vanesp
Posts: 3
Joined: Thursday 08 September 2016 12:30
Target OS: Raspberry Pi
Domoticz version:
Contact:

Weatherstation WH2600

Post by vanesp » Thursday 08 September 2016 12:50

I have recently bought a weatherstation that has a small web-server with actual measurement values. It has functionality to upload these measurements automatically to Weatherunderground. It is known as the FOSHK WH2600 (also sold as Froggit WH2601 LAN, by Conrad as Renkforce WH2600, by Ambient Weather USA as WS-1400). It costs EUR 180, and can be ordered here from Conrad.

I wrote a PHP script to scrape the actual measurement values from the internal webpage of the weatherstation. I then create json messages in the Domoticz style for temperature, humidity, pressure, wind, lux etc. These are sent via MQTT to Domoticz.

The script is run once every 5 minutes using crontab, and the measurement values are updated.

I'm enclosing my code as an example.

Code: Select all

<?php

// here we publish MQTT
// https://www.cloudmqtt.com/docs-php.html
// https://github.com/bluerhinos/phpMQTT

require("phpMQTT.php");

$mqtt = new phpMQTT("localhost", 1883, "ambient"); //Change client name to something unique

define ("PRODUCTION", "True");
// comment out to go to test mode

// array with sensor values for Domoticz.
// 0 means: do not send
$idxlookup = array (
	'IndoorID' => 0,
	'Outdoor1ID' => 0,
	'inTemp' => 3,
	'inHumi' => 5,
	'AbsPress' => 0,
	'RelPress' => 7,
	'outTemp' => 4,
	'outHumi' => 6,
	'windir' => 0,
	'avgwind' => 9,
	'gustspeed' => 0,
	'solarrad' => 0,
	'uv' => 10,
	'uvi' => 10,
	'solarrad' => 11,
	'rainofhourly' => 8,
	'rainofdaily' => 0,
	'rainofweekly' => 0,
	'rainofmonthly' => 0,
	'rainofyearly' => 0,
	'CurrTime' => 0,
	'inBattSta' => 0,
	'outBattSta1' => 0,
	'Apply' => 0,
	'Cancel' => 0,
	'rain_Default' => 0,
);

if (defined('PRODUCTION')) {
	// create curl resource to retrieve the data from the weatherstation
	$ch = curl_init();

	// set url to the right page
	curl_setopt($ch, CURLOPT_URL, "192.168.2.22/livedata.htm");

	//return the transfer as a string
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

	// $output contains the output string
	$html = curl_exec($ch);

	// close curl resource to free up system resources
	curl_close($ch);
} else {
    $html = file_get_contents('livedata.htm'); //get the html returned from the test page
}

$ambient_doc = new DOMDocument();

libxml_use_internal_errors(TRUE); //disable libxml errors

if(!empty($html)){ //if any html is actually returned

    $ambient_doc->loadHTML($html);
    libxml_clear_errors(); //remove errors for yucky html

    $ambient_xpath = new DOMXPath($ambient_doc);

    //get all the input fields which represent data from the weather station
	// the name and the value are stored in attributes of the input field
	// e.g:
	//    <td bgcolor="#EDEFEF"><div class="item_1">Indoor Temperature</div></td>
	//    <td bgcolor="#EDEFEF"><input name="inTemp" disabled="disabled" type="text" class="item_2" style="WIDTH: 80px" value="21.5" maxlength="5" /></td>
    $ambient_row = $ambient_xpath->query('//input');

    foreach ($ambient_row as $value) {
		$attr = $value->getAttribute("name");
		if ($attr) {
			// store the name and the value for later processing
			$ambient[$attr]['name'] = $attr;
			$ambient[$attr]['value'] = $value->getAttribute("value");
			$ambient[$attr]['idx'] = $idxlookup[$attr];
		}
	}


if ($mqtt->connect()) {

	// now we have all values... go and create the JSON strings...

	// note, string differs depending on kind of value... needs some work for Domoticz
	// see: https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s#Temperature

	// Temperature
	// json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP
	//IDX = id of your device (This number can be found in the devices tab in the column "IDX")
	//TEMP = Temperature

	// indoor temperature
	$arr = array ('idx' => $ambient['inTemp']['idx'], 'nvalue' => 0, 'svalue' => $ambient['inTemp']['value']);
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	// outdoor temperature
	$arr = array ('idx' => $ambient['outTemp']['idx'], 'nvalue' => 0, 'svalue' => $ambient['outTemp']['value']);
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	// Humidity
	//json.htm?type=command&param=udevice&idx=IDX&nvalue=HUM&svalue=HUM_STAT
	//The above sets the parameters for a Humidity device
	//IDX = id of your device (This number can be found in the devices tab in the column "IDX")
	//HUM = Humidity: 45%
	//HUM_STAT = Humidity_status

	//Humidity_status can be one of:
	//0=Normal (30-70)
	//1=Comfortable (50-60)
	//2=Dry <30
	//3=Wet >70

	// indoor humidity
	$val = $ambient['inHumi']['value'];
	if ($val < 30) {
		$s = 2;
	} else if ($val > 70) {
		$s = 3;
	} else if (($val >= 50) && ($val <= 60)) {
		$s = 1;
	} else {
		$s = 0;
	}

	// $arr = array ('idx' => $ambient['inHumi']['idx'], 'nvalue' => 'Humidity: ' . $val . '%', 'svalue' => $s);
	$arr = array ('idx' => $ambient['inHumi']['idx'], 'nvalue' => (int)$val, 'svalue' => strval($s));
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	$val = $ambient['outHumi']['value'];
	// outdoor humidity
	if ($val < 30) {
		$s = 2;
	} else if ($val > 70) {
		$s = 3;
	} else if (($val >= 50) && ($val <= 60)) {
		$s = 1;
	} else {
		$s = 0;
	}

	// $arr = array ('idx' => $ambient['outHumi']['idx'], 'nvalue' => 'Humidity: ' . $val . '%', 'svalue' => $s);
	$arr = array ('idx' => $ambient['outHumi']['idx'], 'nvalue' => (int)$val, 'svalue' => strval($s));
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	//Barometer
	//json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=BAR;BAR_FOR
	//The above sets the parameters for a Barometer device from hardware type 'General'
	// BAR = Barometric pressure
	// BAR_FOR = Barometer forecast

	// Barometer forecast can be one of:
	// 0 = Stable
	// 1 = Sunny
	// 2 = Cloudy
	// 3 = Unstable
	// 4 = Thunderstorm
	// 5 = Unknown
	// 6 = Cloudy/Rain
	$arr = array ('idx' => $ambient['RelPress']['idx'], 'nvalue' => 0, 'svalue' => $ambient['RelPress']['value'] . ';5');
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	//Rain
	//json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=RAINRATE;RAINCOUNTER
	//RAINRATE = amount of rain in last hour
	//RAINCOUNTER = continues counter of fallen Rain in mm
	$arr = array ('idx' => $ambient['rainofhourly']['idx'], 'nvalue' => 0, 'svalue' => $ambient['rainofhourly']['value'] . ';' .  $ambient['rainofyearly']['value']);
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	//Wind
	//json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=WB;WD;WS;WG;22;24
	//WB = Wind bearing (0-359)
	//WD = Wind direction (S, SW, NNW, etc.)
	//WS = 10 * Wind speed [m/s]
	//WG = 10 * Gust [m/s]
	//22 = Temperature
	//24 = Temperature Windchill

	// First build the datastring
	$data = $ambient['windir']['value'];
	$data = $data . ';' . degToCompass($ambient['windir']['value']);
	$data = $data . ';' . $ambient['avgwind']['value'] * 10;
	$data = $data . ';' . $ambient['gustspeed']['value'] * 10;
	$data = $data . ';' . $ambient['outTemp']['value'];

	// T_{\rm wc}=13.12 + 0.6215 T_{\rm a}-11.37 V^{+0.16} + 0.3965 T_{\rm a} V^{+0.16}\,\!
	//where
	//T_{\rm wc}\,\! is the wind chill index, based on the Celsius temperature scale,
	//T_{\rm a}\,\! is the air temperature in degrees Celsius (°C), and
	//V\,\! is the wind speed at 10 metres (standard anemometer height), in kilometres per hour (km/h).[9]
	$v = $ambient['avgwind']['value'] * 3.6;
	$twc = 13.12 + 0.6215 * $ambient['outTemp']['value'] - (11.37 * pow ($v, 0.16)) + (0.3965 * $ambient['outTemp']['value'] * pow ($v, 0.16));
	$data = $data . ';' . $twc;
	$arr = array ('idx' => $ambient['avgwind']['idx'], 'nvalue' => 0, 'svalue' => $data);
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	//UV
	//json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=COUNTER;0
	// COUNTER = Float (in example: 2.1) with current UV reading.
	// Don't loose the ";0" at the end - without it database may corrupt.
	$arr = array ('idx' => $ambient['uv']['idx'], 'nvalue' => 0, 'svalue' => $ambient['uvi']['value'] . ';0');
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

	//Lux
	//json.htm?type=command&param=udevice&idx=IDX&svalue=VALUE
	//VALUE = value of luminosity in Lux
	$arr = array ('idx' => $ambient['solarrad']['idx'], 'svalue' => $ambient['solarrad']['value']);
	// echo json_encode($arr) . "\n";
	$mqtt->publish("domoticz/in",json_encode($arr),0);

    $mqtt->close();
    } else {
    	echo "No MQTT connection";
    }

}

function degToCompass($num) {
	// from a degree value on the compass rose, create the textual representation
    if ($num < 0) $num += 360;
    if ($num >= 360) $num -= 360;

    $val = round (($num-11.25) / 22.5); // each segment is 22.5 degrees... place the number in the middle
    $arr = array ("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW");
    return $arr[abs($val)]; // use absolute values to ensure that 359 degrees translates as N, like 1 degree
}

?>
Enjoy!

Peter

jendrush
Posts: 16
Joined: Wednesday 21 May 2014 20:39
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Weatherstation WH2600

Post by jendrush » Thursday 06 October 2016 13:27

Hi. Could you describe briefly how to get it to work?

vanesp
Posts: 3
Joined: Thursday 08 September 2016 12:30
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Weatherstation WH2600

Post by vanesp » Thursday 06 October 2016 13:52

See code in my earlier post. Run the php script as a cron job every 5 minutes. It scrapes all the weatherstation values and publishes them on MQTT.

Setup Domoticz to support MQTT (see https://www.domoticz.com/wiki/MQTT)

Define virtual sensors for temperature, humidity, windspeed in Domoticz using these MQTT values (see the php script). For details on the json formatting see https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s.

Use the corresponding IDX values in the php script, to update the table $idxlookup. Everytime the php script is run the virtual devices in Domoticz will receive a new, updated value.

What part of this are you having difficulty setting up ?

Peter

jendrush
Posts: 16
Joined: Wednesday 21 May 2014 20:39
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Weatherstation WH2600

Post by jendrush » Thursday 06 October 2016 13:57

Thank you for fast answer. I've just bought my weather station yesterday, and i am planning to mount it today. I am not a big linux guy, so i needed little tutorial how to make it work from scratch. I think that your reply made almost everything clear, so i will try to set this up soon. Thank you again.

Doudy
Posts: 41
Joined: Tuesday 09 August 2016 9:09
Target OS: -
Domoticz version:
Contact:

Re: Weatherstation WH2600

Post by Doudy » Monday 23 October 2017 17:23

Hello,

I am stuck in the first line:

Code: Select all

require("phpMQTT.php");
When I start the order :

Code: Select all

 sudo /usr/bin/php5 /home/pi/domoticz/scripts/php/wh2600.php
I have the following message:
PHP Warning: require(phpMQTT.php): failed to open stream: No such file or directory in /home/pi/domoticz/scripts/php/wh2600.php on line 7
PHP Fatal error: require(): Failed opening required 'phpMQTT.php' (include_path='.:/usr/share/php:/usr/share/pear') in /home/pi/domoticz/scripts/php/wh2600.php on line 7
an idea ?
Thanks

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest