Determining if two directional bearing are similar/within a range (except for pesky 330 degrees - 10 degrees)

Hello all,

working away at my bushfire automation and have hit another speed bump.

I want to determine a risk level based on the direction of an incident from home (bearing 1) and the wind direction (bearing 2).

In effect, I am looking for a method to compare two directional bearing values to check if they are similar. they are both compass bearings so in a range of 0-360 degrees. Say one is 8 degrees, and another is 355 degrees. Or one is 192 degrees and the other is 199 degrees.

Very similar (e.g. 8 degrees and 10 degrees) = Highest risk (or the 8deg and 355deg spanner in the works!)
Quite similar (e.g. 8 degrees and 25 degrees) = High risk
Somewhat similar (e.g. 8 degrees and 85 degrees) = Moderate risk,
Not similar = (e.g. 8 degrees and 193 degrees) = Low risk.

Or compare compass directions, which I also have to hand (like NNE and NE = High risk. NNE and SE = low risk).

Has anyone happened to write a template that compares values in such a way that they have handy?

I have something along the lines of:


{% set dir1 = states('sensor.bearing_1')|float %}
{% set dir2 = states('sensor.bearing_2')|float %}
{% if dir1 - dir2 <= 22.4 %} Extreme
{% elif dir1 - dir2 <= 44.8 %} Higher
{% elif dir1 - dir2 <= 67.2 %} High
{% elif dir1 - dir2 <= 89.6 %} Mod
{% elif dir1 - dir2 <= 112.0 %} Mid
{% elif dir1 - dir2 <= 134.4 %} Low
{% elif dir1 - dir2 <= 156.8 %} Lowest
{% elif dir1 - dir2 <= 179.2 %} None
{% elif dir1 - dir2 <= 201.6 %} None
{% elif dir1 - dir2 <= 224.0 %} Lowest
{% elif dir1 - dir2 <= 246.4 %} Low
{% elif dir1 - dir2 <= 268.8 %} Mid
{% elif dir1 - dir2 <= 291.2 %} Mod
{% elif dir1 - dir2 <= 313.6 %} High
{% elif dir1 - dir2 <= 360.0 %} Higher
{% elif dir1 - dir2 >= -22.4 %} Extreme
{% elif dir1 - dir2 >= -44.8 %} Higher
{% elif dir1 - dir2 >= -67.2 %} High
{% elif dir1 - dir2 >= -89.6 %} Mod
{% elif dir1 - dir2 >= -112.0 %} Mid
{% elif dir1 - dir2 >= -134.4 %} Low
{% elif dir1 - dir2 >= -156.8 %} Lowest
{% elif dir1 - dir2 >= -179.2 %} None
{% elif dir1 - dir2 >= -201.6 %} Lowest
{% elif dir1 - dir2 >= -224.0 %} Low
{% elif dir1 - dir2 >= -246.4 %} Mid
{% elif dir1 - dir2 >= -268.8 %} Mod
{% elif dir1 - dir2 >= -291.2 %} High
{% elif dir1 - dir2 >= -313.6 %} Higher
{% elif dir1 - dir2 >= -360.0 %} Extreme
{% endif %}

Cheers!

Well hot diggety-dog if I didn’t solve my own problem!

Maybe…

Please still criticise it

Wait…

Should it be:

