Add MELCloud integration#30712
Conversation
|
@frenck Do I need to provide docs PR before any review is done? I can do the docs PR, but I don't want to commit time to doing that without knowing if this is something that can/will be merged. |
|
Docs are required before being able to merge. I've added it to ensure we do not merge it accidentally without documentation. |
|
Excellent work, fingers crossed! |
|
I attempted to test this component on my own HA install, but it appears to assume that MELCloud is only used for HVAC/AC systems. When tested with my system (simply an air-to-water system), I noted that the component just presumed that I had an HVAC system. It also doesn't show any zones, and only the first sensor (the power one) reports anything. Is this out of scope of this PR, or is this unintentional? |
|
I think the air-to-water systems are out of scope, but the lack of filtering is not. I also noticed I'm not filtering out empty model numbers for that device info like I though I did. I have some read-only stuff for air-to-water systems here, but it has just temperatures for now. I would need help with that because I'm doing this with a blackbox or record/replay type approach (just in case) and therefore I don't have access to the source code of the original application. Help would be appreaciated. Right now it would be awesome to have captures of |
|
While working with @vilppuvuorinen on Discord to get some testing data, I produced a Gist with some dumped data. To keep things together and to provide a resource for random internet wanderers, I'm linking it here. Thanks for looking into this! |
| speed = self._api.device.fan_speed | ||
| if speed is None: | ||
| return None | ||
| return speed.replace("-", " ") |
There was a problem hiding this comment.
Maybe this replace belongs to the backend library?
There was a problem hiding this comment.
There's a supposedly dynamic amount of fan speeds available in these devices. The backend lib doing this speed-%d mapping for them and this is just to turn that "constant-y" string to "human readable" variant. What I'm trying to say is that I think the replace belongs here, but it just sucks.
Would it be better to use the FAN_* fan mode constants here instead of sequentially numbered speeds? I should be possible at least, but I don't know if it has any benefits.
There was a problem hiding this comment.
Sorry, I don't know about the details, but maybe using those constants will help when it comes to consistency (think: usage via voice controls)?
|
|
||
| async def async_set_fan_mode(self, fan_mode: str) -> None: | ||
| """Set new target fan mode.""" | ||
| await self._api.device.set({"fan_speed": fan_mode.replace(" ", "-")}) |
There was a problem hiding this comment.
FAN_* built-in mode mappings could work here too.
|
Swing modes (vertical vane adjusting) is missing Auto, Top, MiddleTop, Middle, MiddleBottom, Bottom and Swing |
| speed = self._api.device.fan_speed | ||
| if speed is None: | ||
| return None | ||
| return speed.replace("-", " ") |
There was a problem hiding this comment.
Sorry, I don't know about the details, but maybe using those constants will help when it comes to consistency (think: usage via voice controls)?
|
@MuppetOwl I'll have to backtrack on my comments on the forum. |
rytilahti
left a comment
There was a problem hiding this comment.
This looks fine to me, I left a couple of comments on very minor issues, maybe someone else can also take a quick look before getting this merged?
rytilahti
left a comment
There was a problem hiding this comment.
Looks good to me, but considering the PRs merged by myself often get commented after the merge, I hope someone else will also take a quick look before we proceed with merging :-) (ping @MartinHjelmare ;-))
MartinHjelmare
left a comment
There was a problem hiding this comment.
Don't we want to set up a way to refresh the token automatically?
|
@MartinHjelmare Regarding the token update. I don't think it's possible to setup automatic token update without storing the password. There's a OAuth provider attached to the service, but that's aimed at Alexa integration and such. The response from customer service was hostile enough so that's definitely off the table. I was hoping I could avoid storing the password. Should I just bite the bullet and store the password and implement token refresh? The tokens seem to be extremely long lived and therefore it is also difficult to assess how the expiry logic would work. Regarding imports: Should I use relative imports for importing things from the I'll see about the other comments later today. |
|
Ok, let's keep the token handling like it is for now. We have helpers for implementing an oauth flow in the config flow if you want to try that in the future. Maybe you've already read that? Yes, intra-package imports should be relative. |
* Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background.
Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib.
* Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow.
* any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list
ca414fd to
1acac8b
Compare
|
That test failure does not make sense to me. As if pylint didn't see the usage at |
Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>
|
Should I squash the commits now? |
|
No, please don't do that. We'll squash when merging. |
This comment has been minimized.
This comment has been minimized.
|
Considering we have already three approvals, let's get this merged. Thanks @vilppuvuorinen! 🎉 |

Description:
This stuff is not supported nor in any way affiliated with Mitsubishi Electric.
Provides climate and sensor platforms for Mitsubishi Electric heat pumps connected to MELCloud service. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. This thing started as a
custom_component.Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. This is a bit unorthodox, but at least I like it better than storing the plain-text password.
Additional information
Link to documentation pull request: home-assistant/home-assistant.io#11930
Checklist:
tox. Your PR cannot be merged unless tests passIf user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
python3 -m script.hassfest.requirements_all.txtby runningpython3 -m script.gen_requirements_all..coveragerc.