Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use query string for set_zone on airbase #11

Merged
merged 6 commits into from
Jul 4, 2024

Conversation

kingy444
Copy link
Collaborator

Params do not work for the set_zone function. Revert to Query string

fixes #10

Please bump version and publish after merge, an incremental to 2.13.1 should be sufficient

@fredrike
Copy link
Owner

Please make sure pre-commit runs cleanly.

@kingy444
Copy link
Collaborator Author

Please make sure pre-commit runs cleanly.

I think it should all be good - could we get the version bumped with these changes ?

@cremor
Copy link
Collaborator

cremor commented Jun 28, 2024

@fredrike Is there anything that prevents this PR from being merged?
It would be great if this could be merged and released as a new version because this issue blocks the HA PR home-assistant/core#118679

@fredrike
Copy link
Owner

fredrike commented Jul 1, 2024

@fredrike Is there anything that prevents this PR from being merged? It would be great if this could be merged and released as a new version because this issue blocks the HA PR home-assistant/core#118679

I'm waiting for @kingy444 to do some more testing on why we can't use params when configuring zones. I do not have an airbase unit so I can't test and verify this myself.

@kingy444
Copy link
Collaborator Author

kingy444 commented Jul 1, 2024

@fredrike Is there anything that prevents this PR from being merged? It would be great if this could be merged and released as a new version because this issue blocks the HA PR home-assistant/core#118679

I'm waiting for @kingy444 to do some more testing on why we can't use params when configuring zones. I do not have an airbase unit so I can't test and verify this myself.

This PR was raised to fix the issue that params don't work.

What else are you wanting me to test ?

They don't work so this PR makes Airbase use query string (which does work)

@fredrike
Copy link
Owner

fredrike commented Jul 1, 2024

@fredrike Is there anything that prevents this PR from being merged? It would be great if this could be merged and released as a new version because this issue blocks the HA PR home-assistant/core#118679

I'm waiting for @kingy444 to do some more testing on why we can't use params when configuring zones. I do not have an airbase unit so I can't test and verify this myself.

This PR was raised to fix the issue that params don't work.

What else are you wanting me to test ?

They don't work so this PR makes Airbase use query string (which does work)

I really apprechiate your work so don't get me wrong the problem is that we need to understand what's going on here so we don't change this to param later on. I did write some comments here: https://github.com/fredrike/pydaikin/pull/11/files/70f1d1c6b4c44aef037594eb4a98a8d28ccb5677

@kingy444
Copy link
Collaborator Author

kingy444 commented Jul 1, 2024

All good from my end - I'm just not sure what else you need.

All i can put it down to is the airbase unit must process these differently - any request with a POST body fails and it requires them in query string GET

@fredrike
Copy link
Owner

fredrike commented Jul 1, 2024

There are no POST going on, only get: https://github.com/fredrike/pydaikin/blob/master/pydaikin/daikin_base.py#L140

Please show me what's different with the request, enable verbose logging in HTTPX with: https://www.python-httpx.org/logging/

@kingy444
Copy link
Collaborator Author

kingy444 commented Jul 2, 2024

Well that explains why POSTMAN failed before... GET with params does seems to be working.

Query String

2024-07-01 23:16:16.201 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/get_zone_setting {}
2024-07-01 23:16:16.318 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK,zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38,zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0
2024-07-01 23:16:16.319 DEBUG (MainThread) [pydaikin.daikin_airbase] Updating ['aircon/set_zone_setting']: zone_name=       Zone1;       Zone2;       Zone3;       Zone4;       Zone5;       Zone6;       Zone7;       Zone8,zone_onoff=1;0;0;0;0;0;0;0
2024-07-01 23:16:16.319 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38&zone_onoff=1%3b0%3b0%3b0%3b0%3b0%3b0%3b0 {}
2024-07-01 23:16:16.435 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK
>>> httpx.get('http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38&zone_onoff=1%3b0%3b0%3b0%3b0%3b0%3b0%3b0')
DEBUG [2024-07-01 23:22:18] httpx - load_ssl_context verify=True cert=None trust_env=True http2=False
DEBUG [2024-07-01 23:22:18] httpx - load_verify_locations cafile='/home/vscode/.local/ha-venv/lib/python3.12/site-packages/certifi/cacert.pem'
DEBUG [2024-07-01 23:22:18] httpcore.connection - connect_tcp.started host='10.1.0.231' port=80 local_address=None timeout=5.0 socket_options=None
DEBUG [2024-07-01 23:22:18] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f86739e51c0>
DEBUG [2024-07-01 23:22:18] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:22:18] httpcore.http11 - send_request_headers.complete
DEBUG [2024-07-01 23:22:18] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:22:18] httpcore.http11 - send_request_body.complete
DEBUG [2024-07-01 23:22:18] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:22:18] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.0', 200, b'OK', [(b'Content-Length', b'6'), (b'Content-Type', b'text/plain')])
INFO [2024-07-01 23:22:18] httpx - HTTP Request: GET http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38&zone_onoff=1%3b0%3b0%3b0%3b0%3b0%3b0%3b0 "HTTP/1.0 200 OK"
DEBUG [2024-07-01 23:22:18] httpcore.http11 - receive_response_body.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:22:18] httpcore.http11 - receive_response_body.complete
DEBUG [2024-07-01 23:22:18] httpcore.http11 - response_closed.started
DEBUG [2024-07-01 23:22:18] httpcore.http11 - response_closed.complete
<Response [200 OK]>

