Continue to...
VolunteerEMS.org - The directory of Emergency Medical Services volunteers


retr-jemstat.pl - a Perl script to retrieve hospital divert status information from New Jersey's JEMSTAT website. You will need to configure your username and password for the website, along with the names of the hospitals you wish to monitor. (If you do not have one yet, you can register for one there. Please do not share your password with others.)

Each time this script is run, it will check the JEMSTAT site for the status of the hospitals you listed and, for each hospital that is not "Open," it will print the hospital name, current status, and start and end times for that status. What you do with this information is up to you.

For example, on the Springfield (Vol.) First Aid Squad, our dispatch system is setup so that this retr-jemstat.pl script is called automatically everytime an ambulance is sent out. If a hospital is on divert, a text message is generated and sent to a cell phone in the responding ambulance. The result is that the crew knows the status of the local hospitals without having to run over to check a computer as they go out the door and without the dipatcher having to repeat divert statuses over the radio each time a different crew responds.

This script should run on any system which can run Perl scripts, including Unix-like (*BSD, Linux, etc.) systems, Mac OS X and Windows (when you add a Perl distribution such as is available from ActiveState). You will need the LWP, HTTP::Cookie and HTML::Parser modules which can be obtained for free from CPAN if they are not already installed on your system.

If you have a question or problem, please contact Apu. The NJ Dept. of Health and Senior Services, Office of Emergency Medical Services, and Technology Investments Group cannot help you with anything related to this script. Also, note that there is no guarantee that changes will not be made to the JEMSTAT website that will break this script; when a more formal method of obtaining divert statuses from the site is available, this script will be updated.

Are you associated with a volunteer emergency medical services organization? Come visit VolunteerEMS.org.

#!/usr/bin/perl -w

###########################################################################
# retr-jemstat.pl - Version 2.0    March 22, 2006
# -------------------------------------------------------------------------
# An automated solution for querying hospital status information
# from the JEMSTAT.org website.  You will need a valid username
# and password for that website, obtained directly from them.
# -------------------------------------------------------------------------
# Copyright 2006 by Apu <apu@VolunteerEMS.org>
# VolunteerEMS.org - The directory of EMS Volunteers
# -------------------------------------------------------------------------
#
#
# It is intended that this script be called once per EMS dispatch.
# It will POST login credentials to get a login cookie and then GET
# the divert status of all NJ hospitals.  (Two HTTP requests total)
#
# This script will then parse the information returned for those hospitals
# that interest the user and determine the current status, the time of the
# last status change and the time that the status is set to expire.
# For any hospital of interest that does not have an "Open" status,
# information about that hospital is printed on STDOUT for the user
# to act upon.
#
# As an example, I would text message (via e-mail) this information to
# a cell phone in the responding ambulance.  You could add that code to 
# this script or, as I prefer, call this script from a second script which 
# handles such details as which ambulance gets the message so we are not 
# sending information to an ambulance that is not going anywhere.
#
# If you have any questions, please feel free to contact me via e-mail.
# However, this script is provided "as-is" without any warranty.
# I am most interested in any enhancements you make and would ask
# that you not redistribute a modified version without permission.
# 
# Other than to get a login to the JEMSTAT website, please do not contact
# the NJ Dept. of Health and Senior Services, Office of Emergency Medical
# Services, or Technology Investments Group (the maintainers of the JEMSTAT
# website), about this script.  They have nothing to do with this script.
###########################################################################


###########################################################################
# Things to do...
#
# - Check that we actually get a valid response from the server
#   instead of blindly assuming things worked ($response->is_success)
#
# - Respect robots.txt (though I'm asking for the server administrator's
#   permission before distributing this so its pretty much implied that
#   we may query the site using this tool and a valid username/password)
#
###########################################################################


###########################################################################
# Login information for JEMSTAT.org website
# -------------------------------------------------------------------------
my $username = 'YourUsernameGoesHere';
my $password = 'YourPasswordGoesHere';
my $URLlogin = 'http://www.jemstat.org/frmlogin.aspx';
my $URLstatus = 'http://www.jemstat.org/frmFacilityStatus.aspx?ID=7&command=Hospital';


###########################################################################
# An array of hospitals that interest us
# -------------------------------------------------------------------------
my @hospitals = (
	# Essex County
	'Newark Beth Israel Medical Center- Adult ED',
	'Newark Beth Israel Medical Center- Pediatric ED',
	'Saint Barnabas Medical Center- Adult ED',
	'Saint Barnabas Medical Center- Pediatric ED',

	# Morris County
	'Morristown Memorial Hospital',

	# Union County
	'Muhlenberg Regional Medical Center',
	'Overlook Hospital',
	'Union Hospital',
);


###########################################################################
# You should not need to modify anything in this section or below
# -------------------------------------------------------------------------
use strict;
use warnings;
use LWP 5.64;
use LWP::ConnCache;
my $browser = LWP::UserAgent->new;
$browser->agent('retr-jemstat/2.0 (+http://www.VolunteerEMS.org/retr-jemstat.html)');
$browser->conn_cache(LWP::ConnCache->new());

use HTTP::Cookies;
$browser->cookie_jar({});

