Apple II Weather Display (part 1)

Diablo

New member
hadweather.jpg


Due to computer issues I had to rob some parts from my “electronics” computer, which wasn’t bad, since I was not working on anything at the time and I felt a software project itch. I also wanted to do something with my Apple //c, which resides on my computer desk, so this ghetto brute force “solution” to use the 25 year old computer as a weather display came about.

In a nutshell there is the Apple II, a serial cable, and a PC running linux mint 10 and a handful of command line utilities. My specific Apple is the fist revision of the //c which means its got a buggy rom and the serial port(s) can be troublesome, the best speed I was able to get was 600 baud with just basic, though every other model could probably go a little faster.

On the linux side, wget downloads html and the radar image from Weather Underground’s mobile site, which is not a perfect source, but its easy. A lua script phrases text and graphics into string patterns that the Apple II can handle as keyboard input, and its sent down a serial cable where it is drawn on screen in basic.

Yea its pretty darn slow … it typically takes about eight to twelve minutes to redraw the screen, which is not all that horrid (imo) considering what is going on, but anyone with a more serious take on this could find numerous ways to optimize it, I just wanted to see what it would look like.

Join us after the break for a short video and to read all the details about how this all works!


Stuff you need:

*nix PC with a serial port and something with the following software

GNU Wget

GNU core utilities

(both are* probably already installed )

Lua 5.1 (I used sudo apt-get install lua5.1)

ImageMagick (again sudo apt-get install imagemagick)

Lynx (I am just using it to strip html tags and didnt feel like using anything “proper”)

Sjinn, which is a nifty little command line program that lets you deal with the serial port without having to manually set it up and fuss with redirecting i/o in the terminal.

And my project folder.

On the Apple II side, you need a 128k IIe or newer, disk drive/controller, serial card, blank disk,* and high resolution graphics. For software you will need ADT Pro,* and the disk image I made. ADT Pro is the currently developed Apple Disk Transfer utility that allows you to copy disk images to and from the Apple II, and the disk image is contained in the zip file above.

Transfer the disk image to the Apple and reboot with that disk in the drive, once the screen is at the white box, you are free to run “lua a2weather.lua” on the PC. The lua script fetches data, pipes it to the Apple, and then goes to sleep for 45 min using the gnu sleep() command.

Since lua is doing all the lifting, I guess that’s a good place to start. Also, let’s get this out of the way in case you missed it, I am not a programmer, much like my writing, be prepared to see some massive sins!

First up is the main a2weather.lua script* (and I see wordpress is going to murder my formating)

-- Weather Underground to Apple // -- 2011 Kevin Dady -- -- main script: -- read data off of the http://www.wunderground.com/ mobile site -- phrase it -- process text & graphics -- send -- sleep -- loop -- -- This software is provided 'as-is', without any express or implied -- warranty.* In no event will the authors be held liable for any damages -- arising from the use of this software. -- -- Permission is granted to anyone to use this software for any purpose, -- including commercial applications, and to alter it and redistribute it -- freely, subject to the following restrictions: -- -- 1. The origin of this software must not be misrepresented; you must not --*** claim that you wrote the original software. If you use this software --*** in a product, an acknowledgment in the product documentation would be --*** appreciated but is not required. -- 2. Altered source versions must be plainly marked as such, and must not be --*** misrepresented as being the original software. -- 3. This notice may not be removed or altered from any source distribution. require("req/web") require("req/text") require("req/radar") require("req/os_commands") graphicsKey = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" cmd.serialPort = "/dev/ttyS0" cmd.webURL = "http://m.wund.com/US/FL/Orlando.html" --cmd.webURL = "http://m.wund.com/cgi-bin/findweather/getForecast?brand=mobile&query=West+Yellowstone%2C+MT" while true do web.get() web.sortTXT() web.cleanTXT() text.createIMG() text.convertIMG() text.sortIMG() text.packageIMG() text.sendIMG() radar.convertIMG() radar.sortIMG() radar.packageIMG() radar.send() -- clean up data radar.data.input* = {} radar.data.packed = {} radar.data.apl2 = {{},{},{},{},{},{}} text.data.input* = {} text.data.packed = {{},{},{},{}} text.data.apl2** = {{},{},{}} cmd.sleep("45m") -- after sleep do tell the apple and do it again cmd.sjinn("update") end … pretty straight forward, some comments, zlib license, Ah, required files! These are just other lua scripts with functions and variables in them, though there is no reason all of those functions could not be in this script, I just find it easier to deal with.

web.lua downloads html and the radar image from weather underground, strips HTML tags via lynx, searches for keywords, and packs those keywords into a table (tables in lua are like arrays, but you can put pretty much anything you want in them, even functions)

text.lua takes the text data gathered in web.lua and passes it to ImageMagick to make simple text images, then phrases those images into data strings and transfers that data to the Apple.

radar.lua dithers the radar image with ImageMagick, phrases the that file, builds data strings, and* transfers that image data to the Apple.