Params

2024-07-01 23:17:56.813 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/get_zone_setting {}
2024-07-01 23:17:56.932 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK,zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38,zone_onoff=1%3b0%3b0%3b0%3b0%3b0%3b0%3b0
2024-07-01 23:17:56.932 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting {'zone_name': '%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38', 'zone_onoff': '1%3b1%3b0%3b0%3b0%3b0%3b0%3b0'}
2024-07-01 23:17:57.046 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=PARAM NG
>>> 4 = httpx.get('http://10.1.0.231/skyfi/aircon/set_zone_setting', params={'zone_name': '%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38', 'zone_onoff': '1%3b1%3b0%3b0%3b0%3b0%3b0%3b0'})
DEBUG [2024-07-01 23:24:52] httpx - load_ssl_context verify=True cert=None trust_env=True http2=False
DEBUG [2024-07-01 23:24:52] httpx - load_verify_locations cafile='/home/vscode/.local/ha-venv/lib/python3.12/site-packages/certifi/cacert.pem'
DEBUG [2024-07-01 23:24:53] httpcore.connection - connect_tcp.started host='10.1.0.231' port=80 local_address=None timeout=5.0 socket_options=None
DEBUG [2024-07-01 23:24:53] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f86739e68d0>
DEBUG [2024-07-01 23:24:53] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:24:53] httpcore.http11 - send_request_headers.complete
DEBUG [2024-07-01 23:24:53] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:24:53] httpcore.http11 - send_request_body.complete
DEBUG [2024-07-01 23:24:53] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:24:53] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.0', 200, b'OK', [(b'Content-Length', b'6'), (b'Content-Type', b'text/plain')])
INFO [2024-07-01 23:24:53] httpx - HTTP Request: GET http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38&zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0 "HTTP/1.0 200 OK"
DEBUG [2024-07-01 23:24:53] httpcore.http11 - receive_response_body.started request=<Request [b'GET']>
DEBUG [2024-07-01 23:24:53] httpcore.http11 - receive_response_body.complete
DEBUG [2024-07-01 23:24:53] httpcore.http11 - response_closed.started
DEBUG [2024-07-01 23:24:53] httpcore.http11 - response_closed.complete
<Response [200 OK]>
>>>  r.url
URL('http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38&zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0')

image

All this led me to check the response url in the daikin_base which returned

2024-07-01 23:43:38.698 WARNING (MainThread) [pydaikin.daikin_base] <ClientResponse(http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2531%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2532%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2533%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2534%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2535%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2536%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2537%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2538&zone_onoff=1%253b0%253b0%253b0%253b0%253b0%253b0%253b0) [200 OK]>
<CIMultiDictProxy('Content-Length': '12', 'Content-Type': 'text/plain')>

