Not scalable icons with openweathermap

Tags: #<Tag:0x00007faee871f1a8>

Raspberry Pi v.3+
Openhab 2.4
myOpenHub Cloud connection with:
iphone 6 - iOS 12.2
Samsung G8 - Android 8.0.0

I use openweathermap account. This API works quite OK with one problem.
The icon of the current weather condition on Android device is not scalable (big pixels are awful) and on iPhone not visible at all :frowning: . I do not know where these icons are located, how to influence their visibility on mobile devices?
Does someone knows how can i fix this or mitigate it?
Appreciate support.

Thanks

weather.items

String localStationId "ID [%s]" { channel="openweathermap:weather-and-forecast:api:local:station#id" }
String localStationName "City [%s]" <my_city> { channel="openweathermap:weather-and-forecast:api:local:station#name" }
Location localStationLocation "Location [%2$s°N %3$s°E]" <location> { channel="openweathermap:weather-and-forecast:api:local:station#location" }

//DateTime localLastMeasurement "Timestamp of last measurement [%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS]" <time> { channel="openweathermap:weather-and-forecast:api:local:current#time-stamp" }
DateTime localLastMeasurement "Timestamp of last measurement [%1$tH:%1$tM]" <time> { channel="openweathermap:weather-and-forecast:api:local:current#time-stamp" }
String localCurrentCondition "Current condition [%s]" <sun_clouds> { channel="openweathermap:weather-and-forecast:api:local:current#condition" }
Image localCurrentConditionIcon "Icon" { channel="openweathermap:weather-and-forecast:api:local:current#icon" }
Number:Temperature localCurrentTemperature "Outside temperature [%.1f %unit%]" <temperature> { channel="openweathermap:weather-and-forecast:api:local:current#temperature" }
Number:Pressure localCurrentPressure "Current barometric pressure [%.1f %unit%]" <pressure> { channel="openweathermap:weather-and-forecast:api:local:current#pressure" }
Number:Dimensionless localCurrentHumidity "Outside humidity [%d %unit%]" <my_humidity> { channel="openweathermap:weather-and-forecast:api:local:current#humidity" }
Number:Speed localCurrentWindSpeed "Current wind speed [%.1f km/h]" <wind> { channel="openweathermap:weather-and-forecast:api:local:current#wind-speed" }
//Number:Angle localCurrentWindDirection "Current wind direction [%d %unit%]" <wind> { channel="openweathermap:weather-and-forecast:api:local:current#wind-direction" }
Number:Dimensionless localCurrentCloudiness "Current cloudiness [%d %unit%]" <my_clouds> { channel="openweathermap:weather-and-forecast:api:local:current#cloudiness" }
Number:Length localCurrentRainVolume "Current rain volume [%.1f %unit%]" <rain> { channel="openweathermap:weather-and-forecast:api:local:current#rain" }
Number:Length localCurrentSnowVolume "Current snow volume [%.1f %unit%]" <snow> { channel="openweathermap:weather-and-forecast:api:local:current#snow" }

openweather.things

Bridge openweathermap:weather-api:api "OpenWeatherMap Account" [apikey="xxxxx", refreshInterval=30, language="de"] {
    Thing weather-and-forecast local "Local Weather And Forecast" [location="xxx,yyy", forecastHours=3, forecastDays=0]
    //Thing uvindex local "Local UV Index" [location="xxx,yyy", forecastDays=1]
    //Thing weather-and-forecast miami "Weather And Forecast In Miami" [location="25.782403,-80.264563", forecastHours=24, forecastDays=0]
}

basic.ui

https://192.168.1.114:8443

The image is created and provided by the OpenWeathermap service. OH has no control over them. It is explicitly labeled as an icon so a high resolution version of the image should not be expected.

If you want a way to apply that icon to the Current Conditions String Item, see OpenWeatherMap Use Icon Channel as icon on Sitemap.

Thank you Rich for the answer. Appreciate your time on probably trivial questions. I am ok to use the icon. I do not expect high quality pictures. I just expect them to work.
Is there really not possible to scale received icons withing openhab/myopenhabian? Nobody really complained on that?

Coming back to your workaround. Can you confirm I do understand your approach properly:

  1. Existing contrition icon is being downloaded to weather.gif file
  2. Converted to string
  3. Converted/replaced to png
  4. Output back again
  5. Downloaded icon deleted

Strange procedure and I do not understand it well. Could you explain again why string? Why to png? What if the icon will not be .gif some day?