os_commands.lua contains functions to run command line programs like wget, lynx, etc.

The graphics key needs to remain constant, I will go into how that works in a little while, but each character represents a numeric value within a 35 pixel column of the screen, there are 280 horizontal pixels in Apple // high res graphics. Its ripped from base36, missing the zero value and you dont add the numbers up, each is its own.

Theres also a string to define your serial port, and one to put the url for the area you want to see, go to Weather Underground’s mobile site search for wherever (I dont know how well it works outside North America)* and copy/paste the resulting page url.

Next is a infinite while loop and the various functions contained within the above required scripts. Then, a little blurb where I define a bunch of empty tables (thats just me being re-assured tables start fresh and I didn’t goof up).

Next is web.lua

-- Weather Underground to Apple // -- 2011 Kevin Dady -- -- Web Processing: -- get text data -- get radar image -- phrase text for apple // web = {} web.data = {} web.keywords = { "National Weather Service:", "Updated","Windchill","Temperature","Humidity", "Conditions","Dew Point","animated radar image"} web.get = function() -- download html from website cmd.wget(cmd.webURL, "text.html") -- look for the radar image url local file = io.open("temp/text.html") local image = "" for line in file:lines() do if string.find(line, "jpg") then image = line break end end file:close() -- remove the html tags from image url local firstQuote = string.find(image, "\"") + 1 local secondQuote = string.find(image, "\"", firstQuote) - 1 image = string.sub(image, firstQuote, secondQuote) -- download image cmd.wget(image, "radar.jpg") end web.sortTXT = function() local fileLines = {} -- use lynx to strip html tags cmd.lynx("temp/text.html") -- dump the lynx output file into a table local file = io.open("temp/text.txt") for line in file:lines() do table.insert(fileLines, line) end -- look for keywords and scrape data for y = 1, #fileLines do local sub = "" -- storm advisory if string.find(fileLines[y], web.keywords[1]) ~= nil and web.data[1] == nil then sub = string.gsub(fileLines[y + 1], "%d", "!") sub = string.gsub(sub, " , ", " ") table.insert(web.data, 1, sub) -- last updated date and time elseif string.find(fileLines[y], web.keywords[2]) ~= nil then table.insert(web.data, 2, fileLines[y]) -- windchill elseif string.find(fileLines[y], web.keywords[3]) ~= nil then sub = string.gsub(fileLines[y], web.keywords[3], "") table.insert(web.data, 3, sub) -- everything but forecast else for keyWord = 4, (#web.keywords - 1) do if string.find(fileLines[y], web.keywords[keyWord]) ~= nil and web.data[keyWord] == nil then sub = string.gsub(fileLines[y], web.keywords[keyWord], "") table.insert(web.data, keyWord, sub) end end end end end web.cleanTXT = function() for y = 1, #web.data do if web.data[y] ~= nil then -- remove extra spaces from start of each string while (string.sub(web.data[y], 1, 1) == " ") do web.data[y] = string.sub(web.data[y], 2, -1) end -- remove degrees character web.data[y] = string.gsub(web.data[y], "°", "") end end -- Add keywords back in (skipping nill values, and tempature) for keyWord = 3, (#web.keywords - 1) do if web.data[keyWord] ~= nil then if keyWord ~= 4 then web.data[keyWord] = web.keywords[keyWord] .. ": " ..web.data[keyWord] end end end -- remove / from Temperature web.data[4] = string.gsub(web.data[4], " / ", " ") end Yea I know its a mess, WordPress is ignoring tabs and it is only 40 columns if I had to guess. At the top there is a function called web.get(), this function uses wget to download the html page from weather underground, it then opens that file and scans through it for a JPG image, as luck would have it, the only jpg on the entire page is the radar. Once it has the URL for the radar it strips the HTML tags and uses wget again to download just the radar image.

The next function is web.sortTXT(), this sends the downloaded HTML file to lynx where it strips out the tags and spits out a plain text file. The function then reads each line looking for keywords. Some keywords require special action … like if it finds a storm advisory, it then knows to skip to the next line, because that line just says “National Weather Service:” and change the link number inserted by lynx to a” !”.* At the end of the function there is a little loop that looks for the rest of the keywords and then removes the actual keyword, this is needed to remove unwanted spaces between the keyword and data.

The final function is web.cleanTXT(), this goes through all the lines of data we have and removes all the leading spaces. It then adds back keywords to the appropriate line, while it ignores nil values as they were not present (like advisories or windchill). It also ignores the Temperature keyword as I don’t need the word Temperature in the display. Lastly I remove the “/” in my temperature data as it makes the graphics format funny, and its just to separate F and C values in the original string.

So we now have the software installed and running, data and radar downloaded from weather underground, text data scrapped, sorted and cleaned and we are now ready to make some graphics!

Join me in part 2 where I explain how graphics are reduced, encoded and drawn on the Apple II computer.




Filed under: how-to, misc hacks, software hacks
b.gif



rpbhC-zq218
 
Back
Top