ScottSturdivant / rpi_metar

METAR LED Display for a Raspberry Pi
MIT License
26 stars 17 forks source link

Individual thresholds for flight categories #20

Closed peterbickel closed 3 years ago

peterbickel commented 3 years ago

I would like to adjust the thresholds for the color of the flight categories (VFR, MVFR, ...). I have found a section to do this at the end of wx.py. But the changes don't work because there seems to be another place where the categories are automatically taken from METAR. It doesn't have to be a solution in the configuration, I can adjust the code.

ScottSturdivant commented 3 years ago

You're correct, the flight category is first pulled from the METAR data source directly, if it exists. If it does not exist, it will fall back and try to manually parse the ceiling and visibility values into the appropriate categories.

This happens here: https://github.com/ScottSturdivant/rpi_metar/blob/develop/rpi_metar/airports.py#L102

You can remove the try section and then your updates should be applied!

peterbickel commented 3 years ago

Thx for the fast reply. Can you specify which lines I have to remove?

ScottSturdivant commented 3 years ago

Sure, change this:

        # Flight categories. First automatic, then manual parsing.
        try:
            if metar['flight_category'] is None:
                log.error('flight category is missing: {}', metar)
            self.category = wx.FlightCategory[metar['flight_category']]
        except KeyError:
            log.info('%s does not have flight category field, falling back to raw text parsing.', self.code)
            self.visibility, self.ceiling, self.wind_speed, self.wind_gusts = wx.get_conditions(metar['raw_text'])
            self.category = wx.get_flight_category(self.visibility, self.ceiling)

To this:

            self.visibility, self.ceiling, self.wind_speed, self.wind_gusts = wx.get_conditions(metar['raw_text'])
            self.category = wx.get_flight_category(self.visibility, self.ceiling)
ScottSturdivant commented 3 years ago

