#!/usr/bin/env node
//
// streaming.js
//
// Stream data from Tesla's streaming API to either a flat file or a MongoDB database
//
var request = require('request');
var teslams = require('../teslams.js');
var fs = require('fs');
var util = require('util');

function argchecker( argv ) {
	if (argv.db == true) throw 'MongoDB database name is unspecified. Use -d dbname or --db dbname';
}

var usage = 'Usage: $0 -u <username> -p <password> [-sz] [--file <filename> || --db <MongoDB database>] \n' +
	'	[--values <value list>] [--maxrpm <#num>] \n' +
	'# if --db <MongoDB database> argument is given, store data in MongoDB, otherwise in a flat file';

var p_url = 'https://portal.vn.teslamotors.com/vehicles/';
var s_url = 'https://streaming.vn.teslamotors.com/stream/';
var collectionS, collectionA;
var firstTime = true;
var MongoClient;
var stream;
var last = 0; // datetime for checking request rates
var rpm = 0; // REST API Request Per Minute counter
var slast = 0; // datetime for checking streaming request rates
var srpm = 0; // Streaming URL Request Per Minute counter
var lastss = "init"; // last shift state
var ss = "init"; // shift state
var napmode = false; // flag for enabling pause to allow sleep to set in 
var sleepmode = false;
var napTimeoutId;
var sleepIntervalId;
// various instance counters to avoid multiple concurrent instances
var pcount = 0; 
var scount = 0;
var icount = 0;
var ncount = 0;
var checkcounterperminute = 0 ;

var argv = require('optimist')
	.usage(usage)
	.check(argchecker)
	.alias('u', 'username')
	.describe('u', 'Teslamotors.com login')
	.alias('p', 'password')
	.describe('p', 'Teslamotors.com password')
	.alias('d', 'db')
	.describe('d', 'MongoDB database name')
	.alias('s', 'silent')
	.describe('s', 'Silent mode: no output to console')
	.alias('z', 'zzz')
	.describe('z', 'enable sleep mode checking')
	.boolean(['s', 'z'])
	.alias('f', 'file')
	.describe('f', 'Comma Separated Values (CSV) output file. Defaults to streaming.out')
	.default('f', 'streaming.out')
	.alias('r', 'maxrpm')
	.describe('r', 'Maximum number of requests per minute')
	.default('r', 6)
	.alias('N', 'napcheck')
	.describe('N', 'Number of minutes between nap checks')
	.default('N', 1)
	.alias('S', 'sleepcheck')
	.describe('S', 'Number of minutes between sleep checks')
	.default('S', 1)
	.alias('v', 'values')
	.describe('v', 'List of values to collect')
	.default('v', 'speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading')
	.alias('?', 'help')
	.describe('?', 'Print usage information');

// get credentials either from command line or ~/.teslams/config.json
var creds = require('./config.js').config(argv);

argv = argv.argv;
argv.napcheck *= 60000;
argv.sleepcheck *= 60000;

if ( argv.help == true ) {
	console.log(usage);
	process.exit(1);
}

var nFields = argv.values.split(",").length + 1; // number of fields including ts

if (argv.db) {
	console.log("database name", argv.db);
	MongoClient = require('mongodb').MongoClient;
	var mongoUri = process.env.MONGOLAB_URI|| process.env.MONGOHQ_URI || 'mongodb://127.0.0.1:27017/' + argv.db;

	MongoClient.connect(mongoUri, function(err, db) {
		if(err) throw err;
		collectionS = db.collection('tesla_stream');
		collectionA = db.collection('tesla_aux');
	});
} else {
	stream = fs.createWriteStream(argv.file);
}

function loop_schedule() {
    	setTimeout(function() { check_schedule();}, 10000);	// 10 seconds loop
}

function pr( stuff ) {
	console.log( util.inspect(stuff) );
}


