Transforming JSON number into Number item

Hey,

I’m trying to bring values from velux ( Options for connecting Velux Active KIX 300 (via homekit?) ) into openhab without learning all the osgi addon writing. My idea was to have a program (some go binary using swagger definition to call the API) which produces a json file. Then read this via the exec binding and transform it into Items.

That all works but I can only produce a String - not a Number

// what I want
Number:Temperature VeluxBedroomTemperature
    "Schlafzimmer Temperatur [%.1f %C]"
    <temperature>
    (Bedroom, gTemperature)
    {channel="exec:command:velux-temperature-bedroom:output", alexa="CurrentTemperature"}

// what works
String VeluxBedroomTemperature2
    "Schlafzimmer Temperatur 2"
    (Bedroom)
    {channel="exec:command:velux-temperature-bedroom:output"}

Things I tried:

// one thing per input value with JSONPATH (that would be nice)
Thing exec:command:velux-co2-bedroom [command="cat /openhab/conf/velux-state.json", transform="JSONPATH($.Co2.Bedroom)", interval=30]
Thing exec:command:velux-temperature-bedroom [command="cat /openhab/conf/velux-state.json", transform="JSONPATH($.Temperature.Bedroom)", interval=30]

// reading the full state into one output and splitting in Item
Thing exec:command:velux [command="cat /openhab/conf/velux-state.json", interval=30]

// transforming using JS
Thing exec:command:velux-temp-bedroom [command="cat /openhab/conf/velux-state.json", transform="JS(jsonextract.js)", autorun=true]

Items I tried

String TestOutput1a "temp 1a" (Bedroom) {channel="exec:command:velux-temp-bedroom:output"}
Number TestOutput1b "temp 1b" (Bedroom) {channel="exec:command:velux-temp-bedroom:output"}

String TestOutput2a "temp 2a [%s]" (Bedroom) {channel="exec:command:velux-temp-bedroom:output"}
Number TestOutput2b "temp 2b [%s]" (Bedroom) {channel="exec:command:velux-temp-bedroom:output"}

String TestOutput3a "temp 3a" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JSONPATH", function="JSONPATH($.Temperature.Bedroom):%s"]}
Number TestOutput3b "temp 3b" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JSONPATH", function="JSONPATH($.Temperature.Bedroom):%s"]}

String TestOutput4a "temp 4a [JSONPATH($.Temperature.Bedroom):%s]" (Bedroom) {channel="exec:command:velux:output"}
Number TestOutput4b "temp 4b [JSONPATH($.Temperature.Bedroom):%d]" (Bedroom) {channel="exec:command:velux:output"}

String TestOutput5a "temp 5a" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JSONPATH", function="JSONPATH($.Temperature.Bedroom)"]}
Number TestOutput5b "temp 5b" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JSONPATH", function="JSONPATH($.Temperature.Bedroom)"]}

String TestOutput6a "temp 6a" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JS", function="jsonextract.js"]}
Number TestOutput6b "temp 6b" (Bedroom) {channel="exec:command:velux:output"[profile="transform:JS", function="jsonextract.js"]}

String TestOutput7a "temp 7a" (Bedroom) {channel="exec:command:velux-temperature-bedroom:output"}
Number TestOutput7b "temp 7b" (Bedroom) {channel="exec:command:velux-temperature-bedroom:output"}

jsonextract.js transform

(function(i) {
    return parseInt(JSON.parse(i)["Temperature"]["Bedroom"])/10;
})(input)

Results

  • All Number items do not work :frowning:
  • 1a, 2a, 4a, 6a, 7a show the temperature but just as string (some of them of course don’t do the divide by 10 - but that’s expected)
  • 5a and 3a just return the full json blob
  • 3a, 4a and 5a contain the full json blob as state

I’m out of ideas. Sure I can create a rule which just converts the string state of one item into a Number state in another item but thats sounds super ugly.

I could try to use mqtt or http instead of exec - but that makes my program more complicated.

any Ideas?

exec binding always returns a string in output channel.

What you would like is a profile you could link to the channel, that parses to “real” Number. Unfortunately that doesn’t exist yet, it would be generally useful.

I’d live with a rule and revisit if ever profile handles numbers.

thank you @rossko57 ! that helped :slight_smile:

I have now:

Thing exec:command:velux [command="cat /openhab/conf/velux-state.json", interval=30]
String TestExec2 (Bedroom) {channel="exec:command:velux:output"}

Number:Temperature VeluxBedroomTemperature
    "Schlafzimmer Temperatur [%.1f °C]"
    <temperature>
    (Bedroom, gSensors, gTemperature)
    {alexa="CurrentTemperature"}

Number VeluxBedroomCo2
    "Schlafzimmer Co2 [%s]"
    (Bedroom, gSensors, gCo2)

and the rule for copying from TestExec2 into the right Number items:

rule "velux item update"
when
   Item TestExec2 changed 
then
  val jsonstate = triggeringItem.state.toString
  logInfo("velux item update", jsonstate)

  val temp = transform("JSONPATH", "$.Temperature.Bedroom", jsonstate)
  VeluxBedroomTemperature.postUpdate(Integer::parseInt(temp)/10.0)

  val co2 = transform("JSONPATH", "$.Co2.Bedroom", jsonstate)
  VeluxBedroomCo2.postUpdate(Integer::parseInt(co2))
  ...
end

That works nicely

1 Like