HTTP commandTransformation XML

Hey there,

I would like to send XML code to a device via HTTP binding.
I manually created a Thing:

Thing http:url:MoehlenhoffCacheChangesEG "MoehlenhoffCacheChangesEG" [ baseURL="http://192.168.1.3/data/changes.xml"]  {        
   Channels:  
      Type number : FBH_Wohnen_SOLL [ commandTransformation="magic stuff here" ]   
      Type number : FBH_WC_SOLL [ commandTransformation="magic stuff here" ]   
 	  
}

The Item Linked to it looks like:
// SOLL TEMPERATUREN FBH

Number FBH_Wohnen_SOLL "Wohnen [%s]" { channel="http:url:MoehlenhoffCacheStaticEG:FBH_Wohnen_SOLL", channel="http:url:MoehlenhoffCacheChangesEG:FBH_Wohnen_SOLL  }
Number FBH_WC_SOLL "WC [%s]" { channel="http:url:MoehlenhoffCacheStaticEG:FBH_WC_SOLL", channel="http:url:MoehlenhoffCacheChangesEG:FBH_WC_SOLL }

so when I set a new value for the Item
Number FBH_Wohnen_SOLL "Wohnen [%s]"

I would like to send the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<Devices>
  <Device>
    <ID>FIXID</ID>
    <HEATAREA nr="7">
      <T_TARGET>THIS_VALUE_COMES_FROM_THE_LINKED_NUMBER_ITEM</T_TARGET>
    </HEATAREA>
  </Device>
</Devices>

T_TARGET should be value of the Item. All other is fix Xml code.
And then send it to the device via:

Channels:  
      Type number : FBH_Wohnen_SOLL [ commandTransformation="magic stuff here" ]

any tips appreciated

Your magic stuff could be a JS script (JavaScript transformation) that concatenates the XML part before the value, the value and the XML part after the value.

@J-N-K
so it not possible to concat directly in the commandTransformation?
like
commandTransformation=""string1" + item.state.toString + "string2""
if this does work … I didn’t find the correct way how to put it in there and how to escape stuff.

and no way around to call a JS?
So must look like this?
commandTransformation: JS:myCmd.js

thanks

Yes, unfortunately that is not possible at the moment. Maybe a formatBeforeSend like the MQTT binding implements would be a good idea. However, for a complete XML this is probably not a perfect fit, either.

My choice would be a new formatTransformation, which takes an input file, applies String.format on that file with value (probably transformed by other transformations before) as parameter. Unfortunately that transformation does not exist in openHAB.

ok thanks
the Docs are not too lenghty
https://www.openhab.org/addons/transformations/javascript/

I guess my (input) is just the value of the item itself then?
If I make 1 JS per room this works but If I want to use just one JS for all the room heatings I would need a reference within the JS by what Item or Channel it was triggered to slightly modify the first part of the xml aswell.
The part before the value in the XML has a number (Heatarea) which is for the individual room.

Example:

Channel:
Type number : FBH_Wohnen_SOLL [ commandTransformation="SOLLwert.js ]
Type number : FBH_Schlafen_SOLL [ commandTransformation="SOLLwert.js ]

Concat in the JS
Triggered by FBH_Wohnen_SOLL

<?xml version="1.0" encoding="UTF-8"?><Devices><Device><ID>fixed</ID><HEATAREA nr="1"><T_TARGET>" 
+ value from the input item + 
</T_TARGET></HEATAREA></Device></Devices>

Triggered by FBH_Wohnen_SOLL

<?xml version="1.0" encoding="UTF-8"?><Devices><Device><ID>fixed</ID><HEATAREA nr="2"><T_TARGET>" 
+ value from the input item + 
</T_TARGET></HEATAREA></Device></Devices>

Is that possible?
Cheers

edit:

(function(i) {
  var str1 = "xmlpart1";
  var str3 = "xmlpart3";
  result = str1 + i + str3;
  return result;
})(input)

probably this should be the script for a single room.
and “xmlpart1” should be filled by a case statement where the triggering item is considered.
just don’t know how :slight_smile:

@J-N-K
Ok I tried the above for a single room.
Unfortunately I am not there yet.
I see 2 issues.

  1. I get an error in the log
16:33:25.388 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'FBH_BueroUG_SOLL' received command 20.0
16:33:25.391 [INFO ] [openhab.event.ItemStatePredictedEvent] - Item 'FBH_BueroUG_SOLL' predicted to become 20.0
16:33:25.394 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'FBH_BueroUG_SOLL' changed from 24.8 to 20.0
16:33:28.509 [WARN ] [tp.internal.http.HttpResponseListener] - Requesting 'http://192.168.1.4/data/static.xml' (method='GET', content='null') failed: HttpConnectionOverHTTP@31ab14c7::SocketChannelEndPoint@411db89{/192.168.1.4:80<->/192.168.1.1:43630,ISHUT,fill=-,flush=-,to=1/0}{io=0/0,kio=0,kro=1}->HttpConnectionOverHTTP@31ab14c7(l:/192.168.1.1:43630 <-> r:/192.168.1.4:80,closed=false)=>HttpChannelOverHTTP@455a0017(exchange=HttpExchange@711d6a50 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP

The error shows method=GET… I actually defined the thing to be “POST”:

Thing http:url:MoehlenhoffCacheChangesOG "MoehlenhoffCacheChangesOG" [ baseURL="http://192.168.1.4/data/changes.xml", commandMethod="POST"]  {        
   Channels:
  1. the error shows up every 30 seconds in the log.
    But this Thing/Channel is not configured with a refresh parameter?
    (For the same item there is another Thing/Channel defined which actually has a refresh of 30 secs …however I would expect that this only applies for the channel where it is configured?)

sigh

If you use the channel only for sending commands, set it to WRITEONLY, otherwise there will be a request every refresh seconds (as configured in the thing configuration).

thanks: one problem solved it seems :slight_smile:
also now It updated the thing it seems and shows a POST.

Unfortunately I still don’t get the base unit to accept it:

6:49:11.435 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'FBH_BueroUG_SOLL' received command 20.0
16:49:11.446 [INFO ] [openhab.event.ItemStatePredictedEvent] - Item 'FBH_BueroUG_SOLL' predicted to become 20.0
16:49:11.449 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'FBH_BueroUG_SOLL' changed from 24.0 to 20.0
16:49:14.640 [WARN ] [tp.internal.http.HttpResponseListener] - Requesting 'http://192.168.1.4/data/changes.xml' (method='POST', content='org.eclipse.jetty.client.util.StringContentProvider@60a753cc') failed: Total timeout 3000 ms elapsed

edit:
I didn’t change anything … just tried another time and now it shows method GET again in the log … super strange

16:56:38.144 [WARN ] [tp.internal.http.HttpResponseListener] - Requesting 'http://192.168.1.4/data/static.xml' (method='GET', content='null') failed: HttpConnectionOverHTTP@4144fb7d::SocketChannelEndPoint@53ec411b{/192.168.1.4:80<->/192.168.1.1:46084,ISHUT,fill=-,flush=-,to=0/0}{io=0/0,kio=0,kro=1}->HttpConnectionOverHTTP@4144fb7d(l:/192.168.1.1:46084 <-> r:/192.168.1.4:80,closed=false)=>HttpChannelOverHTTP@4b8d7141(exchange=HttpExchange@424b755b req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@6cf66d7b(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@5d231d67{s=START}],recv=HttpReceiverOverHTTP@7d8468fb(rsp=CONTENT,failure=null)[HttpParser{s=CLOSED,7396 of 16960}]]

edit 2:
I still see the WARN in the log
but the base unit actually gets the value !
So I guess the WARN is about the Answer from the base unit.
The manual say (sorry german) that the unit responds.

Is there a way to do something with the response? at least suppress the WARN or something? hopefully my final question.
Thank you @J-N-K or guiding me to this point :slight_smile: happy already :smiley:
I will write up a small tutorial for the forum and post it so others can copy if needed.

You shouldn’t see GET requests for WRITEONLY channels. My best advice at that point is restarting openHAB. I have seen things not properly disposed when textual configuration is used, so it could be that the warnings are GET requests from a channel that should have been discarded.

1 Like

Were you able to write a small tutorial on how to XML Posts via HTTP?