I have a FineOffset WH3081 weather station which I monitor with ‘weewx’ on a Linux Mint PC. There’s an extension for weewx that adds MQTT functionality and I’ve used this to also display info on an OpenHAB2 page. Written by Matthew Wall and available HERE.
Anyway, the wind and wind gust directions are returned as angular degrees (0 being North, 90 East etc), so I’ve knocked up a script to turn that input into compass points (NE, SW etc). I thought I’d share it here for those that could take advantage of it. It’s not limited to my situation, it should work on any weather page where this conversion would be handy.
Modify the ‘return’ lines to achieve the output you’d prefer, currently I’m showing both the angular direction and compass point for testing purposes, and seeing what my weather station is returning via weewx mqtt:
(function(i) {
if(i >= 349 && i <= 11){
return +i + "° -=- N";
} else if (i >= 12 && i <= 33) {
return +i + "° -=- NNE";
} else if (i >= 34 && i <= 56) {
return +i + "° -=- NE";
} else if (i >= 57 && i <= 78) {
return +i + "° -=- ENE";
} else if (i >= 79 && i <= 101) {
return +i + "° -=- E";
} else if (i >= 102 && i <= 123) {
return +i + "° -=- ESE";
} else if (i >= 124 && i <= 146) {
return +i + "° -=- SE";
} else if (i >= 147 && i <= 168) {
return +i + "° -=- SSE";
} else if (i >= 169 && i <= 191) {
return +i + "° -=- S";
} else if (i >= 192 && i <= 213) {
return +i + "° -=- SSW";
} else if (i >= 214 && i <= 236) {
return +i + "° -=- SW";
} else if (i >= 237 && i <= 258) {
return +i + "° -=- WSW";
} else if (i >= 259 && i <= 281) {
return +i + "° -=- W";
} else if (i >= 282 && i <= 303) {
return +i + "° -=- WNW";
} else if (i >= 304 && i <= 326) {
return +i + "° -=- NW";
} else if (i >= 327 && i <= 348) {
return +i + "° -=- NNW";
}
})(input)
Item config, the script in my case is named windDir.js in the the CONFIG/transform directory:
String windDir "Wind Direction [JS(windDir.js):%s]" <wind> (Weather) channel="mqtt:topic:mosquitto:weather:windDir"}
String windGustDir "Wind Gust Direction [JS(windDir.js):%s]" <wind> (Weather) channel="mqtt:topic:mosquitto:weather:windGustDir"}
Nit-Pick: You are producing holes in your calculation. I am pretty aware that wind direction degrees will not be issued in scales lower than one degree, but I would suggest you do it like this:
if(i > 348 && i <= 11){
return +i + "° -=- N";
} else if (i > 11 && i <= 33) {
return +i + "° -=- NNE";
} else if (i > 33 && i <= 56) {
return +i + "° -=- NE";
} else if (i > 56 && i <= 78) {
...
That way you ensure you will even catch those numbers correctly.
Sorry, but the old navigator has to step in.
It might be that I do not understand the used code but IMHO the used steps are wrong!
N for North would be assigned to courses from above 348,75 over 360 (which is 0 ) to 11,25
NNE from above 11,25 to 33,75 …
The steps are all 22,5 ° wide.
My amended version using the actual compass points even though my readings are integers, this still holds true. Yes I know if we get down to the final condition it could simply be an ‘else’ statement, and that all of the conditions could be one liners, but to me it’s more readable in this form.
(function(i) {
if(i >= 348.75 || i < 11.25){
return +i + ". -=- N";
} else if (i >= 11.25 && i < 33.75) {
return +i + ". -=- NNE";
} else if (i >= 33.75 && i < 56.25) {
return +i + ". -=- NE";
} else if (i >= 56.25 && i < 78.75) {
return +i + ". -=- ENE";
} else if (i >= 78.25 && i < 101.25) {
return +i + ". -=- E";
} else if (i >= 101.25 && i < 123.75) {
return +i + ". -=- ESE";
} else if (i >= 123.75 && i < 146.25) {
return +i + ". -=- SE";
} else if (i >= 146.25 && i < 168.75) {
return +i + ". -=- SSE";
} else if (i >= 168.75 && i < 191.25) {
return +i + ". -=- S";
} else if (i >= 191.25 && i < 213.75) {
return +i + ". -=- SSW";
} else if (i >= 213.75 && i < 236.25) {
return +i + ". -=- SW";
} else if (i >= 236.25 && i < 258.75) {
return +i + ". -=- WSW";
} else if (i >= 258.75 && i < 281.25) {
return +i + ". -=- W";
} else if (i >= 281.25 && i < 303.75) {
return +i + ". -=- WNW";
} else if (i >= 303.75 && i < 326.25) {
return +i + ". -=- NW";
} else if (i >= 326.25 && i < 348.75) {
return +i + ". -=- NNW";
}
})(input)
Brilliant, thanks for that @cweitkamp. I was looking for a way to do that with a normal transform, but as far as I understood it, it only allows a single value either side of the =. Didn’t know about the Scale Transformation, thanks for bringing it to my attention. I’ll stick to my script for now though so I can return both the angular direction and the compass point together. But I’ll definitely use the scale transform once I’m happy with the values my weather station provides.
For shure I don’t know the to much about the JS Implementation within OH rules, but my installation complains about val but not about var.
var: object; val: method
Happy to find this. However, having a problem with the item definitions…
I am not sure how this code works with item definitions, but it breaks my sitemap (where only frame names are shown, no items). If I remove it, the value is shown as null.
I’ve tried with and without the padding spaces, confirmed javascript transformation, confirmed string item type… what am I missing?
Take the <----> and <> parts out and replace with spaces, they’re tabs, that was me copying from my editor which was set to show tabs which then became part of that copy.
EDIT: I’ve now cleaned up that copy problem in the original post.