###########################################################################
# Subclass HTML::Parser and configure to parse the JEMSTAT HTML
# -------------------------------------------------------------------------
package GetSummary;
use base "HTML::Parser";

# Flags used to indicate what type of HTML tag we are processing
my $rFlag = 0;	# record (used with <TR>)
my $fFlag = 0;	# Facility Name (used with <TD>)
my $sFlag = 0;	# Facility Status (used with <TD>)
my $cFlag = 0;	# Time of Last Status Change (used with <TD>)
my $eFlag = 0;	# Time Status Expires (used with <TD>)

# These variables are used to store the info from each record
my ($facility, $status, $change, $expire) = ('', '', '', '');

sub start {
  my ($self, $tag, $attr, $attrseq, $origtext) = @_;

  if ($tag =~ /^tr$/i && $attr->{'class'})
    {
      # Does the <TR> we are processing concern a facility status?
      if ($attr->{'class'} =~ /^StatusFacilityRow$/i)
      { $rFlag = 1; }
    }
    elsif ($tag =~ /^td$/i && $attr->{'class'})
    {
      # Does the <TD> we are processing contain a facility name?
      if ($attr->{'class'} =~ /^FacilityCell$/i)
      { $fFlag = 1; }

      # Does the <TD> we are processing concern a facility status?
      elsif ($attr->{'class'} =~ /^StatusCell$/i)
      { $sFlag = 1; }

      # Does the <TD> we are processing contain a status change time?
      elsif ($attr->{'class'} =~ /^ChangeTimeCell$/i)
      { $cFlag = 1; }

      # Does the <TD> we are processing contain a status expiration time?
      elsif ($attr->{'class'} =~ /^ExpireTimeCell$/i)
      { $eFlag = 1; }
    }
}

sub text {
    my ($self, $text) = @_;

    # If any of the flags are set, save the $text in the appropriate variable
    if ($fFlag) { $facility = $text; } 
    elsif ($sFlag) { $status = $text; }
    elsif ($cFlag) { $change = $text; } 
    elsif ($eFlag) { $expire = $text; }
}

sub end {
    my ($self, $tag, $origtext) = @_;

    # If we are closing a <TR> and we are in a facility record,
    if ($tag =~ /^tr$/i && $rFlag)
    {
      my $hospital;
      foreach $hospital (@hospitals)
      {
        # If we are looking at a facility that concerns us and it is not open,
        # print out the status information and then reset flag and variables 
        if ( ($facility =~ /$hospital/i) && ($status !~ /open/i) )
        { print "$facility\t$status\t$change\t$expire\n"; }
      }
      $rFlag = 0;
      $facility = ''; $status = ''; $change = ''; $expire = '';
    }

    # If we are closing a <TD>, reset the <TD> flags
    if ($tag =~ /^td$/i)
    {
      $fFlag = 0; $sFlag = 0; $cFlag = 0; $eFlag = 0;
    }
}


########################################################################### 
# POST login information to get login cookie
# -------------------------------------------------------------------------
my $response = $browser->post( $URLlogin,
  [
    '__EVENTTARGET' => '',
    '__EVENTARGUMENT' => '',
    '__VIEWSTATE' => 'dDw2MDU2NDcwMjI7dDw7bDxpPDE+Oz47bDx0PDtsPGk8MT47PjtsPHQ8O2w8aTwwPjtpPDE+O2k8Mj47PjtsPHQ8O2w8aTwwPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPGk8MT47aTwzPjtpPDU+O2k8OT47PjtsPHQ8cDxsPHNyYzs+O2w8fi9JbWFnZXMvbmplbXNfYmFubmVyLmpwZzs+Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFR1ZXNkYXksIE1hcmNoIDIxLCAyMDA2Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxcZTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8TG9naW47Pj47Pjs7Pjs+Pjs+Pjs+Pjt0PDtsPGk8MT47PjtsPHQ8O2w8aTwxPjs+O2w8dDw7bDxpPDE+Oz47bDx0PHA8bDxUZXh0Oz47bDxOZXcgSmVyc2V5IEVNUyBTdGF0dXM7Pj47Oz47Pj47Pj47Pj47dDw7bDxpPDA+Oz47bDx0PDtsPGk8MD47PjtsPHQ8O2w8aTwzPjtpPDU+O2k8Nz47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8Q29weXJpZ2h0IFRlY2hub2xvZ3kgSW52ZXN0bWVudHMgR3JvdXAgMjAwNTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8VmVyc2lvbiAzLjAuMzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8UmV2aXNlZCAzLzExLzIwMDY7Pj47Pjs7Pjs+Pjs+Pjs+Pjs+Pjs+Pjs+PjtsPFJlbWVtYmVyOz4+rsViAjuf00IXeHN71iChqximf+c=',
    'UserName' => $username,
    'Password' => $password,
    'Remember' => 'on',
    'LoginButton' => 'Login',
  ]
);


########################################################################### 
# Now that we have the login cookie, GET the hospital status
# -------------------------------------------------------------------------
$response = $browser->get($URLstatus);


########################################################################### 
# And parse the HTML we retreived
# -------------------------------------------------------------------------
my $p = new GetSummary;
$p->parse($response->content);