Skip to content

Commit

Permalink
Flags make external weather and forecast optional
Browse files Browse the repository at this point in the history
1. Added two flags to $weatherConfig
2. Added processing for forecast flag
3. thermo.php had other changes that required addition of new
register.class file.
  • Loading branch information
ThermoMan committed Sep 27, 2013
1 parent a65f540 commit e5fa306
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 64 deletions.
2 changes: 2 additions & 0 deletions config.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
* noaa requires an api_loc - see http://w1.weather.gov/xml/current_obs/ for the correct xml url for your location
*/
$weatherConfig = array(
'useWeather' => TRUE, // TRUE, FALSE (Flag to use external temperature for all stats)
'useForecast' => TRUE, // TRUE, FALSE (Flag to show forecast on dashboard))
'type' => 'weatherunderground', // weatherunderground, noaa, weatherbug
'units' => 'F', // F, C
'api_key' => '0000000000000000', // Registered API key
Expand Down
47 changes: 21 additions & 26 deletions get_instant_forecast.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,19 @@
/* Put useful comments here and either merge code with get_instant_status.php or make this a virtual clone of that file */

$lastZIP = '';
$returnString = '';


try
{
if( $weatherConfig['useForecast'] )
{ // Only check forecast if we're asking for it.
try
{
/** Get stat info
*
*/
foreach( $thermostats as $thermostatRec )
{
$returnString = '';
/* DO NOT NEED TO GET LOCK, NOT TALKING TO THERMOSTAT!
$lockFileName = $lockFile . $thermostatRec['id'];
$lock = @fopen( $lockFileName, 'w' );
if( !$lock )
{
logIt( "get_instant_forecast: Could not write to lock file $lockFileName" );
continue;
}
if( flock($lock, LOCK_EX) )
{
*/
//logIt( "get_instant_forecast: Fetching forecast" );
//$log->logInfo( "get_instant_forecast: Fetching forecast" );

//$stat = new Stat( $thermostatRec['ip'], $thermostatRec['tstat_id'] );
$stat = new Stat( $thermostatRec['ip'] );
Expand All @@ -42,9 +33,11 @@
*
*/
$forecastData = $externalWeatherAPI->getOutdoorForcast( $ZIP );
//logIt( "get_instant_forecast: I got data" );
//$log->logInfo( "get_instant_forecast: I got data" );

// Format data for screen presentation
if( is_array( $forecastData ) )
{
$returnString .= "<p>The forecast for {$ZIP} is</p><br><table><tr>";
foreach( $forecastData as $day )
{
Expand All @@ -71,28 +64,30 @@

$returnString .= "<td style='text-align: center;'>$tth&deg;$weatherConfig[units] / $ttl&deg;$weatherConfig[units]</td>";
}
$returnString .= "</tr></table>";
$returnString .= '</tr></table>';
}
else
{
$log->logError( 'Expected to get an array back from $externalWeatherAPI->getOutdoorForcast( $ZIP ) but did not.' );
$returnString .= 'No response from forecast provider.';
}
}

}
catch( Exception $e )
{
logIt( 'get_instant_forecast: External forecast failed: ' . $e->getMessage() );
$log-logError( 'get_instant_forecast: External forecast failed: ' . $e->getMessage() );
// Need to add the Alert icon to the sprite map and set relative position in the thermo.css file
$returnString = $returnString . "<p><img src='images/Alert.png'/>Presently unable to read forecast.</p>";
}
/* DO NOT NEED TO GET LOCK, NOT TALKING TO THERMOSTAT!
}
fclose( $lock );
*/
}
}
catch( Exception $e )
{
logIt( 'get_instant_forecast: Some bugs failure or other ' . $e->getMessage() );
catch( Exception $e )
{
$log->logError( 'get_instant_forecast: Some bugs failure or other ' . $e->getMessage() );
$returnString = "<p><img src='images/Alert.png'/>Presently unable to read forecast.</p>";
}
}

echo $returnString;

?>
16 changes: 15 additions & 1 deletion lib/ExternalWeather.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,17 @@ public function __construct( $config = array() )
}
}

