Number to String

Hi All,

do you know if with OH2 there is a way to go from Number to String without a Rule?

Is Scale only a Num-Num solution?

thanks
Andrea

Let me clarify with an example. I know, this code is working but definitely HORRIBLE!!! Any better solution to convert a number in a more readable string?

Example: wind strength classified with Beaufort index

two items:
Number Http_Wunderground_WindBeaufort â€śBeaufort Index: [%s]â€ť (gOutdoor, gWeather) {weather=â€ślocationId=Home_WU, type=wind, property=speed, unit=beaufortâ€ť}
String Http_Wunderground_WindBeaufortIndex â€śBeaufort Index: [MAP(beaufort.map):%s]â€ť (gOutdoor, gWeather)

the beaufort.map:
-=na
0=calm
1=Light Air
2=Light Breeze
3=Gentle Breeze
4=Moderate Breeze
5=Fresh Breeze
6=Strong Breeze
7=High Wind
8=Gale
9=Strong Gale
10=Storm
11=Violent Storm
12=Hurricane

and the rule:

// Wind Beaufort Rules

rule â€śWind Beaufort Ratingâ€ť
when
Item Http_Wunderground_WindBeaufort changed or
System started
then
// if (Http_Wunderground_WindBeaufort.state == Undefined || Http_Wunderground_WindBeaufort.state == Uninitialized)
// return false
// else {
var Number bf = Http_Wunderground_WindBeaufort.state as DecimalType
var Number w
if (bf = 12) {w = 12}
else if (bf = 11) {w = 11}
else if (bf = 10) {w = 10}
else if (bf = 9) {w = 9}
else if (bf = 8) {w = 8}
else if (bf = 7) {w = 7}
else if (bf = 6) {w = 6}
else if (bf = 5) {w = 5}
else if (bf = 4) {w = 4}
else if (bf = 3) {w = 3}
else if (bf = 2) {w = 2}
else if (bf = 1) {w = 1}
else {w = 0}
postUpdate(Http_Wunderground_WindBeaufortIndex, w)
// }
end

the â€śif/return falseâ€ť is not working for now.

Any better idea?
Thanks for your support. Any suggestion will be much appreciated.

Andrea

Hi Andrea!

I will try to help you but I must say that I do not fully understand what you are trying to achieve. I assume you have a Number item updated by a binding and want to convert that number to a String for display in a sitemap (using a transformation).

``````rule "Wind Beaufort Rating"
when
Item Http_Wunderground_WindBeaufort changed or
System started
then
if (Http_Wunderground_WindBeaufort.state == NULL) {
// no need to return false
return
}
// Use a val (constant) instead of a var (variable)
val Number bf = Http_Wunderground_WindBeaufort.state as DecimalType
var Number w

/*
* You are assigning a Number to a Number (I do not really know why)
* which could be done by just assigning the value:
*/
w = bf

/*
* But if you must convert a value by a list of known values, use the
* switch statement instead of if-elseif-else.
*/
// switch bf {
//     case 2: w = 2
//     case 1: w = 1
//     default: w = 0
// }

// Use Item.postUpdate() instead of global method
Http_Wunderground_WindBeaufortIndex.postUpdate(w)

end
``````

Now that thatâ€™s out of the way I will try to answer your question. Your approach should work without the need for a â€śdummyâ€ť String item. Just use the MAP approach with the Number item and define a Text in your sitemap displaying the Number item:

``````Number Http_Wunderground_WindBeaufort "Beaufort Index: [MAP(beaufort.map):%s]" (gOutdoor, gWeather) {weather=â€ślocationId=Home_WU, type=wind, property=speed, unit=beaufortâ€ť}
``````

``````sitemap home label="My Home" {
Text item=Http_Wunderground_WindBeaufort
}
``````

Which should give you (assuming Http_Wunderground_WindBeaufort.state == 0):

``````Beaufort Index: calm
``````

Thank you very much, @jewesta â€¦ your post is very informative for me.

Now it works like a charm
I donâ€™t know why the same approach was not working with OH1 (tried in the past, for sure).

thanks again
Andrea

I have another question, I donâ€™t know if you can help me.

The solution above is perfect when I have a Number and I need to convert to a String

example: â€ś1â€ť -> Wind

But what about when I receive in the same array 2 values?

I receve â€ś21â€ť and it means â€ś2â€ť and â€ś1â€ť

At the moment Iâ€™ve created the entry 21 in the map file, and I say â€śFog/Windâ€ť for example, if 2 means â€śFogâ€ť and 1 â€śWindâ€ť.

But Iâ€™m wondering to know if there is a better way for doing that.
thanks
Andrea

The problem here is that â€ś21â€ť is not really an array. OH will interpret that as a string containing a number.
You may want to have a look at a javascript transform

