Use MQTT for Shelly Thermostatic Radiator Valves

Yes indeed that might be an option. But I had hoped the Shellies could do this out of the box. They are not really cheap after all...

Talking about this, I think I have misinterpreted the "desired temperature" that you can set for a specific timestamp via a profile. Suppose I activate those schedule_rules:

"0000-0123456-15"
"0700-0123456-20"
"0800-0123456-15"

That the result will be:

I have not had time to install my TRV to test this, but if this is the case then the TRV is less smart as a thought. Which means a profile would be used to set temperatures on the TRV automatically, instead of having to press manually on the physical TRV up/down buttons.

Of course then you could indeed measure a temperature sensor via Node-RED, and adjust in the morning the profile before you send it to the TRV. When it is cold outside, you have to move your switchpoints foreward because it will take more time to heaten up the room:

image

The only problem I see is that your Node-RED flow needs to learn how the room's heating time depends on the outside temperature. And to measure that, you need to send frequently requests to the TRV to get the current temperature. And that will drain the TRV battery fast...

That might be a good idea indeed yes, as soon as I have got it up and running...

I put together a very over-the-top flow (based on something totallyInformation said) and get this graph for each of my TRV's. The data is sent by the TRV, and sensor, not requested, when they feel like it (about every 1/2 an hour). The position line is the actual open position of the valve (between 0 - 100%). I have only been running this for the last day (the graph covers 24hrs) so it is too early to tell if I am going to learn anything. (but it was fun doing it)

image

The only problem I see is that your Node-RED flow needs to learn how the room's heating time depends on the outside temperature.

This is a problem with any system that tries to anticipate a start time, not only does the TRV need to be trained but so does your boiler. If you do come up with something I bet there are bunches of people who would be interested. The only way I have come up with is to use a lookup table, but it would take a fair while to compile the data required.

And to measure that, you need to send frequently requests to the TRV to get the current temperature

Just use the temperature from a temperature sensor (I use Aqara zigbee units which seem fairly accurate - sensor in graph)

1 Like

Don't want to too much off topic here, but you might ask your question in this discussion.

ext_t.enabled is indeed a temperature sensor external to the Shelly TRV. I use a room sensor I have built from an ESP8266, but of course, as long as the Shelly can see the temperature on the Network, it doesn't care where it comes from.

The Profile/Schedule event shows what the desired temperature needs to be at a certain time. I think there may possibly be (distancing myself from this statement) some kind of predictive algorithm for 'thinking forward', but details are distinctly fuzzy as far as I can tell.

I am a strong believer that when you have several 'intelligent' items working together, unless they are designed to do so, it is better if they are made dumb and a Co-ordinator used to act as the intelligence. I have always found that intelligent thing are more likely to fight rather than assist each other with no proper integration.

I also feel from my experiments that there is enough inertia in the heating system to allow jut on/off operation, which I control with Node-RED. Currently, it doesn't seem to need a Deadband for the Living Room. This would hopefully mean that operation of the TRV uses the least amount of power, so extending lifetime.

Basically, I am heading along a path that (I hope) will use the minimum of interaction with the TRV (with maximum control).

  1. Load Qty 5 Profiles/Schedules with x events in each to suit what is needed.
  2. Schedules can be selected via Node-RED Dashboard.
  3. Use of local external temperature sensor (never liked measuring temperature at the point of a heat source, they cross talk too much!)
  4. Use Node-RED to also monitor same local temperature and 'drive' the boiler.

(I am not a believer in leaving boilers on all the time 'as it is cheaper'. Higher dwelling internal temperatures mean higher losses. But there is a minimum temperature above which a dwelling should be kept to enable a reasonable recovery time after no occupation.)

  1. Develop predictive routines to help attain profile desired.

