Making a LED powered METAR map for your wall

While waiting for my airplane kit to arrive I got inspired to make a small crafty project after seeing someone post about it on reddit and showing it to my girlfriend who said we can make one together.

We did a bit more research and because I’ve made some projects with Raspberry Pi before, we decided to go that route. Here’s a picture of the finished project:

METAR Map

Supplies needed

Here’s a list of the things you will need:

Plotting your chart area

Unless you want to make your own frame, the dimensions of your project will be limited by what size shadow box frame you can easily purchase. The simplest size is 16 x 20 inch frames, so I used that as a guide of the area to size out.
This worked out great for the Puget Sound Area to cover the airports from Bellingham in the north to Olympia in the South and Hoquiam and Quillayute on the coast using my old expired sectional chart from my private pilot training.

Plotting out the area and using some wooden meeples to highlight the airports

To light up the airports with the flight category, we’re using the data reported from www.aviationweather.gov so we checked the airports we want to highlight via the API to ensure they are reporting data.

After we were satisfied with the area, we created a 16 x 20 inch transparent sheet by cutting up some sheet protectors and taping them together and then overlaying them onto the area and marking down the airports so we could transfer the locations onto the back of foam board for the LEDs to go into.

Transparent sheet with airport locations

Software and Wiring

Since the project is pretty simple, we used a Raspberry Pi Zero W, which has WIFI built in and can run the code to download the weather data using the above mentioned web API to pull the weather for all the airports in one go.

For the code, I’ve started by looking at some of the other projects people have done and the NeoPixel documentation for python.

We wrote an updated and optimized script and published it on Github, along with the instructions to set it up.

We ended up with a total of 22 lit up LEDs, so we wired it directly to the Raspberry as shown here. Before attaching the wires to the Raspberry headers, I soldered the header strip onto the Raspberry so it creates a good connection.

