Closed lukazareba closed 1 year ago
I can't decipher how the "api" 😆 would do this. By reverse-engineering the UI, I came up with:
curl -s http://infinitude/systems.json | jq '.system[0].config[0].heatsource[0] = "odu only"' | curl http://infinitude/systems/infinitude -d @-
To force it to heat pump only. For aux/gas heat use "idu only"
and for system in control, "system"
.
The method @thekev mentions will work and if you're willing to the mutations in jq it's the most flexible. However the (apparently laughable) api will do the json merge for you if you'd rather not do it yourself. I think the equivalent api call would be /api/config/?heatsource=odu only
(and yes, mutations should not be allowed on GET - but Infinitude supports that since many automation controllers are unable to generate POST/PUT)
https://github.com/nebulous/infinitude/wiki/Infinitude-API-calls
(apparently laughable) api
I tried posting json fragments to /api/config
and it temporarily corrupted the xml config. The code path for /api/*variable_path
is quite generic, lacks validation (curl 'http://infinitude/api/config' -d heatsource=hamster
), and documentation is limited. My 😆 wasn't meant to be personal. I apologize for my choice of words, and do appreciate your efforts.
I was able to modify the heatsource
as you described, using both post and get. Thanks for your assistance.
So turns out heat source isn’t actually updating on the thermostat via /api/config?heatsource
. I can see in the UI and /api/config
JSON that the value is being changed, but the thermostat stays the same. However, if I set it in the UI, the thermostat does update. My ugly curl|jq|curl
mutation above also is effective.
An example: curl 'http://localhost:3001/api/config?heatsource=odu%20only'
. @nebulous How can I help debug this? (I used to write Perl, but it’s been 10 years or so).
Yeah, that’s because the changed flag isn’t being set on GET. If you use PUT or POST it will be, or if you change anything else in the stat to force a change event, or if I change the code to stop disallowing mutations on GET or to have a flag to force a change cycle. Another contributor made the change to disallow GET mutations, which is the more correct behavior, but sometimes one just wants to bend the rules to getThingsDone. I’m open to hearing preferences in this regard.
On Mar 11, 2023, at 12:55 AM, Kevin Blackham @.***> wrote:
So turns out heat source isn’t actually updating on the thermostat via /api/config?heatsource. I can see in the UI and /api/config JSON that the value is being changed, but the thermostat stays the same. However, if I set it in the UI, the thermostat does update. My ugly curl|jq|curl mutation above also is effective.
An example: curl 'http://localhost:3001/api/config?heatsource=odu%20only'. @nebulous https://github.com/nebulous How can I help debug this? (I used to write Perl, but it’s been 10 years or so).
— Reply to this email directly, view it on GitHub https://github.com/nebulous/infinitude/issues/166#issuecomment-1464835748, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABLKZWGCTEMZLMFO3IOWNTW3QHTTANCNFSM6AAAAAAVJJHCYA. You are receiving this because you were mentioned.
I thought you just implied mutations are allowed on GET, even if it's bad form? So, they are accepted into local state, but don't work for updating the thermostat document? I was going down the path of POST because it's more correct, but my HA controller is easier to implement with GET. Confirmed with curl
that POST will update the thermostat. I'll go have an argument with OpenHAB about doing a proper POST.
I'll go have an argument with OpenHAB about doing a proper POST.
Simply changing the method to POST is fully effective while still using the query string. A configuration snippet:
Thing http:url:hvacbeds "HVAC Beds" [ baseURL="http://127.0.0.1:3002/api", refresh=5, commandMethod="POST" ] {
Channels:
Type string : heatsource [ stateExtension="/config", stateTransformation="JSONPATH:$.data.heatsource", commandExtension="/config?heatsource=%2$s" ]
}
A change command sent and captured with tcpdump:
POST /api/config?heatsource=system HTTP/1.1
Accept-Encoding: gzip
User-Agent: Jetty/9.4.46.v20220331
Host: 127.0.0.1:3002
Content-Type: text/plain;charset=UTF-8
Content-Length: 6
system
I tried convincing it to use application/x-www-form-urlencoded
instead of the query string, and supplying form data per typical - which Mojolicious accepts, but OpenHAB doesn't want to do that. It only allows application/json
application/xml
text/html
text/plain
or text/xml
.
It would be excellent if I could post json fragments as payload and have that get merged in the same way as query/form does.
I thought you just implied mutations are allowed on GET, even if it's bad form?
yep. I did imply that and I was wrong, because despite it "working" to mutate the document in Infinitude, we intentionally do not set the change flag unless the http verb is POST or PUT. So you'll be able to see the change until the next refresh cycle when it will revert back. As you discovered subsequently however, it plays pretty fast and loose with the rules of rest(and http for that matter) by merging query and body parameters. What's your opinion on how it should behave on the spectrum of convenient-wrongness to inconvenient-correctness? Some ideas
/api/config?heatsource=system?changes=true
/api/config?heatsource=system
automatically set changes=true like we did before a0c3b7a58c but with change detection/api/config
force correct behavior with formdata containing heatsource=system
and disallow query parameters/api/config
with body containing json to merge /api/config
with body containing json to replace
/api/config?heatsource=system&changes=true
This makes sense. Needs documentation. Probably simplest to implement.
/api/config?heatsource=system
automatically set changes=true like we did before a0c3b7a but with change detection
I like this best. I think changes=true
should also be permitted, and then just skip the change detection function.
- what we have now
It's sufficient. Just need to find the right incantation.
/api/config
force correct behavior with formdata containingheatsource=system
and disallow query parameters
I wouldn't favor being strict on the verbs, for reasons that sometimes it's the only option. I like having the query string or the form data be interchangeable, for the same reason.
- PUT
/api/config
with body containing json to merge
This seems like the wrong verb for a partial change.
- POST
/api/config
with body containing json to replace
I think this makes sense, and fits into my system with a small javascript transform to format the json. Use the Content-type
to determine if it's form or json data.
What about POST and GET at /api/config/{key}
? I think this is more RESTy. Example:
POST /api/config/heatsource HTTP/1.1
Content-Type: text/plain;charset=UTF-8
Content-Length: 6
system
Not sure if that fits nicely into the data model, or how flat that map is, but it’s the best for simple integrations. What are your thoughts?
ok, modified to accept a set_changes
flag to force a change cycle which will be set automatically if a value is changed.
Hi
I am reading and reading your posts and I don't understand. I see that there is a possibility to change the heating source but I don't know how to do it in HA. Could one of you please explain it to me. Please help me a lot
@lukazareba Changing the heating source is something that can only be done via Infinitude's API. MizterB's Infinitude HA integration doesn't expose the heat source mutating functionality as far as I'm aware. So if you want to have HA change the heat source you'll need to write a script to set the source and call it via the command line integration, or use the REST switch integration, or possibly other integrations under the REST/HTTP HA ubbrella.
@nebulous
Thanks for the info, I guessed there was no built-in function. Could you help me in writing a script that would call the rest function in HA?
I tried calling "/api/config/?heatsource=odu only" and "/api/config/?heatsource=idu only". Entries in the XML file changed, but not on the thermostat. That's why all my attempts failed. So what am I doing wrong?
@lukazareba if you're using GET
for that, the commit referenced above added a set_changes=1
you might want to add to the query string. It also appears to have added change detection, so maybe you just need to be on the latest code?
@thekev I tried using the browser only. I typed in http://192.168.0.86:3000/api/config/?heatsource=odu only and other than the information from http://192.168.0.86:3000/api/config nothing changed on the thermostat. So please help me how to change it in HA using a script or something else.
@thekev I tried using the browser only. I typed in http://192.168.0.86:3000/api/config/?heatsource=odu only and other than the information from http://192.168.0.86:3000/api/config nothing changed on the thermostat. So please help me how to change it in HA using a script or something else.
Since you’re using the GET method in this case, try adding set_changes=1
to the query string. I.e. http://192.168.0.86:3000/api/config?heatsource=odu%20only&set_changes=1
@thekev I tried using the browser only. I typed in http://192.168.0.86:3000/api/config/?heatsource=odu only and other than the information from http://192.168.0.86:3000/api/config nothing changed on the thermostat. So please help me how to change it in HA using a script or something else.
Since you’re using the GET method in this case, try adding
set_changes=1
to the query string. I.e. http://192.168.0.86:3000/api/config?heatsource=odu%20only&set_changes=1
@thekev it doesn't work unfortunately
is odu only
a valid value?
do you have the latest version of Infinitude?
It worked, everything works.
I made mistakes typing odu_only
instead of idu only
and had an old version of infinitude.
Thank you for your help
Hi
Is avaible any method to change heat source in HA? If not could you pls add?