diff --git a/CREATE-SP.sql b/CREATE-SP.sql index fd7a19d..98aefe0 100644 --- a/CREATE-SP.sql +++ b/CREATE-SP.sql @@ -1,7 +1,24 @@ -DELIMITER $$ DROP PROCEDURE IF EXISTS GETRECENTOBS; DROP PROCEDURE IF EXISTS GETDAILYRECORDS; +DROP PROCEDURE IF EXISTS GETWUNDERGROUNDDATA; + +-- Create the Settings table if it doesn't exist +CREATE TABLE IF NOT EXISTS `SETTINGS` ( + `idSETTINGS` int(11) NOT NULL AUTO_INCREMENT, + `NAME` varchar(45) DEFAULT NULL, + `VALUE` varchar(45) DEFAULT NULL, + PRIMARY KEY (`idSETTINGS`), + UNIQUE KEY `NAME_UNIQUE` (`NAME`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; + +-- Add the known settings. This won't add them if they are there because of the Unique key. +INSERT IGNORE INTO SETTINGS (name) VALUE ('WUNDERGROUND_ID'); +INSERT IGNORE INTO SETTINGS (name) VALUE ('WUNDERGROUND_PASSWORD'); +INSERT IGNORE INTO SETTINGS (name) VALUE ('showMetricAndCelsiusMeasurements'); +INSERT IGNORE INTO SETTINGS (name) VALUE ('showPressureInMillibars'); +-- Create the stored procedures +DELIMITER $$ CREATE PROCEDURE `GETRECENTOBS`() BEGIN (SELECT @@ -66,4 +83,14 @@ BEGIN @stormTotal AS LastStormTotal, @LowSinceMidnight AS LowSinceMidnight, @HighSinceMidnight AS HighSinceMidnight; -END## \ No newline at end of file +END## + +DELIMITER && +CREATE PROCEDURE `GETWUNDERGROUNDDATA`() +BEGIN + SELECT SUM(Rainfall) FROM WEATHER_MEASUREMENT WHERE created >= DATE_SUB(NOW(),INTERVAL 1 HOUR) INTO @rainPastHour; + SELECT SUM(Rainfall) FROM WEATHER_MEASUREMENT WHERE created >= DATE(NOW()) INTO @rainSinceMidnight; + SELECT VALUE FROM SETTINGS WHERE NAME = 'WUNDERGROUND_ID' LIMIT 1 INTO @WUNDERGROUND_ID; + SELECT VALUE FROM SETTINGS WHERE NAME = 'WUNDERGROUND_PASSWORD' LIMIT 1 INTO @WUNDERGROUND_PASSWORD; + SELECT CONVERT_TZ(CREATED, @@session.time_zone, '+00:00') as CREATEDUTC, WIND_DIRECTION, WIND_SPEED, WIND_GUST_SPEED, HUMIDITY, AMBIENT_TEMPERATURE, AIR_PRESSURE, GROUND_TEMPERATURE, @rainPastHour, @rainSinceMidnight, @WUNDERGROUND_ID, @WUNDERGROUND_PASSWORD FROM WEATHER_MEASUREMENT ORDER BY created DESC LIMIT 1; +END&& \ No newline at end of file diff --git a/README-API-WeatherUnderground.md b/README-API-WeatherUnderground.md new file mode 100644 index 0000000..901e8ac --- /dev/null +++ b/README-API-WeatherUnderground.md @@ -0,0 +1,23 @@ +Weather Underground API integration +=================================== + +1. Run the SQL statement again. This is written in such a way that it will only add whatever you don't have. + + `mysql -u root -p weather < CREATE-SP.sql` + +2. Add your own values to the settings table. + + ``` + mysql -u root -p weather -e "update SETTINGS set value='YOUR-STATION-ID' where name='WUNDERGROUND_ID'" + mysql -u root -p weather -e "update SETTINGS set value='YOUR-STATION-PASSWORD' where name='WUNDERGROUND_PASSWORD'" + ``` + +3. Open CRONTAB to configure a recurring task. + + `crontab -e` + +4. Set up a CRON job to automatically send data to Weather Underground every 10 minutes. (Change the URL to match your environment.) + + `*/10 * * * * curl http://localhost/dashboard/wunderground-api.php` + +5. Press `Ctrl O` then `Enter` to save and `Ctrl X` to quit nano. \ No newline at end of file diff --git a/README.md b/README.md index 9d74a96..cd27fb0 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,13 @@ You should now be in `/var/www/html/dashboard` `ifconfig` - The IP address will be on the second line just after `inet addr:` + The IP address will be on the second line just after `inet addr:`. Enter this IP address into a browser followed by `/dashboard`. For example: -Enter this IP address into a browser followed by `/dashboard`. For example: + `http://192.168.0.X/dashboard` + +### Set up external API's (optional) - - `http://192.168.0.X/dashboard` +- Weather Underground: See [README-API-WeatherUnderground.md](README-API-WeatherUnderground.md). ---------- diff --git a/current.php b/current.php index 2b5d0cc..59e1732 100644 --- a/current.php +++ b/current.php @@ -2,7 +2,7 @@ include 'variables.php'; header('content-type: application/json; charset=utf-8'); header("access-control-allow-origin: *"); -$con = new mysqli($databaseAddress,$databaseUsername,$databasePassword,'weather'); +$con = new mysqli($databaseAddress,$databaseUsername,$databasePassword, $databaseSchema); // Check connection if (mysqli_connect_errno()) { @@ -23,58 +23,66 @@ $numberOfRows = 0; while($row = mysqli_fetch_array($result)) { // Rows - $numberOfRows++; + $numberOfRows++; if ($numberOfRows > 1) { echo ", "; } - echo "\r\n\t\t\"Observation" . $numberOfRows . "\" : {"; - - for ($i = 0; $i < $fieldcount; $i++) { // Columns - $fieldName = $fields[$i]; - $fieldValue = $row[$i]; - + echo "\r\n\t\t\"Observation" . $numberOfRows . "\" : {"; - if (strpos($fieldName, "_TEMPERATURE")) { - if ($showMetricAndCelsiusMeasurements) { - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . "° C\","; - } - else { - $fieldValue = convertCelsiusToFahrenheit($fieldValue); - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . "° F\","; + if ($numberOfRows == 1) { + $feelsLike = calculateFeelsLike($row["AMBIENT_TEMPERATURE"], $row["HUMIDITY"], $row["WIND_SPEED"]); + if (!$showMetricAndCelsiusMeasurements) { + $feelsLike = convertCelsiusToFahrenheit($feelsLike); } + echo "\r\n\t\t\t\"FEELS_LIKE\" : " . "\"" . $feelsLike . "\","; } - if (strpos($fieldName, "_SPEED")) { - if ($showMetricAndCelsiusMeasurements) { - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " Km/H\","; + for ($i = 0; $i < $fieldcount; $i++) { // Columns + $fieldName = $fields[$i]; + $fieldValue = $row[$i]; + + if (strpos($fieldName, "_TEMPERATURE")) { + if ($showMetricAndCelsiusMeasurements) { + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . "° C\","; + } + else { + $fieldValue = convertCelsiusToFahrenheit($fieldValue); + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . "° F\","; + } } - else { - $fieldValue = convertKilometersToMiles($fieldValue); - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " MPH\","; + + if (strpos($fieldName, "_SPEED")) { + if ($showMetricAndCelsiusMeasurements) { + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " Km/H\","; + } + else { + $fieldValue = convertKilometersToMiles($fieldValue); + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " MPH\","; + } } - } - - if (strpos($fieldName, "_PRESSURE")) { - if ($showPressureInMillibars) { - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " mb\","; + + if (strpos($fieldName, "_PRESSURE")) { + if ($showPressureInMillibars) { + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " mb\","; + } + else { + $fieldValue = convertMillibarsToInches($fieldValue); + echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " in\","; + } } - else { - $fieldValue = convertMillibarsToInches($fieldValue); - echo "\r\n\t\t\t\"" . $fieldName . "_STRING\" : " . "\"" . $fieldValue . " in\","; + + echo "\r\n\t\t\t\"" . $fieldName . "\" : " . "\"" . $fieldValue . "\""; + + if ($i+1 < $fieldcount) { + echo ","; } } - echo "\r\n\t\t\t\"" . $fieldName . "\" : " . "\"" . $fieldValue . "\""; - - if ($i+1 < $fieldcount) { - echo ","; - } - } - - echo "\r\n\t\t}"; + echo "\r\n\t\t}"; } + $result->close(); $con->next_result(); } @@ -137,9 +145,51 @@ function convertCelsiusToFahrenheit($celsiusDegrees) { return $F; } +function convertFahrenheitToCelsius($fahrenheitDegrees) { + $C = ($fahrenheitDegrees - 32) * 5 / 9; + return $C; +} + function convertMillibarsToInches($millibars) { $inches = $millibars * 0.0295301; return $inches; } +function calculateFeelsLike($temperature, $humidity, $windSpeed) { + $tempF = convertCelsiusToFahrenheit($temperature); + $windMPH = convertKilometersToMiles($windSpeed); + + // Calculate Heat Index based on temperature in F and relative humidity (65 = 65%) + if ($tempF > 79 && $humidity > 39) { + $feelsLike = -42.379 + 2.04901523 * $tempF + 10.14333127 * $humidity - 0.22475541 * $tempF * $humidity; + $feelsLike += -0.00683783 * pow($tempF, 2) - 0.05481717 * pow($humidity, 2); + $feelsLike += 0.00122874 * pow($tempF, 2) * $humidity + 0.00085282 * $tempF * pow($humidity, 2); + $feelsLike += -0.00000199 * pow($tempF, 2) * pow($humidity, 2); + $feelsLike = round($feelsLike); + } + elseif (($tempF < 51) && ($windMPH > 3)) { + $feelsLike = 35.74 + 0.6215 * $tempF - 35.75 * pow($windMPH, 0.16) + 0.4275 * $tempF * pow($windMPH, 0.16); + $feelsLike = round($feelsLike); + } + else { + $feelsLike = $tempF; + } + + return convertFahrenheitToCelsius($feelsLike); +} + +// Calculate Wind Chill Temperature based on temperature in F and wind speed in miles per hour +function get_wind_chill($tempF, &$wxInfo) { + if ($tempF < 51 && $wxInfo['WIND'] != 'calm') { + $pieces = explode(' ', $wxInfo['WIND']); + $windspeed = (integer) $pieces[2]; // wind speed must be in miles per hour + if ($windspeed > 3) { + $chillF = 35.74 + 0.6215 * $tempF - 35.75 * pow($windspeed, 0.16) + 0.4275 * $tempF * pow($windspeed, 0.16); + $chillF = round($chillF); + $chillC = round(($chillF - 32) / 1.8); + $wxInfo['WIND CHILL'] = "$chillF°F ($chillC°C)"; + } + } +} + ?> diff --git a/variables.php b/variables.php index ca34b9f..c78c4fe 100644 --- a/variables.php +++ b/variables.php @@ -4,6 +4,7 @@ $databaseAddress = '127.0.0.1'; $databaseUsername = 'root'; $databasePassword = 'tiger'; +$databaseSchema = 'weather'; // ___ Preferences _____________________________________________________ // These settings only change the display. Does not effect the values stored in the database. diff --git a/wunderground-api.php b/wunderground-api.php new file mode 100644 index 0000000..f23f54f --- /dev/null +++ b/wunderground-api.php @@ -0,0 +1,61 @@ +query('call GETWUNDERGROUNDDATA'); +if ($result->num_rows > 0) { + $row = mysqli_fetch_array($result); + + $url .= "dateutc=" . $row["CREATEDUTC"] . "&"; + $url .= "winddir=" . $row["WIND_DIRECTION"] . "&"; + $url .= "windspeedmph=" . convertKilometersToMiles($row["WIND_SPEED"]) . "&"; + $url .= "windgustmph=" . convertKilometersToMiles($row["WIND_GUST_SPEED"]) . "&"; + $url .= "humidity=" . $row["HUMIDITY"] . "&"; + $url .= "tempf=" . convertCelsiusToFahrenheit($row["AMBIENT_TEMPERATURE"]) . "&"; + $url .= "baromin=" . convertMillibarsToInches($row["AIR_PRESSURE"]) . "&"; + $url .= "soiltempf=" . convertCelsiusToFahrenheit($row["GROUND_TEMPERATURE"]) . "&"; + $url .= "rainin=" . convertmillimetersToInches($row["@rainPastHour"]) . "&"; + $url .= "dailyrainin=" . convertmillimetersToInches($row["@rainSinceMidnight"]) . "&"; + $url .= "ID=" . $row["@WUNDERGROUND_ID"] . "&"; + $url .= "PASSWORD=" . $row["@WUNDERGROUND_PASSWORD"] . "&"; +} + +$result->close(); +$con->close(); + +$url = str_replace(" ", "%20", $url); + +echo file_get_contents($url); + +// =============================================================== +function convertKilometersToMiles($kilometers) { + $miles = $kilometers * 0.621371; + return $miles; +} + +function convertCelsiusToFahrenheit($celsiusDegrees) { + $F = ((($celsiusDegrees * 9) / 5) + 32); + return $F; +} + +function convertMillibarsToInches($millibars) { + $inches = $millibars * 0.0295301; + return $inches; +} + +function convertmillimetersToInches($mm) { + $inches = $mm * 0.039370; + return $inches; +} + + +?>