RESTful Command to UVR16x2

Hello everyone,

I just logged in and haven’t introduced myself yet. I’m a bit older but also new here. My name is Nick, and I dabble in IT and “smart” stuff from time to time, mostly at home.

Anyway, currently, I’m trying to prevent my heater and my home battery from arguing with each other. Both are trying to consume the surplus PV power, with the battery system naturally being faster than the heater. Later on, the heater punishes it by ruthlessly draining it empty. Not ideal. It would be better if I could distribute the surplus power. Since I lack the appropriate system, I started integrating and rudimentarily controlling the systems. I found a guide regarding my heater here:
[Link to the guide]

However, I didn’t feel like installing Node-RED, so I wanted to solve everything using REST commands and automation. Based on the guide, I added the following entry to my configuration.yaml:

rest_command:
  sme_auto:
    url: http://username:password@ipaddress/menupage.cgi?page=0301580E&changeadr=039003301D&changeto=2
    method: GET

This link isn’t correct, but I can paste the one from my configuration.yaml into my browser, press Enter, and the action triggers on my heater. So, it should work.

I designed the automation as follows for testing:

alias: Test RESTful
description: ""
trigger: []
condition: []
action:
  - service: rest_command.sme_auto
    data: {}
mode: single

That’s all. As you can see, without any triggers. I have to manually trigger the automation. In my opinion, this should work. I’ve also restarted HA. But when I trigger the automation, my heater doesn’t respond. Since I’m stuck, I thought I’d reach out to you guys.

What happens if you call the service from Developer Tools / Service?

Hi

Hey, that’s really great, I hadn’t thought of that at all. I just tried it and it was also quoted with a green checkmark. However, nothing happened, so there was no reaction from the heater.

Have a look in your browser DevTools (usually F12) to see what the request headers are when you send the response. Then duplicate those in the rest command.

Perhaps you need to supply username and password separately rather than building it into the URL.

You are right. I tested that with the browser’s incognito mode. You actually have to log in first for any changes to take effect. But how do I do that now? I tried it here, but it seems to be incorrect.

rest_command:
  my_request:
    username: user
    password: pass
    url: http://ipadress/menupage.cgi?page=0301580E&changeadr=039003301D&changeto=1
    method: GET

Hi,

I’m writing here again because I could gather some information. It seems that with the x2 devices, unlike with the UVR1611 as mentioned in the post by @Holo_San, things are a bit different. For some reason, the TA seems to enjoy appending an x or x2 to them. So, for example:

menupage.cgi = menupagex.cgi
page = pagex2
changeadr = changeadrx2
changeto = changetox2

Additionally, I have created a rest_command.yaml , paying attention to the formatting, and tried the following:

my_request:
  url: http://username:password@ipaddress/menupagex.cgi?pagex2=01005800#01045800&changeadrx2=01000C40DA1202&changetox2=2
  verify_ssl: false

my_2_request:
  url: http://ipaddress/menupagex.cgi?pagex2=01005800#01045800&changeadrx2=01000C40DA1202&changetox2=2
  username: !secret cmi
  password: !secret cmi
  verify_ssl: false

When I enter this URL in the browser, even in incognito mode, even after clearing the cache, the URL works.

However, attempts with curl fail. By “fail” in this context, I mean that the desired change does not occur on the recipient’s side.

curl -X GET -u username:password http://ipaddress/menupagex.cgi?pagex2=01005800#01045800&changeadrx2=01000C40DA1202&changetox2=2

And also, the rest_command my_request and my_2_request fail. In the devtools under services, after triggering successfully, I receive a status 200. I have also contacted TA support now; perhaps they might know something.

just in case its still relevant for someone, i got it to work with rest commands:

cmi_circulation_pump_set_auto:
    url: "http://<cmi-ip>/INCLUDE/change.cgi?changeadrx2=<address>&changetox2=<valueToChangeTo>"
    method: get
    username: <user>
    password: <password>
    headers:
      accept: "*/*"
      Referer: 'http://<cmi-ip>/menupagex.cgi?nodex2=<nodeId>'

in the example above make sure to replace

  • <cmi-ip> with the ip of your cmi
  • <address> with the address of the node you want to change
  • <valueToChangeTo> Value that shall be set
  • <user> and <password> obviously
  • <nodeId> as the id of the page which you can take from the url when opening the web ui of your uvr : http://<ip>/menupagex.cgi?nodex2=<nodeid>#<someOtherId>, so just use the id until the #

Note that the referer must be in the headers, otherwise for me the command returned OK, but nothing changed.

In terms of the address and the nodeId I just reverse engineered the values from the developer tools of my browser (i started a recording which records all network activity) and just used the web ui of the uvr and set the according command.

Hope this helps someone.

1 Like

This works really well, :+1: I had invested a lot of time in this and had already given up when I discovered your post, and I have to admit: it was almost annoying how close I was to the solution. But this :point_down: solved everything.

    headers:
      accept: "*/*"
      Referer: ..

Thank you very much for your effort!


So I have something here for all solar fans. :v: :sunny:

1. The REST command

cmi_circulation_pump_set_volt:
    url: "http://<cmi-ip>/INCLUDE/change.cgi?changeadrx2={{ adr }}&changetox2={{ value }}"
    method: get
    username: <user>
    password: <password>
    headers:
      accept: "*/*"
      Referer: 'http://<cmi-ip>/menupagex.cgi?nodex2=<nodeId>'

Here we have placed the variables adr and value directly in the URL.

Example calls

For the manual/auto mode (address 01000C40DA1202):

service: rest_command.cmi_sme_a13_set
data:
  adr: "01000C40DA1202"
  value: "4"

For the voltage (address 01000C40D1C10D):

service: rest_command.cmi_sme_a13_set
data:
adr: "01000C40D1C10D"
value: "3.33"

But maybe that’s too complicated. It could be that you have a battery storage unit and there are a few clouds in the sky. So that you can now heat and charge the battery storage at the same time without buying electricity, I have this script here.

2. YAML script for calculation and triggering
The script remains unchanged because the calculation is correct and calls the REST command correctly:

script:      
  set_circulation_pump_volt:
    sequence:
      - variables:
          power_consumption: "{{ states('sensor.power_consumption_inverted') | float(0) }}"
          power_production: "{{ states('sensor.power_production') | float(0) }}"
          value: "{{ (power_consumption + power_production) / 1500 | round(2) }}"
          calculated_value: "{{ [0.00, [value, 10.00] | min] | max }}"
      - service: rest_command.cmi_circulation_pump_set_volt
        data:
          adr: "<address>"
          value: "{{ '%.2f' | format(calculated_value) }}"

You adjust the value 1500 to the maximum output of your heater. But because you want to use the battery storage at the same time, you calculate twice the output. Assuming your heater can produce a maximum of 7.5kW, the calculation is: 7500 / 10 * 2 = 1500. If you want the heater to be supplied with 100% of the power produced, enter 750; if 50% should go to the battery storage, enter 1500.

The automation for this should then look something like this…

automation:
  - alias: "Adjust voltage to production"
    trigger:
      - platform: state
        entity_id:
          - sensor.power_consumption
          - sensor.power_production
    condition:
      - condition: numeric_state
        entity_id: sensor.power_consumption
        above: 0
      - condition: numeric_state
        entity_id: sensor.power_production
        above: 0
    action:
      - service: script.set_circulation_pump_volt
    mode: single

I hope this is helpful to you in some way.