(Currently I change Water Tank temperature and Boiler temperature depending upon Outside Temperature - just a straight y=mx + c straight line graph. More complex models can be developed once the 'inertia' of the dwelling is modelled - if you want to go that far.)

  1. Doing the heavy lifting in one common place over which you have control is easier than in several other places over which you have no proper control, unless those different systems are designed to operate with each other and you can observe what is going on.

Just my tthoughts.

1 Like

I see that they also offer an offset setting:

TEMPERATURE OFFSET
There are two options you can tick to activate - Enable external temperature corrections endpoint http://192.168.207.208/ext_t?temp=measured tĀ° and Enable internal temperature compensation logic. The second feature helps to read the temperature correctly despite the proximity of the heat source. Below that, there is a texbox for you to enter the temperature offset you desire. The Shelly TRV measures the temperature of its immediate environment. For this reason, the Shelly TRV records a temperature slightly higher than the average temperature of your room. Input an offset value so that the Shelly TRV display the accurate, average room temperature.

Could this be useful perhaps?

It would be nice if you could share your updated flow, so I can "loot" some of your ideas :wink:

There is an article on auto-calibration of TRVs here Your TRV is lying to you: TRV auto-calibration - NotEnoughTech

While the TRVs and sensors used are zigbee the concept and ideas are still relevant and could be re-done for the Shellys with no bother.

I started looking at this because the TRVs used are the same as I use and there is a whole series of related articles.

1 Like

Sorry, I am following this thread but we have family visiting so computer time is limited.

Yes, I have seen the offset, but whichever way I do things, I am required to interrogate or update the TRV on a regular basis for the current temperature status. My idea is to only communicate with the TRV when I need to change something.

If I use the offset, I have to interrogate the TRV to update NR with the Current Temperature, or use the regular status message to see what the temperature is. If I use NR and the external source, I only have to communicate with the TRV when I want to change Open/Close and I hope to be able to reduce the sending of Status Message to conserve power.

Of course:

