Purpleair sensor WD reporting strangeness

Hi Brian,

I noticed this morning, that something was odd with the AQI graph, so I updated WD to 10.37S-(b83) (from b78) and saw that a second sensor had been added to the config panel, so I added the 4300 sensor to my 4299 sensor, tested and all seemed well:

But, the AQI graph did not improve

Even the testtags.php values were ‘off’ for PM2.5 and AQI

My Purpleair page (retrieving and formatting the http://www.purpleair.com/json?show=4299 data page showed the data on the prime sensor was working correctly, and the AQI graph (drawn by WD) was still wonky before and after the WD version upgrade.

Yes, our AQI is bad due to smoke from the Camp Fire conflagration drifting over 200 miles from the north to us. I don’t know what happened at 2:11 on the graph, but even after the update of WD and restart, the problem is persisting.

Help??

I need a copy of the airquality.txt and airquality2.txt files when the problem is occuring

Did some more digging and wrote a quick script to locally poll the Purpleair sensor to see how the submissions to Purpleair.com are fairing.

I run this on my local network (which is the same network as the local Purpleair sensor)

<?php
# quick program to read the local Purpleair system and report submission status
#
# Ken True - Saratoga-weather.org - 11-Nov-2018
#
$localURL = 'http://192.168.1.186/json';
date_default_timezone_set("America/Los_Angeles");
$timeFormat = 'd-M-Y H:i:s T';


$rawJSON = file_get_contents($localURL);
$JSON = json_decode($rawJSON,true);
header('Content-type: text/plain,charset=ISO-8859-1');

//print_r($JSON);
/*
Array
(
    [SensorId] => a0:20:a6:a:a2:7a
    [DateTime] => 2018/11/11T22:45:47z
    [Geo] => AirMonitor_a27a
    [Mem] => 25752
    [Id] => 421
    [Adc] => 0.01
    [lat] => 37.2747
    [lon] => -122.022903
    [accuracy] => 0
    [elevation] => 0
    [version] => 2.50i
    [uptime] => 16640
    [rssi] => -70
    [hardwareversion] => 2.0
    [hardwarediscovered] => 2.0+OPENLOG+16021 MB+DS3231+BME280+PMSX003A+PMSX003B
    [current_temp_f] => 75
    [current_humidity] => 9
    [current_dewpoint_f] => 12.31
    [pressure] => 1007.25
    [pm1_0_atm_b] => 105.76
    [pm2_5_atm_b] => 137.73
    [pm10_0_atm_b] => 145.79
    [pm1_0_cf_1_b] => 69.09
    [pm2_5_cf_1_b] => 90.94
    [pm10_0_cf_1_b] => 96.52
    [p_0_3_um_b] => 15434.36
    [p_0_5_um_b] => 4928.36
    [p_1_0_um_b] => 707.55
    [p_2_5_um_b] => 32.79
    [p_5_0_um_b] => 6.61
    [p_10_0_um_b] => 0.55
    [pm1_0_atm] => 101.89
    [pm2_5_atm] => 139.11
    [pm10_0_atm] => 147
    [pm1_0_cf_1] => 67.3
    [pm2_5_cf_1] => 92.04
    [pm10_0_cf_1] => 97.4
    [p_0_3_um] => 17306.36
    [p_0_5_um] => 5124.11
    [p_1_0_um] => 764.96
    [p_2_5_um] => 37.7
    [p_5_0_um] => 11.79
    [p_10_0_um] => 0.89
    [responseCode] => 504
    [responseCode_date] => 1541976327
    [key1_responseCode] => 200
    [key1_responseCode_date] => 1541962057
    [key1_count] => 376476
    [key2_responseCode] => 200
    [key2_responseCode_date] => 1541962067
    [key2_count] => 380139
    [key1_responseCode_b] => 200
    [key1_responseCode_date_b] => 1541962087
    [key1_count_b] => 380002
    [key2_responseCode_b] => 200
    [key2_responseCode_date_b] => 1541976337
    [key2_count_b] => 380863
)
*/
$now = time();

$toPrint = array(
  'responseCode' => 'responseCode_date',
	'key1_responseCode' => 'key1_responseCode_date',
	'key2_responseCode' => 'key2_responseCode_date',
	'key1_responseCode_b' => 'key1_responseCode_date_b',
	'key2_responseCode_b' => 'key2_responseCode_date_b',
	);
print "$localURL status as of ".date($timeFormat,$now)."\n\n";
	
foreach ($toPrint as $rc => $timec) {
	if(isset($JSON[$rc]) and isset($JSON[$timec])) {
	  print "$rc $JSON[$rc] at ".date($timeFormat,$JSON[$timec]). 
		  " (".sec2hms($now-$JSON[$timec]).")\n";
	}
}


function sec2hms ($sec, $padHours = false) 
{

	// holds formatted string
	$hms = "";
	if (! is_numeric($sec)) { return($sec); }
	// there are 3600 seconds in an hour, so if we
	// divide total seconds by 3600 and throw away
	// the remainder, we've got the number of hours
	$hours = intval(intval($sec) / 3600); 

	// add to $hms, with a leading 0 if asked for
	$hms .= ($padHours) 
				? str_pad($hours, 2, "0", STR_PAD_LEFT). ':'
				: $hours. ':';
	 
	// dividing the total seconds by 60 will give us
	// the number of minutes, but we're interested in 
	// minutes past the hour: to get that, we need to 
	// divide by 60 again and keep the remainder
	$minutes = intval(($sec / 60) % 60); 

	// then add to $hms (with a leading 0 if needed)
	$hms .= str_pad($minutes, 2, "0", STR_PAD_LEFT). ':';

	// seconds are simple - just divide the total
	// seconds by 60 and keep the remainder
	$seconds = intval($sec % 60); 

	// add to $hms, again with a leading 0 if needed
	$hms .= str_pad($seconds, 2, "0", STR_PAD_LEFT);

	// done!
	return $hms;
	
}

I can now see results like

http://192.168.1.186/json status as of 11-Nov-2018 15:16:37 PST

responseCode 201 at 11-Nov-2018 15:15:15 PST (0:01:22)
key1_responseCode 200 at 11-Nov-2018 15:15:37 PST (0:01:00)
key2_responseCode 200 at 11-Nov-2018 15:15:47 PST (0:00:50)
key1_responseCode_b 200 at 11-Nov-2018 15:16:07 PST (0:00:30)
key2_responseCode_b 200 at 11-Nov-2018 15:16:17 PST (0:00:20)

I had been seeing responseCode 504 while I was shown offline on purpleair.com. Hmmmm… the more I research it, I think it is a network/server issue on their part,

I wrote to the purpleair.com folks with the query

The last several days, my Purpleair sensor has been dropping off the map (along with many others).
I see in the JSON, that the responseCode is 504 to submissions from the unit (instead of the usual 201 response code).

Is there something amiss with the intake servers that they would return 504 errors instead of processing the upload data?

The reply came back with

Hi Ken,

We discovered over the weekend that one of our partner’s servers stopped responding as expected to PurpleAir sensors. This blocked PurpleAir data from reaching the PurpleAir map. We have suspended the connection with this server and your sensor should now be online. If your sensor is still not online, try unplugging it and plugging it back in.

We will send an update to all PurpleAir sensors once we can confirm with this partner the cause of this error.

Thank you for your patience. Please let us know if you have any questions.

Best,
Mallory

So, I was correct in assigning the cause of the issues to their servers.

I also updated to b84 .zip update yesterday, and that combined with the purpleair.com server fix has now resulted in a stable AQI graph again

and testtags.php values looking normal

//==========
//Air Quality
//==========
$purpleair2_5 = '32.0'; 	 //Value of 2.5 micron particle measure from purple air sensor (see in WD under setup, advanced/misc)
$purpleair1_0 = '186.2'; 	 //Value of 1.0 micron particle measure from purple air sensor
$purpleair10_0 = '282.3'; 	 //Value of 10.0 micron particle measure from purple air sensor
$purpleairaqi = '94.7'; 	 //AQI (air quality index) value from purple air sensor
$purpleairaqidescription = 'Moderate ';	 //AQI description (e.g Good, moderate)
$purpleair60minmean10_0 = '287.0'; 	 //Last 60 minutes average PM 10.0 value
$purpleair60minmean2_5 = '32.9'; 	 //Last 60 minutes average PM 2.5 value
$purpleair24hourmean10_0 = '282.3'; 	 //Last 24 hours average PM 10.0 value
$purpleair24hourmean2_5 = '48.1'; 	 //Last 24 hours average PM 2.5 value
$purpleair60minmin10_0 = '282.3'; 	 //Min value in last 60 minutes PM 10.0 value
$purpleair24hourmin10_0 = '0.0'; 	 //Min value in last 24 hours PM 10.0 value
$purpleair60minmin2_5 = '28.0'; 	 //Min value in last 60 minutes PM 2.5 value
$purpleair24hourmin2_5 = '-1.0'; 	 //Min value in last 24 hours PM 2.5 value
$purpleair60minmax10_0 = '282.3'; 	 //Max value in last 60 minutes PM 10.0 value
$purpleair24hourmax10_0 = '282.3'; 	 //Max value in last 24 hours PM 10.0 value
$purpleair60minmax2_5 = '46.4'; 	 //Max value in last 60 minutes PM 2.5 value
$purpleair24hourmax2_5 = '96.1'; 	 //Max value in last 24 hours PM 2.5 value
$purpleair2_52 ='103.0'; //2nd sensor 2.5 reading
$purpleair1_02 ='103.0'; //2nd sensor 1.0 reading
$purpleair10_02 ='0.0'; //2nd sensor 10 reading 
$purpleairaqi2  ='175.5'; //2nd sensor aqi reading
$purpleairaqidescription2  = 'Unhealthy '; // 2nd sensor aqi description



aqichart.gif