Raspberry Pi LED wiring (image courtesy of adafruit - https://learn.adafruit.com/assets/63929)

Here’s a picture of the wiring while I was testing out the code. I was using a breadboard while doing this since it made it easier to disconnect the wires during testing.

LED wiring in action

To finalize the order of the LEDs you will need to arrange them on the board and make changes to the airport list accordingly.

Another important note is to test the LEDs for all the colors in case there is a bad one, in our case the 5th LED couldn’t show RED light, so we skipped over that one.
The easiest way to test this once you’ve installed the software is to just manually control the colors of the LEDs by opening the python3 console:

sudo python3

Then entering the following to light up 30 LEDs at once (if you are using more, just replace the number below):

import board
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
pixels.fill((0,255,0))

This will light up all LEDs in red, if you see a bad one, mark it with some tape so you don’t use it for an airport.
Repeat the step for green:

pixels.fill((255,0,0))

Blue:

pixels.fill((0,0,255))

Purple:

pixels.fill((0,125,125))

Once you’re done you can turn off the lights by typing

pixels.deinit()

and then pressing CTRL+Z to exit the python console.

Board Assembly

Once we figured out the software portion and what airports to light up it was time to drill some holes in the foam board for the LEDs to go into using the template made earlier.

Foam board holes drilled

After we had the holes made we tested it by temporarily affixing the sectional chart onto the board and sticking some of the LEDs into the holes and turning on the project, but we found that the LEDs created a lot of light and the LEDs were sticking out a bit, so we decided to double up the foam board, which made the light more defined and allowed the sectional chart to sit flush on the board, so we glued together the two foam boards.

We did a second quick test and pinned the sectional chart onto the board for the first complete light up test:

First light up test

After that it was time put everything together. we made the final cuts to the chart to fit perfectly onto the board and align with the lights and then glued it to the board using a glue stick.

Then it was time to glue the LEDs onto the board, as you can see from the picture below, some of the LEDs are not lit, one of them because the red light didn’t work and some others because the gap between two airports was too much and it was easier to just skip the light than to cut the lights and having to solder in some wires. at the end we just cut off the remaining LEDs we didn’t need (disconnect the Raspberry power when you do this).

Lit LEDs back of board

Once that was all done and good it was time to assemble it all into the frame – we drilled a hole into the bottom of the frame for the power cable to go through.

Raspberry assembly in frame

And here is the final picture of the completed project:

METAR Map

I hope this was helpful for you.

Some of the above links to Amazon may earn me a small commission to keep the site running.

I recently added a new functionality to show the complete METAR information for the airports on the chart on a small mini display.

Mini screen embedded in my METAR map

270 thoughts on “Making a LED powered METAR map for your wall

  1. Erick

    This looks great! Question, what are my options for dimmer lights? Something that glows less. Are they certain specifics I would need to meet? Can you recommend something? Cheers!

    Reply
    1. Dave

      Change the color to less intence

      COLOR_VFR= (67,0,0) # Green
      COLOR_MVFR= (0,0,67) # Blue
      COLOR_IFR= (0,67,0) # Red
      COLOR_LIFR= (0,34,34) # Magenta
      COLOR_CLEAR= (0,0,0)

      Thats 25% bright
      you could go (2,0,0) etc for really dim

      D

      Reply
  2. Bob Berlyn

    Looks like a great project and I would like to build. I am an analog electronics guy and pilot but not a programmer. I have discovered that PYTHON is a language but thats really all I know. Does the pi run PYTHON using the operating system (Rasberian) or do I have to get PYTHON software or just load the scrips you wrote into the pi and go.

    Thanks

    Reply
    1. Philip Rueker Post author

      You just need to load the scripts into the Raspberry file system, “install python” by running the scripts that I’ve documented here and and modify the airports file to have the name of the airports that are relevant to you.

      Reply
  3. Ulrich Pommer

    Hey Philip,
    First of all, this is a great project. I’m from Germany and would like to take German airports. Is that possible? Do I have to change only the names in the file (airports)? Sorry for my bad english:-(

    greetings Uli

    Reply
    1. Philip Rueker Post author

      Yes the web service I’m using does also support many international airports, you just need to use the 4 digit ICAO codes like EDDF for Frankfurt and EDDM for Munich.

      Reply
  4. Rick Sayles

    Philip,
    I saw a MetarMap at SUNnFUN last year and then seeing your project you inspired me to give it a go.

    Thanks for your excellent documentation. Made it work for a non-programmer. It all works now, but it doesn’t update, until you rerun the program, and the pi doesn’t automatically run the program. I have it now where the pi is connected to monitor so I can run the program. I assume you have automated both of those operations?

    Thanks!

    Reply
    1. Philip Rueker Post author

      Hi,

      Yes you can automate this using crontab.
      As I mention on the Github, here’s how you do it:

      If you’d like to have the script refresh in regular intervals, use crontab and set the appropriate interval. For an example you can refer to the crontab file in the GitHub repo (make sure you grant the file execute permissions beforehand). To edit your crontab type: crontab -e, after you are done with the edits, exit out by pressing ctrl+x and confirm the write operation
      The sample crontab will run the script every 5 minutes (the */5) between the hours of 7 to 21, which includes the 21 hour, so it means it will run until 21:55
      Then at 22:05 it will run the lightsoff.sh script, which will turn all the lights off

      Reply
  5. Sameer

    This is great! I’m working on this project now as well. I ran into a snag with the level shifter. Everything works great on the breadboard, but when I connect jumper wires to the level shifter directly the LEDs go rainbow colors instead of red or green etc. I just purchased some veroboard to solder the level shifter and create connections without jumper wires.

    How many LEDs are you able to light up directly off the 5v pin without risking the pi? Thx!

    Reply
    1. Philip Rueker Post author

      I’m running 22 active LEDs directly off the Pi 5v without issues.

      Reply
  6. Chris

    Using your command sequence for checking all the LED’s:
    import board
    import neopixel
    pixels = neopixel.NeoPixel(board.D18, 30)
    pixels.fill((0,255,0))
    I am presented with Attribute Error ‘neopixel’ has no attribute ‘Neopixel’
    Any solutions for this? I am not a code literate.

    Reply
    1. Philip Rueker Post author

      Make sure that prior to this you have successfully installed the neopixel library by running the following command as listed in the github instructions:
      sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
      After that command, you open python3 by entering:
      sudo python3
      and then enter the commands and it should work:
      Testing pixels screenshot

      Reply
    1. Bob

      I changed the corntab file by just adding

      */5 7-21 * * * /home/pi/refresh.sh
      05 22 * * * /home/pi/lightsoff.sh

      I guess I am not understanding root permission. I did run sudo chmod +x corntab

      Thanks for the project just wish I knew more about pi but working on it.

      Reply
      1. Philip Rueker Post author

        Ah, you need to grant the files that are being executed inside the crontab execute permissions, so you should run the chmod command for the refresh.sh and the lightsoff.sh file.

        After you have done that you can check that you’ve done it correctly by running "ls -al" and you should see “x” for the files 3 times, similar to this:
        executepermissions

        Also just to be clear, you have to edit your system crontab by typing "crontab -e", not by copying my sample file into the folder.

        Reply
  7. Bob

    looks like it is working, I was doing “sudo nano crontab -e”. Thanks for your help and thanks for the program. I had a thought and it is way above my knowledge with pi. I was thinking could you add a screen somewhere on a chart with 5/10 day forecast or scrolling local weather. Again thanks now I need to start on my frame.

    Reply
  8. Ron Heberlein

    Thanks for the instructions! I was able to get metar.py running manually, but I can’t get it to start on power-up.
    Here’s what the statrup.log shows:

    Thu 07 May 2020 06:46:43 AM PDT
    /home/pi/startup.sh: 2: /home/pi/startup.sh: echo
    : not found
    Running metar.py
    /home/pi/startup.sh: 4: /home/pi/startup.sh:
    : not found
    /usr/bin/python3: can’t open file ‘/home/pi/metar.py
    ‘: [Errno 2] No such file or directory

    And here is my ls -al:
    pi@raspberrypi:~ $ ls -al
    total 132
    drwxr-xr-x 17 pi pi 4096 May 7 06:46 .
    drwxr-xr-x 3 root root 4096 Feb 13 07:55 ..
    -rw-r–r– 1 pi pi 244 May 6 06:50 airports
    -rw——- 1 pi pi 905 May 7 06:46 .bash_history
    -rw-r–r– 1 pi pi 220 Feb 13 07:55 .bash_logout
    -rw-r–r– 1 pi pi 3523 Feb 13 07:55 .bashrc
    drwxr-xr-x 7 pi pi 4096 May 5 22:11 .cache
    drwx—— 11 pi pi 4096 May 6 07:20 .config
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Desktop
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Documents
    drwxr-xr-x 2 pi pi 4096 May 6 20:42 Downloads
    drwx—— 3 pi pi 4096 Feb 13 08:17 .gnupg
    -rwxr-xr-x 1 pi pi 53 Apr 19 14:48 lightsoff.sh
    drwxr-xr-x 3 pi pi 4096 Feb 13 08:03 .local
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:03 MagPi
    drwxr-xr-x 3 pi pi 4096 May 7 06:46 METARMAP
    -rwxr-xr-x 1 pi pi 2568 May 5 22:51 metar.py
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Music
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Pictures
    -rw-r–r– 1 pi pi 108 Apr 19 14:48 pixelsoff.py
    drwx—— 3 pi pi 4096 May 5 21:41 .pki
    -rw-r–r– 1 pi pi 807 Feb 13 07:55 .profile
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Public
    -rwxr-xr-x 1 pi pi 48 Apr 19 14:48 refresh.sh
    -rw-r–r– 1 pi pi 74 May 7 06:44 .selected_editor
    -rw-r–r– 1 root root 264 May 7 06:46 startup.log
    -rwxr-xr-x 1 pi pi 107 Apr 19 14:48 startup.sh
    -rwxr-xr-x 1 pi pi 129 May 6 20:48 startup.sh_test
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Templates
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Videos
    -rw——- 1 pi pi 56 May 7 06:46 .Xauthority
    -rw——- 1 pi pi 2425 May 7 06:47 .xsession-errors
    -rw——- 1 pi pi 2425 May 7 06:35 .xsession-errors.old

    Any thoughts as to what is going on?
    Thanks! Ron

    Reply
    1. Philip Rueker Post author

      Hi,
      I just updated the instructions on the github and removed the step about setting up rc.local since it seems to cause strange issues with startup.
      I found it easier to just rely on the crontab instead to automatically run the script regularly, so I suggest you just forget the rc.local startup and instead use the crontab.

      Reply
      1. Ron Heberlein

        That did it. It took a minute to start after a restart, but it came on automatically!
        50 lights setup, now I have to get the sectionals. Thanks for the help!

        Reply
        1. Spencer Hamons

          Ron…I am going to do this project at Christmas with my son. Did you run into any problems running 50 LEDs off the 5v pin directly on the Pi?

          Reply
  9. Steve Peck

    there is no startup.sh file in github now… and can you please update the instructions about what you’re saying about cron?

    Reply
    1. Philip Rueker Post author

      Correct, I removed the startup.sh file, since for the crontab I just used refresh.sh (which basically does the same).
      The instructions about crontab have been on the Github all this time:

      To have the script start up automatically and refresh in regular intervals, use crontab and set the appropriate interval. For an example you can refer to the crontab file in the GitHub repo (make sure you grant the file execute permissions beforehand to the refresh.sh and lightsoff.sh file). To edit your crontab type: crontab -e, after you are done with the edits, exit out by pressing ctrl+x and confirm the write operation
      The sample crontab will run the script every 5 minutes (the */5) between the hours of 7 to 21, which includes the 21 hour, so it means it will run until 21:55
      Then at 22:05 it will run the lightsoff.sh script, which will turn all the lights off

      Reply
  10. Ron Heberlein

    Phillip,

    Have you tried to incorporate blinking lights into the program?
    I’d like to be able to have a light blink if the wind speed (or gust) exceeds a certain value. I’ve been searching on the internet for this and haven’t seen anything that seemed like it would plug into your code. That being said I’m not a programmer…

    Reply
    1. Philip Rueker Post author

      I felt inspired by your question and since I am a programmer, I expanded the script to support blinking for windy conditions.

      I just uploaded the updated version of the script that now supports animation for wind conditions, if you go to the github, please use the updated refresh.sh, metar.py and lightsoff.sh with the latest version I just uploaded (it makes sure that any currently running scripts will be closed when the next one runs).

      I also added some information to the Readme instructions about the new parameters that I’ve added to the metar.py script that you can adjust as needed.

      Reply
      1. Ron Heberlein

        How awesome!!!
        I found one error in your code. On line 22 and 23, both variables were named “COLOR_IFR_FADE”. I updated line 22 to remove the “_FADE” and everything worked perfectly!

        Reply
  11. Jordan

    Hi Philip,

    Thanks so much for the tutorial, build a huge map to go in my work area and everyone loves it. Ive seen now the commercial Maps have the ability to flash white when there is lightning reported in the area? Is there any way we could add a line in the script to run this kind of like how you ran the wind one? That would be super cool!

    Reply
    1. Philip Rueker Post author

      Hey,
      Sure, I just added this functionality in the script, it will flash to white to represent lightning in the vicinity as reported by that airports METAR.
      You can get the latest version with the updated changes from the github.

      Reply
  12. Kit

    Hi Philip.

    I have an issue where only the first led lights up. I have a strand of 50, the ones you suggested. I can issue “pixels = neopixel.NeoPixel(board.D18, 30)” or use 20, or 10, or 50, I still only get the first led to light up after issuing “pixels.fill()”. Do you think I have a bad strand of leds?

    Reply
    1. Philip Rueker Post author

      I think there’s two possibilities.
      1) Yes maybe the strand is bad
      2) Did you make sure that you connect the correct ends to the Raspberry? On the LEDs you will find a small arrow on one side like this, this is the side that you have to connect the wires to the Raspberry. direction on LEDs.

      Reply
      1. Kit

        I did connect the pi to the input end of the led strand. After some testing, the strand is defective. Will give it a try again when the new strand arrives! Thanks for the help.

        Reply
        1. Colin

          I’m also having issues with the strand. I got about half of them to light up red (not seeming to be talking to the code?), but now none are lighting up. I’ve triple checked the connections. Is it possible the LEDs got fried? I noticed in the link you provided it mentioned that as a possibility I recall reading or seeing any level shifting in your setup.

          “Powering NeoPixels from Raspberry Pi Without Level Shifting”
          https://learn.adafruit.com/neopixels-on-raspberry-pi/raspberry-pi-wiring

          Reply
          1. Colin

            Ok, I was able to get the lights working with the python commands you provided to others. Now I can’t seem to get it to light up to the metars. Maybe its a permissions/executable issue?
            When you enter the “chmod +x lightsoff.sh” etc. command are you suppose to see some message after? I just enter it and it cycles down to a new line.
            I’ve also noticed that when I run “ls -al” some files are in “root” and some in “pi” like “airports”.

          2. Philip Rueker Post author

            Yes sounds like a permissions issue.
            You can fix to take over the file ownership by running this:
            sudo chown pi:pi FILENAME

            This will make pi the owner and then it should hopefully work.

          3. Jonathan

            Collin,
            How did you finally get them to light up? I have an issue where none of mine light up. I had thought that I needed to order a new strand. Was that you solution?

        2. Jonathan

          Kit,
          Did the new strand work? I am having an issue where none of mine light up either.

          Reply
      2. Paul

        Great project! I’m sure I’m missing something but both ends of the strand I ordered from your pats list have the white forward arrow..can you show the connector end that is correct? Is it the male or female end?

        Reply
        1. Philip Rueker Post author

          Hey,
          So if you take the lights, There should be one side on each LED that has the forward arrow and the back side won’t.
          The cables that are on the top side going into the light on the side with the forward arrow is the input end.
          Lights

          Reply
  13. Chuck

    I just finished making one of these, i love it! thanks for putting together this guide, and the upkeep with the code!

    Reply
  14. Ron Heberlein

    I wanted to see if anyone else was having issues with the map not refreshing?
    For about the past week, I have to turn the Pi off and then back on to get the map to refresh with the latest weather data. It then will refresh for a while (maybe a few hours), and then gets stuck again.

    Is there a way to plug in a monitor and see how the program is running (other than manually starting the program)?

    Reply
    1. Philip Rueker Post author

      Maybe your WIFI connection is weak and it fails at some point randomly? I’m not quite sure how the raspberry PI handles that.

      In any case, you could write to a logfile every time the script gets executed.
      If you just want to see if the script get’s started at all you could add something like this to the start of the refresh.sh script:
      echo $(date) - running metar script >> myfile.txt
      This will write the current date/time into a new text file called myfile.txt

      And if you want to just print the entire output of every time the script gets executed automatically, you can modify your crontab to something like this and it will print the entire output that would usually be seen on the console:
      * 7-21 * * * /home/pi/refresh.sh > /home/pi/outputlog.log 2>&1
      This will print everything that happens in the script into a new file called outputlog.log

      Reply
  15. Randy

    Great post. I frequently visit Aero Maintenance at Pearson airport and have always liked the METAR chart they have in their office. I was looking for different addressable LED products to make my own METAR chart and, bam!, full build instructions and parts list!

    My plan is to combine this with a previous (insanely over-designed) project of mine: https://github.com/slakpi/piwx. Basically, I’m thinking about building the METAR chart, then cutting out a part of the sectional for the PiTFT screen so it can also display METAR details.

    Reply
  16. Tony

    Philip, fantastic project. I noticed there is a guy in the US (Metarmaps) selling these so i was curious to see if the code/project existed and found you. A couple of hours work and it was up and running. The VNC charts in Canada are paper only and huge so I discovered the US charts are free and downloadable so I am going to have a poster shop print up the size I want ( 2′ x 3′) and then complete the LED install. Bought you more than a coffee 🙂 Thanks for the project.

    Tony Varga
    C-FFOM
    CYKF

    Reply
  17. Scott

    You may not know this for sure but I’m about to start a very large map and I’m up to 81 LEDs so far. Can this project use more than 50? Do you happen to know the limit?

    Reply
    1. Philip Rueker Post author

      Yes you can, but you will have to wire an external power supply to the LEDs as the internal power coming from the Raspberry Pi won’t be enough to power that many LEDs.

      Reply
      1. Scott

        Just got my 5050 LEDs and the code works great. The fading confused me a bit because I was expecting a fade but found that it just blinks with a set brightness. I’m using 107 5050 LEDs and the current draw is 0.81A.

        Reply
  18. Anthony Varga

    Philip, to conserve the lifetime of the LEDs (they are long but really only about 5 years on 24/17) I purchased a micro PIR sensor that I am going to flush mount into my map to trigger the lights on when motion is detected. I am planning to put a 60 minute countdown in Python that when triggered, would start counting and when t=0 the lights would go off. I am not an adept Python programmer but will figure it out but just wondering if you have any thoughts about placement of the timer in the code ?

    Reply
    1. Philip Rueker Post author

      So the script will just turn on the light and will keep them lit when the script finishes by default.
      So you could just add a sleep timer and then deinit the LEDs which turns them off at the end. So you can just add this to the bottom of the metar.py script and it will wait for 3600 seconds and then pixels.deinit() will turn off the LEDs until the next time the script starts and turns them back on.

      time.sleep(3600.0)
      pixels.deinit()

      Reply
  19. Anthony Varga

    I think the problem with that is that during the sleep, the metars will not update every five minutes like they do now ?

    Reply
    1. Philip Rueker Post author

      Yes in that case, what you’ll need to do is make use of a temporary file where you store the time when you started the timer after motion was triggered.
      You can insert the code just after the initialization of the LEDs.
      Here’s a sample that should work, there are 2 new imports in line 9 and 10 and you need to replace the sensor piece of code in line 59 with your reading of your actual motion sensor to return True when motion is detected: https://gist.github.com/prueker/12945cbf4220ce0221e79174db7c5cc9

      Reply
  20. Anthony Varga

    Really appreciate the code insert. I will play this weekend and report back.

    Reply
  21. Anthony Varga

    Hi Philip, I was looking at and playing with the code you created. I am not a strong Python programmer at all but more an old guy C++ programmer so I can follow it somewhat. When I look at metar.py it looks like the code runs every 5 minutes via cron and when it does, the first part of the code captures the web metar data and then at the bottom there is a loop that cycles for the time set to do the flashing lights. So, my understanding is that when the python script runs, it is only testing the PIR input once so it must be triggered to 1 exactly when the script is run by cron. Is my understanding correct ? If that is correct, the chances of it pickup up a motion trigger are slim to none. I know the code allows flexibility to define the duration of the ‘flashing’ loop which is 300 by default so basically the script runs for 5 minutes, exits, reruns via cron immediately, updates the metar data and then loops at the bottom until exit. Python is somewhat new to me so I am playing with a side script that is detecting the PIR and running a 60 minute countdown timer and setting a global variable. Metar.py would then test that variable and if 1 would operate as it does now but if zero would deinit() and exit. My other thought is to just have Metar.py running all the time, jumping to the top to do an update every 5 minutes but managing the PIR detector and timing within.

    Sorry, long comment. Basically want to confirm my understanding on how the script is operating and the reason for exiting every five minutes and rerunning immediately to ensure I am not on a wrong track here.

    Thanks !

    PS : I am following your Sling build as well. I own a Commander 112 but contemplating building an RV-10 as a retirement project in a few years.

    Reply
  22. Scott Moody

    Is there a way to run this without using file PID? The reason I ask, I want to make the file system read-only and this won’t run that way.

    Reply
    1. Philip Rueker Post author

      You could, but you’d need to make sure that the runtime of the script is less than the trigger time in order to make sure that there are no race-conditions in accessing the LEDs.

      So if you set the script to run for say 270 seconds (4 1/2 minutes) and trigger the script every 5 minutes using the cronjob, then you should be okay (usually the weather fetching and all takes about 5-10 seconds) and you could remove the file PID action.

      It’s basically just a protective layer to make sure only one instance of the script is running at any given time.

      Reply
  23. Phil Lightstone

    Hi Gang,

    I’m working on a map as well. I was wondering if anyone has sourced a ws2811 string that had more wire in between the LEDs? I believe that most have 3” of wire.

    P …

    Reply
    1. Philip Rueker Post author

      I have not seen premade strings with longer distances as you said, but you can buy individual LEDs and solder your own custom wire lengths, or use of the premade ones and cut and solder in longer wire where needed.

      Reply
  24. Phil Lightstone

    Hi Philip,

    I built one for my son’s birthday in October (PS it was a hit), collaborating with Tony. Bought the Alitov on Amazon. Lots of soldering to get the inter LED lengths right. I’ve sent an email out to a few vendors. We’ll see what they come back with.

    Reply
  25. Nicholas

    Just before I begin, I wanted to make sure I get the airports right. Is there anyway to confirm the airport LED in the code is physically in the correct position on the map? I saw another example and they had some blinking setup tutorial.

    Thanks!

    Reply
    1. Philip Rueker Post author

      When you run the code it will print out the statement saying that it have a message showing which LED is set for which airport, so you can use that to reference to make sure it’s in the right spot.
      LEDs message
      It will count starting from 0 for the first LED and if you have some LEDs that you are skipping and use NULL in the airports file for them it will just skip over them, but the LED count includes them, so like you can see in the image above, I have some gaps for example it goes from LED 0 to LED 2 and skips over the LED 1.

      Reply
      1. Nicholas

        Got it – I managed to do exactly that and the code appears to be working (just like you said it would). Unfortunately, I incorrectly wired something because I fried the pi and I found the error. I had a spare pi and tried to get it to work and the pi/code works fine but the lights wont turn on. I’m just not sure how to check if the lights are working or if it’s the pi again.

        Reply
        1. Philip Rueker Post author

          So if you’ve wired them correctly, then you can test just the lights by themselves if you open python and run the following:
          To open python:
          sudo python3
          Then entering the following to light up 30 LEDs at once (if you are using more, just replace the number below):
          import board
          import neopixel
          pixels = neopixel.NeoPixel(board.D18, 30)
          pixels.fill((0,255,0))

          That will fill 30 LEDs with one color.
          If that doesn’t work, then either the Pi is bad, or something is wrong with the wiring.

          Reply
          1. Nicholas

            I figured it out – thanks for the help!

            I’m getting this error with your new code you made:

            Traceback (most recent call last):
            File “metar.py”, line 67, in
            ast = astral.Astral()
            AttributeError: module ‘astral’ has no attribute ‘Astral’

            I’ve attempted it numerous times with no avail. I just set it to false for now.

          2. Philip Rueker Post author

            My apologies, my new code for Astral had an unintended sideeffect in that it only worked for older Raspberries running an older version of the library.
            I just checked in the fix, so please take the newer version of metar.py and everything should be working again.

          3. Nicholas

            No need to apologize. Everything is working perfectly now! However, I am just trying to get the code to start up basically as soon as I power the pi. I have done the crontab and I am still running into a bit of a roadblock. All permissions are set properly.

            Thanks for your help with these replies man. You’ve definitely done a great project.

          4. Philip Rueker Post author

            This article helps troubleshoot the crontab https://garyhall.org.uk/troubleshooting-cron-raspberry-pi.html
            If you just set it up, then chances are it might just not be running yet, you can restart the crontab with this command:
            sudo /etc/init.d/cron restart

            If it’s running ok, then you should see something like here in the last line saying that it triggered the refresh.sh file:
            crontab

  26. Chris

    This project just rocks. Got me excited about my crappy programming skills. I have much better woodworking skills. And decent Photoshop skills. Just a couple of suggestions that have worked out for me and some that didn’t.

    You can download a sectional (or area maps) for free from the FAA website:
    https://www.faa.gov/air_traffic/flight_info/aeronav/digital_products/vfr/

    Crop and size it as you like and print it at your local Wal-Mart. I suggest matte finish and no frame.
    https://photos3.walmart.com/category/332

    I used 1/4 inch plywood for better durability. Spray mount is great stuff that is more forgiving than many spray adhesives. I have a dozen art projects still holding 25 years later and still used the same can. Worth the money.
    https://amzn.to/3gFqkfX

    Use a 5/16 Forstner bit to cut your paper + plywood. This is a very nice bit and cuts a perfect hole in the plywood and also doesn’t tear the chart paper. Make sure to put some wood behind your hold so it doesn’t splinter the plywood when the bit exits. https://amzn.to/37RixY8

    My mistakes:
    * Trying to save 10 bucks and solder more length in between bulbs. OMG, it was a not worth it. Just NULL the bulbs and buy another set. I wired some in reverse, which you can’t do, and wasted more of my life. I also tried to find longer lengths as above but to no avail.
    * Make sure your paper and plywood is clean and wiped before adding spray mount. I got too much junk in between and is noticeable in the right light. Presentation is everything.
    * I made my own frames. Well, this wasn’t as hard and turned out real nice, but a pre-made from would be much easier.
    * I’m not good at instructions. Read where each file goes during init and during setup. Make sure you have a K in front of all airports. Mine still doesn’t start at boot, so I have to figure that one out.

    Reply
  27. Randy

    Almost done with my build: https://1drv.ms/u/s!Ar5QrtP9ZYyWkp05MZCKMqjXnKjiag?e=if99aE

    Totally did what Chris above did. I used the FAA’s TIFF’s to combine the Seattle and KFalls sectionals to cover Astoria, OR down to Roseburg, OR and east to Redmond, OR. Basically my regular range for drilling holes in the sky. I had FedEx Office print them on foam board. Kind of expensive for a 22×28 poster, but looks pretty great.

    Biggest mistake I made was using a wood drill bit to make the holes for the LEDs. It worked, but more or less tore into the lamination and required a lot of cleanup with an Xacto knife.

    Mounting the screen in the poster worked out pretty nicely. Cut it just right so that the screen fits tightly in the foam board and does not need any extra support in the back.

    Reply
      1. Randy

        Ha! Very cool!

        Forgot to mention the Yellow lights are mine are airports where the wind or gust exceeds 25 knots. Thought about doing blinking lights like you did, but didn’t want to spend the time implementing it.

        Reply
      2. Anthony Varga

        If anyone is interested, I designed a nice front/flush mounted bezel for the display. You can cut a hole in the map and drop it in. If interested PM me at ve3zav63@gmail.com

        I also did a spinoff from a published light block for these LEDs that enables you to pop the led into the block sideways and a ‘light pipe’ protrudes through a hole in the map. This allows the long LED units to be side mounted and much shallower shadow box.

        These are .STL files that you can slice with Cura or your favourite slicer and 3D print. Whichever colour you want for the display bezel and clear for the light blocks.

        Reply
  28. Isaac

    Thanks for the very cool project write up! I’ve never used rasberry pi, linux, python, or any of that business before so it has been quite the learning curve.

    I wanted the lights to also light up a little sooner than the 5 minute mark when I first booted the project up, so I did some googling and added

    @rebooth sleep 30 && /pi/home/refresh.sh

    and that seemed to get the job done! Without the sleep 30 seconds it didn’t seem to want to work.. maybe because it was running the script too soon after boot, before it connected to the WiFi?

    I haven’t touch coding since high school (15 years probably!) and that was C++.. I tried a little Python right after that class and it was way over my head. So I’m very happy to be able to learn so much on a project like this now.

    Cheers.

    Reply
    1. Jeff

      Phillip, anyone
      I have read all the data here on how to get the Crontab to work and I’m still having issues with it starting up without me telling it to. Im a noob at programming, so any helpful tips or tricks you might have would be greatly appreciated. thanks
      Jeff

      Reply
      1. Philip Rueker Post author

        Hey,

        hopefully this article might help with troubleshooting the cron tab https://garyhall.org.uk/troubleshooting-cron-raspberry-pi.html

        Usually it’s around permissions, so you can try and make sure that your normal “pi” user account owns the file and that they have read and execute permissions.
        You can check that by typing “ls -al” and seeing that “pi” is listed as the owner and not root.
        To change ownership you can run “sudo chown pi:pi FILENAME” and “sudo chmod +x FILENAME” for execute and “sudo chmod +r FILENAME” for read permissions and that should *usually* help.

        The article I just referenced above has a couple of other tips to troubleshoot it.

        Reply
  29. Colin

    Troubleshooting tip I encountered when setting up the wifi connection.
    The Raspberry Pi Zero W only supports 2.4 GHz networks, not 5 GHz. In other words, if you are having trouble connecting to wifi with the wpa_supplicant.conf file described, make sure the network you’re trying to connect to is 2.4 GHz.

    Reply
  30. Anthony Varga

    Phil, the mini display is a great add. What would I do to keep the display static on one airfield ? I would like to mount it by my home field and only report on that field.

    Reply
    1. Philip Rueker Post author

      Hey,

      In the metar.py file, instead of looping through the airports towards the bottom of the file (there’s a comment “Rotate through airports METAR on external display”)
      Remove the indented code under:
      if disp is not None:
      and replace it with this (replace “KPAE” for whatever airport you want to show it for, just make sure that airport is present in the airports file for the LEDs):
      displaymetar.outputMetar(disp, "KPAE", conditionDict.get("KPAE", None))

      Reply
  31. Phil benyo

    Food for thought out there for people that might be struggling with getting the lights to start automatically- remember to set the timezone for your raspberry pi…keeping in mind time off times set in crontab as well…. pulled my hair out for a few hours this afternoon when I got it working for a brief moment then it wouldn’t work for the life of me… 5 hours later I had the epiphany. Im not smart- just persistent.

    just ordering my map now and will update later!

    Reply
  32. Adam

    Hi Phillip! Great project – has been a lot of fun so far.
    We got most of the PI/LED/Screen stuff working today – and it has been great.

    Any idea on how to make the Screen show a subset of METARs? I have 45 airports on the map – but only want the screen to show 5-10 of the most important to me.

    Reply
    1. Philip Rueker Post author

      That’s a neat idea.
      I just updated the script to support this, so you just need to take the updated metar.py file and add a new file “displayairports” into the folder with the list of airports you want to show on the LED display.

      Reply
  33. Andre

    What a wonderful project – thank you Philip for posting! Can you answer what are the maximum number of addressable LED’s the Raspberry Pi can support?

    Reply
    1. Philip Rueker Post author

      It depends a bit on how bright you set them.
      But using the ones that I’ve used, they are rated to use 0.3W per LED at full power and I have mine set to 50% power, so with using 50% power and assuming that draws 0.15W per LED then you can probably safely power about 40-50 from the direct 5v pin as that would draw about 1.5 amps.
      If you want to control more LEDs than that, then I suggest you use a higher rated external power supply like this one https://amzn.to/3aUem14 to power the LEDs.
      You can find some details on the wiring for this here: https://learn.adafruit.com/neopixels-on-raspberry-pi/raspberry-pi-wiring

      Reply
      1. Andre

        So the limiting factor is the power supply current to the LED’s and not the number of LED addresses available?

        Reply
        1. Philip Rueker Post author

          Correct, addressing wise there’s no real limit (that I know of) and some people have built maps of the entire US with 200 LEDs.

          So the power supply is the only limit, so for bigger maps you just use a larger separate power supply to provide power to the LEDs.

          Reply
          1. Philip Rueker Post author

            They are addressed in sequence from the IO pin through the communications wire from the raspberry.

          2. Kit

            I’m running 145 leds off the Raspberry Pi alone. The key is not to exceed 5 volts that the Raspberry Pi provides. I use this formula to figure out the max setting I can use for the LED_BRIGHTNESS variable in metar.py:

            (5v / # of LEDs) / 0.1v

            This formula assumes a 50 led strand rated for 5v at 100% power, so each LED would pull 0.1v at 100% power (5v / 50 = 0.1v). Using my example of 145 leds, from the formula I get a max led brightness setting of about 0.34, so I would make sure the LED_BRIGHTNESS variable was not set higher than 0.34 so I would not harm the Raspberry Pi circuit board.

            I am actually using 0.15 because I found the leds blinding even at 0.25! They look great during the day and at night. Your milage may vary.

      2. Anthony Varga

        FYI my current map (v2) has 60 LEDs powered directly from the Pi Zero W with no issues and does not get hot.

        Reply
  34. Spencer Hamons

    I am building this project and would like to put a “Legend” in the lower left of my sectional. Would like to have four LEDs, one each for LIFR, IFR, MVFR, VFR. Is there a way to add-in this details in the AIRPORTS.py file to have it statically display these?

    Reply
    1. Philip Rueker Post author

      The easiest would be to just add a small bit of code to the metar.py file for this right before the “pixels.show()” on line 239:
      pixels[i] = COLOR_VFR
      pixels[i+1] = COLOR_MVFR
      pixels[i+2] = COLOR_IFR
      pixels[i+3] = COLOR_LIFR

      This will illuminate the 4 LEDs after looping through all the airports in the respective colors. If you needed to add a gap from the last airport to where your legend LEDs are then just increment the distance to the “i” variable.

      Reply
      1. Spencer Hamons

        Forgive my ignorance here, but when I try to add the code listed above, I get an error that says:

        IndentationError: unindent does not match any outer indentation level

        I am hitting “tab” and picking the colors from the declarations, but not sure what is causing the script to error.

        Reply
        1. Spencer Hamons

          Disregard my comment Philip. I made the change in a plain text editor instead of the Python editor and it worked fine.

          Reply
          1. Spencer Hamons

            Yeah, that was the problem I was running into with the Python editor in the Pi, all looked indented correctly but the editor would generate an error. I defaulted back to just doing it in a plain text editor and it worked fine. Not really sure what the Python editor was expecting.

            Appreciate your quick response. Building this out with my son now, hopefully will have it built and mounted by the middle of the week. Will post pictures.

  35. Ted

    Phillip,

    Amazing project, I learned so much by making this.

    I’m having issues when I change the airport list, I’ve populated the list with 15 ICAO codes and changes the metar.py configuration LED_COUNT=15. It worked fine with the airport list provided but with my new list I get this error:

    Setting LED 0 for CYQG to MVFR (0, 0, 255)
    Setting LED 1 for CYCK to MVFR (0, 0, 255)
    Setting LED 2 for CYZR to MVFR (0, 0, 255)
    Setting LED 3 for CYXU to MVFR (0, 0, 255)
    Setting LED 4 for CYKF to MVFR (0, 0, 255)
    Setting LED 5 for CYHM to MVFR (0, 0, 255)
    Setting LED 6 for CYYZ to MVFR (0, 0, 255)
    Setting LED 7 for CYSN to MVFR (0, 0, 255)
    Setting LED 8 for CYOO to MVFR (0, 0, 255)
    Setting LED 9 for CYBN to MVFR (0, 0, 255)
    Setting LED 10 for CYPQ to MVFR (0, 0, 255)
    Setting LED 11 for CYQA to MVFR (0, 0, 255)
    Setting LED 12 for CYTR to VFR (255, 0, 0)
    Setting LED 13 for CYOW to IFR (0, 255, 0)
    Setting LED 14 for CYND to IFR (0, 255, 0)
    Setting LED 15 for CYMX to LIFR (0, 125, 125)
    Traceback (most recent call last):
    File “metar.py”, line 235, in
    pixels[i] = color
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 314, in __setitem__
    self._set_item(index, r, g, b, w)
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 280, in _set_item
    raise IndexError
    IndexError

    Reply
    1. Philip Rueker Post author

      I count 16 in there (note that the first LED is LED 0).

      So if you give it LED_COUNT 15 then you’re one short, hence the error.

      Reply
  36. Julius

    I think this is so cool. I decided to build one. When I test run it I get these errors and cannot figure out how to correct the error. My manual test of the lights is good. Can you help? Here are the errors:
    File “metar.py”, line 226, in
    pixels[i] = color
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 314, in __setitem__
    self._set_item(index, r, g, b, w)
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 280, in _set_item
    raise IndexError

    Reply
    1. Philip Rueker Post author

      An IndexError usually means that you are trying to address more LEDs than you’ve specified in the LED_COUNT, so make sure you increase the LED_COUNT variable to be at least as big as the amount of LEDs you are using (including NULLS if used).

      Reply
    2. Julius

      Never mind! It was a problem between the table and the chair. When I checked the airports file I found there were two blank lines after the last airports files. I spent hours years ago with a BASIC program that was failing when it got to a point in the program reading a file. After having another set of eyes look at my data file, he spotted a missing comma right away.

      Reply
  37. Alex

    Hello. First of all congratulations and thanks to Philip Rueker for putting this together and inspiring the res to us.

    I have and odd issue my ALITOVE WS2811 12mm Diffused Digital RGB LED Pixel Light seems to be
    pixels.fill((0,255,0)) Blue
    pixels.fill((255,0,0)) RED
    pixels.fill((0,0,255)) Green

    Not like on the tutorial, Is this common..?
    So I simply changed the metal file.
    But then found that when tested I get for example my first ten led all do
    All red
    All blue
    All green
    Just fine
    I but when I setup the airports, after an airport that is IFR ( red) the next led will glow purple, regardless of the metal code . I can see the code saying the correct color but it glows differently.

    Is there a test code sequence that runs the pixels thru a color range? Or any ideas on how to test my leds?

    Reply
    1. Philip Rueker Post author

      That’s very strange. May be a faulty string of lights.

      If you scroll up in the article I explain how you can test all the LEDS for the colors.
      Basically connect to the py, then enter sudo python3 and then you can just initialize the LEDS with one color at a time to test like this:
      import board
      import neopixel
      pixels = neopixel.NeoPixel(board.D18, 30)
      pixels.fill((0,255,0))

      Reply
      1. Alex

        Hello again, just as an update
        I have an interesting problem. I bought the alitove pixels. (twice)

        I returned the first strip because i thought it had defective pixels. Wrong colors or dim pixels.
        The second one got in, and it is behaving the similarly.

        I found that EVERY time i have a RED pixel , the one before it, turns dim blue. Regardless of the color it is programed to.

        I have tested it now with raspberry pi power only, AND now im testing it with independent power supply .
        Seems the RED command screws things up.
        To add to the oddities. this ones light up differently i had to do this adjustment.
        COLOR_VFR = (0,0,255) # Green
        COLOR_VFR_FADE = (0,0,125) # Green Fade for wind
        COLOR_MVFR = (0,255,0) # Blue
        COLOR_MVFR_FADE = (0,125,0) # Blue Fade for wind
        COLOR_IFR = (255,0,0) # Red
        COLOR_IFR_FADE = (125,0,0) # Red Fade for wind
        COLOR_LIFR = (125,125,0) # Magenta
        COLOR_LIFR_FADE = (75,75,0) # Magenta Fade for wind
        COLOR_CLEAR = (0,0,0) # Clear
        COLOR_LIGHTNING = (255,255,255) # White

        I re flashed the SD card and started over, same thing. Could it be the pi? Any ideas or suggestions are all welcomed.

        Reply
        1. Philip Rueker Post author

          That’s very strange and I have never heard of that, so yes, maybe indeed something is up with your Pi?
          Maybe the solder connection on the board isn’t solid or something, but it’s hard to say.
          I guess maybe trying another Pi might be the easiest way to troubleshoot it.

          Reply
          1. Alex

            Hello Philip, just back to thank you. It seems it was the darn ground solder. Cleaned and re did them all.
            Seems to be working.

            im now working on the startup after boot, for some reason it wont.
            you mentioned the refresh.py file should be owned by user pi
            What would be the command for that? im no linux guru but can type lol
            thanks!

          2. Philip Rueker Post author

            Hi,
            You can change the ownership of the file like this:
            sudo chown pi:pi FILENAME
            And to change the permissions:
            sudo chmod +x FILENAME to give execute permissions (for the .sh files)
            and:
            sudo chmod +r FILENAME to give read permissions

            First make sure that you can run the ./refresh.sh and ./lightsoff.sh file from the console and if that works, then you can add them to the crontab.
            If you have trouble with the crontab, here is some tips for troubleshooting it – https://garyhall.org.uk/troubleshooting-cron-raspberry-pi.html

  38. Andre

    On your GitHub page, the 1st Software Setup instruction is to download Raspberry Buster Lite. That link takes me to a Raspberry Pi 404 error page. Where can I find Buster Lite?

    Reply
  39. Andre

    Thanks Philip. After successfully downloading Raspberry Pi OS Lite and unzipping, I tried flashing my SD card with the .img file using Etcher and receive the error message: “Something went wrong. If it is a compressed image, please check that the archive is not corrupted. ENOENT: No such file or directory, open ‘C:\Users\Andre\AppData\Local\Temp\balena-etcher-electron–752-to2cuXRb9arS-.cmd’
    As mentioned, has been unzipped/not compressed. How can I flash this file?

    Reply
    1. Philip Rueker Post author

      Not sure about etcher.

      I used the Raspberry Pi imager last time, which will let you select the image, it’s available at the same link.

      Reply
  40. Andre

    I added the wpa_supplicant.conf (with my WiFi’s network & password names included) and ssh files as instructed but my Zero is not connecting to my WiFi – it doesn’t appear in my router/modem’s Device Table list. When I remove the SD card after it’s been in the Pi, it appears the Pi is removing the SSH file when viewed on my Win 10 machine.

    With every step I’ve so far had issues – is this the best way for us to communicate?

    Reply
    1. Philip Rueker Post author

      Here’s some tips to get the wifi working: https://raspberrytips.com/raspberry-pi-wifi-setup/ or alternatively you could try to use this image called BerryLan that has an app to hook up the wifi, though I have no experience with it.

      Yes I believe the ssh file goes away once it’s been absorbed by the raspberry pi if you put the sd card back into the pc.

      Sharing problems via the comments here is helpful for others who run into issues.

      Reply
  41. Andre

    Progress! Where do I find /home/pi to store the scripts? Do I have to create it? All I have currently are files in the root and an overlays folder.

    Reply
    1. Philip Rueker Post author

      /home/pi is the default user directory, so if you SSH into the raspberry using the default pi user, you will land in the /home/pi folder.
      you can also type “cd /home/pi” and you should land in the same folder.

      Reply
  42. Andre

    How do I copy the 5 script files on my Win 10 computer into the /home/pi directory? Can I do this with the SD card plugged into my Win 10 Computer?

    Reply
    1. Philip Rueker Post author

      I use a tool called WinSCP to transfer files between my computer and my raspberry.

      Reply
  43. Andre

    I’ve successfully uploaded all files into the Pi and changed permissions as instructed. When I run metar.py, I see the statement messages (Wind animation: False, etc.), the https://www.aviationweather.gov… line, then Done appears and I’m returned to the pi@raspberrypy prompt, but I see no LED’s light up. I’ve verified the LED’s operate correctly with your command to sequence prior to running metar.py. I’m not sure what the next steps are to troubleshoot and make the system work?

    Reply
    1. Philip Rueker Post author

      Make sure your airports file is set up. Do you see a list of airports in the aviationweather.gov line?
      This is how it should look if it’s working:metar.py output

      Reply
  44. Andre

    Excellent reference – my system is now working!!! What I had wrong – in my airports file, I had included the line number before each airport identifier. Once I removed the numbers, the system began working. I even have the Uctronics display connected and working.
    Awesome coaching, Philip – thank you so much!

    Reply
  45. Andre

    Observation – the Uctronics display is cycling through my airports list backwards/in reverse order as to how they’re listed in my airports file (from the last airport listed to the first). Can I change/reverse this?

    Reply
    1. Philip Rueker Post author

      The order for the display is somewhat random and is currently determined by the order that the weather is returned from aviationweather.gov for simplicity, so there’s no easy way to change the order at the moment.

      Reply
  46. Andre

    I’ve also noted the program quits running after about 4 minutes. After the “Setting for LED . . .” info, I see Done, the program stops and then displays the prompt. I have installed Crontab and have the refresh cycle set for 1 minute. How can I get it to keep running indefinitely?

    Reply
    1. Philip Rueker Post author

      The default is 5 minutes via the BLINK_TOTALTIME_SECONDS being 300.
      So the crontab if you set it to run every 5 minutes like in the example crontab on the github should run it indefinitely, but you can change the combination of crontab and the total time as you like.

      Reply
  47. Andre

    After I edit and run crontab as instructed, the system operates but I no longer see the stream of LED or airport callsigns? I’ve logged in with Putty, WinSCP and have a monitor connected to the Zero with the same results – nothing indicates it’s running like it does when I run the program from the prompt. Also, when using crontab, it takes a few minutes for the program to start after reboot – again, different from when the program is started from the prompt, where it begins to run immediately.

    Reply
    1. Philip Rueker Post author

      Yes that’s normal. Crontabs operate in the background, so you won’t see anything on the screen when it’s running.
      The program will start automatically via the crontab based on your interval, in my case every 5 minutes, so as you said, it might take a minute or a few to start after you restart the raspberry, which should generally be fine for what the project is doing.

      Reply
  48. Andre

    After it first cycles and then waits the 5 minutes, the Qctroncis display blanks out then starts jumping back and forth between airports, quickly changing all the data. It doesn’t hold for the 8-10 seconds per airport like it does when it first starts. Is this normal?

    Reply
    1. Philip Rueker Post author

      If you didn’t change any of the timings from the default and just activated the Display functionality, then the crontab will re-run the script once every 5 minutes to fetch latest weather and the script will run for 300 seconds (aka 5 minutes), changing the screen every 5 seconds.

      Whether you run it from the console directly, or via the crontab makes no difference functionality wise, the crontab just simply triggers the script.

      Reply
  49. Andre

    I would like the display to stay fixed on my home airport KEIK (I saw your note on what to change in METAR.PY for this change). KEIK updates METARS every minute. Would I change crontab to the following to change the refresh rate: */1 7-21 * * * /home/pi/refresh.sh

    I’m still unclear about the timing relationship between crontab and BLINK_TOTALTIME_SECONDS in metar.py? If I change crontab to update every minute, do I also need to change the BLINK statement from 300 (5 mins) to 60 (1 min)?

    Reply
    1. Philip Rueker Post author

      Per the instructions on the github:

      If you want to only show a subset of the airports on the display, create a new file in the folder called displayairports and add the airports that you want to be shown on the display to it

      Yes the general principle is you’d keep them in sync, but if you’re using the refresh.sh script, then it doesn’t really matter if the blink time is longer as the refresh.sh will just cancel the currently running script and then start it anew whenever the crontab gets executed.

      Reply
    1. Philip Rueker Post author

      No, the only one I worked with is the one I used, so you will have to do your own research using a different one.

      Reply
  50. Andre

    I am using different addressable LEDs than listed in your Supplies Needed list. As they are individual LEDs and not a pre-wired string, I will need to wire & connect each one by hand. Is there a short routine I could use (similar to what you posted for checking all LED colors) that would step through and light each individual LED in sequence to verify I have them connected in the order matching my airports list?

    Reply
    1. Philip Rueker Post author

      As long as they are also WS2811, they should work just the same once you wired them correctly. If they are a different type then you’ll have to figure out what library to use to make them work.

      Reply
  51. Andre

    They are WS2811’s.

    What would be the command line to turn on each LED individually so I can verify the airport being lit on my map is wired in the same sequence as the airports listed in my airports file? (#1 = KCOS, #2 = KDEN, etc.)

    Reply
  52. Julius Garrett

    Hi Phil,

    This has been a great project. Thank you so much for the work and time put into it. I got my map that I had mounted and installed the lights. The script runs fine. I am using the mini display and a displayairports subset for it. One thing I noticed is it randomly stops scrolling when it reaches no particular airport. Then it starts again. Would I be correct in my thinking that it does this until the next refresh? If so, is there a change I can make for the display to keep rotating?

    I read your reply to another gentleman above. But, I am not sure if it is the same thing. I did not change any of the default times.

    Thanks,

    Reply
    1. Philip Rueker Post author

      Yes the scrolling of the display, along with blinking for weather is controlled by the BLINK_TOTALTIME_SECONDS, so you should set up your crontab to trigger the script again overlapping this.
      I have mine set to 300 seconds (aka 5 minutes) and the crontab to re-trigger every 5 minutes, which basically overlaps, so it appears more or less continuously.

      There will always be a very short pause when the new script triggers at the time where it retrieves the new weather at the beginning, so depending on your internet speed, that might be a few seconds where the scrolling is paused.

      Reply
      1. Julius Garrett

        Thank you! Letting it run to see the turn off feature and auto start again in the morning.

        Is there a place to drop a dime contribution?

        Reply
  53. Andre

    Is it possible for an airport to report CLEAR conditions but also have wind speeds above 15 kts? If so, what how will that airport’s LED respond?

    Reply
  54. Kevin

    Thank you for this. Your instructions are well written and easy to follow.

    I am thinking of attempting this as a gift. How would I get it connected to the recipient’s WiFi?

    Reply
    1. Philip Rueker Post author

      So you could either give them instructions on how to modify the wifi settings on the sd card like on initial setup, or maybe instead of using the bare Raspberry Pi OS, you could use this Image called BerryLan- http://berrylan.org/ with which you can set up the wifi using an app over Bluetooth.

      I haven’t used it myself, but have heard from others that that’s a possible solution that might work for you here.

      Reply
  55. Andre

    In the metar.py file, under NeoPixel LED Configuration, the entry for #38 is COLOR CLEAR = (0,0,0). Doesn’t that turn all LED’s off all? How/when would that setting be used?

    Reply
  56. Spencer Hamons

    Philip,

    Thanks again for your directions, and continuing to help the community on this with all of our questions. Very generous with your time for something you aren’t getting any renumeration for. Hope you know it is appreciated.

    One more question for you. I found a display that is slightly larger on Amazon and thought I would give it a try on my 2nd project I am doing for my son as a present for just finishing up his Private Pilot Cert. This board came in with a SSH1106 driver requirement instead of the SSH1306 chipset. Would like to see if this looks as good as the .96″ OLED display, even though it is the same resolution, just with a larger size of 1.3″. What would be required to load the driver for the SSH1106 chipset and send the display information to it? If this is overly difficult to do, feel free to disregard. If it is fairly simply, would be interested in trying it. Here is the one I bought. It says it could come with either the SSH1106 or the SSH1306 chipset, but you don’t get to pick which one. I got unlucky I guess. https://amzn.to/3cAQjoN

    Reply
    1. Philip Rueker Post author

      Hey,
      So if that display requires the SSH1106 driver you will have to install a different library and change the initialization of the display to use that different library inside the displaymetar.py file.
      It looks like some people have used this one here successfully with SSH1106 https://luma-oled.readthedocs.io/en/latest/
      So to install that library you’d do:
      sudo pip3 install luma.oled
      and then inside the displaymetar.py file instead of referencing the adafruit_ssd1306 library you’d reference the luma library and then the initialization of it, you’d have to replace the “disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) line with the appropriate initialization of that library.
      Looks like some samples are here:
      https://luma-oled.readthedocs.io/en/latest/python-usage.html
      And here’s some more references as the commands to fill the display with an image and turn it on and off are slightly different to the adafruit library:
      https://luma-oled.readthedocs.io/en/latest/api-documentation.html
      So you’d have to replace most of the “disp.XXXX” lines with the appropriate substitution from the api documentation.

      So assuming you can make those few substitutions, it should hopefully be relatively straightforward.

      Reply
      1. Spencer Hamons

        Thanks Philip. I’m good up to changing the display lines, but can hopefully pull use the links you provided and gather what I need to make the syntax changes. Appreciate your quick response as always.

        Reply
  57. Matt R

    Philip, thank you for the project. I’ve been wanting to do this for years, but don’t have the acumen myself to program. Your step by step has made it accomplishable.

    I need your help. There is a possibility of a dead LED I need to test, and I’m now in the end-stage of my build. I used your commands to test initially and all pixels worked fine on arrival, but I’ve done some butchery and might have ruined one. I’ve also confirmed the airport is transmitting METARs to aviationweather.gov.

    When I run your suggested commands to fill all LED’s to a single color, it only lasts for a second before the background running code changes the LED’s back to the airport METARs.

    Do you have a suggestion on how to stop the code from refreshing the LED’s? I tried researching into kill commands and stopping python but both are ineffective on my end… Thanks for your help! (new to Pi’s!)

    Reply
    1. Philip Rueker Post author

      Hey,
      I suggest you just temporarily remove the line from the crontab to trigger the automatic refresh of the LEDS while you do the separate test and then just add it back in the crontab again to re-trigger the METAR script when you are done with your testing.

      You can also always trigger the lightsoff.sh script that should kill the last run of the metar script (assuming you started it via the refresh.sh script).
      so if you type ./lightsoff.sh it will kill the last run of the script.

      Reply
      1. Matt R

        Thanks Philip, that did it. I greatly appreciate your help and again thanks for making the project possible

        Reply
  58. Carder Gregory

    Hi Philip,
    Is there a way to be able to assign each LED to a certain airport without the airport list? I plan on doing the entire state of Texas (everything is bigger here) and since I don’t know which LED’s will be skipped or which LED is going to whatever airport, I wanted to see if there was a way to illuminate each LED, one by one and assign its own airport? I saw a video on YouTube by Rhino Offroad who did this but wanted to see if there’s a way to incorporate this into your script? Or if there’s even a backdoor way around this issue? Thanks for everything!

    Reply
    1. Philip Rueker Post author

      Hey,
      So the way I did it was to first make sure all LEDs were working (with the details on how to test that in my instructions above) and if any of them are not, to just mark that one off (I just taped it with some black tape to mark it so I wouldn’t use it).

      Then to just build out the foam board with all the holes cut ready (using the template on which I wrote down the airport name, so it’s easy to know which hole is which airport) for the LEDs to be glued in and basically building the path from start to end for the LED string and so it becomes self-evident which LEDs are being skipped, so you basically just write down the airports in order following the string of lights into your notepad and put NULL for each LED skipped.

      Since it’s one continuous line of wire for the LEDs it’s pretty easy to just write down the list as you go.

      Reply
  59. Andre

    How can we check the airports we select actually have METARS available to turn on the LEDs? I created my airports file by looking at the sectional chart and selecting airports that show ATIS/ASOS frequencies but some LEDs never light. I’ve verified all LEDs do light/are wired correctly with your pixels.fill routine.

    Reply
    1. Philip Rueker Post author

      So at a quick glance, you can use your EFB like ForeFlight, or online on sites like https://skyvector.com/ and if that has a color light for an airport, then that airport probably reports online METAR.
      To verify you can type this into your browser and replace the airport code at the end with whatever airport you want to check, so for example:
      https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=5&mostRecentForEachStation=true&stationString=KPAE
      If it returns data, then that airport reports METAR information online, if it doesn’t, then it won’t light the LED.

      Reply
  60. Andre

    I’m having trouble with my system refreshing and staying active. After about 8-9 minutes, all flashing LEDs (indicating wind) turn solid and the system/LEDs no longer update. If I cycle power off/on to the Pi, after the boot cycle completes the LEDs again become active but this cycle repeats, the system seems to freeze and not refresh after 8-9 minutes. After this happens, I am still able to connect with Putty & WinSCP. I’ve edited and enabled crontab per your instructions (including setting it to run every 5 minute as per your example), running sudo /etc/init.d/cron restart after editing crontab, have granted the proper permissions to the 5 files you mentioned on GitHub and have reset BLINK_TOTALTIME_SECONDS to 300. Is there something else I need to change/add to keep my system running continuously?

    Reply
    1. Philip Rueker Post author

      If you follow my standard guide numbers, then the crontab should be re-running every 5 minutes to re-fetch the latest weather and update the LEDs continuously.
      This guide here – https://garyhall.org.uk/troubleshooting-cron-raspberry-pi.html – has a lot of useful tips to troubleshoot the crontab.
      In particular I suggest seeing the syslog to see if it is indeed running correctly.
      If you run tail -n 30 /var/log/syslog you should see a line every 5 minutes indicating that the /home/pi/refresh.sh script is being triggered like this:
      syslog output

      Reply
  61. Andre

    If I turn on the Pi, the LEDs never lite. I ran tail -n 30 /var/log/syslog and this is what I see:
    pi@raspberrypi:~ $ tail -n 30 /var/log/syslog
    Feb 4 10:38:28 raspberrypi systemd[450]: Reached target Sockets.
    Feb 4 10:38:28 raspberrypi systemd[450]: Reached target Basic System.
    Feb 4 10:38:28 raspberrypi systemd[1]: Started User Manager for UID 1000.
    Feb 4 10:38:28 raspberrypi systemd[450]: Reached target Default.
    Feb 4 10:38:28 raspberrypi systemd[450]: Startup finished in 632ms.
    Feb 4 10:38:28 raspberrypi systemd[1]: Started Session 1 of user pi.
    Feb 4 10:38:32 raspberrypi dhcpcd[437]: wlan0: no IPv6 Routers available
    Feb 4 10:38:36 raspberrypi systemd[1]: systemd-fsckd.service: Succeeded.
    Feb 4 10:41:34 raspberrypi systemd-timesyncd[198]: Synchronized to time server for the first time 149.56.121.17:123 (2.debian.pool.ntp.org).
    Feb 4 10:41:42 raspberrypi systemd[1]: systemd-hostnamed.service: Succeeded.
    Feb 4 10:41:53 raspberrypi CRON[476]: (pi) CMD (1/home/pi/refresh.sh)
    Feb 4 10:41:53 raspberrypi CRON[475]: (CRON) info (No MTA installed, discarding output)
    Feb 4 10:41:54 raspberrypi dhcpcd[437]: wlan0: hardware address 00:00:00:00:00: 00 claims 192.168.0.56
    Feb 4 10:41:56 raspberrypi dhcpcd[437]: wlan0: hardware address 00:00:00:00:00: 00 claims 192.168.0.56
    Feb 4 10:41:56 raspberrypi dhcpcd[437]: wlan0: 10 second defence failed for 192 .168.0.56
    Feb 4 10:41:56 raspberrypi avahi-daemon[259]: Withdrawing address record for 19 2.168.0.56 on wlan0.
    Feb 4 10:41:56 raspberrypi avahi-daemon[259]: Leaving mDNS multicast group on i nterface wlan0.IPv4 with address 192.168.0.56.
    Feb 4 10:41:56 raspberrypi dhcpcd[437]: wlan0: deleting route to 192.168.0.0/24
    Feb 4 10:41:56 raspberrypi dhcpcd[437]: wlan0: deleting default route via 192.1 68.0.1
    Feb 4 10:41:56 raspberrypi avahi-daemon[259]: Interface wlan0.IPv4 no longer re levant for mDNS.
    Feb 4 10:41:57 raspberrypi dhcpcd[437]: wlan0: rebinding lease of 192.168.0.56
    Feb 4 10:41:57 raspberrypi dhcpcd[437]: wlan0: probing address 192.168.0.56/24
    Feb 4 10:42:01 raspberrypi dhcpcd[437]: wlan0: leased 192.168.0.56 for 86400 se conds
    Feb 4 10:42:01 raspberrypi avahi-daemon[259]: Joining mDNS multicast group on i nterface wlan0.IPv4 with address 192.168.0.56.
    Feb 4 10:42:01 raspberrypi dhcpcd[437]: wlan0: adding route to 192.168.0.0/24
    Feb 4 10:42:01 raspberrypi dhcpcd[437]: wlan0: adding default route via 192.168 .0.1
    Feb 4 10:42:01 raspberrypi avahi-daemon[259]: New relevant interface wlan0.IPv4 for mDNS.
    Feb 4 10:42:01 raspberrypi avahi-daemon[259]: Registering new address record fo r 192.168.0.56 on wlan0.IPv4.
    Feb 4 10:42:02 raspberrypi dhcpcd[437]: wlan0: hardware address 00:00:00:00:00: 00 claims 192.168.0.56
    Feb 4 10:42:18 raspberrypi systemd[1]: Started Session 4 of user pi.

    Reply
    1. Philip Rueker Post author

      It looks like your Raspberry Pi was trying to get a valid IP address right after it triggered the script, so maybe your internet connection isn’t very stable?
      You should check the log again after logging in a bit longer before to see if there’s multiple lines of the crontab line indicating whether the crontab does indeed run okay every 5 minutes or not.
      You can also change the number of lines for the command by increasing the -n parameter.

      Please also read the article I referred to and try to follow it, as it has several tips on how to troubleshoot what might be going wrong.

      Reply
  62. Andre

    After I enter & run sudo python3 metar.py using Putty, I see the “Setting LED for KXXX to VFR (255,0,0)” statements for all my airports (67). After about 5 minutes, the LED statements stop scrolling, I see Done and the LEDs no longer flash/the program seems to stop.
    If I enter & run the sudo python3 metar.py command again, this cycle repeats and ends the same way.

    Reply
    1. Philip Rueker Post author

      Can you please run ./refresh.sh
      That should trigger the script and if that works, the crontab should work, if it doesn’t, then it means you don’t have the permissions set up correctly and might have to use chmod and chown on some of the files.

      Reply
  63. Andre

    ./refresh.sh does start my script. Do I need to change permissions on crontab or just the 5 files as you mention on GitHub?

    Reply
    1. Philip Rueker Post author

      Just the files should be enough. If you scroll up in the comments you can see how to use the chown command.

      Reply
  64. Andre

    I changed the permissions on all the files using chown – WinSCP now shows pi as the owner for all files. The only change has been when I power off/on the pi, the program starts automatically after booting instead of me having to start it manually. It is still stopping after about 8 minutes.
    Using crontab -e, I have verified the 2 bottom lines are identical to yours:
    */5 7-21 * * * /home/pi/refresh.sh
    05 22 * * * /home/pi/lightsoff.sh

    I re-ran tail -n 50 /var/log/syslog and below is the result – it does appear cron is running refresh.sh every 5 minutes but I’m not sure what the MTA not installed message is about?
    pi@raspberrypi:~ $ tail -n 50 /var/log/syslog
    Feb 4 14:04:05 raspberrypi systemd[1]: Started Getty on tty1.
    Feb 4 14:04:05 raspberrypi systemd[1]: Reached target Login Prompts.
    Feb 4 14:04:05 raspberrypi systemd[1]: Started OpenBSD Secure Shell server.
    Feb 4 14:04:05 raspberrypi systemd[1]: Reached target Multi-User System.
    Feb 4 14:04:05 raspberrypi systemd[1]: Starting Update UTMP about System Runlevel Changes…
    Feb 4 14:04:06 raspberrypi systemd[1]: systemd-rfkill.service: Succeeded.
    Feb 4 14:04:06 raspberrypi systemd[1]: systemd-update-utmp-runlevel.service: Succeeded.
    Feb 4 14:04:06 raspberrypi systemd[1]: Started Update UTMP about System Runlevel Changes.
    Feb 4 14:04:06 raspberrypi systemd[1]: Startup finished in 5.539s (kernel) + 36.897s (userspace) = 42.436s.
    Feb 4 14:04:06 raspberrypi systemd[1]: Created slice User Slice of UID 1000.
    Feb 4 14:04:06 raspberrypi systemd[1]: Starting User Runtime Directory /run/user/1000…
    Feb 4 14:04:06 raspberrypi systemd[1]: Started User Runtime Directory /run/user/1000.
    Feb 4 14:04:06 raspberrypi systemd[1]: Starting User Manager for UID 1000…
    Feb 4 14:04:07 raspberrypi systemd[452]: Listening on GnuPG cryptographic agent (ssh-agent emulation).
    Feb 4 14:04:07 raspberrypi systemd[452]: Listening on GnuPG cryptographic agent and passphrase cache (restricted).
    Feb 4 14:04:07 raspberrypi systemd[452]: Listening on GnuPG cryptographic agent and passphrase cache.
    Feb 4 14:04:07 raspberrypi systemd[452]: Reached target Timers.
    Feb 4 14:04:07 raspberrypi systemd[452]: Listening on GnuPG network certificate management daemon.
    Feb 4 14:04:07 raspberrypi systemd[452]: Listening on GnuPG cryptographic agent and passphrase cache (access for web browsers).
    Feb 4 14:04:07 raspberrypi systemd[452]: Reached target Sockets.
    Feb 4 14:04:07 raspberrypi systemd[452]: Reached target Paths.
    Feb 4 14:04:07 raspberrypi systemd[452]: Reached target Basic System.
    Feb 4 14:04:07 raspberrypi systemd[1]: Started User Manager for UID 1000.
    Feb 4 14:04:07 raspberrypi systemd[452]: Reached target Default.
    Feb 4 14:04:07 raspberrypi systemd[452]: Startup finished in 648ms.
    Feb 4 14:04:07 raspberrypi systemd[1]: Started Session 1 of user pi.
    Feb 4 14:04:13 raspberrypi dhcpcd[439]: wlan0: no IPv6 Routers available
    Feb 4 14:04:18 raspberrypi systemd[1]: systemd-fsckd.service: Succeeded.
    Feb 4 14:05:33 raspberrypi systemd-timesyncd[225]: Synchronized to time server for the first time 204.93.207.12:123 (2.debian.pool.ntp.org).
    Feb 4 14:05:41 raspberrypi systemd[1]: systemd-hostnamed.service: Succeeded.
    Feb 4 14:05:54 raspberrypi systemd[1]: Started Session 3 of user pi.
    Feb 4 14:06:10 raspberrypi CRON[486]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:06:10 raspberrypi CRON[485]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:10:01 raspberrypi CRON[495]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:10:02 raspberrypi CRON[494]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:15:01 raspberrypi CRON[506]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:15:01 raspberrypi CRON[505]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:16:00 raspberrypi systemd[1]: Started Session 7 of user pi.
    Feb 4 14:17:01 raspberrypi CRON[538]: (root) CMD ( cd / && run-parts –report /etc/cron.hourly)
    Feb 4 14:20:01 raspberrypi CRON[548]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:20:02 raspberrypi systemd[1]: Starting Cleanup of Temporary Directories…
    Feb 4 14:20:02 raspberrypi CRON[547]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:20:02 raspberrypi systemd[1]: systemd-tmpfiles-clean.service: Succeeded.
    Feb 4 14:20:02 raspberrypi systemd[1]: Started Cleanup of Temporary Directories.
    Feb 4 14:25:01 raspberrypi CRON[562]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:25:02 raspberrypi CRON[561]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:30:01 raspberrypi CRON[573]: (pi) CMD (/home/pi/refresh.sh)
    Feb 4 14:30:01 raspberrypi CRON[572]: (CRON) info (No MTA installed, discarding output)
    Feb 4 14:30:51 raspberrypi crontab[587]: (pi) BEGIN EDIT (pi)
    Feb 4 14:32:52 raspberrypi crontab[587]: (pi) END EDIT (pi)

    Reply
    1. Philip Rueker Post author

      I suggest you output the results of the crontab to a temporary log file to see if you can find any errors:
      So change the crontab to this:
      */5 7-21 * * * /home/pi/refresh.sh > /home/pi/templog.log 2>&1

      This will output the results of the script run into a temporary file called “templog.log” in the same folder, and then I suggest you see what you can find in there (particularly when the time where you say the script stops).

      Reply
  65. Andre

    I read your link on Troubleshooting Cron and verified the first five steps. I added your suggested line to crontab and have run the script for a while. As I write, the LEDs have again frozen but according to the temp.log, the program is still outputting LED data. Here is the beginning of the log – after the last line below, it continues repeating the airport data (not posted as it is a very long file):

    pkill: pidfile not valid
    Try `pkill –help’ for more information.
    pkill: pidfile not valid
    Try `pkill –help’ for more information.
    Running metar.py at 04/02/2021 16:25
    Wind animation:True
    Lightning animation:True
    Daytime Dimming:False
    External Display:True
    Using subset airports for LED display
    https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=5&mostRecentForEachStation=true&stationString=KLAA,KTAD,KPUB,KVTP,KALS,KRCV,KCPW,KPSO,KDRO,KFMN,KCEZ,KMTJ,KTEX,K04V,K1V6,KPUB,KLHX,KLAA,KITR,KLIC,KFLY,KCOS,KAFF,K4BM,KAEJ,KANK,KMYP,K7BM,KGUC,KMTJ,KAJZ,KGJT,KRIL,K5SM,KEGE,KASE,KLXV,KCCU,K0CO,KC99,KAPA,KCFO,KDEN,KEIK,KLMO,KBJC,KBDU,K20V,K20V,KEEO,K4V0,KCAG,KSBS,KC07,KFNL,KGXY,KFMM,KAKO,K2V6,K2V5,KHEQ,KSTK,KSNY,KIBM,K82V,KCYS,K33V,KDWX
    KAEJ:VFR:240@11G16:10SM::-3/-15:29.9:False
    KSTK:VFR:340@20G29:10SM::3/-10:29.85:False
    K7BM:VFR:270@28G49:10SM::-6/-17:29.82:False
    KVTP:VFR:250@11G19:10SM::-6/-18:29.86:False

    Reply
    1. Philip Rueker Post author

      Ah ok so here might be your error.
      If you’re getting an error about the pidfiles not valid, then it basically means that the refresh.sh script can’t do it’s job, which is to first kill the existing running script and then trigger a new clean run of the script.
      Without it being able to kill the previous instance of the script, you basically run into a dead-lock where the new script can’t actually do it’s job, because there’s already currently a copy of the script running.

      Can you please check that the two files “offpid.pid” and “metarpid.pid” exist and are owned by the “pi” user, if not, please use chown on them to give the pi user ownership of the files. If that doesn’t work, you can delete the files and they should be re-generated automatically.
      The files automatically get created when you run either ./refresh.sh or ./lightsoff.sh script (that’s what the “& echo $! > /home/pi/metarpid.pid” is for, the store the latest script process id).

      You should only trigger the script by using the ./refresh.sh script and turn them off using the ./lightsoff.sh script to ensure that the above runs fine.

      Reply
  66. Andre

    I did verify both .pid files are owned by pi. As you suggested, I had to run refresh.sh and lightsoff.sh before they were created. They also have read-only permissions – should I give them executable permissions?
    My system is still acting the same way – stops working after about 8 minutes.
    When I run./refresh.sh, I see the messages below before it executes metar.py. Do you need to see the pid file values?
    pkill: pidfile not valid
    Try `pkill –help’ for more information.
    pkill: pidfile not valid
    Try `pkill –help’ for more information.

    Reply
    1. Philip Rueker Post author

      I suggest you delete both files, something must have gone wrong with why they are considered not valid.
      then re-run the refresh.sh script and then the .lightsoff.sh script and that should re-generate both files.

      Reply
  67. Andre

    I deleted both files, turned off/on the pi and the script started automatically. It stopped again after about 8 minutes. It did create a metarspid.pid but not offpid.pid in the pi directory.

    Reply
    1. Philip Rueker Post author

      Check the logs again to see whether the refresh.sh script was able to run correctly now or if there’s still errors about the pidfile not being valid.
      If so, then the only other idea I have is that something is wrong with your refresh.sh script, so maybe copy the latest from the github.

      Reply
  68. Matt R

    Philip, thanks for helping us newbies. I also am getting an error. All I’ve been configuring is the number of active LED’s in the config section and the ‘airports’ file. (my project is huge and I’m testing every 10 or so LED’s as I wire them). The lights stopped initializing on their own, so I ran metar.py on it’s own and got this at the end of the return and the script stopped.

    […Setting LED 79 for KDWX to VFR (255, 0, 0)
    Traceback (most recent call last):
    File “metar.py”, line 226, in
    pixels[i] = color
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 314, in __setitem__
    self._set_item(index, r, g, b, w)
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 280, in _set_item
    raise IndexError
    IndexError
    pi@raspberrypi:~ $]

    I tried to reload the files installed with in this process but it didn’t (and I’m not sure it would) help. I believe this is pointing to a conflict in python’s included packages? Thanks

    Reply
    1. Philip Rueker Post author

      IndexError indicates you are trying to set more LEDs than you initialized, so make sure you increase the LED_COUNT variable in the metar.py file to be bigger-than-or-equal to the LED being addressed (note it’s 0-based, so LED 79 indicates it was the 80th LED).
      You’ll also need to update the number in the pixelsoff.py file to coincide with it.

      Reply
      1. Matt R

        Thank you, this is exactly right. I entered all of the airport identifiers in my project thinking it would save time. The numbers mismatch. I appreciate your help.

        Reply
    1. Philip Rueker Post author

      They are similar, but not identical, one calls metar.py, the other calls pixelsoff.py.

      Can you (not turning raspberry pi on/off) run from putty the ./refresh.sh and then again in a second putty window run the ./lightsoff.sh file, while the refresh.sh is still running in the other window?
      As soon as you start ./lightsoff.sh in the second window, the execution in the first should stop if everything is configured correctly.

      If not, then please check file permissions and ownership of all files again.
      If in doubt, delete the two files (offpid.pid and metarpid.pid) again and then from putty run the ./refresh.sh and ./lightsoff.sh script and they should correctly generate the two files.

      If you have correctly copied the files from my instructions, then it should work once you’ve ensured all the permissions are set correctly.

      Reply
  69. Adam Howard-Dobson

    Loved this project! Thanks so much for sharing the guide it made for a great lockdown project. For anyone just starting a build I am running 32 LEDs straight of the Pi without any trouble. The Pi and the LEDs are drawing less than 2A. During the build I was running the whole lot off a USB power brick. Would it be possible to add a small touchscreen that would allow you to swipe between airports? https://photos.app.goo.gl/8TcACsSR9DkKKdUg7

    Reply
    1. Philip Rueker Post author

      Awesome picture of your completed map, I always love to see when people share their completed projects with me and even cooler when I see it’s from all over the world like yours from England, with good weather in London even 🙂

      As for your question about the touchscreen, yes it would be possible, but you would have to write some code for the swiping action and you’ll have to look for one that is compatible with the Pi Zero, as many are designed for the bigger Raspberry Pi.
      This one here mentions it might work with a Pi Zero https://www.adafruit.com/product/2455 and guide https://learn.adafruit.com/adafruit-2-4-pitft-hat-with-resistive-touchscreen-mini-kit

      Reply
      1. Adam Howard-Dobson

        Ha yeah the weather’s not awful here all the time! Thanks for the links. If need be I’ll run it off a full size Pi. Will take a look at the screens out there and see what I can come up with.

        Reply
  70. Scott Moody

    I have made several modifications to this project. I wanted to add one here that may help.
    Add this to the cronjob to start the script after booting. It saves you from waiting up to 5 minutes for the script to start.

    @reboot sleep 20 && /home/pi/refresh.sh

    The sleep 20 allows the Rpi to boot before trying to run the script.

    Reply
  71. Zane

    When I try to run metar.py is gives me an error “ModuleNotFoundError: No module named RPi”. I have all the files installed into home/pi, I’m not sure what I’ve done wrong.

    pi@raspberrypi:~ $ sudo python3 metar.py.txt
    Traceback (most recent call last):
    File “metar.py.txt”, line 5, in
    import board
    File “/usr/local/lib/python3.7/dist-packages/board.py”, line 48, in
    from adafruit_blinka.board.raspberrypi.raspi_40pin import *
    File “/usr/local/lib/python3.7/dist-packages/adafruit_blinka/board/raspberrypi/raspi_40pin.py”, line 3, in
    from adafruit_blinka.microcontroller.bcm283x import pin
    File “/usr/local/lib/python3.7/dist-packages/adafruit_blinka/microcontroller/bcm283x/pin.py”, line 2, in
    import RPi.GPIO as GPIO
    ModuleNotFoundError: No module named ‘RPi’

    Reply
    1. Philip Rueker Post author

      Hey,
      it looks like your file ends in .txt and not .py

      If you did all the updates and installed the libraries as outlined in the github, then it should work.
      You can always just try to run the commands to install the libraries again and see if it runs without errors.

      This guide (which is also linked in the github) has some more details to possibly help troubleshoot – https://learn.adafruit.com/neopixels-on-raspberry-pi/python-usage

      But otherwise, this guide might help you troubleshoot

      Reply
      1. Zane

        When copying over metar.py, do I just copy and paste the text into putty and run it? I copied it into a notepad and saved it as .txt and placed it into the root file for the Pi, then moved it to home/pi. Only part of the install that was confusing for me, how would I make it a file that ends in .py? I googled it a bit and couldn’t figure it out. This is my 2nd time doing something with a Pi

        Reply
        1. Philip Rueker Post author

          If you’re connected to the pi using putty you can create text files by typing “nano FILENAME”, so for example “nano metar.py” would start a new text file ending in .py.

          You could also download the files from the github on your computer and transfer them to the pi using a tool like WinSCP.

          Reply
  72. Andre

    Referencing the crontab instructions posted on your github link:
    */5 7-21 * * * /home/pi/refresh.sh
    05 22 * * * /home/pi/lightsoff.sh
    as explained, the above will run the refresh script runs every 5 minutes between 7 AM and 11PM, with the last cycle running at 11:05 PM.

    I would like crontab to run the ./refresh.sh script every 5 minutes between 6 AM and 10:30 PM. At 10:30 PM, I would like crontab to run ./lightsoff.sh and keep the lights off until 6 AM the following day. How do I get the refresh script to stop running after 10:30 PM?

    Reply
    1. Philip Rueker Post author

      Hey,
      So with the below, you’ll run every 5 minutes between 6am and 9pm (inclusive, so until 9:55pm), then on the 0th,5th,10th,15th,20th,25th minute of 10pm and then at the 30th minute of 10pm it will run lightsoff:
      */5 6-21 * * * /home/pi/refresh.sh
      0,5,10,15,20,25 22 * * * /home/pi/refresh.sh
      30 22 * * * /home/pi/lightsoff.sh

      You can find more reference on crontab here: https://help.ubuntu.com/community/CronHowto

      Reply
  73. Daniel Kapeller

    Hey. Thanks for the great instructions and for providing the GitHub software. I built mine and have two suggestions for you regarding the software.

    1) Lightning Feature

    I noticed that in the lightning display feature, it is only triggered if there is LGT reported in the METAR, which is usually only when there is distant lightning. It does not take into account cases when there is lightning more near to the airport (TS, VCTS, +TSRA, etc). I fixed this by changing:

    lightning = False if rawText.find(‘LTG’) == -1 else True

    with

    lightning = False if ((rawText.find(‘LTG’) == -1 and rawText.find(‘TS’) == -1) or rawText.find(‘TSNO’) != -1) else True

    This way, all cases of lightning near the airport are taken account, but it is not triggered if the METAR reports the thunderstorm sensor inoperable.

    2) Wind Blinking Threshold

    This is more of a minor thing, but in the configuration part of the file, I expected the wind listed in the wind blinking threshold to be where the lights started blinking (at or above speed x, blink). It turned out to be greater than. So for example, if you have 15 in the config, an airport reporting 15 knots will not blink. This is probably more personal preference, but it makes sense for that speed to be when the blinking starts. I fixed this just be replacing > with >= in the windy variable.

    Thanks for the great guide!

    Reply
    1. Philip Rueker Post author

      Hey,
      Thanks for the suggestions, I’ll add them to my todo list and will update the code with them soon.

      Cheers,
      Philip

      Reply
  74. Phil benyo

    Update- first one built! on the the second one
    I decided to try to find a less cumbersome light source and found these BTF-lighting WS2812B presoldered LED strip- advantages to them are that they are lower profile, and distance between LED is greater.. Problem I encountered is that they use a different lighting code for the colors
    RED 255,0,0
    GRN 0,255,0
    BLUE 0,0,255 (was the same )
    purple 125,0,125
    took hours of hair pulling until a ran the neopixel test
    I did lower the output and running 50 LED nicely, will update with some pics when done

    Reply
  75. Alex

    Note…on the crontab demo file on https://github.com/prueker/METARMap/blob/master/crontab

    it shows
    */5 7-21 * * * /home/pi/refresh.sh
    05 22 * * * /home/pi/lightsoff.sh

    but the files on the directory are .py
    i was getting not being able to get it to work until i changed the crontab file to match .py
    is this correct?

    I also ran htop to look around and i can see sometimes up to 4 instances of metar.py running under root.
    https://postimg.cc/G84zjwYz
    is this normal?

    thanks!!!

    Reply
    1. Philip Rueker Post author

      Nope, please recheck the github, there are metar.py, pixelsoff.py and displaymetar.py (if you’re using a LED display) files and the 2 refresh.sh and lightsoff.sh files. https://github.com/prueker/METARMap

      The crontab should trigger the .sh files like my sample shows, which in turn ensure that only one instance of metar.py runs at any given time (by cancelling the previous run).

      Reply
      1. Alex

        I thinks i messed up when i created the files , i named all of them .py

        So renamed the refresh.py to refresh.sh and lightsoff.py to lightsoff.sh then fixed the crontab back as your example. I guess i was too hyped up and missed that, my mistake.

        lighstoff seems to work fine now, but ./refresh goes into an endless loop, starting with

        pi@raspberrypizero:~ $ ./refresh.sh
        pkill: pidfile not valid
        Try `pkill –help’ for more information.
        pkill: pidfile not valid
        Try `pkill –help’ for more information.
        ./refresh.sh: line 3: /home/pi/metarpid.pidy: Permission denied
        pi@raspberrypizero:~ $ Running metar.py at 21/02/2021 21:10
        Wind animation:True
        Lightning animation:False
        Daytime Dimming:False
        External Display:False
        Rotating through all airports on LED display
        https://www.aviationweather.gov/adds/dataserver_current/httppar….

        i thinks i might have some permission problems?
        I have chmod as instructed. any ideas?

        Reply
        1. Philip Rueker Post author

          The pidfiles should be automatically generated the first time you run the ./refresh.sh and ./lightsoff.sh script.
          If there’s something wrong, you could delete the pidfiles if they are there.
          Also check that the ownership of the files looks all good by typing “ls -al”.

          Also one of the errors says “metarpid.pidy” so you might have accidentally added a y at the end of the end of the refresh.sh script there, as it should be “/home/pi/metarpid.pid” (not pidy, so no y).

          Reply
          1. Alex

            i appreciate the reply.

            i did accidentally add a y when closing nano. thanks

            lightsoff.sh works fine, does turn the leds off
            but
            when i run ./refresh.sh is goes into a continuous loop, i see it load the airports and their colors again and again and can’t break the loop.

            what could be causing this?

          2. Philip Rueker Post author

            Ah,
            well that’s how it works if you’re using the blinking/lightning, it will loop the LEDs for however long you set the total blinktime (default 5 minutes) and then it will finish.
            That’s where the crontab comes in to then re-trigger the script again to fetch the latest weather and then again loop the LEDs for the total time.

            When you manually run the ./refresh.sh to kick it off, you can break out of it by quickly hitting ctrl+c and typing ./lightsoff.sh (while the looping will continue, so you have to type it somewhat blind), you can type ./ligh and hit the tab key to autocomplete the thing and just hit enter, or by opening a second window and typing ./lightsoff.sh in there and it will halt the script execution in the other window (that’s what the pidfile process killing is for, to ensure that the script only runs one-at-a-time for when the crontab is running to ensure that there’s no overlap).

  76. Andre

    On 12-16-2020 Randy posted he turns his LEDs to Yellow when winds exceed 25 knots. What code changes would be needed to fade an LED from COLOR_FADE (color) to Yellow when winds speeds exceed 25 kts?

    Reply
    1. Philip Rueker Post author

      You would have to define a new color for yellow, add another variable for the higher threshhold where you want to blink to yellow instead of normal fade color and then the main part will be at the blocks where the LED color decision is mine (between line 223-230) you would add another condition towards the end of the 4 long lines where it does
      (COLOR_VFR FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy
      In there, you would want to add another check along the lines of:
      COLOR_YELLOW if conditions["windSpeed"] > EXTREME_WIND_THRESHOLD else (the above)

      Reply
  77. Andre

    Very helpful, Philip. Based on your instructions, I was able to make this work. My LEDs now flash Yellow anytime winds are reported at 25 knots or above at any location.

    Lines added:
    40) COLOR_HIGH_WINDS = (255,255,0) # Yellow
    50) HIGH_WINDS_THRESHOLD = 25 # Knots of windspeed to trigger Yellow LED indicating High Winds

    Insert:
    else COLOR_HIGH_WINDS if conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD
    as shown:

    224) color = COLOR_VFR if not (windy or lightningConditions) else COLOR_LIGHTNING if lightningConditions else COLOR_HIGH_WINDS if conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD else (COLOR_VFR_FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy else COLOR_CLEAR

    226) color = COLOR_MVFR if not (windy or lightningConditions) else COLOR_LIGHTNING if lightningConditions else COLOR_HIGH_WINDS if conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD else (COLOR_MVFR_FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy else COLOR_CLEAR

    228) color = COLOR_IFR if not (windy or lightningConditions) else COLOR_LIGHTNING if lightningConditions else COLOR_HIGH_WINDS if conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD else (COLOR_IFR_FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy else COLOR_CLEAR

    230) color = COLOR_LIFR if not (windy or lightningConditions) else COLOR_LIGHTNING if lightningConditions else COLOR_HIGH_WINDS if conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD else (COLOR_LIFR_FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy else COLOR_CLEAR

    Reply
    1. Philip Rueker Post author

      Yes, you could just add an “OR” statement to check for if windgusts are present. So something like this:
      COLOR_HIGH_WINDS if (conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD or conditions["windGust"] == True)

      Reply
      1. K4DQP

        Where does this code go exactly?

        COLOR_HIGH_WINDS if (conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD or conditions[“windGust”] == True)

        Reply
        1. Philip Rueker Post author

          It would go into the lines as Andre has shown, so something like this:
          color = COLOR_VFR if not (windy or lightningConditions) else COLOR_LIGHTNING if lightningConditions else COLOR_HIGH_WINDS if (conditions[“windSpeed”] >= HIGH_WINDS_THRESHOLD or conditions[“windGust”] == True else (COLOR_VFR_FADE if FADE_INSTEAD_OF_BLINK else COLOR_CLEAR) if windy else COLOR_CLEAR

          Reply
  78. Alex

    I found something interesting in my setup.
    i deleted the pid files… and

    If i comment the crontab and start the show with ./refresh the pid files are owned by pi
    and in htop i only see one meter.py process works perfect.
    https://postimg.cc/9wHqhfTB

    But if start the show via the crontab on boot one of the pid files is owned by root,
    and in htop i see a lot of metar.py processes and the pi eventually crahses.
    https://postimg.cc/mcDL61XH

    What could be causing this? thanks

    Reply
    1. Philip Rueker Post author

      So when you start it directly it runs as you (pi) and thus pi owns the pid file, but via crontab it will run the execution as root via the sudo and so the file ends up being owned by root and so then it can’t update the metarpid.pid file when metar.py runs and thus you’ll run into some unexpected behaviour.

      If you run the ./refresh and ./lightsoff once yourself, the files should be owned by pi and then also crontab should be fine to be able to access them correctly, but the other way round creates some issues.

      The other workaround is, to set the two pidfiles to write for “others” by using chmod +w, so then both users should be able to write it and it should work fine too then.

      Reply
  79. Andre

    What’s needed to change the LEDs flashing yellow when winds or wind gusts are 25 knots or above?
    With the code changes I listed above, winds above 25 knots or any wind gusts turn the LEDs yellow.

    Reply
    1. Philip Rueker Post author

      Instead of using the conditions["windGust"] variable that just says true or false when there’s gusts, you’d have to use the conditions["windGustSpeed"] and check the speed you want to change on.

      Reply
  80. Ben

    Philip,

    Thank you so much for all of this. I’ve never done a project like this and was thinking about just starting with the Raspberry PI and lights to make sure I could figure it all out. Do you have a certain breadboard you would recommend?

    Reply
    1. Philip Rueker Post author

      Breadboards are all the same really, there’s just difference sizes and it’s not really needed for this project, I only used it while I was testing, but the final wiring is just done directly.

      But if you do want to use a breadboard, this is the one I have used.

      Reply
  81. John

    Phillip,

    Upon wiring up the mini display it became rather hot, once powered on. Wondering if something was wired incorrectly or if yours tends to carry some heat with it as it is operates?

    Reply
    1. Philip Rueker Post author

      Hi, I honestly can’t tell as I never checked whether it got hot, but it seems fine in my installation running for quite a while now.

      Reply
  82. Adam Howard-Dobson

    Have been refining my build and have now got a really nice process going. I’m doing my first build that’s using 100 LEDs (two bunches of 50 clipped together) and I’m getting an odd result from the second set of 50 LEDs. They show Red, Blue and Green just fine but with Magenta they flicker like mad and don’t show the correct colour at all. The first set of 50 are absolutely fine and if I swap sets around the problem always happens with the second set of 50. I have found a work around by running the second set directly back to the power supply. Any idea what might be causing this?
    https://photos.app.goo.gl/VPNLpVAphfgEUSQF7

    Reply
    1. Brian Bauer

      Adam,
      Are you driving the LED’s directly from the Pi? For strings over 50, it would be best to have the + and – hooked up directly to the power supply. Or you can try and lower the brightness for all LEDs. Flickering happens when the voltage has dropped past the point that the LED’s can be driven. You can also check and see what the voltage is at the end of the 100 string.
      Another thing to check is what your power supply amp is.

      Reply
      1. Adam Howard-Dobson

        Hey Brian, no I’m driving the LEDs from a 5v 10A power supply. I’ve done some further testing and you’re right, the voltage drop by the end of the 100 string is quite significant. I’ve modified my wiring to introduce power at the beginning and the join point for the additional 50 and that’s solved it, looking great now.

        Reply
  83. Jim Rowe

    Hi Philip – Thanks so much for sharing these instructions. I’ve wanted one of these for a while and finally built one over the winter. Project went great and I’m very pleased with the end result, which now proudly hangs over my desk. Surprisingly, I had more trouble with the construction (joining sectionals and gluing to backer) than I did with the technical stuff.

    I am, however, finding that the map freezes every few days and I need to unplug and restart. Any idea why?

    Reply
    1. Philip Rueker Post author

      Hard to say, the main time I’ve seen people having random issues is if it’s a power problem, like too many LEDs running directly of the Raspberry Pi drawing too much power and that can cause unexpected behavior.

      Since it’s intermittent it’s hard to say for sure, but if a reboot fixes it, you could try to add a reboot routine to your crontab during the night, maybe that could help alleviate it.
      If you added something like this to crontab, then the raspberry would initiate a reboot at 4am (the 0 4) +5 minutes, so at 4:05am every night it would reboot.
      0 4 * * * /sbin/shutdown -r +5

      Reply
      1. Jim

        Makes sense, I’ll give it a try! Thanks for your help with this awesome project.

        Reply
  84. Adam

    Fun project, I just finished mine. Thanks for the inspiration! Here’s my twist: I wanted an easier way to see which station was being displayed, so I added a fast-blinking option that highlights the currently shown station,. You can see a video of it in action here: https://youtu.be/hvp_BR90GYA

    But to also have the wind blinking work, I needed to completely rewrite the main display loop logic and implement multi threading..so now windy stations blink slowly and the highlighted station flashes quickly, all modifiable with flags in the program. Happy to share the code if anyone’s interested

    Reply
  85. K4DQP

    Very cool project! I just received my ALITOVE WS2811 lights and have two questions. I am planning on wiring directly to Raspberry PI Zero.

    At the first and last LED, there is a black connector with a black plug, one male and one female. There is also two extra wires, one red and one blue from each led (open wire).

    1. Which side of the LED string is connected to the PI? I am assuming I will clip off this black connector and wire directly to the pi, using the appropriate GPIO pins.

    2. What do I do with the extra wires coming from the last/first LED?

    Reply
    1. Philip Rueker Post author

      Hey,
      you’ll find there’s a small arrow on the top side of the LEDs, the Pi connects into the arrow side.
      This here shows it: https://slingtsi.rueker.com/wp-content/uploads/2021/04/Screenshot-2021-04-03-214210.jpg
      The 2 extra wires coming out of the first LED are if you want to connect an external power supply to the LEDs, but isn’t needed if you’re going to power them directly from the Pi.

      You can use pinned wires like these – https://amzn.to/2PqSSRc to connect the Pi Pins directly into the black clip.

      Reply
      1. K4DQP

        That worked. Thanks.

        Note: I made one change to the crontab procedure that seemed to work better for me. It seemed like it was timing out or just not refreshing like it should. Now it works perfect…enjoy the coffee!

        My crontab: “*/5 * * * * sudo ./refresh.sh”

        Reply
  86. Jeremiah

    I cannot get the lightsoff.sh to work. when i attempt “sudo python3 lightsoff.sh”, i get:

    File “lightsoff.sh”, line 1
    usr/bin/sudo pkill -F /home/pi/offpid
    ^
    SyntaxError: invalid syntax

    Reply
    1. Philip Rueker Post author

      The shell files don’t need to be run with python.
      So you just need to type:
      ./lightsoff.sh
      to run it.

      Reply
      1. Jeremiah

        Okay, that helped out a lot. So i know lightsoff is working, but my crontab isnt turning it off when i expect it to. Here is what I have in the crontab:

        */5 6-22 * * * /home/pi/refresh.sh
        5 22 * * * /Home/pi/lightsoff.sh

        I assumed that would run it from 6am – 11:05 and then shut it off, but it never shuts off.

        Reply
        1. Philip Rueker Post author

          Your instructions show to run the refresh every 5 minutes between 6am and 10pm (inclusive) so until 10:55pm.
          But your light off is set to run at 10:05pm (22 = 10pm).
          You need to set it to 23 for 11pm.

          Reply
          1. Jeremiah

            Wow, I feel dumb now. lolol. Thank you for pointing that out and helping me realize my mistake. I love this project and cant wait to get it all put together!

  87. Chris

    I hate to bug you, but I need some help. I’ve made 3 of these. On this third one, I tried a different set of lights. I also tried making a disk image copy instead of going through the whole setup. Somewhere something has gone wrong and unfortunately I’m not a programmer.

    The lights themselves are strange in that they light up white immediately when powered on. But they respond correctly to the test commands. They even turned off automatically last night. But metar.py is not lighting them up. This is the last bit of code returned when I run it manually.

    Setting LED 47 for KAPT to None (0, 0, 0)
    Traceback (most recent call last):
    File “metar.py”, line 236, in
    pixels[i] = color
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 314, in __setitem__
    self._set_item(index, r, g, b, w)
    File “/usr/local/lib/python3.7/dist-packages/adafruit_pypixelbuf.py”, line 280, in _set_item
    raise IndexError
    IndexError

    Again I want to thank you. I hosted an EAA chapter party where we I helped people make these. Most were computer guys, but it was a fun event.

    If I need to rip all these lights out, so be it. I’ll just buy more of the correct ones on amazon.

    Reply
    1. Chris

      I tried on a different board with new strings so it wasn’t that. It must be my disk image. Maybe can’t shortcut the setup. 😐

      Reply
    2. Philip Rueker Post author

      Hey,
      An index error usually means you are trying to address more LEDS than you initialized in the LED_COUNT variable.
      So make sure your LED count variable is set higher than the amount of lines in your airport file.

      Reply
  88. Ray

    Hi Philip, this is awesome! Thank you so much. Couple of questions: is there a way to only trigger the high winds animation if the gust spread exceeds a certain threshold?
    Also, is there a way to add the wind animations to the legend. I have the solid LEDS for VFR, MVFR, IFR, and LIFR, but is there a way to add a fifth and sixth LED to demonstrate the wind/high winds?

    Thanks again for posting this!

    Reply
    1. Philip Rueker Post author

      Yes, you could modify the calculation for when the high winds animation trigger to calculate the difference between the gust speed and the wind speed instead.
      So if you change the formula on line 225 to something like this, I believe it will do what you’re asking for:
      highWinds = True if (windy and HIGH_WINDS_THRESHOLD != -1 and ((conditions["windGustSpeed"] - conditions["windSpeed"]) >= HIGH_WINDS_THRESHOLD)) else False
      You’d just then define whatever difference between the two values you’d want in the HIGH_WINDS_THRESHOLD variable. So for example if you set it to say 5 and the winds were 10 Gusting 15, then it would trigger the high winds animation.

      As for the animation legend, yes that can be done, since someone else wanted a legend before as well, I decided to just code it up now including the animations for wind and lightning.
      So if you use the new copy of metar.py from my METARMap Github, you can get the functionality.
      Here’s the instructions on how to activate it: https://github.com/prueker/METARMap/#legend, please let me know if all works like you’d expect.

      Reply
  89. Denis

    Hi! First of all let me thank you for this great project idea and for the great instructions! I knew nothing about Raspberry but a couple of hours were enough to get everything to work!
    I do have one question. Our homebase airfield has an automatic METAR station but it is only possible to retrieve it via a login access. I found a way to create a URL that only gets the METAR without asking for the login, and which is able to determine the color for VFR, IFR etc, is there a way to send this metar and the color code to the Raspberry using another source than aviationweather.gov? (I contacted them to ask if they could add the METAR to their site but they are not able to do so)

    Thanks for your help and enjoy your day!

    Reply
    1. Philip Rueker Post author

      Hi,
      Yes it would be possible to make a second call to your URL to get the weather for that airport, but you would have to make a few changes in the main section of the metar.py script to fetch that information for that airport and add it to the list of airports.

      So you’d just do another web request (the urllib.request.urlopen(..) part) and store it in a second variable and then after the code added the conditions for the rest of the airports in the loop you would just add a section to parse your url for that condition and then add that condition in the conditionDict and append it to the airports and stationList.

      Reply
      1. Denis

        Hi! I have been trying to apply the correction you mentioned to the METAR.PY as you explained me above. However, Raspberry is still kinda new to me so I must say I am struggling a little bit.. sorry to bother you with this but can you tell me how to set up the URL of my Metar in the request.urlopen… part? The URL I use is a website dedicated to display this METAR only so I don’t even need the Raspberry to search for a specific code.

        I also added the airport in the light sequence inside my Airports file, is that ok if it is mixed with the other airports taking data from aviationweather? Or does my airport need to be separated from the others?

        Sorry for the beginner questions again! Thanks anyway as the entire project is already working apart from this small detail! I owe you more than a coffee for sure!

        Reply
  90. Paul

    Bought you a cup of Joe!
    Couple questions I didn’t see in the thread or instructions (I’m new to raspberrypi) :
    1) Do you recommend the breadboard first?
    2) How many points do you need to solder on the pin header to the board?

    Reply
    1. Philip Rueker Post author

      1) It’s not really necessary to use the breadboard, you can also just directly hook up the pins on the Raspberry to the LED lights
      2) The minimum would be the pins needed for the LED lights per this diagram pins, but it won’t hurt to solder all of them (other than the extra time it takes) in case you want to extend functionality in the future, such as adding the mini display that would require extra pins.

      Reply
  91. Paul

    ran sudo python3 metar.py and got error msg:
    file metar.py line 3
    import urllib.request
    Import Error: No Module named request

    Reply
    1. Philip Rueker Post author

      That error usually indicates you tried to run it with python, not python3.

      Make sure you use python3 if you want to test it directly, or even better just use the ./refresh.sh file.
      So just run ./refresh.sh which will trigger the script as well.

      Reply
  92. Paul

    you were right. I had typo. used python2 instead of python3.

    It just dawned on me that you have to solder the pin you want to connect to so the connection between the header pin piece and the board is solid? correct?
    curious because script ran but no lights lit up.

    Also, the example you have for the raspberry pi board above is not the same as the one in the parts list so I’m trying to figure out what the proper orientation is for using the right pins?

    Reply
    1. Philip Rueker Post author

      Correct, you’ll have to solder those pins between the board and the header pin piece so there’s a solid electrical connection (which is why to be safe you’re not soldering the wrong ones, it’s easiest to just solder all of them).

      Yes, the example picture is that of a full size Raspberry Pi, but the pin order is the exact same with the smaller model. There is one pin on the board that is square instead of round, that’s pin one (top left). You can see the mapping between here: https://pinout.xyz/

      Reply
      1. Philip Rueker Post author

        I suggest you try to manually light the LEDs first for testing as I’ve outlined further up on the page here. If you installed all the libraries and did the soldering and connecting of the pins correctly, then that should work.

        If not then I suggest to re-check the wiring and the soldering connections.

        Reply
    1. Philip Rueker Post author

      Not neccesarily, though creating a bridge from ground to power may be an issue.
      If you have a de-soldering suction that would be best, if not then checking that it’s only some not-used gpio pins (https://pinout.xyz/) is probably (though no guarantees) fine.

      Reply
  93. Paul

    I noticed when I wiggled the connections to the header pins that the red lights flickered.
    I ordered a new board.
    Can you confirm if I get the soldering right and run the metar.py file will the red lights stay on steady? or what should I expect to know I’m good and can then manage the settings via the files?

    Reply
    1. Philip Rueker Post author

      Yes if you’ve correctly soldered the pins and connected them, then running the the couple commands up on the page would make the LEDs steady red until you run the pixels.deinit() command. Or by running the metar.py script, it will illuminate them based on the weather condition of the aiports listed in the airports file.

      If you have some trouble with the soldering, you can look and probably find a pre-soldered Raspberry Pi mini as well, then you just need to connect the pins.

      Reply
  94. Paul

    So, I ordered a MUCH better Dremel to solder/fix the old board but I also ordered a pre-soldered board.

    I’d expect to move the SD card and connect the pins, run the script and it lights up steady?

    I have the connections as follows from lights:
    red to pin 4 on right side of board from top right (5v)
    white to pin 12 (GPIO 18/CLK/PCM)
    blue to pin 14 (GND)
    correct?

    If so, any ideas on where to look next

    Reply
    1. Philip Rueker Post author

      Yes that’s the right wiring.

      And yes, if it’s connected correctly, then if you run the script, the LEDs should stay illuminated based on the the weather (or blink if you’re using the wind blinking functionality and it’s windy at that LEDs airport).

      Reply
  95. Paul

    Update:
    Not sure if this was confusing to others but the instructions for connecting to the lights mention the white arrow but both ends of the lights are the same..only difference is one end has the male end to plug into other lights and the other end has the female end..is the female end the correct end?? I tried this end and used female to female ELEGOO wires you recommended and only the first light lights up blue. test script doesn’t light any others up…

    also, the blue wire from the lights when plugged into the board at location 14 (GND) turns the light off

    not sure if I just have this hooked up wrong or if it is the lights or maybe a permission issue…code seems to run fine

    Reply
  96. Paul

    P.S. I’m using a new board I got with pre-soldered pin header.

    I get that part with the top/arrows. You can hook up wiring from the board to either end of the light strand.

    https://images-na.ssl-images-amazon.com/images/I/618sPBfPe-L._AC_SL1000_.jpg

    One end I would call the male end (bottom right of the picture in link above) and female end (top right in picture). I got them to all flicker when jiggling connectors to the board around using female and and the first one to light steady when using the male end.

    Reply
      1. Paul

        So I ordered a new pi board with pre-soldered pins, a new strand of the same lights and an external 5V power supply with converter.

        I put the SD card into the new board and hooked up to both the old strand and the new strand. Still nothing.
        Then hooked up the 5v power supply to the female end of the light strand using only the white data wire from lights to the board and connected the blue and red from lights to the external power supply. Now all the lights light up but only white.

        Tried to test the light colors using script above and no color changes.

        I’m at a loss.

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.