/**
* Should the calling function test $this->config['useWeather']
* or should that happen in here and just return -1 for each value
*/
public function getOutdoorWeather( $zip = null )
{
if( ! $this->config['useWeather'] )
{
return array( 'temp' => -1, 'humidity' => -1 );
}

if( empty($zip) )
{
throw new ExternalWeather_Exception( 'Zip not set' );
Expand Down Expand Up @@ -132,11 +141,16 @@ public function getOutdoorWeather( $zip = null )
$this->outdoorHumidity = str_replace('%', '', $this->outdoorHumidity);
break;
}
return array('temp' => $this->outdoorTemp, 'humidity' => $this->outdoorHumidity);
return array( 'temp' => $this->outdoorTemp, 'humidity' => $this->outdoorHumidity );
}

public function getOutdoorForcast( $zip = null )
{
if( ! $this->config['useForecast'] )
{
return NULL;
}

if( empty($zip) )
{
throw new ExternalWeather_Exception( 'Zip not set' );
Expand Down
195 changes: 195 additions & 0 deletions register.class
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<script type='text/javascript'>
/** Callback for checking availability of requested username.
*
*/
function processAjaxReply()
{
if( xmlDoc.readyState != 4 ) return ;

var xml = new DOMParser().parseFromString( this.response, 'text/xml' );

var cmd = xml.getElementsByTagName('command')[0].childNodes[0].nodeValue;
var val = xml.getElementsByTagName('value')[0].childNodes[0].nodeValue;

switch( cmd )
{
case 'name_avail':
document.getElementById( 'name_avail' ).innerHTML = val;
break;

default:
// Do nothing
break;
}


}
/** On these ajax things I need a common call out that has a function name passed to server.
* And a common answer that uses a case statement to process replies.
* The call out should set a flag for what function was called and the answer should check that the flag was set and clear it before processing the answer
*/
function checkAvailability()
{
var desiredUsername = document.getElementById( 'username' ).value;
if( desiredUsername == "" ) return;

document.getElementById( 'name_avail' ).innerHTML = 'Checking availability of requested ID.';
if( typeof window.ActiveXObject != 'undefined' )
{
xmlDoc = new ActiveXObject( 'Microsoft.XMLHTTP' );
xmlDoc.onreadystatechange = process ;
}
else
{
xmlDoc = new XMLHttpRequest();
xmlDoc.onload = processAjaxReply;
}
xmlDoc.open( 'GET', 'action.php?' + 'ac=name_avail' + '&data=' + desiredUsername, true );
xmlDoc.send( null );
}

function checkComplexity()
{
document.getElementById( 'pass_complex' ).innerHTML = 'Is PW good enough?';
// Borrow idea from here: http://www.passwordmeter.com/
// And link users to this http://xkcd.com/936/
}

function strncmp( a, b, length )
{
a = a.substring( 0, length );
b = b.substring( 0, length );

return a == b;
}

function checkDuplicate()
{
//Not a direct string compare. Match length and show incrementally that you are correct or incorrect. When an exact match is found say so.
//Can a 'bong' on an error/mismatch?
var p1 = document.getElementById( 'password' ).value;
var p2 = document.getElementById( 'password2' ).value;
var msg = 'no';
if( strncmp( p1, p2, p2.length ) )
{
msg = 'sort of';
}
if( strncmp( p1, p2, p2.length ) && p1.length == p2.length )
{
msg = 'Yes!';
}
if( p2.length == 0 )
{
msg = '';
}
document.getElementById( 'pass_duplicate' ).innerHTML = msg;
}

function validateUsername()
{
//Check length.
//Put message text on screen
//return true/false
return false;
}
function validatePassword()
{
//Check length and complexity.
//Put message text on screen
//return true/false
return false;
}
function validateEmail()
{
// Check format str1 @ str2 (str2 contains one or more dots)
//return true/false
return false;
}

function validateBeforeSubmit()
{
//Just to help the user out validate all the data. On the server side do not rely upon this fact.
// Call all validate functions. Return overall true/false for submit action.
// On the server side, don't trust that the input is in any proper format. Re-validate it all!
//Perhaps do that action as AJAX and put message on screen with results (one of "Error" or "Look for validate email")
// And read this page: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
return false;
}
</script>

<style>
fieldset.auto-width
{
border: 1px solid #FF0000;
/* width: 40em; */
width: 50%;
display: inline-block;
padding: 10px;
}
fieldset.auto-width legend
{
/* margin: 0 15px; */
padding: 0 10px;
}
table.form
{
}
table.form td.label
{
text-align: right;
}
table.form td.input, td.hint
{
test-align: left;
}
</style>

<?php
/* The point of this is that the $secureConfig may be DIFFERENT than the thermostat DB info.
require_once( dirname( __FILE__ ) . '/config.php' );
if( ! isset( $secureConfig ) )
{
die();
}
*/

class register
{
function __construct()
{
//echo 'hi!';
}

function displayForm()
{
$htmlString = '';

// All attempts to center the red box have failed
// $htmlString .= "<div sytle='margin-left: auto; margin-right: auto;' >";

// Do not use an "action", send the data via Ajax instead. Want to limit the number of page reloads.
// But only if it is secure. Really need https, otherwise all the security is just pretend.
//

$htmlString .= "<form id='register' action='index.php' method='post' accept-charset='UTF-8'>";
$htmlString .= " <fieldset class='auto-width'>";
$htmlString .= " <legend>Register</legend>";
$htmlString .= " <input type='hidden' name='ac' value='register'>";
$htmlString .= " <table class='form'>";
$htmlString .= " <tr><td class='label'><label for='username' >UserName* </label></td> <td class='input'><input type='text' name='username' id='username' maxLength='25' size='25' onBlur='javascript: checkAvailability();' /></td><td class='hint'><span id='name_avail'></span></td></tr>";
$htmlString .= " <tr><td class='label'><label for='password' >Password* </label></td> <td class='input'><input type='password' name='password' id='password' maxLength='25' size='25' onKeyUp='javascript: checkComplexity();' /></td><td class='hint'><span id='pass_complex'></span></td></tr>";
$htmlString .= " <tr><td class='label'><label for'password2' >Re-enter password </label></td><td class='input'><input type='password' name='password2' id='password2' maxLength='25' size='25' onKeyUp='javascript: checkDuplicate();'></td><td class='hint'><span id='pass_duplicate'></span></td></tr>";
$htmlString .= " <tr><td class='label'><label for='email' >Email address* </label></td> <td class='input'><input type='text' name='email' id='email' maxLength='75' size='25' /></td></td><td class='hint'></td></tr>";
$htmlString .= " </table>";
$htmlString .= " <span style='float: right;'><input type='submit' value='Submit' />";
$htmlString .= " <input type='reset' value='Reset' /></span>";
$htmlString .= " </fieldset>";
$htmlString .= "</form>";
// $htmlString .= '</div>';

echo $htmlString;
}
}


?>
23 changes: 0 additions & 23 deletions resources/thermo.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,27 +142,4 @@ body.account
{
margin: 10px;
}
fieldset.auto-width
{
border: 1px solid #FF0000;
width: 50em;
display: inline-block;
padding: 10px;
}
fieldset.auto-width legend
{
/* margin: 0 15px; */
padding: 0 10px;
}
table.form
{
}
table.form td.label
{
text-align: right;
}
table.form td.input, td.hint
{
test-align: left;
}

Loading

0 comments on commit e5fa306

Please sign in to comment.