Formatting items in rules to generate a string

I am implementing a rule that generates a statement like this one.

“Presently, we are experiencing scattered clouds with the temperature a pleasant 74.642 °F. Your pool’s Temperature is 80.4 degrees Fahrenheit. There is a calm wind around 6.084461846818496440785810864551022 mph. For the immediate forecast, we are expecting few clouds skies with temperatures ranging from 74.282 °F to 91.742 °F degrees. Expect a light breeze around 17.22439566930236124781277340332458 mph.”

The items I highlighted in bold are being picked up from the openweathermap api. I have just two items below as illustrations but there are many more. I pretty much copied and pasted from the openhab binding addon description page and made a few minor edits since I wanted mph instead of km/h. If you notice below, the formatting of the string is set to 1 significant digit but when I create my string, it is not conforming to that. I pass this string on to my Amazon Echo for alexa to say the report first thing in the morning when I wallk into the kitchen. It is rather annoying to hear her say things like Expect a light breeze around 17.22439566930236124781277340332458 mph." when i would rather her just say 17.2 mph.

The items

Number:Temperature localDailyForecastTodayMinTemperature "Minimum temperature for today [%.1f %unit%]" <temperature> { channel="openweathermap:weather-and-forecast:api:local:forecastToday#min-temperature" }
Number:Speed localDailyForecastTodayWindSpeed "Wind speed for today [%.1f km/h]" <wind> { channel="openweathermap:weather-and-forecast:api:local:forecastToday#wind-speed" }

As you can see below my sitemap looks ok and I do not do anything special to make that happen.

The sitemap source

Frame label="Current local weather" {
        Text item=localLastMeasurement
        Text item=localCurrentCondition
        Image item=localCurrentConditionIcon
        Text item=localCurrentTemperature
        Text item=localCurrentApparentTemperature
        Text item=localCurrentPressure
        Text item=localCurrentHumidity
        Text item=localCurrentDewpoint
        Text item=localCurrentWindSpeed
        Text item=localCurrentWindDirection
        Text item=localCurrentGustSpeed
        Text item=localCurrentCloudiness
		Text item=localCurrentRainVolume
		Text item=localCurrentSnowVolume
		Text item=localCurrentVisibility
		Text item=localCurrentUvindex label="Current UV Index [%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
		{
			Frame label="UV-Index (Tomorrow)" {
				Text item=localUVIndexTomorrow label="UV-Index (Tomorrow) [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexTomorrow valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexLastChangeTomorrow
			}
			Frame label="UV Index (in 2 days)" {
				Text item=localUVIndexDay2 label="UV Index (in 2 days) [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexDay2 valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexLastChangeDay2
			}
			Frame label="UV Index (in 3 days)" {
				Text item=localUVIndexDay3 label="UV Index (in 3 days) [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexDay3  valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexLastChangeDay3
			}
			Frame label="UV Index (in 4 days)" {
				Text item=localUVIndexDay4 label="UV Index (in 4 days) [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexDay4  valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexLastChangeDay4
			}
			Frame label="UV Index (in 5 days)" {
				Text item=localUVIndexDay5 label="UV Index (in 5 days) [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexDay5  valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]
				Text item=localUVIndexLastChangeDay5
			}
		}
		Text item=localCurrentUvindex label="UV-Index [SCALE(uvindex.scale):%s]" valuecolor=[<3="green", <6="yellow", <8="orange", <11="red", >=11="purple"]		

		Text label="Local forecast for today" {
			Text item=localTodayTimestamp
			Text item=localTodayPrecipProbability
			Text item=localTodaySunrise
			Text item=localTodaySunset
			Text item=localTodayCondition
			Image item=localTodayConditionIcon
			Text item=localTodayMinTemperature
			Text item=localTodayMaxTemperature
			Text item=localTodayMorningTemperature
			Text item=localTodayMorningApparent
			Text item=localTodayDayTemperature
			Text item=localTodayDayApparent
			Text item=localTodayEveningTemperature
			Text item=localTodayEveningApparent
			Text item=localTodayNightTemperature
			Text item=localTodayNightApparent
			Text item=localTodayPressure
			Text item=localTodayHumidity
			Text item=localTodayDewpoint
			Text item=localTodayWindSpeed
			Text item=localTodayWindDirection
			Text item=localTodayGustSpeed
			Text item=localTodayCloudiness
			Text item=localTodayUvindex
			Text item=localTodayRainVolume
			Text item=localTodaySnowVolume
			Text item=localTodayVisibility
		}
    }

