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

One climate is not being reconized correctly anymore as an climate device #39

Open
HSken opened this issue Oct 19, 2024 · 42 comments
Open

Comments

@HSken
Copy link

HSken commented Oct 19, 2024

I got the update of HA today: 2024.10.3 (I'm guessing this is what broke it, didn't change much more today)

Sinse then one of the 3 A/C isn't reconized correcly anymore, only some of the entities are added, they do work, so its not like it got new ip or forgot it... I tried removing it and adding it again, but that didn't help:
Note its missing A/C icon with on/off status and temps also not the model name, that used to be there, its an other model then the other two
image

This is one of the others that sill work: The is an A/C bureau-airco icon with status off and temps
image

Also when I try to add it again on the dashboard and type climate. I only get the two other A\C's don't know what to do.

@HSken
Copy link
Author

HSken commented Oct 19, 2024

I enabled debugging when reloading and noticed this error:

2024-10-20 00:05:20.164 ERROR (MainThread) [homeassistant.components.climate] Error adding entity None for domain climate with platform fujitsu_airstage
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 595, in _async_add_entities
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 813, in _async_add_entity
    capabilities=entity.capability_attributes,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 324, in __getattribute__
    return super().__getattribute__(__name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 489, in capability_attributes
    supported_features = self.supported_features
                         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 328, in __getattribute__
    _supported_features: ClimateEntityFeature = super().__getattribute__(
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 270, in supported_features
    if self.swing_mode:
       ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 324, in __getattribute__
    return super().__getattribute__(__name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 189, in swing_mode
    if self._ac.get_vertical_direction() != None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pyairstage/airstageAC.py", line 173, in get_vertical_direction
    return VALUE_TO_VERTICAL_POSITION[int(value)]
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 6

@HSken
Copy link
Author

HSken commented Oct 19, 2024

Ok looking at the error and my programming experience, I expected it recieved some unknow value (6?) for the VALUE_TO_VERTICAL_POSITION key, so I changed the position of the AC Vent and reloaded and its fixed 👍 .

I have zero experience with Python, but can't you do something like this:
return VALUE_TO_VERTICAL_POSITION.get(int(value), "unknown") to gracefully handle the unknow values?

@ohshazbot
Copy link
Collaborator

Yeah, there's a lot of chatter in the debug logs, with my current impression being it's due to some loose awkward handling of entities when the device is off. I've been waiting to get some time to come up with a better solution, but I'm similarly weary about side effects. I don't want to lose the original issue around your primary issue.

Are all of your units the same model or are they different? While there could be a low brain solution around hardening the climate retrieval path, I think it would help to get a better understanding of your problem.

@ohshazbot
Copy link
Collaborator

ohshazbot commented Nov 18, 2024

Oh wait a minute, value 6. What are the vertical positions avaialble to your unit? Our current enumerations are 1-4: https://github.com/danielkaldheim/pyairstage/blob/master/pyairstage/constants.py#L114-L119. My device only has 4 positions available for swing, so there may be some additional parameters that indicate the possible range.

@HSken
Copy link
Author

HSken commented Nov 20, 2024

Yes I have 6 see screenshot
Screenshot_20241120_222907_AIRSTAGE

@HSken
Copy link
Author

HSken commented Nov 21, 2024

Yeah, there's a lot of chatter in the debug logs, with my current impression being it's due to some loose awkward handling of entities when the device is off. I've been waiting to get some time to come up with a better solution, but I'm similarly weary about side effects. I don't want to lose the original issue around your primary issue.

Are all of your units the same model or are they different? While there could be a low brain solution around hardening the climate retrieval path, I think it would help to get a better understanding of your problem.

Yes I have thee:
One ASYG 14 KMCE The one that had the issues, and idd 6 vertical positions
And two ASYG 18 KMTE No issues and idd only 4 positions.

@HSken
Copy link
Author

HSken commented Nov 21, 2024

Oh wait a minute, value 6. What are the vertical positions avaialble to your unit? Our current enumerations are 1-4: https://github.com/danielkaldheim/pyairstage/blob/master/pyairstage/constants.py#L114-L119. My device only has 4 positions available for swing, so there may be some additional parameters that indicate the possible range.

Look like it once supported 6: VerticalPositionDescriptors has 6 values.
Maybe this unkown propertie: af_vertical_num_dir collerates to the number of positions?

@ohshazbot
Copy link
Collaborator

That's a good contender. I do not have that param on my device, so it was probably added later. If you're savvy enough to do curls to your device, you can validate with sending

curl --no-progress-meter -X POST --data '{"device_id":<DEVICE_ID>,"device_sub_id":0,"req_id":"","modified_by":"""list":["af_vertical_num_dir"]}' 'http://<DEVICE_IP>/GetParam'

Otherwise I'll put together a test fork within a few days you can trial since I am unable to repro myself.

@ohshazbot
Copy link
Collaborator

Sorry, looks like this got away from me. I've set myself a reminder

@ohshazbot
Copy link
Collaborator

Alright, I put together a test repo that in theory works for your devices. I'm flying blind though so this will require someone to test to validate. And then it may be a slower turnaround as upstream changes to pyairstage need to occur, but one step at a time: https://github.com/ohshazbot/ha_airstage

@Tw3aky81
Copy link
Contributor

As I was experiencing the same issue after the firmware update of my ASYG09KMCC units to version 2.45, I've installed your test-repo. Where they were no longer working properly from HA anymore, it seems they are working again. No more messages with KeyError: 6 in the system logs atm.

I do still see some messages with TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType' and Error fetching Fujitsu Airstage data: No valid response after 10 failed attempts. Last error was: Connection timed out., but I'm not sure this is related to this issue. I need to investigate that a little further this weekend.

@HSken
Copy link
Author

HSken commented Dec 13, 2024

Alright, I put together a test repo that in theory works for your devices. I'm flying blind though so this will require someone to test to validate. And then it may be a slower turnaround as upstream changes to pyairstage need to occur, but one step at a time: https://github.com/ohshazbot/ha_airstage

I'm still very new to HA and have no idea how I can just switch to an other repo without braking everything, got quite some integrations on it and renamed the entities, I may try and setup temp HA on my desktop and see if I can get that working.

@ohshazbot
Copy link
Collaborator

As I was experiencing the same issue after the firmware update of my ASYG09KMCC units to version 2.45, I've installed your test-repo. Where they were no longer working properly from HA anymore, it seems they are working again. No more messages with KeyError: 6 in the system logs atm.

When you get an opportunity, please try adjusting the different fan direction settings, see if you have all 6 available or just 4 (or if things just start braking)

I do still see some messages with TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType' and Error fetching Fujitsu Airstage data: No valid response after 10 failed attempts. Last error was: Connection timed out., but I'm not sure this is related to this issue. I need to investigate that a little further this weekend.

Connection timeout does seem out of scope, but if you see a stack coming out of get_vertical_direction it would be relevant information to share

@ohshazbot
Copy link
Collaborator

Alright, I put together a test repo that in theory works for your devices. I'm flying blind though so this will require someone to test to validate. And then it may be a slower turnaround as upstream changes to pyairstage need to occur, but one step at a time: https://github.com/ohshazbot/ha_airstage

I'm still very new to HA and have no idea how I can just switch to an other repo without braking everything, got quite some integrations on it and renamed the entities, I may try and setup temp HA on my desktop and see if I can get that working.

So if your using HACS, you can remove and add custom repositories in the three dot menu. And if you remove this repo and add it you will not lose your configured entities (as long as a functioning repo is installed). But you should definitely take things at your speed

@Tw3aky81
Copy link
Contributor

Tw3aky81 commented Dec 14, 2024

When you get an opportunity, please try adjusting the different fan direction settings, see if you have all 6 available or just 4 (or if things just start braking)

Well, I did by accident, actually. 😄
I wanted to change the climate mode to heating, after the unit was used during the day in ventilation mode through HA... Seems, somehow the unit changed to position 6 again. Confirmed that through the Airstage app. (Not really sure how it happened, because I didn't really put it there intentionally...)

And, guess who's back:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 608, in _async_add_entities
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 825, in _async_add_entity
    capabilities=entity.capability_attributes,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 337, in __getattribute__
    return super().__getattribute__(name)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 502, in capability_attributes
    supported_features = self.supported_features
                         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 341, in __getattribute__
    _supported_features: ClimateEntityFeature = super().__getattribute__(
                                                ~~~~~~~~~~~~~~~~~~~~~~~~^
        "supported_features"
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 285, in supported_features
    if self.swing_mode:
       ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 337, in __getattribute__
    return super().__getattribute__(name)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 204, in swing_mode
    if self._ac.get_vertical_direction() != None:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/pyairstage/airstageAC.py", line 173, in get_vertical_direction
    return VALUE_TO_VERTICAL_POSITION_BY_POSITIONS[self.get_vertical_swing_positions()][int(value)]
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 6

Not sure if anything different in this stack trace, but definitely KeyError: 6 again. Going to play a bit with that curl command you've requested later today and post its results. Maybe there's some more info. Any other API calls you know of, maybe? Some kind of debug dump of the unit or something, perhaps?

EDIT:
Confirming I also got only 4 direction settings + vertical swing available in the climate card of HA.
image

EDIT2:
I've been playing with the Fujitsu app a bit more to see how it's working from there... It seems when I switch the unit's mode to heating, it automatically selects the most vertical position = 6.
Switching it to ventilation mode, switches to the most horizontal position = 1

So at least, that's explaining why it's automatically getting set back to six, even if I didn't set it specifically.

@Tw3aky81
Copy link
Contributor

Ok, last comment from me today, as I have some other stuff to do too. 😅

If you're savvy enough to do curls to your device, you can validate with sending

It seems I'm always getting {"result":"NG","error":"0002"} back as a response. Perhaps this gives you an extra clue.
I've changed the data a bit, though, because I think you've missed a comma between "modified_by":"" and "list":["af_vertical_num_dir"]?
At least, it didn't seem valid JSON-data to me, but correct me if I'm wrong, though. I've also tried to put in my device_id in uppercase and lowercase, but it doesn't seem to make a difference.

@HSken
Copy link
Author

HSken commented Dec 14, 2024

I tryed it also, I got this error, when I tryed settings the swingmode:

Logger: homeassistant
Source: custom_components/fujitsu_airstage/climate.py:204
integration: Fujitsu Airstage
First occurred: 6:32:03 PM (6 occurrences)
Last logged: 6:33:08 PM

Error doing job: Task exception was never retrieved (None)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 267, in _handle_refresh_interval
    await self._async_refresh(log_failures=True, scheduled=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 478, in _async_refresh
    self.async_update_listeners()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 177, in async_update_listeners
    update_callback()
    ~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 558, in _handle_coordinator_update
    self.async_write_ha_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1023, in async_write_ha_state
    self._async_write_ha_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1148, in _async_write_ha_state
    self.__async_calculate_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1081, in __async_calculate_state
    capability_attr = self.capability_attributes
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 337, in __getattribute__
    return super().__getattribute__(name)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 502, in capability_attributes
    supported_features = self.supported_features
                         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 341, in __getattribute__
    _supported_features: ClimateEntityFeature = super().__getattribute__(
                                                ~~~~~~~~~~~~~~~~~~~~~~~~^
        "supported_features"
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 285, in supported_features
    if self.swing_mode:
       ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 337, in __getattribute__
    return super().__getattribute__(name)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/config/custom_components/fujitsu_airstage/climate.py", line 204, in swing_mode
    if self._ac.get_vertical_direction() != None:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/pyairstage/airstageAC.py", line 173, in get_vertical_direction
    return VALUE_TO_VERTICAL_POSITION[int(value)]
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 6

When changing HVAC mode to heating from Drying, it seem to work when I check the airstage app, but in HA I get this error message: Failed to perform the action climate/set_hvac_mode. 6
And I don't see it change in HA.

When checking logs; I don't see any new errors?

Maybe an idea to setup some call? PM me I'm in Belgium, you profile sais Boston, thats 5 houres difference if I'm not mistaking, can be challaging.

@ohshazbot
Copy link
Collaborator

Looks like I'm not finding the right magic key to get the number of swing positions. My devices does not report it at all (I think) so hard to test.

And yes, I apparently butchered the curl command when I transposed it, so that comma was correct. But here's an amended one that throws in a few different possible parameters plus an always valid one just to make sure it returns properly.

curl --no-progress-meter -X POST --data '{"device_id":<DEVICE_ID>,"device_sub_id":0,"req_id":"","modified_by":"", "list":["af_vertical_num_dir","iu_op_mode","iu_af_vertical_num_dir","iu_vertical_num_dir","iu_vertical_num_dir"]}' 'http://<DEVICE_IP>/GetParam'

If you fail to provide at least one valid parameter (in additional to some of the other attributes in the json) then you get the NG/0002 error, so that would explain why you're getting that.

@marhilde
Copy link

marhilde commented Dec 19, 2024

I have the same symptoms, but it is about fan speed. My HP has more fan speed options than what is in the code, is my uneducated guess:

File "/usr/local/lib/python3.13/site-packages/pyairstage/airstageAC.py", line 116, in get_fan_speed

return VALUE_TO_FAN_SPEED[
       ~~~~~~~~~~~~~~~~~~^
    
int(self._get_cached_device_parameter(ACParameter.FAN_SPEED))

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]
^
KeyError: 9

My HP model is General ASHH14KHCBN
Firmware for indoor unit is "01.01"
Firmware for WLAN adapter is 02.45

In the Airstage app, under Fan speed, I have 7 options:
Silent
Low
Medium-Low
Medium
Medium-High
High
Auto
(could it be that "Eco" and "Powerful" also counts as fan speed settings?)

...which is not 10 (key value 0-9) as indicated by the error log in HA.

Btw: I have 4 possible vertical positions, and 5 horizontal positions, and I don't seem to have any problems with these, only the fan speed.

If someone could make me a curl command to list fan speed options, I could try to investigate some more.

PS: sorry about the bad formatting. I can't seem to get It right on my phone...

@ohshazbot
Copy link
Collaborator

@marhilde Still pretty decent for phone formatting :)

Do you mind spinning this out to a new issue, fan speed is different then fan directions, so whatever solution we come up for this will probably not satisfy that. Want to make sure your issue isn't lost.

When you do repost, if you can, run the following curl when you fan is at speeds:

  • Silent
  • Medium-Low
  • Medium-High

And the command (note the placeholders for DEVICE_ID and DEVICE_IP) will be

curl --no-progress-meter -X POST --data '{"device_id":"<DEVICE_ID>","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_fan_spd"]}' 'http://<DEVICE_IP>/GetParam'

@marhilde
Copy link

Sure, thanks! I will post a new issue once I get home to my computer. Sorry about the derailing...

@ohshazbot
Copy link
Collaborator

You're fine, I can understand why you thought to chime in here :)

@Tw3aky81
Copy link
Contributor

Right, found some time again to play around with it...

I managed to get 'some' output, but I needed to have another argument (at least for me and my unit) in the curl command.
I found out that I needed to add "set_level":"03" after modified_by and before list on HA forum. Also, the device ID definitely needs to be entered in uppercase.

So the command became:

curl --no-progress-meter -X POST --data '{"device_id":"<DEVICE_ID>","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["af_vertical_num_dir","iu_op_mode","iu_af_vertical_num_dir","iu_vertical_num_dir","iu_vertical_num_dir"]}' 'http://<DEVICE_IP>/GetParam'

Response:

{"value":{"iu_op_mode":"3"},"read_res":"ack","device_id":"<DEVICE_ID>","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","cause":"","result":"OK","error":""}

However, the response still doesn't show the info you're looking for, I'm afraid. No matter if I change the op_ mode to something else, like heating (op_mode:4) or cooling (op_mode:1) for instance, I only get the iu_op_mode value back in the response. Not sure if I need (or if there is) another set_level value that I could pass it...

If only I could find some service manual or something on the internet... But I guess that's classified info hidden on some private and proprietary servers of Fujitsu probably, is it? Whatever the case, I've had no luck finding any of that kind (yet), unfortunately.

Some more context:
The thing is, I only seem to get the KeyError: 6 still when I try switching the op_mode in HA from whatever op_mode to heating mode. The unit seems to default to vertical position 6 (fully vertical). All the other modes, like cooling, fan only, etc. seem to work fine in HA with your test-repo, because it then switches back to position 1 (fully horizontal). So basically, I only seem to 'break' the climate widget in HA when is press the heating mode button. Now, if I then change the vertical posistion through the AirStage app, while still in heating mode, the widget seems to work fine again.

@ohshazbot
Copy link
Collaborator

There's a few other things I can try to resolve this, thank you for checking.

As for your additional context, how are you enabling heat mode that results in the swing position change (remote, airstage app, HA)?

@Tw3aky81
Copy link
Contributor

Tw3aky81 commented Dec 23, 2024

Doesn't matter, really. All 3 options actually make the unit's swing position turn into the full vertical position when changing to heating mode. Where switching it to fan, it always defaults to the horizontal position. It doesn't seem to 'remember' its swing position it had before when changing modes.

However, the climate card in HA is always broken for a unit whenever its swing position gets set beyond position 4. Then I need to 'manually' reset it through the Airstage app or remote to get the unit working again in HA. So even though the climate card doesn't respond anymore for a unit with its swing position beyond 4, it does seem to have picked up the last command sent to it. At least, I always find the unit set to whatever I last set it to through HA.

EDIT; fixed some typos

@ohshazbot
Copy link
Collaborator

Hi @Tw3aky81 I did some more sleuthing and I found another paramter from the unit that I'm hopeful about. In the curl command from before, I would like to inspect iu_af_inc_hrz and iu_af_inc_vrt. So can you run:

curl --no-progress-meter -X POST --data '{"device_id":"<DEVICE_ID>","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["af_vertical_num_dir","iu_op_mode","iu_af_vertical_num_dir","iu_vertical_num_dir","iu_vertical_num_dir","iu_af_inc_vrt","iu_af_inc_hrz"]}' 'http://<DEVICE_IP>/GetParam'

@Tw3aky81
Copy link
Contributor

Hi John,
Bingo! Those extra parameters do provide some output. See the response output below:

{"value":{"iu_op_mode":"3","iu_af_inc_vrt":"6","iu_af_inc_hrz":"0"},"read_res":"ack","device_id":"<DEVICE_ID>","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","cause":"","result":"OK","error":""}

@ohshazbot
Copy link
Collaborator

SWEEET, I know what I'm doing this weekend

@ohshazbot
Copy link
Collaborator

I have updated my fork with this new information, if one of you with a 6 position device could test, that would be swell: https://github.com/ohshazbot/ha_airstage

@Tw3aky81
Copy link
Contributor

Hi @ohshazbot I found some time to play around with it and by my testing on my units, it looks like the integration still can't cope with a value of 6.

One of the things I find out during my poking around with the curl command, is that the iu_af_inc_vrt value didn't change at all while testing. I did find a iu_af_dir_vrt parameter in the pyairstage code repo and that one did change accordingly to the flap's position.

What I did for testing your test-repo was going through the swingposition value from highest to lowest through the integration in HA. I've then switched to using the remote, with the SET button, to get it even further as I couldn't bump it higher than position 4 through the integration (yet! 😃 ). Each time I'd changed the position, I've issued the same curl command. I'm including all the responses I got back in a text file as it's too long to just post it in the comments.

test_output.txt

TL;DR
I found out that the iu_af_dir_vrt parameter doesn't get updated anymore as soon as I'd started using the remote, until I changed to another op_mode. As changing to the heat mode puts the flap on position 6 by default, I changed it to op_mode=4, so I was able to force iu_af_dir_vrt to 6, eh voilà, the integration crashed on me again for the unit I was testing with.

Based on the error pointing towards the pyairstage module and learning from what you did in your commits, I think might just be setting it up locally here too and have a go at trying to fix this myself. Not promising anything though, but it's a good learning experience after all. 😺

@ohshazbot
Copy link
Collaborator

I mean, the worse case scenario is a literal user configuration to declare how many positions your device has, I've been trying to leverage information coming out of the unit to make that determination automatically. My thought was that iu_af_inc_vrt was purely a report of the number of positions, so I would not expect it to be changing. It does look like it's behaving the way I expect, but I probably am not plumbing things right. I'll probably do an adjustment of the logging to get some more details to drive this to ground.

@ohshazbot
Copy link
Collaborator

@Tw3aky81 I have updated my branch with another version. Two changes I made:

  1. Removed defaulting to 4 when absent. I validated that my devices reports 4 so I'm not that concerned about backwards compatability (waiting for egg on my face for that one, but we shall see)
  2. Updated the bootstrapping which fetches all the parameters at startup. Because I was purely looking in the cache for these values (because the positions value should never change) it was always missing.

@Tw3aky81
Copy link
Contributor

@ohshazbot, should I see the extra swing positions you've added in the selection box of the climate control in HA? If so, I don't have them, even after deleting and re-adding the unit into the integration. Maybe I'm doing something wrong when updating?

For the rest, I still seem to get the same output as in my previous test. Finally giving the error below, when hitting '6' in iu_af_dir_vrt parameter.

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 267, in _handle_refresh_interval
    await self._async_refresh(log_failures=True, scheduled=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 478, in _async_refresh
    self.async_update_listeners()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 177, in async_update_listeners
    update_callback()
    ~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 558, in _handle_coordinator_update
    self.async_write_ha_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1023, in async_write_ha_state
    self._async_write_ha_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1148, in _async_write_ha_state
    self.__async_calculate_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1081, in __async_calculate_state
    capability_attr = self.capability_attributes
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 372, in capability_attributes
    supported_features = self.supported_features
                         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/fujitsu_airstage_original/climate.py", line 285, in supported_features
    if self.swing_mode:
       ^^^^^^^^^^^^^^^
  File "/config/custom_components/fujitsu_airstage_original/climate.py", line 204, in swing_mode
    if self._ac.get_vertical_direction() != None:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/pyairstage/airstageAC.py", line 173, in get_vertical_direction
    return VALUE_TO_VERTICAL_POSITION_BY_POSITIONS[self.get_vertical_swing_positions()][int(value)]
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 6

It does seem to have picked up your changes in airstageAC.py, but still doesn't like the '6' it receives.
If you got a specific test-scenario in mind that I could perform, I'd be happy to run it.

Cheers.

@ohshazbot
Copy link
Collaborator

Drat, that test seems fine. I was probably a little arogant when I saw the missed initial lookup. I'm gonna add some logging so we can root this out

@ohshazbot
Copy link
Collaborator

Well, not thrilled with this hack, but I have updated my branch and pyairstage to including printing out debug details because I could not get debug logging from pyairstage working. While doing so, I had to manually intervene in the pyairstage version for my HA container to ensure it actually applied. So with the new change, you should see output from home assistant like

homeassistant  | Fetched vertical_swing_positions 4 based on capability available True

In order to ensure that the right version of pyairstage is installed, you can do a docker exec -it homeassistant pip install --force-reinstall pyairstage@git+https://github.com/ohshazbot/pyairstage.git@main if you're using the docker container. Then restart and you should start seeing these in the output as the system initialized, docker compose logs --tail 500 homeassistant | grep vertical_swing.

Hopefully the shortcomings to this point were due to versions not updating as intended, but if your standing test does not work, that output line should help paint a picture for whats going on.

@Tw3aky81
Copy link
Contributor

Aha! Making progress, I think. Hooray!
After some fiddling around to get the intented pyairstage version, I can see a bunch of messages obsessively logged ...

Fetched vertical_swing_positions 6 based on capability available True

I'm using HAOS btw, but it turned out I could use the exact docker commands you gave me through the Terminal & SSH add-on's web GUI, apart from the docker compose logs .... Instead, I just used docker logs ... to check for the messages. 😄

And although I don't have the extra options available in the unit's swing_position select box of the climate card yet, I could switch to heat mode, forcing position 6, without any problem now! 🥳
However, HA did post this message at certain point, right after switching to lowest through the HA climate card, while still in fan mode:

[139638676054816] Swing mode is not valid. Valid swing modes are: Vertical Swing, Highest, High, Low, Lowest

Which would make sense if the old lowest representing a certain position while it's returning something different from the library now and that option not being available in the UI?

The good news is we got rid off that key error: 6 message at least. 👍
So, my guess is that updating the backend library didn't go all to well before, he?

@ohshazbot
Copy link
Collaborator

Yeah, seems that way. Once we can actually get a release cut it should go without a hitch.

As for that last error, I did observed a missing step in the ha_airstage repo fork (I missed a reverse translation table), I have made a small update which should address the "Swing mode is not valid" error. Can you give it a go for a day so we can see if that gets that error to go away. Meanwhile I'm gonna try to get pyairstage updated for realsies

@Tw3aky81
Copy link
Contributor

@ohshazbot, I updated the ha_airstage repo to your last commit, but unfortunately the Swing mode not valid error didn't go away.
Each time I select Low or Lowest, the error is logged after a second or two. High and Highest don't seem to trigger it.

Seems as if the unit is reporting one of the CENTER_x values, but HA doesn't recognizes these ones.

Could it be that the SWING_MODES constant in climate.py needs an update too? Not sure about that though, because I've seem to have broken the whole integration when I fiddled with that myself, but that could've been me and my skills.

@ohshazbot
Copy link
Collaborator

Without seeing a full trace I'm not certain, but that certainly feels like a reasonable cause for the issue at hand. I have pushed an update to my branch to also populate swing modes, though I still need to test it to make sure this doesn't make for a bad time for us 4-position folks

@Tw3aky81
Copy link
Contributor

Tw3aky81 commented Jan 29, 2025

Progress in the sense that I now have all 6 swing modes available in the climate card... and the swing mode not valid message no longer pops up. But...

Now facing another issue in the backend I guess. When selecting Center High in climate card, message pops up complaing about an invalid fan_direction now. Same for Center Low... Here's the full traceback from the logs:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 245, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2795, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2838, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1006, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
        hass, entity, func, data, call.context
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1078, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 691, in async_handle_set_swing_mode_service
    await self.async_set_swing_mode(swing_mode)
  File "/config/custom_components/fujitsu_airstage/climate.py", line 266, in async_set_swing_mode
    await self._ac.set_vertical_direction(HA_SWING_TO_FUJITSU[swing_mode])
  File "/usr/local/lib/python3.13/site-packages/pyairstage/airstageAC.py", line 180, in set_vertical_direction
    raise AirstageACError(f"Invalid fan direction value: {direction}")
pyairstage.airstageAC.AirstageACError: Invalid fan direction value: CENTER_HIGH

Never thought that what seemed to be a small difference could be that big of a PITA. 😄
Not sure If we're steering in the right direction by continuing this way or if this is still of concern for this particular issue, cause it's starting to look more like a complete overhaul, imo.

@ohshazbot
Copy link
Collaborator

ohshazbot commented Jan 29, 2025

I'm still comfortable with this being the right direction, looks like vertical positioning is just a rats nest of doubled up double translation layers. That stack trace was incredibly helpful, turns out I used the wrong constants for HA_SWING_TO_FUJITSU and I need to come up with a solution for VerticalSwingPosition as that also needs to rely on the encoding number for translation. I'm not sure how I want to address it, hopefully will have time Friday to take a stab as I'm starting to think a broader refactor for positions between ha_airstage and pyairstage needs to happen

@Loudinc
Copy link

Loudinc commented Mar 12, 2025

I have an ASEH12KHCBN and can also confirm that it has seven fan speeds (including Quiet and Auto).
When choosing 'Medium-Low' or 'Medium-High,' the Device becomes Unavailable.

Thanks for all the effort—great to have the ability to control my HVAC in HA.

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

No branches or pull requests

5 participants