Somewhat shorter template:
{% set seg = ((states('sensor.wind_direction')|float(0) + 11.25) / 22.5)|int %}
{{ 'N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N'.split()[seg] }}
Somewhat shorter template:
{% set seg = ((states('sensor.wind_direction')|float(0) + 11.25) / 22.5)|int %}
{{ 'N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N'.split()[seg] }}
Great thanks!
The readings are still not correct.
Maybe you could help me with this, I’ve been trying for so long to get this working.
I’m using a mlx90393 for the wind vane, the sensors change value when I rotate the vane, however im not sure how to convert the value into the correct corresponding directional heading.
Could you help me out.
Hello @deanfourie I am not sure what sensor you have but normally you use
calibrate_linear:
on your sensor component. It allows you to map the output of the sensor to the value that you want to show to the world. So for a windvane the world output is 0 - 360 degrees. The ESPHome explanation for calibrate_linear is below.
for some strange reason I did both in HA and ESPhome… this is the one I use in ESPHome… probably copied from you or somebody else smart!
text_sensor:
# Cardinal Wind direction
- platform: template
name: Cardinal Wind Direction
lambda: |-
if (id(winddirection1).state < 11.25 || id(winddirection1).state >= 348.75) {
return {"N"};
} else if (id(winddirection1).state >= 11.25 && id(winddirection1).state < 33.75) {
return {"NNE"};
} else if (id(winddirection1).state >= 33.75 && id(winddirection1).state < 56.25) {
return {"NE"};
} else if (id(winddirection1).state >= 56.25 && id(winddirection1).state < 78.75) {
return {"ENE"};
} else if (id(winddirection1).state >= 78.75 && id(winddirection1).state < 101.25) {
return {"E"};
} else if (id(winddirection1).state >= 101.25 && id(winddirection1).state < 123.75) {
return {"ESE"};
} else if (id(winddirection1).state >= 123.75 && id(winddirection1).state < 146.25) {
return {"SE"};
} else if (id(winddirection1).state >= 146.25 && id(winddirection1).state < 168.75) {
return {"SSE"};
} else if (id(winddirection1).state >= 168.75 && id(winddirection1).state < 191.25) {
return {"S"};
} else if (id(winddirection1).state >= 191.25 && id(winddirection1).state < 213.75) {
return {"SSW"};
} else if (id(winddirection1).state >= 213.75 && id(winddirection1).state < 236.25) {
return {"SW"};
} else if (id(winddirection1).state >= 236.25 && id(winddirection1).state < 258.75) {
return {"WSW"};
} else if (id(winddirection1).state >= 258.75 && id(winddirection1).state < 281.25) {
return {"W"};
} else if (id(winddirection1).state >= 281.25 && id(winddirection1).state < 303.75) {
return {"WNW"};
} else if (id(winddirection1).state >= 303.75 && id(winddirection1).state < 326.25) {
return {"NW"};
} else if (id(winddirection1).state >= 326.25 && id(winddirection1).state < 348.75) {
return {"NNW"};
} else return {"Something is not Right..."};
update_interval: 10s
Great thanks ill look into this.
From what I understand, this is not what usually used for wind vanes, this wind vane seems to be a bit of a black sheep of the family.
Its a magnetometer which reads in values of what I believe is magnetic flux so not sure if the calibrate function would work for this particular platform of sensor.
shooting from the hip … again … as none of your stuff is standard
you have a relatively straight diagonal line … correct?
it is giving you the maximum and minimum number… correct?
convert to absolute value i.e. not negative? …
whats the problem???
Edit: OR is the line showing the value being reported is going off-line or unavailable. or is that just because you turned it off??
Nah, at one point the value does change significantly, from thr 1000s to 100s,
Can you give me an example of how I would use the calibrate linear option.
I never paid attention in school, im not good with math.
Thanks
you have a relatively straight diagonal line … correct?
Correct
it is giving you the maximum and minimum number… correct?
Correct
you put maximum and minimum number into the calibrate_linear … the example is the link i posted … no maths… and none of this is taught in school …i fell asleep
This is my ADC sensor… your minimum number goes where it says 0.0 and the maximum where it says 4095…
so your filter section ONLY goes into your sensor platform …
what every your sensor platform is …
I have used a median filter because wind direction is quite violent / turbulent and it needs to be calmed… and same again for wind anemometer … it depends on the exact location of your station…
sensor:
- platform: adc
pin: GPIO34
name: "Wind Direction"
id: winddirection1
icon: mdi:compass-rose
unit_of_measurement: "º"
state_class: measurement
update_interval: 1s
accuracy_decimals: 0
attenuation: 11db
raw: True
filters:
- calibrate_linear:
- 0.0 -> 0.0
- 4095-> 360
- median:
window_size: 30
send_every: 30
send_first_at: 30
nice!
I had this:
{% set degrees = states('sensor.buienradar_wind_direction_azimuth')|float(0) %}
{% set abbr = ['N','NNNO','NNO','ONNO','NO','NONO','ONO','OONO',
'O','OOZO','OZO','ZOZO','ZO','OZZO','ZZO','ZZZO',
'Z','ZZZW','ZZW','ZZW','ZW','ZWZW','WZW','WWZW',
'W','WWNW','WNW','NWNW','NW','WNNW','NNW','NNNW' ] %}
{%- set i = ((degrees/11.25)|round(0))|int %}
{%- set i = 0 if i == 32 else i %}
{{abbr[i]}}
and need to find a way to get more granularity into your template
I can’ follow all that C++, but rainfall is not measured in ml, it is measured in mm.
I know, I just used ml to test with to make it easier, then when calibrated to ml ill change it back to mm
Doesnt like something. Pretty sure the indentation is correct.
- platform: mlx90393
id: mlx
x_axis:
name: "mlx_x"
id: "x"
y_axis:
name: "mlx_y"
id: "y"
z_axis:
name: "mlx_z"
update_interval: 1s
filters:
- calibrate_linear:
- 0.0 -> 0.0
- 4095-> 360
- median:
window_size: 30
send_every: 30
send_first_at: 30
Failed config
sensor.mlx90393: [source /config/esphome/weather-station.yaml:130]
platform: mlx90393
id: mlx
x_axis:
name: mlx_x
id: x
y_axis:
name: mlx_y
id: y
z_axis:
name: mlx_z
update_interval: 1s
[filters] is an invalid option for [sensor.mlx90393]. Did you mean [filter]?
filters:
- calibrate_linear:
- 0.0 -> 0.0
- 4095-> 360
- median:
window_size: 30
send_every: 30
send_first_at: 30
Also, trying out this template. I have not put the values in yet, but U get the following error.
So what I understand from this is that this particular sensor does to print a STATE value?
Maybe use something else?
- platform: template
name: Cardinal Wind Direction
lambda: |-
if (id(mlx).state < 11.25 || id(mlx).state >= 348.75) {
return {"N"};
} else if (id(mlx).state >= 11.25 && id(mlx).state < 33.75) {
return {"NNE"};
} else if (id(mlx).state >= 33.75 && id(mlx).state < 56.25) {
return {"NE"};
} else if (id(mlx).state >= 56.25 && id(mlx).state < 78.75) {
return {"ENE"};
} else if (id(mlx).state >= 78.75 && id(mlx).state < 101.25) {
return {"E"};
} else if (id(mlx).state >= 101.25 && id(mlx).state < 123.75) {
return {"ESE"};
} else if (id(mlx).state >= 123.75 && id(mlx).state < 146.25) {
return {"SE"};
} else if (id(mlx).state >= 146.25 && id(mlx).state < 168.75) {
return {"SSE"};
} else if (id(mlx).state >= 168.75 && id(mlx).state < 191.25) {
return {"S"};
} else if (id(mlx).state >= 191.25 && id(mlx).state < 213.75) {
return {"SSW"};
} else if (id(mlx).state >= 213.75 && id(mlx).state < 236.25) {
return {"SW"};
} else if (id(mlx).state >= 236.25 && id(mlx).state < 258.75) {
return {"WSW"};
} else if (id(mlx).state >= 258.75 && id(mlx).state < 281.25) {
return {"W"};
} else if (id(mlx).state >= 281.25 && id(mlx).state < 303.75) {
return {"WNW"};
} else if (id(mlx).state >= 303.75 && id(mlx).state < 326.25) {
return {"NW"};
} else if (id(mlx).state >= 326.25 && id(mlx).state < 348.75) {
return {"NNW"};
} else return {"Something is not Right..."};
update_interval: 10s
Compiling /data/weather-station/.pioenvs/weather-station/src/main.cpp.o
/config/esphome/weather-station.yaml: In lambda function:
/config/esphome/weather-station.yaml:210:16: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
if (id(mlx).state < 11.25 || id(mlx).state >= 348.75) {
^~~~~
update
/config/esphome/weather-station.yaml:210:38: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
if (id(mlx).state < 11.25 || id(mlx).state >= 348.75) {
^~~~~
update
/config/esphome/weather-station.yaml:212:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 11.25 && id(mlx).state < 33.75) {
^~~~~
update
/config/esphome/weather-station.yaml:212:46: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 11.25 && id(mlx).state < 33.75) {
^~~~~
update
/config/esphome/weather-station.yaml:214:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 33.75 && id(mlx).state < 56.25) {
^~~~~
update
/config/esphome/weather-station.yaml:214:46: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 33.75 && id(mlx).state < 56.25) {
^~~~~
update
/config/esphome/weather-station.yaml:216:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 56.25 && id(mlx).state < 78.75) {
^~~~~
update
/config/esphome/weather-station.yaml:216:46: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 56.25 && id(mlx).state < 78.75) {
^~~~~
update
/config/esphome/weather-station.yaml:218:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 78.75 && id(mlx).state < 101.25) {
^~~~~
update
/config/esphome/weather-station.yaml:218:46: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 78.75 && id(mlx).state < 101.25) {
^~~~~
update
/config/esphome/weather-station.yaml:220:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 101.25 && id(mlx).state < 123.75) {
^~~~~
update
/config/esphome/weather-station.yaml:220:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 101.25 && id(mlx).state < 123.75) {
^~~~~
update
/config/esphome/weather-station.yaml:222:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 123.75 && id(mlx).state < 146.25) {
^~~~~
update
/config/esphome/weather-station.yaml:222:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 123.75 && id(mlx).state < 146.25) {
^~~~~
update
/config/esphome/weather-station.yaml:224:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 146.25 && id(mlx).state < 168.75) {
^~~~~
update
/config/esphome/weather-station.yaml:224:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 146.25 && id(mlx).state < 168.75) {
^~~~~
update
/config/esphome/weather-station.yaml:226:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 168.75 && id(mlx).state < 191.25) {
^~~~~
update
/config/esphome/weather-station.yaml:226:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 168.75 && id(mlx).state < 191.25) {
^~~~~
update
/config/esphome/weather-station.yaml:228:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 191.25 && id(mlx).state < 213.75) {
^~~~~
update
/config/esphome/weather-station.yaml:228:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 191.25 && id(mlx).state < 213.75) {
^~~~~
update
/config/esphome/weather-station.yaml:230:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 213.75 && id(mlx).state < 236.25) {
^~~~~
update
/config/esphome/weather-station.yaml:230:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 213.75 && id(mlx).state < 236.25) {
^~~~~
update
/config/esphome/weather-station.yaml:232:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 236.25 && id(mlx).state < 258.75) {
^~~~~
update
/config/esphome/weather-station.yaml:232:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 236.25 && id(mlx).state < 258.75) {
^~~~~
update
/config/esphome/weather-station.yaml:234:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 258.75 && id(mlx).state < 281.25) {
^~~~~
update
/config/esphome/weather-station.yaml:234:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 258.75 && id(mlx).state < 281.25) {
^~~~~
update
/config/esphome/weather-station.yaml:236:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 281.25 && id(mlx).state < 303.75) {
^~~~~
update
/config/esphome/weather-station.yaml:236:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 281.25 && id(mlx).state < 303.75) {
^~~~~
update
/config/esphome/weather-station.yaml:238:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 303.75 && id(mlx).state < 326.25) {
^~~~~
update
/config/esphome/weather-station.yaml:238:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 303.75 && id(mlx).state < 326.25) {
^~~~~
update
/config/esphome/weather-station.yaml:240:23: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 326.25 && id(mlx).state < 348.75) {
^~~~~
update
/config/esphome/weather-station.yaml:240:47: error: 'class esphome::mlx90393::MLX90393Cls' has no member named 'state'; did you mean 'update'?
} else if (id(mlx).state >= 326.25 && id(mlx).state < 348.75) {
^~~~~
update
/config/esphome/weather-station.yaml:243:3: warning: control reaches end of non-void function [-Wreturn-type]
update_interval: 10s
^
*** [/data/weather-station/.pioenvs/weather-station/src/main.cpp.o] Error 1
========================== [FAILED] Took 3.79 seconds ==========================
Ok sorry got this one,
Using the wrong sensor, was using the entire MLX instead of one of its actual sensors, X for example.
id(x).state
Ok, I tried this and that didnt work…
text_sensor:
# Cardinal Wind direction
- platform: template
name: Cardinal Wind Direction
lambda: |-
if (id(x).state < 318.10000 || id(x).state >= 2700.00000) {
return {"N"};
} else if (id(x).state >= 7200.10000 && id(x).state < 3320.00000) {
return {"NE"};
} else if (id(x).state >= 3320.10000 && id(x).state < 1600.00000) {
return {"E"};
} else if (id(x).state >= 1600.10000 && id(x).state < -815.00000) {
return {"SE"};
} else if (id(x).state >= -815.10000 && id(x).state < -2530.00000) {
return {"S"};
} else if (id(x).state >= 2530.1000 && id(x).state < -3330.00000) {
return {"SW"};
} else if (id(x).state >= 3330.10000 && id(x).state < -2140.00000) {
return {"W"};
} else if (id(x).state >= -2140.10000 && id(x).state < 318.00000) {
return {"NW"};
} else return {"Something is not Right..."};
update_interval: 10s
Just displays N and something is not Right…
N - start: 318.10000 finish 2700.00000
NE - start: 7200.10000 finish 3320.00000
E - start: 3320.10000 finish 1600.00000
SE - start: 1600.10000 finish -815.00000
S - start: -815.10000 finish -2530.00000
SW - start: 2530.1000 finish -3330.00000
W - start: 3330.10000 finish -2140.00000
NW - start -2140.10000 finish 318.00000
How about logging id(x).state and the return.
The log output of the state for X
[11:43:36][D][text_sensor:064]: 'Cardinal Wind Direction': Sending state 'N'
[11:43:36][D][mlx90393:070]: received 1109.359985 3087.979980 -12769.560547
[11:43:36][D][sensor:094]: 'mlx_x': Sending state 1109.35999 µT with 0 decimals of accuracy
[11:43:36][D][sensor:094]: 'mlx_y': Sending state 3087.97998 µT with 0 decimals of accuracy
[11:43:36][D][sensor:094]: 'mlx_z': Sending state -12769.56055 µT with 0 decimals of accuracy