Appreciate your answer.
Thank you

rule "Copy the conditions icon"
when
  Item vWeather_Conditions_Icon changed
then
    // Were to save the downloaded file
    val file = "/openhab/conf/icons/classic/weather.gif"

    // Download it using wget
    executeCommandLine("/usr/bin/wget -q -O " + file + " " + vWeather_Conditions_Icon.state.toString, 5000)

    // Convert from gif to png
    val input = new File(file)
    val output = new File(file.replace("gif", "png"))
    ImageIO::write( ImageIO::read(input), "png", output)

    // Remove the gif
    executeCommandLine("rm " + file)
end

The purpose of this procedure is to fetch the image from OpenWeatherMap and then use it as though it were one of the standard openHAB icons, like the temperature or humidity icons.
Those are png (or svg).

No. openHAB doesn’t create these image files. openHAB isn’t an image file processor or creator. openHAB isn’t able to magically create out of thin air details that do not exist in the original image so it scales nicer. And because the image is an icon it is appropriately sized for the the purpose for which it is intended.

You are attempting to use the icon image file in a way that it was not intended. I suppose no one has complained before because no one else is trying to use the icon image in this way.

Not quite.

  1. The weather binding sets the URL to the image file vWeather_Conditions_Icon Item which triggers the Rule.

  2. I execute wget using the executeCommandLine Action to download the file at that URL to a file to the path I saved to the file varaible: /openhab/conf/icons/classic/weather.gif

  3. I create two Objects that represents a File, input and output.

  4. I use the built in ImageIO library to read in the file at input and write out that image file in png format.

  5. I delete the gif.

I don’t know where you are getting this. There is no conversion to String anywhere. I saved the path to where I want to write the git file to a variable so I don’t have to keep retyping it. You will notice that file is used four times in that short Rule.

Because openHAB only supports png and svg formatted images to be used as icons in sitemaps.

Then the Rule would have to be rewritten if it is changed to a format that ImageIO doesn’t support.

Thank you very much for explanations. No let me try. I will come back if this gonna work :wink:

My system complains on File and ImageIO
Are these specific to openhab version or I am missing some lib?

    val input = new File(file)
    val output = new File(file.replace("gif", "png"))
    ImageIO::write( ImageIO::read(input), "png", output)

It’s a standard Java class. But you do have to import it.

import javax.imageio.ImageIO

right. Not complaining anymore. Thanks!

Unfortunately the rule does not work.

  • notification comes

  • the gif file is being created (is empty). The file is not being deleted so the error must be just after executeCommandLine

  • Following error comes:

==> /var/log/openhab2/openhab.log <==

2019-05-25 18:36:57.860 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Copy the conditions icon': image == null!
import javax.imageio.ImageIO;
import java.io.File; 

rule "Copy the conditions icon"

when
  Item localCurrentConditionIcon changed
then
    // Were to save the downloaded file
    sendNotification("mymail@domain.com", "Weather icon changed.")
    val file = "/etc/openhab2/icons/classic/tmp_weather.gif"

    // Download it using wget
    executeCommandLine("/usr/bin/wget -q -O " + file + " " + localCurrentConditionIcon.state.toString, 5000)

    // Convert from gif to png
    val input = new File(file)
    val output = new File(file.replace("gif", "png"))
    ImageIO::write( ImageIO::read(input), "png", output)

    // Remove the gif
    executeCommandLine("rm " + file)
end

item:

Image localCurrentConditionIcon "Icon" { channel="openweathermap:weather-and-forecast:api:local:current#icon" }

Add logging to determine which line it’s failing on and log out the contents of the Item and the results of the executeCommandLine. That will probably tell you what is going wrong.

log files attached.

Error captured at:

2019-05-26 15:37:27.302 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Copy the conditions icon': image == null!

unfortunately it does not tell me too much. Can you find any miss behavior?

log.txt (638.6 KB)

I think Rick may have been suggesting that you add some logging to your rule, at least to find what variables you are dealing with.
For example, it’d be a good idea to find out what the mysterious value is that you are trying to wget.

logInfo("test", "fetching icon " + localCurrentConditionIcon.state.toString)

Maybe the wget will tell us something interesting

val String results = executeCommandLine( ...... )
logInfo("test", "wget says " + results)

not exactly…@rlkoshak but really appreciate you spend time to support.

I placed log requests between the lines to see what is going on:

import javax.imageio.ImageIO;
import java.io.File; 

rule "Copy the conditions icon"

when
  Item localCurrentConditionIcon changed
then
    // Were to save the downloaded file
    sendNotification("mymail@domain.com", "Weather icon changed.")
    val file = "/etc/openhab2/icons/classic/tmp_weather.gif"

    // Download it using wget
    logWarn("icon_rescaling.rules", "Command Line execution start...")
    executeCommandLine("/usr/bin/wget -q -O " + file + " " + localCurrentConditionIcon.state.toString, 5000)
    logWarn("icon_rescaling.rules", "Command Line execution finish...")

    // Convert from gif to png
    logWarn("icon_rescaling.rules", "Conversion started...")
    val input = new File(file)
    val output = new File(file.replace("gif", "png"))
    ImageIO::write( ImageIO::read(input), "png", output)

    // Remove the gif
    executeCommandLine("rm " + file)

end

it seems it goes through all commands and last messages that might mean sth. are these messages:

2019-05-26 18:37:37.716 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 192 SocketChannelEndPoint@144a5a1{/192.168.1.139:64187<->/192.168.1.114:8443,OPEN,fill=-,flush=-,to=31/30000}{io=0/0,kio=0,kro=1}->SslConnection@24c508{NOT_HANDSHAKING,eio=-1/0,di=-1}=>HttpConnection@9ce503[p=HttpParser{s=END,0 of -1},g=HttpGenerator@2b3296{s=COMMITTED}]=>HttpChannelOverHttp@156b375{r=24,c=true,a=ASYNC_WAIT,uri=https://192.168.1.114:8443/rest/events,age=19363304}
2019-05-26 18:37:37.716 [WARN ] [me.model.script.icon_rescaling.rules] - Command Line execution finish...
2019-05-26 18:37:37.717 [DEBUG] [org.eclipse.jetty.io.WriteFlusher   ] - Flushed=true written=163 remaining=0 WriteFlusher@19bb65e{WRITING}->null
2019-05-26 18:37:37.719 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@bd7d7e[PROCESSING][i=null,cb=org.eclipse.jetty.server.HttpChannel$ContentCallback@16ead01] generate: DONE (null,[p=157,l=157,c=32768,r=0],false)@COMMITTED
2019-05-26 18:37:37.719 [WARN ] [me.model.script.icon_rescaling.rules] - Conversion started...
2019-05-26 18:37:37.722 [DEBUG] [org.eclipse.jetty.server.HttpChannel] - sendResponse info=null content=DirectByteBuffer@128f469[p=0,l=157,c=32768,r=157]={<<<event: message\nda...mStateEvent"}\n\n>>>nt"}\n\nAANSUhEUgAA...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00} complete=false committing=false callback=Blocker@95283f{null}
2019-05-26 18:37:37.724 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@108e52f[PROCESSING][i=null,cb=org.eclipse.jetty.server.HttpChannel$ContentCallback@47fe4c] generate: FLUSH (null,[p=0,l=157,c=32768,r=157],false)@COMMITTED
2019-05-26 18:37:37.726 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 157 SocketChannelEndPoint@1857719{/192.168.1.139:64255<->/192.168.1.114:8080,OPEN,fill=-,flush=W,to=32/30000}{io=0/0,kio=0,kro=1}->HttpConnection@14e7bea[p=HttpParser{s=END,0 of -1},g=HttpGenerator@1898bb3{s=COMMITTED}]=>HttpChannelOverHttp@1b6109a{r=1,c=true,a=ASYNC_WAIT,uri=//192.168.1.114:8080/rest/events?topics=smarthome/items,age=19343875}
2019-05-26 18:37:37.727 [DEBUG] [org.eclipse.jetty.io.WriteFlusher   ] - Flushed=true written=157 remaining=0 WriteFlusher@10ea63c{WRITING}->null

Unfortunately I am not familiar with java or/eclipse and can not figure out what is wrong.

log2.txt (322.6 KB)

Well, there are four lines of code after your last log statement which could be the source of the error.

The point of the logging is to:

  • figure out exactly what line is generating the error
  • what all the variables and values you are using on that line are
  • any output from that line

Without this information all we can do is guess.

Furthermore, rossko57 is right, we want to know what the other if the executeCommandLine is to know whether the wget succeeded or failed and if it failed to see why it failed.

@rossko57
placing INFO in log files gives this:

2019-05-31 15:40:18.606 [INFO ] [.eclipse.smarthome.model.script.test] - Command Line execution start...
2019-05-31 15:40:18.606 [DEBUG] [org.eclipse.jetty.server.HttpChannel] - COMPLETE for /icon/sun_clouds written=2154
2019-05-31 15:40:18.608 [DEBUG] [g.eclipse.jetty.io.ssl.SslConnection] - flush b[161]=6576656E743A206D6573736167650A646174613A207B22746F...656E74227D0A0A SslConnection@12db6e6{NOT_HANDSHAKING,eio=-1/-1,di=-1}=>HttpConnection@c276e0[p=HttpParser{s=END,0 of -1},g=HttpGenerator@106ccba{s=COMMITTED}]=>HttpChannelOverHttp@eb40c0{r=34,c=true,a=ASYNC_WAIT,uri=https://192.168.1.114:8443/rest/events,age=5793190}<-SocketChannelEndPoint@17bb5e5{/192.168.1.139:60240<->/192.168.1.114:8443,OPEN,fill=-,flush=-,to=63/30000}{io=0/0,kio=0,kro=1}->SslConnection@12db6e6{NOT_HANDSHAKING,eio=-1/-1,di=-1}=>HttpConnection@c276e0[p=HttpParser{s=END,0 of -1},g=HttpGenerator@106ccba{s=COMMITTED}]=>HttpChannelOverHttp@eb40c0{r=34,c=true,a=ASYNC_WAIT,uri=https://192.168.1.114:8443/rest/events,age=5793199}
2019-05-31 15:40:18.607 [DEBUG] [org.eclipse.jetty.server.HttpChannel] - COMMIT for /icon/my_clouds on HttpChannelOverHttp@c7bf39{r=5,c=true,a=DISPATCHED,uri=https://192.168.1.114:8443/icon/my_clouds?state=40%20%25&format=png,age=74}
200 null HTTP/1.1
Content-Type: image/png
Last-Modified: Fri, 31 May 2019 13:40:18 GMT
2019-05-31 15:40:18.609 [DEBUG] [clipse.jetty.server.HttpChannelState] - recycle HttpChannelState@14e80dc{s=COMPLETED a=NOT_ASYNC i=false r=IDLE w=false}
2019-05-31 15:40:18.609 [DEBUG] [io.socket.client.Manager            ] - writing packet io.socket.parser.Packet@50147c
2019-05-31 15:40:18.610 [DEBUG] [org.eclipse.jetty.http.HttpParser   ] - reset HttpParser{s=END,0 of -1}
2019-05-31 15:40:18.610 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@13d35af[PROCESSING][i=HTTP/1.1{s=200,h=2,cl=-1},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback@efedc3] generate: NEED_HEADER (null,[p=0,l=894,c=32768,r=894],false)@START
2019-05-31 15:40:18.611 [DEBUG] [io.socket.parser.Parser             ] - encoding packet io.socket.parser.Packet@50147c
2019-05-31 15:40:18.611 [DEBUG] [org.eclipse.jetty.http.HttpParser   ] - END --> START
2019-05-31 15:40:18.613 [DEBUG] [org.eclipse.jetty.server.HttpChannel] - HttpChannelOverHttp@17b5227{r=1,c=false,a=IDLE,uri=null,age=0} handle exit, result COMPLETE
2019-05-31 15:40:18.613 [DEBUG] [org.eclipse.jetty.http.HttpGenerator] - generateHeaders HTTP/1.1{s=200,h=2,cl=-1} last=false content=HeapByteBuffer@11ad59f[p=0,l=894,c=32768,r=894]={<<<\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00...\x9bp\x87\x00\x00\x00\x00IEND\xAeB`\x82>>>1j\xE5\xE2\xC4\xC7* \xCb\x9b3\xB2|\xCe$\xEb\xF5...tructural}),p.s}
2019-05-31 15:40:18.615 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - filled 0 SocketChannelEndPoint@395aaa{/192.168.1.139:61566<->/192.168.1.114:8443,OPEN,fill=-,flush=-,to=23/30000}{io=0/0,kio=0,kro=1}->SslConnection@581804{NOT_HANDSHAKING,eio=17408/-1,di=-1}=>HttpConnection@123019c[p=HttpParser{s=START,0 of -1},g=HttpGenerator@8285f5{s=START}]=>HttpChannelOverHttp@17b5227{r=1,c=false,a=IDLE,uri=null,age=0}
2019-05-31 15:40:18.615 [DEBUG] [org.eclipse.jetty.http.HttpGenerator] - Content-Type: image/png
Last-Modified: Fri, 31 May 2019 13:40:18 GMT
2019-05-31 15:40:18.615 [DEBUG] [io.socket.parser.Parser             ] - encoded io.socket.parser.Packet@50147c as 2["notification",{"message":"Weather icon changed.","userId":"jacek.debski@outlook.com"}]
2019-05-31 15:40:18.607 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - filled 0 SocketChannelEndPoint@1107f63{/192.168.1.139:61568<->/192.168.1.114:8443,OPEN,fill=-,flush=-,to=23/30000}{io=0/0,kio=0,kro=1}->SslConnection@191023e{NOT_HANDSHAKING,eio=17408/-1,di=-1}=>HttpConnection@19d5f1[p=HttpParser{s=START,0 of -1},g=HttpGenerator@17976ac{s=START}]=>HttpChannelOverHttp@1910503{r=1,c=false,a=IDLE,uri=null,age=0}
2019-05-31 15:40:18.618 [INFO ] [.eclipse.smarthome.model.script.test] - fetching icon raw type (image/png): 2565 bytes

seems there is sth. fetched

execute command returns “nothing visible”

2019-05-31 15:40:18.907 [DEBUG] [org.eclipse.jetty.io.ChannelEndPoint] - flushed 216 SocketChannelEndPoint@17bb5e5{/192.168.1.139:60240<->/192.168.1.114:8443,OPEN,fill=-,flush=-,to=17/30000}{io=0/0,kio=0,kro=1}->SslConnection@12db6e6{NOT_HANDSHAKING,eio=-1/0,di=-1}=>HttpConnection@c276e0[p=HttpParser{s=END,0 of -1},g=HttpGenerator@106ccba{s=COMMITTED}]=>HttpChannelOverHttp@eb40c0{r=34,c=true,a=ASYNC_WAIT,uri=https://192.168.1.114:8443/rest/events,age=5793498}
2019-05-31 15:40:18.908 [DEBUG] [org.eclipse.jetty.io.WriteFlusher   ] - Flushed=true written=187 remaining=0 WriteFlusher@fb759b{WRITING}->null
2019-05-31 15:40:18.910 [DEBUG] [.eclipse.jetty.server.HttpConnection] - org.eclipse.jetty.server.HttpConnection$SendCallback@295a94[PROCESSING][i=null,cb=org.eclipse.jetty.server.HttpChannel$ContentCallback@14ce590] generate: DONE (null,[p=181,l=181,c=32768,r=0],false)@COMMITTED
2019-05-31 15:40:19.155 [INFO ] [.eclipse.smarthome.model.script.test] - wget says
2019-05-31 15:40:19.157 [INFO ] [.eclipse.smarthome.model.script.test] - Command Line execution finish...
2019-05-31 15:40:19.162 [INFO ] [.eclipse.smarthome.model.script.test] - Conversion started...
2019-05-31 15:40:19.170 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Copy the conditions icon': image == null!

The whole logfile:
log3.txt (125.5 KB)

rule “then” code:

    // Were to save the downloaded file
    sendNotification("mymail@domain.com", "Weather icon changed.")
    val file = "/etc/openhab2/icons/classic/tmp_weather.gif"

    // Download it using wget
    logInfo("test", "Command Line execution start...")
    logInfo("test", "fetching icon " + localCurrentConditionIcon.state.toString)
    val String result = executeCommandLine("/usr/bin/wget -q -O " + file + " " + localCurrentConditionIcon.state.toString, 5000)
    logInfo("test", "wget says " + result)
    logInfo("test", "Command Line execution finish...")

    // Convert from gif to png
    logInfo("test", "Conversion started...")
    val input = new File(file)
    val output = new File(file.replace("gif", "png"))
    ImageIO::write( ImageIO::read(input), "png", output)
    logInfo("test", "Conversion finished...")
    // Remove the gif
    logInfo("test", "removing temp icon file...")
    executeCommandLine("rm " + file)
    logInfo("test", "temp icon file shall be removed...")

Okay, so is it your new File() or ImageIO that breaks?

new file is being created but it is empty. 0kB Script does not go into the rm +file command
I assume this is ImageIO that brakes.

Image has been received because we see as a result:

fetching icon raw type (image/png): 2565 bytes

Any idea?