[{"id":"4f90b9a595b6f9b3","type":"inject","z":"29ddb158bef0fd2c","name":"Select current Profile","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[     {         \"schedule_profile\": 1,         \"profile_name\": \"Living Room\",         \"rules\": [             {                 \"days\": \"0123456\",                 \"time\": \"06:00\",                 \"temperature\": 19             },             {                 \"days\": \"0123456\",                 \"time\": \"08:00\",                 \"temperature\": 21             },             {                 \"days\": \"0123456\",                 \"time\": \"10:30\",                 \"temperature\": 19             },             {                 \"days\": \"0123456\",                 \"time\": \"15:00\",                 \"temperature\": 20             },             {                 \"days\": \"0123456\",                 \"time\": \"17:00\",                 \"temperature\": 21             },             {                 \"days\": \"0123456\",                 \"time\": \"18:00\",                 \"temperature\": 22             },             {                 \"days\": \"0123456\",                 \"time\": \"21:30\",                 \"temperature\": 16             }         ]     },     {         \"schedule_profile\": 2,         \"profile_name\": \"Living Room Weekend\",         \"rules\": [             {                 \"days\": \"06\",                 \"time\": \"07:00\",                 \"temperature\": 21             },             {                 \"days\": \"06\",                 \"time\": \"10:00\",                 \"temperature\": 20             },             {                 \"days\": \"06\",                 \"time\": \"16:00\",                 \"temperature\": 20             },             {                 \"days\": \"06\",                 \"time\": \"18:00\",                 \"temperature\": 22             },             {                 \"days\": \"06\",                 \"time\": \"22:00\",                 \"temperature\": 16             }         ]     },     {         \"schedule_profile\": 3,         \"profile_name\": \"AM Visitors\",         \"rules\": [             {                 \"days\": \"0123456\",                 \"time\": \"07:00\",                 \"temperature\": 21             },             {                 \"days\": \"0123456\",                 \"time\": \"13:00\",                 \"temperature\": 19             },             {                 \"days\": \"0123456\",                 \"time\": \"16:00\",                 \"temperature\": 20             },             {                 \"days\": \"0123456\",                 \"time\": \"18:00\",                 \"temperature\": 22             },             {                 \"days\": \"0123456\",                 \"time\": \"21:30\",                 \"temperature\": 16             }         ]     },     {         \"schedule_profile\": 4,         \"profile_name\": \"PM Visitors\",         \"rules\": [             {                 \"days\": \"0123456\",                 \"time\": \"07:00\",                 \"temperature\": 21             },             {                 \"days\": \"0123456\",                 \"time\": \"10:30\",                 \"temperature\": 19             },             {                 \"days\": \"0123456\",                 \"time\": \"12:00\",                 \"temperature\": 21             },             {                 \"days\": \"0123456\",                 \"time\": \"18:00\",                 \"temperature\": 22             },             {                 \"days\": \"0123456\",                 \"time\": \"21:30\",                 \"temperature\": 16             }         ]     },     {         \"schedule_profile\": 5,         \"profile_name\": \"Spare\",         \"rules\": [             {                 \"days\": \"06\",                 \"time\": \"11:30\",                 \"temperature\": 18             },             {                 \"days\": \"06\",                 \"time\": \"14:30\",                 \"temperature\": 20             },             {                 \"days\": \"06\",                 \"time\": \"22:30\",                 \"temperature\": 15             }         ]     }  ]","payloadType":"jsonata","x":410,"y":580,"wires":[["7af6b66a1c9f1fde"]]},{"id":"7af6b66a1c9f1fde","type":"function","z":"29ddb158bef0fd2c","name":"split file","func":"let profileSelected = (global.get('ZprofileSelect') - 1) || 0;\nmsg.payload = msg.payload[profileSelected];\nglobal.set('ZprofileEvents', msg.payload.rules);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":580,"wires":[["6748bf65c6058e19","ca44a403f52e4783"]]},{"id":"e1a0b7a516aa8e84","type":"inject","z":"29ddb158bef0fd2c","name":"Profile 1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":180,"y":520,"wires":[["be2574bab2b971c1"]]},{"id":"4e777a15c7947d51","type":"inject","z":"29ddb158bef0fd2c","name":"Profile 2","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"2","payloadType":"num","x":180,"y":560,"wires":[["be2574bab2b971c1"]]},{"id":"a33af1209e1b80e1","type":"inject","z":"29ddb158bef0fd2c","name":"Profile 3","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"3","payloadType":"num","x":180,"y":600,"wires":[["be2574bab2b971c1"]]},{"id":"4b9692153e429c8c","type":"inject","z":"29ddb158bef0fd2c","name":"Profile 4","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"4","payloadType":"num","x":180,"y":640,"wires":[["be2574bab2b971c1"]]},{"id":"5987db1c2ede4c6a","type":"inject","z":"29ddb158bef0fd2c","name":"Profile 5","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"5","payloadType":"num","x":180,"y":680,"wires":[["be2574bab2b971c1"]]},{"id":"be2574bab2b971c1","type":"change","z":"29ddb158bef0fd2c","name":"Set Profile","rules":[{"t":"set","p":"ZprofileSelect","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":520,"wires":[["ef9a5ec91786e7cb"]]},{"id":"ef9a5ec91786e7cb","type":"debug","z":"29ddb158bef0fd2c","name":"debug 123","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":520,"wires":[]},{"id":"6748bf65c6058e19","type":"debug","z":"29ddb158bef0fd2c","name":"debug 124","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":540,"wires":[]},{"id":"ca44a403f52e4783","type":"function","z":"29ddb158bef0fd2c","name":"set Profile time/deg/days","func":"let eventTime;\nlet eventTimeNC;\nlet eventTemp;\nlet eventDays;\nlet eventString = \"\";\nlet arr = msg.payload.rules;\nlet elements = arr.length;\n\nlet profileNumber = msg.payload.schedule_profile;\nlet profileName = msg.payload.profile_name;\n\nfor (let i = 0; i < elements; i++) {\n    eventTime = msg.payload.rules[i].time;\n    //Remove Colon, Shelly doesn't like\n    eventTimeNC = eventTime.replace(\":\", \"\")\n    eventTemp = msg.payload.rules[i].temperature;\n    eventDays = msg.payload.rules[i].days;\n    eventString = eventString + eventTimeNC + \"-\" + eventDays + \"-\" + eventTemp\n    if (i < elements-1){\n        eventString = eventString + \",\";\n    }\n}\n\nlet messageString = \"http://XXX.XXX.XXX.XXX/settings/thermostat/0?schedule_profile=\" + profileNumber + \"&profile_name=\" + profileName + \"&schedule_rules=\" + eventString\nmsg.url = messageString;\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":580,"wires":[["64f33d3f8e5e561e","73185e4573535fba","5a17e1334ef54a25","3aa3ef0e2d9aa6b4"]]},{"id":"64f33d3f8e5e561e","type":"debug","z":"29ddb158bef0fd2c","name":"debug 125","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"url","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":540,"wires":[]},{"id":"1b7ae76f21b65952","type":"comment","z":"29ddb158bef0fd2c","name":"Select desired Profile (1-5)","info":"","x":370,"y":480,"wires":[]},{"id":"6b7544e1f9b0aa6c","type":"comment","z":"29ddb158bef0fd2c","name":"Assemble message for TRV from JSON","info":"","x":550,"y":620,"wires":[]},{"id":"73185e4573535fba","type":"function","z":"29ddb158bef0fd2c","name":"set CH time/deg/days","func":"let length;\nlet setHours;\nlet setMinutes;\nlet eventTime;\nlet eventDay;\nlet timeEvent;\nlet arr = global.get('ZprofileEvents');\n//CH background temp.\nlet tempDesired\nif (tempDesired === undefined) {\n    tempDesired = 16;\n}\n\n//Get current day start and end timestamp\nlet dateNow = Date.now();\nlet timeFrom = new Date(dateNow).setHours(0, 0, 0, 0);\nlet timeTo = new Date(dateNow).setHours(23, 59, 59, 0);\n\nconst d = new Date();\nlet day = ((d.getDay() + 7) - 1) % 7;\n\n//Add offset, iterate until file time < current time\nfor (let i = arr.length - 1; i >= 0; i--) {\n    eventTime = arr[i].time;\n    eventDay = arr[i].days\n    msg.test1 = eventTime;\n    setHours = eventTime.slice(0, 2);\n    setMinutes = eventTime.slice(3);\n    timeEvent = new Date(timeFrom).setHours(setHours, setMinutes, 0, 0); //Date from midnight this morning\n    tempDesired = parseFloat(arr[i].temperature);\n    msg.tempDesired = tempDesired;\n    msg.dateNow = dateNow;\n    msg.timeEvent = timeEvent;\n    msg.dayNow = day;\n    //msg.dayNow = eventDay.includes(day);\n\n\n    if (i === 0 && (dateNow < timeEvent)) {\n        tempDesired = parseFloat(arr[arr.length - 1].temperature);\n        global.set('ZtempDesiredCH',);\n        node.status({ text: timeEvent + \" | \" + tempDesired + \" | \" + \"<<<<<\" });\n        return msg\n    }\n    else if (dateNow > timeEvent && eventDay.includes(day)) {\n        global.set('ZtempDesiredCH', tempDesired, 'storeInFile');\n        node.status({ text: timeEvent + \" | \" + tempDesired });\n        return msg\n    }\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":660,"wires":[["d19584808941f204"]]},{"id":"d5cc96591e11e507","type":"debug","z":"29ddb158bef0fd2c","name":"debug 126","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":540,"wires":[]},{"id":"dd6d14f02e5c9077","type":"inject","z":"29ddb158bef0fd2c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":620,"y":660,"wires":[["73185e4573535fba"]]},{"id":"5a17e1334ef54a25","type":"debug","z":"29ddb158bef0fd2c","name":"debug 127","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1090,"y":620,"wires":[]},{"id":"212226c1473cf92e","type":"comment","z":"29ddb158bef0fd2c","name":"CH tempDesired","info":"","x":480,"y":700,"wires":[]},{"id":"3aa3ef0e2d9aa6b4","type":"http request","z":"29ddb158bef0fd2c","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"","persist":false,"insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":1090,"y":580,"wires":[["d5cc96591e11e507"]]},{"id":"d19584808941f204","type":"debug","z":"29ddb158bef0fd2c","name":"debug 128","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":680,"wires":[]},{"id":"effb4dbd1604ac66","type":"comment","z":"29ddb158bef0fd2c","name":"using JSON","info":"","x":170,"y":480,"wires":[]}]

'Select desired profile' will allow changing selected profile by sending just a number.
'Assemble message for TRV' removes Colon from the time for the Shelly
'CHtempDesired' is the current temperature desired for the boiler control side of things (OTGW)

I will read @Buckskin link, hopefully today, but I have an inkling of what it is going to say. Solving problems with accurate temperature control was part of my role when I was working. This is the reason that I don't have much faith in temperature sensors being linked to the control unit right next to the heat source. Convenient, but not necessarily that accurate. Having said that, my expectations regarding temperature control are very high!

Keep asking and challenging, it makes me think!

Get this week out of the way and Family commitments drop off to allow more time to 'play'. I want to test the 'Combined Profile' for switching things on/off on different days at different times in the same Profile.

1 Like

Thinking about this at it's most basic level, I guess that I am really only needing a Dumb battery operated TRV with some form of wireless communication for the Main room. Being able to switch the valve Open/Closed would be adequate.

The positional control is something that I think is not required with the 'inertia' of the Main room.

However, a smaller/minor room, not hooked into NR, would benefit from the Profiles and positional control as it could monitor itself using the Profile. The temperature control is probably not as critical for comfort. If the radiator needs heat, but the Main room is up to temperature, then you would need some form of feedback to turn the boiler on. An update frequency of one minute would be more than adequate, even stretching to five or ten minutes, I can't see a problem. iirc In Tasmota, you can change the frequency/period at which status updates are sent, I will look for similar in Shelly. Need to investigate this.

BTW - Family responsibilities have reduced - we have the house to ourselves again.

I think you are aware that this is theoretically not possible :wink:
Think that you better start a new thread. Otherwise this one becomes unreadable. And you will attract more people with a good subject.

1 Like

Agreed. Removed comment and saved for another time!

1 Like

I have changed the last Node, the one that drives the Boiler and Diverter Valve part of the flow, to include the Day so that it will grab the correct day dependent event from the Profile.

[{"id":"fa0523632e083abe","type":"function","z":"29ddb158bef0fd2c","name":"set CH time/deg/days","func":"let length;\nlet setHours;\nlet setMinutes;\nlet eventTime;\nlet eventDay;\nlet timeEvent;\nlet arr = global.get('ZprofileEvents');\n//CH background temp.\nlet tempDesired\nif (tempDesired === undefined){\n    tempDesired = 16;\n}\n\n//Get current day start and end timestamp\nlet dateNow = Date.now();\nlet timeFrom = new Date(dateNow).setHours(0, 0, 0, 0);\nlet timeTo = new Date(dateNow).setHours(23, 59, 59, 0);\n\nconst d = new Date();\nlet day = ((d.getDay() + 7) - 1) % 7;\n\n//Add offset, iterate until file time < current time\nfor (let i = arr.length - 1; i >= 0; i--) {\n    eventTime = arr[i].time;\n    eventDay = arr[i].days\n    msg.test1 = eventTime;\n    setHours = eventTime.slice(0, 2);\n    setMinutes = eventTime.slice(3);\n    timeEvent = new Date(timeFrom).setHours(setHours, setMinutes, 0, 0); //Date from midnight this morning\n    tempDesired = parseFloat(arr[i].temperature);\n    msg.tempDesired = tempDesired;\n    msg.dateNow = dateNow;\n    msg.timeEvent = timeEvent;\n    msg.dayNow = day;\n    //msg.dayNow = eventDay.includes(day);\n\n\n    if (i === 0 && (dateNow < timeEvent)) {\n        tempDesired = parseFloat(arr[arr.length - 1].temperature);\n        global.set('ZtempDesiredCH', );\n        node.status({ text: timeEvent + \" | \" + tempDesired + \" | \" + \"<<<<<\" });\n        return msg\n    }\n    else if (dateNow > timeEvent && eventDay.includes(day)) {\n        global.set('ZtempDesiredCH', tempDesired, 'storeInFile');\n        node.status({ text: timeEvent + \" | \" + tempDesired });\n        return msg\n    } \n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":840,"wires":[[]]}]

            {
                "days": "01234",
                "time": "10:30",
                "temperature": 19
            },
            {
                "days": "56",
                "time": "10:30",
                "temperature": 20
            }

In your new function you have

let day = d.getDay() - 1

to get yesterday. This will give you -1 on Sundays, try

((d.getDay() + 7) - 1) % 7
1 Like

I was going to find that out tomorrow! :lol

Thank you.

EDIT: as predicted, it failed! Luckily, I had the fix at hand :rofl: Thank you @Buckskin

Just checked this configuration for the JSON and the temperatures are running correctly with 19deg during the week and 20deg at the weekend.

1 Like

@Buckskin, @mudwalker,

Really need to install it now, because my TRV is still not in use yet.

But kind of confused at the moment.

So I can enable a schedule via a http request, so the thermostat will switch from temperature automatically at those specified setpoints. But I can also set a specific temperature via a http request. But not sure if that will automatically disable my schedule. And I can set a temperature manually via the buttons on the trv, which will override the schedule until the next switchpoint in the schedule.

But not sure:

  • Which parameters I need to send when I want to request a fixed target temperature. Do I need to disable the current schedule myself, or is that automatically ...
  • Which parameters I need to send when I want to request a schedule. Do I need to disable the current fixed temperature myself, or is that automatically ...
  • And if somebody sets a manual temperature on the trv using the buttons. How do I get informed about that, so I can make sure my button in my dashboard reflects that current status correctly?

Those url parameters drive me crazy...

Thanks a lot!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Bart, I do not have a Shelly but looking at the docs (MQTT command topics) I think that setting a new target_t.value should do the trick..
To request a schedule, schedule: true (or 1 if using MQTT)
As far as the temperature by button, the docs are very confusing but I would check t_auto.enabled as it looks as though that is probably the indicator of a manual setting.

Personally I would get to grips with MQTT on the Shelly as I consider this a much more civilised method of communication.

If Shelly ever start releasing devices using Zigbee I would consider getting some as the control interface is a lot more sophisticated (if confusing) than the TRVs I use at the moment (particularly the option to use an external sensor as a control).

Sorry I can't be more helpful

1 Like

Have you tried the Shelly nodes Bart?

@BartButenaers Give me until later today, I will address each question. Just need to search my flows.

I think that setting a new target_t.value should do the trick..
I agree, see the flow I sent LR Temp.

To request a schedule, schedule: true (or 1 if using MQTT)
If you look at the flow (post #50) in this thread and see node 'set Profile time/deg/days'. this will change the profile being used to be sent by http request.

I would check t_auto.enabled as it looks as though that is probably the indicator of a manual setting
Again, I agree. If you get the Status, you can check this.

As to the buttons setting temperature, I completely ignore these as I do it through MQTT, so I don't even need to get up from my chair! :laughing: :joy:

I do hope that helps, but please ask away!!

just in case you haven't seen this link:

TVR http requests