This was returning %2520 vs the %20 in the the other tools so the below almost works with unquote too - I wasnt sure about the ClientResponse ++ so i checked the app and glad i did....
@fredrike Suggestions on what to change here (it renamed all my zones 🤣 ?
image

        current_group = self.represent(key)[1]
        current_group[zone_id] = value
        self.values[key] = quote(";".join(current_group)).lower()

        path = "aircon/set_zone_setting"
        params = {
            "zone_name": unquote(current_state["zone_name"]),
            "zone_onoff": unquote(self.values["zone_onoff"]),
        }

        if self.support_zone_temperature:
            params.update({"lztemp_c": unquote(self.values["lztemp_c"])})
            params.update({"lztemp_h": unquote(self.values["lztemp_h"])})

        await self._get_resource(path, params)
2024-07-01 23:47:41.561 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK,zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38,zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0
2024-07-01 23:47:41.562 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting {'zone_name': '       Zone1;       Zone2;       Zone3;       Zone4;       Zone5;       Zone6;       Zone7;       Zone8', 'zone_onoff': '1;0;0;0;0;0;0;0'}
2024-07-01 23:47:41.767 WARNING (MainThread) [pydaikin.daikin_base] <ClientResponse(http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=+++++++Zone1%3B+++++++Zone2%3B+++++++Zone3%3B+++++++Zone4%3B+++++++Zone5%3B+++++++Zone6%3B+++++++Zone7%3B+++++++Zone8&zone_onoff=1%3B0%3B0%3B0%3B0%3B0%3B0%3B0) [200 OK]>
<CIMultiDictProxy('Content-Length': '6', 'Content-Type': 'text/plain')>

@kingy444
Copy link
Collaborator Author

kingy444 commented Jul 2, 2024

These were all out of the box names - i forced them back on the device with the below
unfortunately the zone_name is a required property and dropping it from the call does not work

params["zone_name"] = "%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38"

they are padded with spaces when converted

{
    "zone_name": "       Zone1;       Zone2;       Zone3;       Zone4;       Zone5;       Zone6;       Zone7;       Zone8",
    "zone_onoff": "1;1;0;0;0;0;0;0"
}

@kingy444
Copy link
Collaborator Author

kingy444 commented Jul 2, 2024

so it looks like everything within set_zone is ok, the values look correct before sensing through (logging below)

at the start ofget_resource ("Calling xxx url") that too looks ok. this happens prior to the GET request and should be correct as no change is coded here.

but then within the response block the url called is url encoded again rather than treating as url encoded already (%20 is converted to %2520)

as above, when trying to decode the %20 back to spaces prior to the sending to _get_resource this results in the response calling +++++ rather that %20

thoughts?

2024-07-02 12:21:37.852 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/get_zone_setting {}
2024-07-02 12:21:37.966 WARNING (MainThread) [pydaikin.daikin_base] response within _get_resource <ClientResponse(http://10.1.0.231/skyfi/aircon/get_zone_setting) [200 OK]>
<CIMultiDictProxy('Content-Length': '367', 'Content-Type': 'text/plain')>

2024-07-02 12:21:37.966 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK,zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38,zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0
2024-07-02 12:21:37.967 WARNING (MainThread) [pydaikin.daikin_airbase] before _get_resource %20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38
2024-07-02 12:21:37.967 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting {'zone_name': '%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38', 'zone_onoff': '1%3b0%3b0%3b0%3b0%3b0%3b0%3b0'}
2024-07-02 12:21:38.083 WARNING (MainThread) [pydaikin.daikin_base] response within _get_resource <ClientResponse(http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2531%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2532%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2533%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2534%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2535%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2536%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2537%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2538&zone_onoff=1%253b0%253b0%253b0%253b0%253b0%253b0%253b0) [200 OK]>
<CIMultiDictProxy('Content-Length': '12', 'Content-Type': 'text/plain')>

2024-07-02 12:21:38.083 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=PARAM NG

@fredrike
Copy link
Owner

fredrike commented Jul 2, 2024

so it looks like everything within set_zone is ok, the values look correct before sensing through (logging below)

at the start ofget_resource ("Calling xxx url") that too looks ok. this happens prior to the GET request and should be correct as no change is coded here.

but then within the response block the url called is url encoded again rather than treating as url encoded already (%20 is converted to %2520)

as above, when trying to decode the %20 back to spaces prior to the sending to _get_resource this results in the response calling +++++ rather that %20

thoughts?

2024-07-02 12:21:37.852 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/get_zone_setting {}
2024-07-02 12:21:37.966 WARNING (MainThread) [pydaikin.daikin_base] response within _get_resource <ClientResponse(http://10.1.0.231/skyfi/aircon/get_zone_setting) [200 OK]>
<CIMultiDictProxy('Content-Length': '367', 'Content-Type': 'text/plain')>

2024-07-02 12:21:37.966 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=OK,zone_name=%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38,zone_onoff=1%3b1%3b0%3b0%3b0%3b0%3b0%3b0
2024-07-02 12:21:37.967 WARNING (MainThread) [pydaikin.daikin_airbase] before _get_resource %20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38
2024-07-02 12:21:37.967 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting {'zone_name': '%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38', 'zone_onoff': '1%3b0%3b0%3b0%3b0%3b0%3b0%3b0'}
2024-07-02 12:21:38.083 WARNING (MainThread) [pydaikin.daikin_base] response within _get_resource <ClientResponse(http://10.1.0.231/skyfi/aircon/set_zone_setting?zone_name=%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2531%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2532%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2533%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2534%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2535%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2536%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2537%253b%2520%2520%2520%2520%2520%2520%2520%255a%256f%256e%2565%2538&zone_onoff=1%253b0%253b0%253b0%253b0%253b0%253b0%253b0) [200 OK]>
<CIMultiDictProxy('Content-Length': '12', 'Content-Type': 'text/plain')>

2024-07-02 12:21:38.083 DEBUG (MainThread) [pydaikin.daikin_airbase] Parsing ret=PARAM NG

Great findings and analysis! I would guess that we need to use urllib.parse.unquote_plus on the parameters before this line:

2024-07-02 12:21:37.967 DEBUG (MainThread) [pydaikin.daikin_base] Calling: http://10.1.0.231/skyfi/aircon/set_zone_setting {'zone_name': '%20%20%20%20%20%20%20%5a%6f%6e%65%31%3b%20%20%20%20%20%20%20%5a%6f%6e%65%32%3b%20%20%20%20%20%20%20%5a%6f%6e%65%33%3b%20%20%20%20%20%20%20%5a%6f%6e%65%34%3b%20%20%20%20%20%20%20%5a%6f%6e%65%35%3b%20%20%20%20%20%20%20%5a%6f%6e%65%36%3b%20%20%20%20%20%20%20%5a%6f%6e%65%37%3b%20%20%20%20%20%20%20%5a%6f%6e%65%38', 'zone_onoff': '1%3b0%3b0%3b0%3b0%3b0%3b0%3b0'}

So httpx can do an quoute before submitting.

image

@fredrike
Copy link
Owner

fredrike commented Jul 2, 2024

@kingy444 I think you've nailed it. The Daikin implementation does it wrong and expect the string to be urlencoded but that is not according to standard.

Some references: https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20, encode/httpx#3140

I think we can drop this and keep it as you suggested it just add a comment that it shouldn't be sent as parameters as Daikin doesn't parse them correctly.

Or, this actually fixes our issue: https://github.com/encode/httpx/pull/3187/files#diff-e22e5624ca4e994155aa44e1b25f7812b286a8bbbeabdcd6490073ad2f3927dcR293

This is the way:

Screenshot 2024-07-02 at 16 10 24

We add requirement of httpx version greater than 0.23.0

image

And now I realized that we are using aiohttp, I'll get back on this.

@fredrike
Copy link
Owner

fredrike commented Jul 2, 2024

So, aiohttp is using yarl and this is how yarl encodes our string:

Screenshot 2024-07-02 at 16 38 10

So I guess we are back to where we started, we need to keep the query string separate..

_LOGGER.debug("Sending request to %s with params: %s", path, params)
await self._get_resource(path, params)
# # Convert params dictionary to query string format
params_str = "&".join(f"{k}={v}" for k, v in params.items())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think we should try to get the params way to work. Can you add some debugging on what's happening here in contrast to the params way?

Also it seems like httpx are using https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode. Isn't that a better way?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kingy444 could you try to run a few scenarios that uses the inbuilt params in httpx. I would like to understand what's going on here. Perhas you could enable verbose (NOTSET) debugging on httpx so we can see how the request differs.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kingy444 could you have a look at this ⬆️ .

@fredrike fredrike merged commit 22c32e0 into fredrike:master Jul 4, 2024
3 checks passed
@fredrike
Copy link
Owner

fredrike commented Jul 4, 2024

Thanks a lot @kingy444!

New version (2.13.1) pushed to pypi.

v2.11.1...v2.13.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Zone control not working on airbase
3 participants