{% set dir1 = states('sensor.incident_1_bearing')|float %}
{% set dir2 = states('sensor.openweathermap_wind_bearing')|float %}
{% if 0.0 <= dir1 - dir2 <= 22.4 %} Extreme 
{% elif 22.5 <= dir1 - dir2 <= 44.8 %} Higher
{% elif 44.9 <= dir1 - dir2 <= 67.2 %} High
{% elif 67.3 <= dir1 - dir2 <= 89.6 %} Mod
{% elif 89.7 <= dir1 - dir2 <= 112.0 %} Mid
{% elif 112.1 <= dir1 - dir2 <= 134.4 %} Low
{% elif 134.5 <= dir1 - dir2 <= 156.8 %} Lowest
{% elif 156.9 <= dir1 - dir2 <= 179.2 %} None
{% elif 179.3 <= dir1 - dir2 <= 201.6 %} Lowest
{% elif 201.7 <= dir1 - dir2 <= 224.0 %} Low
{% elif 224.1 <= dir1 - dir2 <= 246.4 %} Mid
{% elif 246.5 <= dir1 - dir2 <= 268.8 %} Mod
{% elif 268.9 <= dir1 - dir2 <= 291.2 %} High
{% elif 291.3 <= dir1 - dir2 <= 313.6 %} Highest
{% elif 313.7 <= dir1 - dir2 <= 360.0 %} Extreme
{% elif 0.0 >= dir1 - dir2 >= -22.4 %} Extreme
{% elif -22.5 >= dir1 - dir2 >= -44.8 %} Higher
{% elif -44.9 >= dir1 - dir2 >= -67.2 %} High
{% elif -67.3 >= dir1 - dir2 >= -89.6 %} Mod
{% elif -89.7 >= dir1 - dir2 >= -112.0 %} Mid
{% elif -112.1 >= dir1 - dir2 >= -134.4 %} Low
{% elif -134.5 >= dir1 - dir2 >= -156.8 %} Lowest
{% elif -156.9 >= dir1 - dir2 >= -179.2 %} None
{% elif -179.3 >= dir1 - dir2 >= -201.6 %} Lowest
{% elif -201.7 >= dir1 - dir2 >= -224.0 %} Low
{% elif -224.1 >= dir1 - dir2 >= -246.4 %} Mid
{% elif -246.5 >= dir1 - dir2 >= -268.8 %} Mod
{% elif -268.9 >= dir1 - dir2 >= -291.2 %} High
{% elif -291.3 >= dir1 - dir2 >= -313.6 %} Higher
{% elif -314.7 >= dir1 - dir2 >= -360.0 %} Extreme
{% endif %}

You can reduce the amount of code by:

  • computing the absolute value of the difference
  • storing the values in a dictionary
{% set x = (states('sensor.incident_1_bearing') | float(0) - 
  states('sensor.openweathermap_wind_bearing') | float(0)) | abs %}
{{ { 0.0 <= x <= 22.4: Extreme 
    22.5 <= x <= 44.8: Higher
    44.9 <= x <= 67.2: High
    67.3 <= x <= 89.6: Mod
    89.7 <= x <= 112.0: Mid
   112.1 <= x <= 134.4: Low
   134.5 <= x <= 156.8: Lowest
   156.9 <= x <= 179.2: None
   179.3 <= x <= 201.6: Lowest
   201.7 <= x <= 224.0: Low
   224.1 <= x <= 246.4: Mid
   246.5 <= x <= 268.8: Mod
   268.9 <= x <= 291.2: High
   291.3 <= x <= 313.6: Higher
   313.7 <= x <= 360.0: Extreme }.get(true, 'unknown') }}

Note

You can also reduce the number of keys in the dictionary by combining the keys that have the same values.

{% set x = (states('sensor.incident_1_bearing') | float(0) - 
  states('sensor.openweathermap_wind_bearing') | float(0)) | abs %}
{{ { 0.0 <= x <= 22.4 or 313.7 <= x <= 360.0: Extreme 
    22.5 <= x <= 44.8 or 291.3 <= x <= 313.6: Higher
    44.9 <= x <= 67.2 or 268.9 <= x <= 291.2: High
    67.3 <= x <= 89.6 or 246.5 <= x <= 268.8: Mod
    89.7 <= x <= 112.0 or 224.1 <= x <= 246.4: Mid
   112.1 <= x <= 134.4 or 201.7 <= x <= 224.0: Low
   134.5 <= x <= 156.8 or 179.3 <= x <= 201.6: Lowest
   156.9 <= x <= 179.2: None }.get(true, 'unknown') }}
1 Like

This is amazing. Way more elegant.

Thanks very much!

1 Like