HTTP Binding + dimmer (robodyn)

I’m looking to add 20 dimmers (Robodyn) in OH3.3 through HTTP binding.

I successfully add the dimmer [Thing], status = online.
But, I don’t know how to set Advanced Configuration of the Thing in order to send/receive http commands (dim light). This dimmer is only an electronic board controlled by another NodeMCU 3.22 board (for wifi connection). I’m hopeless because of my lack of knowledge in understanding http protocols.

My project
REFERENCES


Summary:
Procedure from the dimmer producer.
Arduino code (to control dimmer).
Webpage generated by the Arduino code.
OH3 Thing settings - screenshot.
Wireshark - screenshot.


Procedure followed from the dimmer producer :
(Blog - Dimmer and ESP8266 with WEB interface. | robotdyn.com)


This is the code from Arduino / NodeMCU 3.22 board:

//=====
String sliderValue = "0";

const char* PARAM_INPUT = "value";
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Dimmer ESP Controller</title>
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 2.3rem;}
    p {font-size: 1.9rem;}
    body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
    .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
      outline: none; -webkit-transition: .2s; transition: opacity .2s;}
    .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
    .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; } 
    .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
  </style>
</head>
<body>
  <h2>Dimmer ESP Controller</h2>
  <p><span id="textSliderValue">%SLIDERVALUE%</span></p>
  <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="%SLIDERVALUE%" step="1" class="slider"></p>
  </br>
  <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
  
<script>
function updateSliderPWM(element) {
  var sliderValue = document.getElementById("pwmSlider").value;
  document.getElementById("textSliderValue").innerHTML = sliderValue;
  console.log(sliderValue);
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/slider?value="+sliderValue, true);
  xhr.send();
}
</script>
</body>
</html>
)rawliteral";

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if (var == "SLIDERVALUE"){
    return sliderValue;
  }
  return String();
}

//=================================================================== start HTTP_GET communication

   // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Send a GET request to <ESP_IP>/slider?value=<inputMessage>
  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET input1 value on <ESP_IP>/slider?value=<inputMessage>
    if (request->hasParam(PARAM_INPUT)) {
      inputMessage = request->getParam(PARAM_INPUT)->value();
      sliderValue = inputMessage;
//      analogWrite(output, sliderValue.toInt());
        dimmer.setPower(sliderValue.toInt());
    }
    else {
      inputMessage = "No message sent";
    }
    //Serial.println(inputMessage);
    Serial.println(sliderValue);
    request->send(200, "text/plain", "OK");
  });
  
  // Start server
  server.begin();
 //===== 
}

void loop() {
  // put your main code here, to run repeatedly:

}

This is webpage generated by the Arduino code. Page work perfectly, slides the light brightness.

image


This is the Thing configuration in OH3.3 which needs to be set in order to send commands to the dimmer controlled by the Arduino board.




This is Wireshark filtering traffic between through local wifi from my computer [192.168.1.5] (where the already presented screenshot with slider/webpage is running) to the dimmer [192.168.1.11]. OH3 is installed on a Raspebbery Pi [192.168.1.6]


Wireshark traffic between my computer [192.168.1.5] to OH3 / installed on Raspebbery Pi [192.168.1.6].

It would help more to understand the traffice between the different instances if you could upload the wireshark captured file - screenshots are not easy to read.
In case you do not want to upload the captured file as you may fear to give to much insight into your network then please:

  • do the capture again
  • click on the GET /slider?value=58 row
  • do follow TCP ( HTTP ) stream
    This should show the full header, body of the request and the answer for the full communication between both endpoints.

Here is video capture :

@Wolfgang_S , as we can see: from my computer [192.168.1.5] to Raspbbery Pi / OH3 [192.168.1.6] is not sent any value related to “slider?value=” to be received by the dimmer [192.168.1.11].

It means that Thing or Channel in OH3 is not correctly configured ?

The configuration of the thing is not correct yet.
The header section is meant for something else - so please remote /slider?value from there.
/slider?value=%2$ needs to be defined as commandExtension in channel definition

@Wolfgang_S
Found commandExtension. I added as you said:

But nothing changed (no value sent) when I move the slider of the dimmer in OH3 interface.

in previous post - as far as I understand - you wrote that no value is sent from your PC to the dimmer hardware. This indeed will not happen because:

  • the browser sends the info about which value the dimmer needs to be set to to OH ( that is the POST request )
  • the binding on OH server then will sent the value to the dimmer