Without seeing what changes you've made, this is my guess: I believe you're probably hitting this line (https://github.com/ScottSturdivant/rpi_metar/blob/develop/rpi_metar/wx.py#L66) because for whatever reason, the visibility and ceiling values were not able to be determined from the metar raw text. You're going to need to add some debug to determine what's going on.

peterbickel commented 3 years ago

The code works fine and I get the definition for the categories now from wx.py. But I think I found an error in the code of wx.py.

The visibility from METAR is misinterpreted. Here is the official definition of visibility: Visibility = Reported in a four figure group (e.g. 0400 = 400 meters; 8000 = 8 km) up to but excluding 10 km; 9999 = 10km or more; 0000 = less than 50 meters visibility.

In the code of wx.py, the visibility from METAR is divided by 1609 (like nautical miles), but it must be divided by 1000 because it is always in meters.

Am I right?

ScottSturdivant commented 3 years ago

You must be receiving metric data in your METARs!

The code in the get_flight_category function assumes that the visibility and ceiling values are in statue miles. So with that in mind, the block of code here (https://github.com/ScottSturdivant/rpi_metar/blob/develop/rpi_metar/wx.py#L28) will convert a visibility in meters to statue miles. 1 meter is .000621371 miles, hence the division by 1609 to convert to miles.

400 meters ~= 1/4SM 800 meters ~= 1/2SM 8000 meters ~= 5SM

So if your METAR is sending over '0400', I'd expect that to be interpreted as 1/4 SM and ultimately LIFR...

That was my thinking and it's certainly possible I'm wrong! Can you explain why you think it should be divided by 1000?

peterbickel commented 3 years ago

First of all - the visibility in a METAR is aways in meter. To ensure that the string is reliably recognized this string is always 4-digit. To express the distance 10Kilometers and more, which is important for the evaluation of VFR conditions, the string 9999 is therefore used. CAVOK is a summary of visibility 9999 and cloud height greater than 5000ft above reference altitude. Therefore this is also assigned the value 10 in an extra section.

Now back to the code... In the last section of wx.py the visibilities will be evaluated in km. Visibility = 8 means 8km = 8000meter So if you get the visibility from the metar with 8000 you have to divide it by 1000. If you divide it by 1609 you get the nautical miles - but these are NOT decisive for aviation in the visibility.

ScottSturdivant commented 3 years ago

First of all - the visibility in a METAR is aways in meter.

Unfortunately, that's not the case. When this code was originally written, it was for a U.S. audience, where the visibility is in statue miles. See http://www.faraim.org/aim/aim-4-03-14-446.html and an example US METAR: https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=kbos&hoursBeforeNow=2&mostRecentForEachStation=true

At the time that I write this, the raw_text returned is KBOS 051454Z 18006KT 10SM -RA BKN043 OVC050 01/M02 A2980 RMK AO2 RAB44 SLP089 P0000 60000 T00061022 57004 and the returned data structure contains this data element: <visibility_statute_mi>10.0</visibility_statute_mi>

Now back to the code... In the last section of wx.py the visibilities will be evaluated in km.

So with that in mind, the original get_flight_category assumes it is operating on miles. Hence the conversion from meters to miles by dividing by 1609.

Visibility = 8 means 8km = 8000meter So if you get the visibility from the metar with 8000 you have to divide it by 1000. If you divide it by 1609 you get the nautical miles - but these are NOT decisive for aviation in the visibility.

Maybe if you want to operate solely in meters, you can remove the division by 1609, and then similarly update the get_flight_category function to operate on meters instead of SM?

peterbickel commented 3 years ago

I just checked this and checked METARS over the whole world. It seems to be a specialty in the USA to indicate the visibility in SM. All other countries use meters.

Then it makes more sense to include a loop that executes the old code (divide by 1609) for SM and divides by 1000 for Meter.

Or what do you think?

ScottSturdivant commented 3 years ago

Let's take a step back and revisit your first comment:

I would like to adjust the thresholds for the color of the flight categories (VFR, MVFR, ...).

Can you tell me what thresholds you would like for them, first in words, and then maybe in pseudo-code?

e.g. When the ceiling is below 400 meters or the visibility is less than 1000 meters (1km) -> LIFR.

peterbickel commented 3 years ago

Hi Scott, there is a misunderstanding. My problem has long been solved - as I wrote to you above. Your code suggestion for the airports.py worked. I marked it with a smile!

I just wanted to give you the hint that the code does not work like this for all METAR. Outside the USA it leads to the fact that the visibility is reduced by the factor 1.609. So if you consider the numbers in the section get_flight_category as kilometers, they are not correct anymore.

I adjusted this for me and also replaced the factor 1609 with 1000. Everything works perfectly. But you might want to make another change so that your code works all over the world. And to work all over the world it makes sense that the determination of the visibilities is done in meters, because that is the preferred unit internationally. My suggestion: Detect if there is a METAR with SM (NM) or meter. Set the factor for the conversion into kilometers accordingly. Comment the get_flight_category section so that the user assumes kilometers.

If I had a little more know-how in programming I would do it myself, but unfortunately I can only make small changes - learning by doing.

Translated with www.DeepL.com/Translator (free version)

thommo17 commented 3 years ago

Just letting you guys know that my fork is based off Australian METARs so it might suit you more.

On Sat, 6 Feb 2021, 06:15 peterbickel, notifications@github.com wrote:

Hi Scott, there is a misunderstanding. My problem has long been solved - as I wrote to you above. Your code suggestion for the airports.py worked. I marked it with a smile!

I just wanted to give you the hint that the code does not work like this for all METAR. Outside the USA it leads to the fact that the visibility is reduced by the factor 1.609. So if you consider the numbers in the section get_flight_category as kilometers, they are not correct anymore.

I adjusted this for me and also replaced the factor 1609 with 1000. Everything works perfectly. But you might want to make another change so that your code works all over the world. And to work all over the world it makes sense that the determination of the visibilities is done in meters, because that is the preferred unit internationally. My suggestion: Detect if there is a METAR with SM (NM) or meter. Set the factor for the conversion into kilometers accordingly. Comment the get_flight_category section so that the user assumes kilometers.

If I had a little more know-how in programming I would do it myself, but unfortunately I can only make small changes - learning by doing.

Translated with www.DeepL.com/Translator (free version)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ScottSturdivant/rpi_metar/issues/20#issuecomment-774264051, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMFBXY7KYHFQRW6AZU7DQCTS5RGV5ANCNFSM4W46TLTA .

peterbickel commented 3 years ago

Just letting you guys know that my fork is based off Australian METARs so it might suit you more. On Sat, 6 Feb 2021, 06:15 peterbickel, @.***> wrote: Hi Scott, there is a misunderstanding. My problem has long been solved - as I wrote to you above. Your code suggestion for the airports.py worked. I marked it with a smile! I just wanted to give you the hint that the code does not work like this for all METAR. Outside the USA it leads to the fact that the visibility is reduced by the factor 1.609. So if you consider the numbers in the section get_flight_category as kilometers, they are not correct anymore. I adjusted this for me and also replaced the factor 1609 with 1000. Everything works perfectly. But you might want to make another change so that your code works all over the world. And to work all over the world it makes sense that the determination of the visibilities is done in meters, because that is the preferred unit internationally. My suggestion: Detect if there is a METAR with SM (NM) or meter. Set the factor for the conversion into kilometers accordingly. Comment the get_flight_category section so that the user assumes kilometers. If I had a little more know-how in programming I would do it myself, but unfortunately I can only make small changes - learning by doing. Translated with www.DeepL.com/Translator (free version) — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#20 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMFBXY7KYHFQRW6AZU7DQCTS5RGV5ANCNFSM4W46TLTA .

Hi Thommo, your code looks fine. I just added some changes for a new version - it´s up to you if you like it or not.