This is an adaptation of yaakov's original program to allow you to simply specify a location textually and have it look up the ICAO code to use to get the weather report.

The weather report displays as 4 20-character lines on the printer's front panel. Time to make that display do something useful instead of just sitting there saying "READY".

Lexmark printers seem to understand the PJL language used to set the display; try yours!

#!/usr/bin/perl -w # $Id: 4200wx.pl 2 2008-07-10 00:05:58Z yaakov $ # Current Weather Condition on an HP 4200 Printer # # This program gets METAR weather conditions from the NOAA webiste a +nd uses # Geo::METAR to parse the result. It then hard formats the result s +o it # looks reasonably good on the 4200's display. # # The program need to know the four-letter ICAO airport code for you +r area, # as well as the IP address of the target printer. I run this progr +am as a # cron job at 10 minute intervals. You can change the "WEATHER COND +ITIONS" # heading to reflect your cities name. You will have to pad it prop +erly # to center it. # # THIS PROGRAM IS PROVIDED WITH NO WARRANTY OF ANY KIND EXPRESSED OR + IMPLIED # THE AUTHOR CANNOT BE RESPONSIBLE FOR THE EFFECTS OF THIS PROGRAM # IF YOU ARE UNCERTAIN ABOUT THE ADVISABILITY OF USING IT, DO NOT! # # Yaakov (http://kovaya.com/) # # Updated 12/04/2008 by Joe McMahon # - options parsing with Getopt::Long # - lookup of ICAO code from location name # - Fetches METAR data via JSON (Geo::METAR no longer works) use strict; use LWP::Simple; use IO::Socket; use Getopt::Long; use WWW::Mechanize; use JSON; my($opt_n, $opt_v, $ip, $station_code, $location); GetOptions( "n" => \$opt_n, "v" => \$opt_v, "ip=s" => \$ip, "icao=s" =>\$station_code, "location=s" => \$location, ); $ip = '172.21.42.200' unless $ip; my $mech = new WWW::Mechanize; $|++ if $opt_v; # Figure out ICAO code if not specified. if ($station_code and $location) { warn "Both station code and location specified, choosing code\n"; } elsif (!$station_code and !$location) { die "Must specify either -icao or -location to continue\n"; } elsif ($location) { # Convert location into a station code. my ($city, $state, $error) = split /,\s*/, $location; $city =~ s/\s+/+/g; $state=~ s/\s+/+/g; print "Obtaining ICAO code ... " if $opt_v; $mech->get("http://www.jfast.org/Tools/Port2PortAirDist/GeoLookup. +asp?Name=$city&Country=$state&Geo=&Icao=&Submit1=Look+up"); die "Can't look up ICAO code for '$location': @{[$mech->status]}\n +" unless $mech->success; my ($table) = ($mech->content =~ /(<TR><TD>.*)$/m); my @lines = ($table =~ m{<TR>(.*?)</TR>}g); my @content; foreach my $line (@lines) { @content = ($line =~ m{<TD>(.*?)</TD>}g); last if $content[3] ne " "; } die "No ICAO station code found for '$location'\n" if $content[3] +eq ' '; $station_code = $content[3]; } # At this point we have an ICAO code. print "Fetching weather info ... " if $opt_v; $mech->get("http://ws.geonames.org/weatherIcaoJSON?ICAO=$station_code" +); die "Can't get weather from geonames.org: @{[$mech->status]}" unless $ +mech->success; my $weather = from_json($mech->content); my $temp_c = $weather->{weatherObservation}->{temperature}; my $temp_f = 9/5*$temp_c + 32; my $conditions = $weather->{weatherObservation}->{weatherCondition}; $conditions = "clear" if $conditions eq 'n/a'; my $wind_speed = $weather->{weatherObservation}->{windSpeed}; # Looks like 4 lines on the printer, but it's really just one. Embeddi +ng # carriage returns in an attempt to format the data will not work! my $wx = qq(@{[hp_pad("Weather")]}@{[hp_pad("${temp_f}F/${temp_c}C")]} +@{[hp_pad(ucfirst($conditions))]}@{[hp_pad("Wind $wind_speed mph")]}) +; setdisplay($wx, $ip); sub hp_pad { my ($string) = @_; return substr($string,0,20) if length($string) >= 20; my $end_pad_length = int((20 - length($string) ) / 2); $string = ' ' x $end_pad_length . $string . ' ' x $end_pad_length; $string = "$string " if length $string == 19; return $string; } sub setdisplay { my ($rdymsg, $peeraddr) = @_; my $socket; if (! $opt_n) { $socket = IO::Socket::INET->new( PeerAddr => $peeraddr, PeerPort => "9100", Proto => "tcp", Type => SOCK_STREAM ) or die "Could not create socket: $!"; } my $data = <<EOJ \e%-12345X\@PJL JOB \@PJL RDYMSG DISPLAY="$rdymsg" \@PJL EOJ \e%-12345X EOJ ; if (! $opt_n) { print "Setting up printer ... "; print $socket $data; } else { print $data; } print "\n"; }

Replies are listed 'Best First'.
Re: Weather reports on the HP4350's front panel
by MidLifeXis (Monsignor) on Dec 05, 2008 at 14:16 UTC

    I was the Unix admin on an academic campus for a while, and I wrote a script with this function to add print job users, names, doc type, pages, number of pending jobs, etc to our Unix (and by use, VMS) print queues. I shared this tool around the office so that the other platforms would also be able to implement this function.

    The script was nice. We had networked serial / parallel port boxes, and could wrap the print job in console commands to change the display to the information for the incoming print job. It also allowed us to send banners to the print console for things like lab hours, etc.

    I am a Green Bay Packer (American football team, for those that do not know) fan, and the Novell guy was a Chicago Bears fan. Around the time of the twice annual installment of the Packer / Bear rivalry, the printer consoles on campus would start cheering for the various teams.

    --MidLifeXis

      Nice :)

      It gives me a great idea actually. A few months ago I finished a little electronics project allows a simple C program to write data to a 16x2 LCD panel via the parallel port.

      Maybe I can hack things together so a cron job can pull a METAR weather report for my local airport (EGNX) and then shove that data through my perl METAR reader into the LCD!

      This is way beyond my skill level so it'll take a while. :)