Dec 112014
 

I’ve had to calculate working time between 2 dates as part of a dashboarding project.
As a result, I’ve built a function to do this for me.

First though I needed the public holidays to make sure that public holidays weren’t counted.
As an example, I’ve only used a couple of days, formatted like ’24-04′.
I’ve stored this in an external php file called hols.php, however this can also be contained within the script.


Then for the main function. This takes 2 dateTime objects to compare. If the start is after the end, then it will return 0.


function work_minutes($dtStart,$dtEnd) {
if($dtStart > $dtEnd) {
return 0;
}
include('hols.php');

$di1Day = new DateInterval('P1D');
$workStartHour = 7; // When the work day starts
$workEndHour = 17; // When the work day ends
$workMinutes = 0; // Initialise the running counter that keeps tracks of the minutes of working time

$diffDays = $dtStart->diff($dtEnd)->format("%a"); // Get the number of days between the 2 timestamps, and add a day to ensure that all the days are checked.

for($x = 0; $x <= $diffDays+1; $x++) { if($dtStart->format('N') < 6) { // checks that it's on a monday-friday if(!in_array($dtStart->format('d-m'),$hols)) { // checks that it's not a public holiday

// Create a couple of new DateTime objects to define the start and end of
// the working day. These will be used to compare against when looping
// through each day to calculate the working minutes.

$dtStartOfDay = new DateTime($dtStart->format('Y-m-d').' '.$workStartHour.':00:00');
$dtEndOfDay = new DateTime($dtStart->format('Y-m-d').' '.$workEndHour.':00:00');
$signStart = '';
$signEnd = '';

// Compare the start of the day, if the starting DateTime Object is before the start of the working day, then the script will calculate the working time from
// the start of the day rather than the starting DateTime Object as any time before the start of the working day is irrelevant.
// The end DateTime objects are compared in a similar way. If the end DateTime object is before the end of the working day, that is used to compare, otherwise
// the end of the day is used to compare.

if($dtStartOfDay >= $dtStart) {
if($dtEndOfDay <= $dtEnd){ $arrDiff = explode(' ',$dtStartOfDay->diff($dtEndOfDay)->format('%H %i));
$signStart = $dtStartOfDay->diff($dtEndOfDay)->format('%R');
} else {
$arrDiff = explode(' ',$dtStartOfDay->diff($dtEnd)->format('%H %i));
$signStart = $dtStartOfDay->diff($dtEnd)->format('%R');
}

// When the starting DateTime object provided is after the start of the working day, then that will be used to calculate working minutes.
} else {
if($dtEndOfDay <= $dtEnd){ $arrDiff = explode(' ',$dtStart->diff($dtEndOfDay)->format('%H %i));
$signEnd = $dtStart->diff($dtEndOfDay)->format('%R');
} else {
$arrDiff = explode(' ',$dtStart->diff($dtEnd)->format('%H %i));
$signEnd = $dtStart->diff($dtEnd)->format('%R');
}
}

// intDiff contains the amount of minutes that was calculated as the amount of time between the start DateTime/Start of the day and end DateTime/End of the day.
$intDiff = $arrDiff[0]*60+$arrDiff[1];
// if theres any negative values, e.g. Starting DateTime stamp was after the end DateTime, the value is ignored, otherwise it adds to the running tally.
if($signStart != '-' && $signEnd != '-') {
$workMinutes += $intDiff;
}
}
}
// Add a day, and loop again.
$dtStart->add($di1Day);
$dtStart->setTime($workStartHour,0);
}

return $workMinutes;
}

Share
Jun 272013
 

I’ve been building a “Stats Grabber” for one of the managers at work. The ServiceNow instance that I’m using only has the XML interface enabled at the moment so I’ll be using that.

This will just be a quick overview of what I’ve used to build this, won’t go into the details too much as each configuration will differ.
The stats that I needed were to be sorted by day, so I’ve defined a function that will return an array that each day will have.
I’ve cut down what I actually had but this gives you a good example.

function CreateArray() {
return array(
"req"=>"0",
"inc"=>"0",
"incMajor"=>"0",
"contacttypePhone"=>"0",
"contacttypeEmail"=>"0",
"contacttypeOther"=>"0",
"contacttypeAuto"=>"0",
"totalTickets"=>"0",
"reqResolved"=>"0",
"incResolved"=>"0",
"totalReqInc"=>"0",
"reqResBySD"=>"0",
"incResBySD"=>"0",
"totalResBySD"=>"0"
);
}

Next up is defining the URLs that are used to retrieve data.
The $instance variable will need to be defined.

// Request Queries
$requrl = "https://".$instance.".service-now.com/u_request_list.do?XML&sysparm_query=u_requestor!%3D9faaf5b90a0a7813005cc0d4347713bc%5Esys_created_onONDateRange%40javascript%3Ags.dateGenerate('".$_POST['startdate']."'%2C'start')%40javascript%3Ags.dateGenerate('".$_POST['enddate']."'%2C'end')";
$resolvedrequrl = "https://".$instance.".service-now.com/u_request_list.do?XML&sysparm_query=u_requestor!%3D9faaf5b90a0a7813005cc0d4347713bc%5Eu_resolvedONDateRange%40javascript%3Ags.dateGenerate('".$_POST['startdate']."'%2C'start')%40javascript%3Ags.dateGenerate('".$_POST['enddate']."'%2C'end')";

// Incident Queries
$incurl = "https://".$instance.".service-now.com/incident_list.do?XML&sysparm_query=sys_created_onONDateRange%40javascript%3Ags.dateGenerate('".$_POST['startdate']."'%2C'start')%40javascript%3Ags.dateGenerate('".$_POST['enddate']."'%2C'end')";
$resolvedincurl = "https://".$instance.".service-now.com/incident_list.do?XML&sysparm_query=u_resolvedONDateRange%40javascript%3Ags.dateGenerate('".$_POST['startdate']."'%2C'start')%40javascript%3Ags.dateGenerate('".$_POST['enddate']."'%2C'end')";

You may also notice the $_POST variables in the url, these will need to be passed to this script in the YYYY-MM-DD format. These will also be used later to construct the array for the days.

I’ve used CURL to retrieve the data, but there are a few different ways to do this
This snippet will create the $ch handle;

$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $un .":". $pw);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

Next we’ll start getting the data.


// Get Requsts
curl_setopt($ch, CURLOPT_URL, $requrl);
$reqreturn = curl_exec($ch);

// Get Incidents
curl_setopt($ch, CURLOPT_URL, $incurl);
$increturn = curl_exec($ch);

// Get Resolved Requests
curl_setopt($ch, CURLOPT_URL, $resolvedrequrl);
$resreqreturn = curl_exec($ch);

// Get Resolved Incidents
curl_setopt($ch, CURLOPT_URL, $resolvedincurl);
$resincreturn = curl_exec($ch);

curl_close($ch);
// Curl End

I haven’t put in any error capturing but that is something that should be there to catch any errors when trying to retrieve the data.

Now to create the array that will contain all of our data.
As I wanted the data sorted by days, I’ve used a for loop with the start and end dates to create the array.

$DateArray = array();
if(isset($_POST['startdate']) && isset($_POST['enddate'])) {
$start = new DateTime($_POST['startdate']);
$end = new DateTime($_POST['enddate']);
$diff = $start->diff($end)->format("%a");
for($x = 0; $x < $diff+1; $x++) { $datestamp = date("Y-m-d",strtotime("+$x days",strtotime($start->format("Y-m-d"))));
$DateArray[$datestamp] = CreateArray();
}
}

Now we’ll start processing the data.
I’ll only post one of the four blocks for brevity as they’re esssentially the same with minor differences when it comes down to the data.
SimpleXML is used here to parse the xml output of ServiceNow

// Load Incidents XML
$xml = simplexml_load_string($increturn);
// Get Total Incidents
$incTotal = $xml->incident->count();
// Parse incidents for date
foreach($xml->incident as $item) {
$datestamp = date("Y-m-d",strtotime("+8 hours",strtotime($item->opened_at)));
$DateArray[$datestamp]["inc"]++;
$DateArray[$datestamp]["totalTickets"]++;
if($item->priority < 3) { $DateArray[$datestamp]["incMajor"]++; $totalMajorInc++; } switch($item->contact_type) {
case "Email":
$DateArray[$datestamp]["contacttypeEmail"]++;
break;
case "phone":
$DateArray[$datestamp]["contacttypePhone"]++;
break;
case "Auto Monitoring":
$DateArray[$datestamp]["contacttypeAuto"]++;
break;
default:
$DateArray[$datestamp]["contacttypeOther"]++;
break;
}
}

Once all four of those blocks have been executed, you now have the data all in a nice array.
You can then use a foreach loop on the DateArray array to get your data out

Share
Jan 302013
 

I’ve gotten some coding done on the Pi’s WiFi configuration portal.

This is a quick snapshot of what it looks like so far.
Does anyone have any feedback or comments ?

WifiPortal

Share
Jan 282013
 

I’ve been doing some coding for my Raspberry Pi’s Wireless Network Configuration page, and was trying to find a good way to get just a single number out of the block that ifconfig outputs –
I wanted to get the number after RX packets: in this example.

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2383877 errors:0 dropped:8221 overruns:0 frame:0
TX packets:2492088 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:734455593 (700.4 MiB) TX bytes:3075500605 (2.8 GiB)

I ended up writing a oneliner to do it for me, and put it into a function so I could use it more.
$strWlan0 is the block of code above.

substr($strWlan0,strpos($strWlan0,"RX packets:")+11,strpos(substr($strWlan0,strpos($strWlan0,"RX packets:")+11)," "));

If anyone has a better way of doing it though, please add it in the comments.

Share