function check_chargestate( something, cb) {
    
      var MongoClient = require('mongodb').MongoClient
    , format = require('util').format;

      MongoClient.connect('mongodb://127.0.0.1:27017/' + argv.db , function(err, db) {
        if(err) {throw err};

            var collection = db.collection('tesla_aux');
 

              // Locate all the entries using find
              collection.find({"chargeState": {$exists:true}, "chargeState.charging_state": {$exists:true} }).limit(2).sort({ts:-1}).toArray(function(err, results) {
               if(err) {throw err};
                 if (results.length == 2) {  
                    //console.dir(results);
                    var soc = results[0].chargeState.battery_level;
                    var current_chargestate = results[0].chargeState.charging_state;
                    var previous_chargestate = results[1].chargeState.charging_state;

                    db.close();

                    var returndata = [];
                    returndata[0] = soc;
                    returndata[1] = current_chargestate;
                    returndata[2] = previous_chargestate;

                    //Returning array (0 = SOC, 1 = Current ChargeState, 2 = previous chargestate)
                    cb(returndata); //"SOC: " + soc + " CS: " + current_chargestate + " PCS " + previous_chargestate);
                 }
                // Let's close the db
                
              });
       
       });
        cb();
            
            // 
}

//notify ( 'Scheduler started', 'Scheduler Started' );

function notify ( NotifySubject, NotifyBody ) {
    
      var NotifyTo = "";
      var NotifySMTP = "";
      var NotifySMTPAuth = "";
      var NotifySMTPPort = "";
      var NotifySMTPUser = "";
      var NotifySMTPPass = "";

      var MongoClient = require('mongodb').MongoClient
      , format = require('util').format;

      MongoClient.connect('mongodb://127.0.0.1:27017/' +argv.db , function(err, db) {
        if(err) {throw err};

        var collection = db.collection('tesla_mailer');

        collection.find({_id : 1}).limit(1).sort({_id:1}).toArray(function(err, results) {
               if(err) {throw err};
            NotifyTo = results[0].NotifyTo;
            NotifySMTP = results[0].NotifySMTP;
            NotifySMTPAuth = results[0].NotifySMTPAuth;
            NotifySMTPPort = parseInt(results[0].NotifySMTPPort);
            NotifySMTPUser = results[0].NotifySMTPUser;
            NotifySMTPPass = results[0].NotifySMTPPass;
            console.dir(NotifyTo);
            console.dir(NotifySMTP);
            console.dir(NotifySMTPAuth);
            console.dir(NotifySMTPPort);
            console.dir(NotifySMTPUser);
            console.dir(NotifySMTPPass);
    
                var nodemailer = require("nodemailer");

                // create reusable transport method (opens pool of SMTP connections)
                var smtpTransport = nodemailer.createTransport("SMTP",{
                    host: NotifySMTP, // hostname
                    secureConnection: false, // use SSL
                    port: NotifySMTPPort, // port for secure SMTP
                    auth: {
                        user: NotifySMTPUser,
                        pass: NotifySMTPPass
                    }
                });


                // setup e-mail data with unicode symbols
                var mailOptions = {
                    from: NotifyTo, // sender address
                    to: NotifyTo, // list of receivers
                    subject: NotifySubject, // Subject line
                    text: NotifyBody, // plaintext body
                    html: "<b>" + NotifyBody + "</b>" // html body
                }

                // send mail with defined transport object
                smtpTransport.sendMail(mailOptions, function(error, response){
                    if(error){
                        console.log(error);
                    }else{
                        console.log("Message sent: " + response.message);
                    }

                    // if you don't want to use this transport object anymore, uncomment following line
                    //smtpTransport.close(); // shut down the connection pool, no more messages
                });   
       
       
       
       
        });

      });
    
    console.dir(NotifySMTPPass);
    
    
}