What about the event.log and error.log file does it give any hint about a problem in the configuration ?

I’ll check logs and get back to you asap.

@Wolfgang_S , I have this error in log :

2022-08-11 18:03:09.791 [WARN ] [ttp.internal.http.RefreshingUrlCache] - Creating request for '192.168.1.11' failed: no protocol: 192.168.1.11

@Wolfgang_S , I’ve added “http://” in front of IP and start sending now, but there is still an error (see bellow: UNDEF).

UID: http:url:dimmerGates
label: Dimmer Gates
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: false
  headers:
    - ""
  baseURL: http://192.168.1.11
  delay: 0
  stateMethod: GET
  refresh: 1
  commandMethod: GET
  contentType: text/plain
  timeout: 3000
  bufferSize: 2048
channels:
  - id: dimmerGatesChannel
    channelTypeUID: http:dimmer
    label: Dimmer Channel
    description: ""
    configuration:
      commandExtension: /slider?value=%2$

Error here :

2022-08-11 18:10:12.549 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'DimmerGates_DimmerChannel' changed from 93 to UNDEF

I haven’t used http binding before that is why I need to collect the pieces for the puzzle as well …
I would assume that the definition for stateExtension is missing and the state that is read back results in UNDEF.
What is the URL to read the current value of the dimmer ?

@Wolfgang_S , I’ve played a little with settings of Channel (choose Follow, instead of Default) and now values in logs show that are changing, no more UNDEF.

2022-08-11 18:33:55.105 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'DimmerGates_DimmerChannel' changed from 73 to 69

But, the light not dimm at all.
Some strange think happenning: if from webpage I move slider of the dimmer to 100% light is opened full… but if I touch the slider from OH light closed completely, instead of dimming.

so it already reacts on the OH slider but not yet in the correct way ?
Do again a Wireshark network traffic capture to see what is sent from OH to the dimmer.

Yeap, you’re right. I’ll open Wireshark…

No values goes out… but, as I said before, something it’s happenning - I mean it reach the dimmer because close the light (no matter where slide is moved, that slider action close the light).

@Wolfgang_S : Here is the TRACE log for http.binding:

2022-08-11 19:44:02.722 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Requesting refresh (retry=false) from 'http://192.168.1.11' with timeout 3000ms
2022-08-11 19:44:02.723 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Sending to 'http://192.168.1.11': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.46.v20220331}, Content = {null}
2022-08-11 19:44:02.771 [TRACE] [p.internal.http.HttpResponseListener] - Received from 'http://192.168.1.11/': Code = {200}, Headers = {Content-Type: text/html, Connection: close, Accept-Ranges: none, Transfer-Encoding: chunked}, Content = {
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Dimmer ESP Controller</title>
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 2.3rem;}
    p {font-size: 1.9rem;}
    body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
    .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
      outline: none; -webkit-transition: .2s; transition: opacity .2s;}
    .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
    .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; } 
    .button { background-color: #003249; border: none; color: white; padding: 16px 40px;}
  </style>
</head>
<body>
  <h2>Dimmer ESP Controller</h2>
  <p><span id="textSliderValue"></span></p>
  <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="100" value="" step="1" class="slider"></p>
  </br>
  <p><a href=/output/on\><button class=\"button\">WiFi RST</button></a></p>
  
<script>
function updateSliderPWM(element) {
  var sliderValue = document.getElementById("pwmSlider").value;
  document.getElementById("textSliderValue").innerHTML = sliderValue;
  console.log(sliderValue);
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/slider?value="+sliderValue, true);
  xhr.send();
}
</script>
</body>
</html>
}

If I read correctly, we sent NULL value.

in sending should be ok as the body of the GET request is empty and the ‘content’ ( value/payload ) should be send via the URL parameter. The parameter should be appended to the URL but it is not shown there. Can you try and replace the %2$ with %2$s in commandExtension.

I cannot read the filter that is being set in the header of wireshark.
If I am not mistaken then the dimmer is not part of the filter which means data being sent to the dimmer will not be shown.

Wireshark is on my computer where I have opened OH GUI, since OH server is on the Raspbbery.
So, we can see only the traffic from my computer to Raspbbery and dimmer, not from Raspbbery to dimmer.

But, we can see that from GUI the command sent is “null”.
Maybe we have to add something here :

@Wolfgang_S
I think we have to fix this : Content = {null}

If content=NULL, means nothing is sent from GUI/my computer where OH is open to OH server /Raspbbery. Am I wrong ?