How can I fix my rule so that it only presents 1 significant digit?

Here is a much simpler example of how I am attempting to do it.

var vTemp = ""
var vWindSpeed = ""
var CurrentTemperature = localCurrentTemperature.state as Number
var CurrentWindSpeed = localCurrentWindSpeed.state as Number

rule "Generate weather statement on weather update"
when
    Item localLastMeasurement received update 
then
    logInfo("weather-speak.rules", "Updating Weather Statement")

    Speak_Weather.sendCommand("")

    switch (CurrentTemperature) {

        case CurrentTemperature > -300 && CurrentTemperature <= 15: {
            vTemp = transform("MAP", "weather-speak.map", "-300")
        }
        case CurrentTemperature >15 && CurrentTemperature <= 30: {
            vTemp = transform("MAP", "weather-speak.map", "15")
        }
        case CurrentTemperature >30 && CurrentTemperature <= 40: {
            vTemp = transform("MAP", "weather-speak.map", "30")
        }
        case CurrentTemperature >40 && CurrentTemperature <= 50: {
            vTemp = transform("MAP", "weather-speak.map", "40")
        }
        case CurrentTemperature >50 && CurrentTemperature <= 60: {
            vTemp = transform("MAP", "weather-speak.map", "50")
        }
        case CurrentTemperature >60 && CurrentTemperature <= 65: {
            vTemp = transform("MAP", "weather-speak.map", "60")
        }
        case CurrentTemperature >65 && CurrentTemperature <= 75: {
            vTemp = transform("MAP", "weather-speak.map", "65")
        }
        case CurrentTemperature >75 && CurrentTemperature <= 85: {
            vTemp = transform("MAP", "weather-speak.map", "75")
        }
        case CurrentTemperature >85 && CurrentTemperature <= 90: {
            vTemp = transform("MAP", "weather-speak.map", "85")
        }
        case CurrentTemperature >90 && CurrentTemperature <= 96: {
            vTemp = transform("MAP", "weather-speak.map", "90")
        }
        case CurrentTemperature >96: {
            vTemp = transform("MAP", "weather-speak.map", "96")
        }
    }

    // The Map
    // 0=calm winds
    // 3=a light breeze
    // 13=a moderate breeze
    // 25=a strong breeze
    // 31=near gale force winds
    // 39=gale force winds
    // 55=severe storm level winds
    // 74=hurricane force winds

    switch (CurrentWindSpeed) {

        case CurrentWindSpeed > 0 && CurrentWindSpeed <= 3: {
            vWindSpeed = transform("MAP", "weather-speak.map", "0")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >3 && CurrentWindSpeed <= 13: {
            vWindSpeed = transform("MAP", "weather-speak.map", "3")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >13 && CurrentWindSpeed <= 25: {
            vWindSpeed = transform("MAP", "weather-speak.map", "13")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >25 && CurrentWindSpeed <= 31: {
            vWindSpeed = transform("MAP", "weather-speak.map", "25")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >31 && CurrentWindSpeed <= 39: {
            vWindSpeed = transform("MAP", "weather-speak.map", "31")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >39 && CurrentWindSpeed <= 55: {
            vWindSpeed = transform("MAP", "weather-speak.map", "39")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
        case CurrentWindSpeed >55 && CurrentWindSpeed <= 74: {
            vWindSpeed = transform("MAP", "weather-speak.map", "55")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
       case CurrentWindSpeed >74: {
            vWindSpeed = transform("MAP", "weather-speak.map", "74")
            //logInfo("weather-speak.rules", vWindSpeed) 
        }
    }

    vSpeakWeather = "Wind Speed is " +vWindSpeed +" and temperature is " +CurrentTemperature 
    
    Speak_Weather.sendCommand(vSpeakWeather)
 
    logInfo("weather-speak.rules", "Weather Statment: " +vSpeakWeather)
    
end

I found the solution at the very end of this post.

String formatting

I want “21.3°C” in my message string, not “21.28478 °C”

var message = "Temperature is " + (tempItemC.state as QuantityType<Temperature>).format("%.1f%unit%")
// returns "Temperature is 10.0°C"
// uses usual Java formatter control string

for speed you can use

+(localTodayWindSpeed.state as QuantityType<Speed>).format("%.1f %unit%")
2 Likes