going more specific.

attached you can find an output from Wunderground Alarms about the current situation in Huesca, Spain. We have 2 alerts, so good example.

zmw_00000.210.08094.xml (3.3 KB)

items:

/*Wunderground Meteoalarm */

in http.cfg:

configuration of the first cache item: Meteoalarm every 5 mins

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl=â€śhttp://www.w3.org/1999/XSL/Transformâ€ť>

``````<xsl:output indent="yes" method="xml" encoding="UTF-8" omit-xml-declaration="yes" />

<xsl:template match="/">
<xsl:value-of select="wtype_meteoalarm"/>
</xsl:for-each>
</xsl:template>
``````

</xsl:stylesheet>

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl=â€śhttp://www.w3.org/1999/XSL/Transformâ€ť>

``````<xsl:output indent="yes" method="xml" encoding="UTF-8" omit-xml-declaration="yes" />

<xsl:template match="/">
<xsl:value-of select="level_meteoalarm"/>
</xsl:for-each>
</xsl:template>
``````

</xsl:stylesheet>

It works, but not as expected. When I have 2 alerts in facts I see:

WuAlarmsCode= â€ś12â€ť because first alert value is â€ś1â€ť, and second is â€ś2â€ť
WuAlarmsLev= â€ś22â€ť, because both alerts are in this case Level 2

Any clue how to solve this issue?

thanks
Andrea

Does the weather underground provide a json result instead of xml?
The you could access each alarm separately on two items with a slightly different JSONPATH transform for each

Yes we have

How can I access each alarm separately?

Then I need to create multiple items? A sort of

Alarm1/Level1
Alarm2/Level2
â€¦

and they will be populated only when Iâ€™ll have multiple alarms?

Andrea

Hi Andrea,

the WU-JSON is much better for automation than the XML. Please have a look on the thread:

From your JSON in Huesca, you can see:

``````	"alerts": [
{
"type": "WND",
"wtype_meteoalarm": "1",
"wtype_meteoalarm_name": "Wind",
"level_meteoalarm": "2",
"level_meteoalarm_name": "Yellow",
...
{
"type": "WIN",
"wtype_meteoalarm": "2",
"wtype_meteoalarm_name": "Snow/Ice",
"level_meteoalarm": "2",
"level_meteoalarm_name": "Yellow",

``````

you get the type and the level in distinct attributes for both alerts WND and WIN.

PS: After settling all that, you should Change your WU API Key! itâ€™s in the URL you providedâ€¦

another Thing unrelated. If youâ€™d like your OH2 to speak spanish on weather, have a look here:

you can add spanish language support for the alerts and weather description.

Thanks all for this clarification.

But how can, for example, populate item1 with alert1 and item2 with alert2, and so on?

Iâ€™ts always alerts.wtype_meteoalarm for both alerts, how to understand what is first and what is, in case, second/third/â€¦?

maybe, using a brute-force approach, I can

1. create 12 items for all 12 alarms we can have via meteoalarm

2. find a way to say "populate item1 if wtype_meteoalarm is â€ś1â€ť, item2 if is â€ś2â€ť, â€¦ and so on.

Does it make any sense?

``````weatherConditions.url=the_url_for_wu_underground_json_with_your_api_key
weatherConditions.updateInterval=360000
``````

items file:

``````String Alarm1 "Alarm1 [%s]" { http="[weatherConditions:360000:JSONPATH(\$.alerts[0].wtype_meteoalarm_name)]" }
String Alarm2 "Alarm2 [%s]" { http="[weatherConditions:360000:JSONPATH(\$.alerts[1].wtype_meteoalarm_name)]" }
``````

If there is only one alarm, the Alarm2 value will be an empty string

You donâ€™t need to, the wtype_meteoalarm_name is provided by the api!!

Yes, idea is

if there is 1 alarm, 1 Alarm will have a value
if there are 2 alarms, 2 Alarms will have a value

Then I will play with visibility in my sitemap, to see only the items with an alarm.

But I need to populate all 12 items, each with the right alarm.

Does it make any sense? any other clue?

Why do you want 12 items? Do you get 12 weather alarms in one location at any one time?

No, correct @vzorglub

with your approach \$.alerts[0] (the number in brackets is the first of the array, right?) we donâ€™t need to have more than 3-4 alerts for sure

shall I also associate the right level of alert for each item?

maybe same approach, then I concat Alarm1 + Level1 and so on?

Correct, unless you live in a place with a hell of a weather you will never have more than two or three weather alerts at any one time. [0] is the first alert, [1] is the secondâ€¦

If you paste your json in jsonpath.com, you can play with the jsonpath expression to get whatever value you want and assign it with an item.

2 Likes