function check_schedule(){

        console.dir("-------------------------------------------------- LOOP STARTING ------------");

    
	    var vid = getAux.vid;
	
	    //console.dir("Vehicle id: " + vid);
	    //console.dir("Stream initialized");
	    var CDb = require('mongodb').Db,
        CMongoClient = require('mongodb').MongoClient,
        CServer = require('mongodb').Server;
    
      // Set up the connection to the local db
      var Cmongoclient = new MongoClient(new CServer("localhost", 27017), {native_parser: true});

      // Open the connection to the server
      Cmongoclient.open(function(err, Cmongoclient) {


        var now = new Date();
        var timestring = now.toLocaleTimeString();
        console.dir("Time now: " + timestring.substring(0,2) + "--" + timestring.substring(3,5) + "--" + timestring.substring(6,8));
        var seconds = parseInt(timestring.substring(6,8));
        var TimeNow = timestring.substring(0,2) + ":" + timestring.substring(3,5);
        var dayofweek = now.getDay();
        var day = "";
        if (dayofweek == 1) {day = "MON"};
        if (dayofweek == 2) {day = "TUE"};
        if (dayofweek == 3) {day = "WED"};
        if (dayofweek == 4) {day = "THU"};
        if (dayofweek == 5) {day = "FRI"};
        if (dayofweek == 6) {day = "SAT"};
        if (dayofweek == 0) {day = "SUN"};
        console.dir("Day: " + dayofweek);


        console.dir(TimeNow + "- Seconds: " + seconds + " Day of week: " + now.getDay());
        //TimeNow = "12:00";

        //console.dir(jsonDate + " - " + TimeNow);

        var findstring = {};
        findstring["TIME"]= TimeNow;
        findstring["Active"]=1;
        findstring[day]=1;
        console.dir("Findstring:");
        console.dir(findstring);
        
        // Get the first db and do an update document on it
        var CDb = Cmongoclient.db(argv.db);
        CDb.collection("tesla_scheduler").find(findstring).toArray( function(err, documents) {
      
 	    if (err) {throw err}

        
        check_chargestate('someone', function (result) {
            if (result) {
                
                var check_soc_text = "";
                var check_soc = result[0];
                var check_currentchargestate = result[1]; 
                var check_previouschargestate = result[2]; 
                console.dir("ChargeCheck: " + check_soc + " || " + check_currentchargestate + " || " + check_previouschargestate);


   

            var pluggedin = 0;
            if (check_currentchargestate == "Charging" || check_currentchargestate == "Stopped" || check_currentchargestate == "Complete"  ) {
                pluggedin = 1;
                check_soc_text = " Vehicle plugged in ";
            }
            else
            {
                check_soc_text = " Vehicle disconnected ";
            }


            if ( check_currentchargestate != check_previouschargestate ) {
                if (notifycounter == 0){ 
                    notify("Chargestatus - Now "  + check_currentchargestate + " SOC: " + check_soc + check_soc_text,"Now: " + check_currentchargestate + " Previous: " + check_previouschargestate + " SOC: "   + check_soc + check_soc_text);
                    notifycounter = 1;
                }
            }
            else {
                 notifycounter = 0;
            }


            if (seconds < 11) {
            checkcounterperminute = 0 }


	        if (documents.length > 0) {

                //console.dir(documents[0].TIME);
                //console.dir(documents);
                if (checkcounterperminute == 1)  {
                 //Initialize connection xx:xx:10
	            initstream();
                }
       
            
                if (checkcounterperminute == 2)  {
                console.dir(TimeNow + ": Executing commands - chargelevel = " + parseInt(check_soc) + "Vehicle plugged in: " + pluggedin);
	
		            for(var i = 0; i < documents.length ; i++) {

                        var safeset = parseInt(documents[i].SAFEABOVE); //25;
                        
                        console.dir("SAFESET: " + safeset);
  			            if (documents[i].TIME == TimeNow  ) {
				            //console.dir("Match" + documents[i].SCHEDULEID);	

				            //HVAC ON
                            //Plugged in state OK or Disregarded and SAFE = 1 and SOC OK
                            if (documents[i].COMMAND == 1) {  
                              //ONLY if plugged in
                               if (parseInt(documents[i].PLUGGEDIN) == 1) {
				               
                                   if (parseInt(documents[i].SAFE) == 1 ) {
                                        if (parseInt(check_soc) >= safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = OK - Climate ON: SOC: " + check_soc + check_soc_text,"1. SAFE = OK Climate ON: SOC: " + check_soc + check_soc_text);  }	

                                        if (parseInt(check_soc) < safeset ) {
					                        var hvacstat = "start";
					                        //teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = Failed - Climate ON Failed: SOC: " + check_soc + check_soc_text,"2. SAFE = Failed - Climate ON Failed : SOC: " + check_soc + check_soc_text);  }	
                                            
                                   }
                                   //SAFE = 0
                                   else
                                   {
                                         if (parseInt(check_soc) >= safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = OK - Climate ON: SOC: " + check_soc + check_soc_text,"3. SAFE = OK Climate ON: SOC: " + check_soc + check_soc_text);  }	

                                         if (parseInt(check_soc) < safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = No - Climate ON: SOC: " + check_soc + check_soc_text,"4. SAFE = No Climate ON: SOC: " + check_soc + check_soc_text);  }	
                                   }

                              			
                               }
                               else
                               //Disregard plugged in state
                               {
                                   if (parseInt(documents[i].SAFE) == 1 ) {
                                        if (parseInt(check_soc) >= safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = OK - Climate ON: SOC: " + check_soc + check_soc_text,"5. SAFE = OK Climate ON: SOC: " + check_soc + check_soc_text);  }	

                                        if (parseInt(check_soc) < safeset ) {
					                        var hvacstat = "start";
					                        //teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = Failed - Climate ON Failed: SOC: " + check_soc + check_soc_text,"6. SAFE = Failed - Climate ON Failed : SOC: " + check_soc + check_soc_text);  }	
                                            
                                   }
                                   //SAFE = 0
                                   else
                                   {
                                         if (parseInt(check_soc) >= safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = OK - Climate ON: SOC: " + check_soc + check_soc_text, "7. SAFE = OK Climate ON: SOC: " + check_soc + check_soc_text);  }	

                                         if (parseInt(check_soc) < safeset ) {
					                        var hvacstat = "start";
					                        teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					                        console.dir("Climate ON");  
                                            notify("SAFE = No - Climate ON: SOC: " + check_soc + check_soc_text,"8. SAFE = No Climate ON: SOC: " + check_soc + check_soc_text);  }	
                                   }	
                               }
                            //HVAC ON END
                            }


				            //HVAC OFF
				            if (documents[i].COMMAND == 2) {
					            var hvacstat = "stop";
					            teslams.auto_conditioning( { id: vid, climate: hvacstat }, pr );
					            console.dir("Climate OFF");
                                notify("Climate OFF: SOC: " + check_soc + check_soc_text,"Climate OFF: SOC: " + check_soc + check_soc_text); }

				            //HVAC TEMP
				            if (documents[i].COMMAND == 3) {
					            var hvacstat = "stop";
                                var rangeset = documents[i].TEMPPERCENT;
					            teslams.set_temperature( { id: vid, dtemp: rangeset}, pr );
					            console.dir("Climate set to " + + " Degrees C");
                                notify("Climate Set to: " +rangeset + " SOC: " + check_soc + check_soc_text,"Climate Set to: " +rangeset + " SOC: " + check_soc + check_soc_text); }

				            //CHARGE ON
				            if (documents[i].COMMAND == 4) {
					            var chargestat = "start";
					            teslams.charge_state( { id: vid, charge: chargestat }, pr );
					            console.dir("Charge ON");
                                notify("Charge ON: SOC: " + check_soc + check_soc_text,"Charge ON: SOC: " + check_soc + check_soc_text); }

				            //CHARGE OFF
				            if (documents[i].COMMAND == 5) {
					            var chargestat = "stop";
					            teslams.charge_state( { id: vid, charge: chargestat }, pr );
					            console.dir("Charge OFF");
                                notify("Charge OFF: SOC: " + check_soc + check_soc_text,"Charge OFF: SOC: " + check_soc + check_soc_text); }

				            //CHARGE STD
				            if (documents[i].COMMAND == 6) {
					            var rangestat = "std";
					            teslams.charge_range( { id: vid, range: rangestat }, pr );
					            console.dir("Charge set to STD");
                                notify("Charge set to STD: SOC: " + check_soc + check_soc_text,"Charge set to STD: SOC: " + check_soc + check_soc_text); }

				            //CHARGE MAX
				            if (documents[i].COMMAND == 7) {
					            var rangestat = "max";
					            teslams.charge_range( { id: vid, range: rangestat }, pr );
					            console.dir("Charge set to MAX");
                                notify("Charge set to MAX: SOC: " + check_soc + check_soc_text,"Charge set to MAX: SOC: " + check_soc + check_soc_text); }

				            //CHARGE PERCENT
				            if (documents[i].COMMAND == 8) {
					            var rangestat = "max";
                                var rangeset = documents[i].TEMPPERCENT
					            teslams.charge_range( { id: vid, range: 'set', percent: rangeset }, pr );
					            console.dir("Charge set to " + rangeset + " Percent");
                                notify("Charge set to " + rangeset + ": SOC: " + check_soc + check_soc_text,"Charge set to " + rangeset + ": SOC: " + check_soc + check_soc_text); }

				            //CHARGE CHECK UNPLUGGED - plugged in = false
				            if (documents[i].COMMAND == 9 && pluggedin == 0) {
					            var rangestat = "max";
					            console.dir("Vehicle not plugged in!: SOC: " + check_soc);
                                notify("Vehicle not plugged in!: SOC: " + check_soc + check_soc_text ,"Vehicle not plugged in!: SOC: " + check_soc + check_soc_text); }

				            //CHARGE CHECK UNPLUGGED - plugged in = true
				            if (documents[i].COMMAND == 9 && pluggedin == 1) {
					            var rangestat = "max";
					            console.dir("Vehicle not plugged in!: SOC: " + check_soc);
                                notify("Phew - Vehicle plugged in!: SOC: " + check_soc + check_soc_text, "Phew - Vehicle plugged in!: SOC: " + check_soc + check_soc_text); }


                                
                        } //END FOR



                    } //END IF = 2

		        }
	

	        }

            //END IF CHECK_CHARGESTATE
            } 
        });     
	    // Close the connection
            Cmongoclient.close();
        
        });
        });
 
  checkcounterperminute = checkcounterperminute +1;
loop_schedule();	
};






function getAux() {
    // make absolutely sure we don't overwhelm the API
    now = new Date().getTime();
    if ( now - last < 120000) { // last request was within the past minute
    	ulog( 'getAux: ' + rpm + ' of ' + argv.maxrpm + ' REST requests since ' + last);
    	if ( now - last < 0 ) {
			ulog('Warn: Clock moved backwards - Daylight Savings Time??');
			rpm = 0;
			last = now;
		} else if ( rpm > argv.maxrpm ) {
			ulog ('Throttling Auxiliary REST requests due to too much REST activity');
			return;
		}
	} else { // longer than a minute since last request
		rpm = 0;
		last = now;
	}
	// check if the car is napping
	if (napmode || sleepmode) {
		ulog('Info: car is napping or sleeping, skipping auxiliary REST data sample');
		//TODO add periodic /vehicles state check to see if nap mode should be cancelled because car is back online again
		return;
	} else {
		rpm = rpm + 2; // increase REST request counter by 2 for following requests
		//ulog( 'getting charge state Aux data');
		//teslams.get_charge_state( getAux.vid, function(data) {
		//	var doc = { 'ts': new Date().getTime(), 'chargeState': data };
		//	collectionA.insert(doc, { 'safe': true }, function(err,docs) {
		//		if(err) throw err;
		//	});
		//});
		//ulog( 'getting climate state Aux data');
		//teslams.get_climate_state( getAux.vid, function(data) {
		//	var ds = JSON.stringify(data), doc;

		//	if (ds.length > 2 && ds != JSON.stringify(getAux.climate)) {
		//		getAux.climate = data;
		//		doc = { 'ts': new Date().getTime(), 'climateState': data };
		//		collectionA.insert(doc, { 'safe': true }, function(err,docs) {
		//			if(err) throw err;
		//		});
		//	}
		//});
	}
};


function storeVehicles(vehicles) {
	var doc = { 'ts': new Date().getTime(), 'vehicles': vehicles };
	collectionA.insert(doc, { 'safe': true }, function (err, docs) {
		if (err) console.dir(err);
	});
	rpm = rpm + 2; // increment REST request counter for following 2 requests
	teslams.get_vehicle_state(vehicles.id, function(data) {
		ulog( util.inspect(data));
		doc = { 'ts': new Date().getTime(), 'vehicleState': data };
		collectionA.insert(doc, { 'safe': true }, function (err, docs) {
			if (err) console.dir(err);
		});
	});
	//teslams.get_gui_settings(vehicles.id, function(data) {
	//	ulog(util.inspect(data));
	//	doc = { 'ts': new Date().getTime(), 'guiSettings': data };
	//	collectionA.insert(doc, { 'safe': true }, function (err, docs) {
	//		if (err) console.dir(err);
	//	});
	//});
};

// if we are storing into a database we also want to
// - store the vehicle data (once, after the first connection)
// - store some other REST API data around climate and charging (every minute)
function initdb(vehicles) {
	storeVehicles(vehicles);
	getAux.vid = vehicles.id;
	// getAux();
	setInterval(getAux, 60000); // also get non-streaming data every 60 seconds
}

function ulog( string ) {
	if (!argv.silent) {
		util.log( string );
	}
}

function initstream() {
	icount++;
	if ( icount > 1 ) {
		ulog('Debug: Too many initializers running, exiting this one');
		icount = icount - 1;
		return;
	}	
	if (napmode) {
		ulog('Info: car is napping, skipping initstream()');
		icount = icount - 1;
		return;
	} 
    // make absolutely sure we don't overwhelm the API
    now = new Date().getTime();
    if ( now - last < 60000) { // last request was within the past minute
    	ulog( rpm + ' of ' + argv.maxrpm + ' REST requests since ' + last);
    	if ( now - last < 0 ) {
			ulog('Warn: Clock moved backwards - Daylight Savings Time??');
			rpm = 0;
			last = now;
		} else if (rpm > argv.maxrpm) { // throttle check
        	util.log('Warn: throttling due to too many REST API requests');
        	setTimeout(function() { 
        		initstream(); 
        	}, 60000); // 1 minute
        	icount = icount - 1;
        	return;
        }       
    } else { // longer than a minute since last request
		last = now;
		rpm = 0; // reset the REST API request counter
	}
	rpm++; // increment the REST API request counter
	teslams.vehicles( { email: creds.username, password: creds.password }, function ( vehicles ) {	
		if ( typeof vehicles == "undefined" ) {
			console.log('Error: undefined response to vehicles request' );
			console.log('Exiting...');
			process.exit(1);
		}
		if (vehicles.state == undefined) {
			ulog( util.inspect( vehicles) ); // teslams.vehicles call could return and error string
		}
		if (argv.zzz && vehicles.state != 'online') { //respect sleep mode
			var timeDelta = Math.floor(argv.napcheck / 60000) + ' minutes';
			if (argv.napcheck % 60000 != 0) {
				timeDelta += ' ' + Math.floor((argv.napcheck % 60000) / 1000) + ' seconds';
			}
			ulog('Info: car is in (' + vehicles.state + ') state, will check again in ' + timeDelta);
			napmode = true;
			// wait for 1 minute (default) and check again if car is asleep
			setTimeout(function() { 
				napmode = false;
				sleepmode = true;
				initstream();
			}, argv.napcheck); // 1 minute (default)
			icount = icount - 1;
			return;		
		} else if ( typeof vehicles.tokens == "undefined" || vehicles.tokens[0] == undefined ) {
			ulog('Info: car is in (' + vehicles.state + ') state, calling /charge_state to reveal the tokens');
			rpm++;	// increment the REST API request counter			
			teslams.get_charge_state( vehicles.id, function( resp ) {
				if ( resp.charging_state != undefined ) {
					// returned valid response so re-initialize right away
					ulog('Debug: charge_state request succeeded (' + resp.charging_state + '). \n  Reinitializing...');
					setTimeout(function() { 
						initstream(); 
					}, 1000); // 1 second
					icount = icount - 1;
					return;
				} else {
					ulog('Warn: waking up with charge_state request failed.\n  Waiting 30 secs and then reinitializing...');
					// charge_state failed. wait 30 seconds before trying again to reinitialize
					// no need to set napmode = true because we are trying to wake up anyway
					setTimeout(function() { 
						initstream(); 
					}, 30000);   // 30 seconds    
					icount = icount - 1;
					return;       
				} 
			});	
		} else { // this is the valid condition so we have the required tokens and ids
			sleepmode = false;
			if (firstTime) {	// initialize only once
				firstTime = false;
				if (argv.db) { // initialize database
					initdb(vehicles);
				} else { // initialize first line of CSV file output with field names 
					//stream.write('timestamp,' + argv.values + '\n');
				}
			}
			icount = icount - 1;
			return;
		}
	}); // end of teslams.vehicles() request
}

// this is the main part of this program
// call the REST API in order get login and get the id, vehicle_id, and streaming password token
//ulog('timestamp,' + argv.values);
//initstream();


check_chargestate('someone', function (result) {
        if (result) {
            //console.dir(result);
        } else {
            console.dir('No result from check_chargestate');
        }
});



loop_schedule();