Add Modbus cover#33642
Add Modbus cover#33642ctalkington merged 16 commits intohome-assistant:devfrom Lutemi:feature/modbus-cover
Conversation
|
Hey there @adamchengtkc, @janiversen, mind taking a look at this pull request as its been labeled with a integration ( |
janiversen
left a comment
There was a problem hiding this comment.
We should think of moving the read functions into modbushub in init.py as it seems there are most (if not all) entities, use the exact same pattern (inclduding the testing for HOLDING or INPUT). However this can be done in another PR.
The code looks good, good work!
|
Your 3 PR are all OK from my side, now we just need to wait for someone with write access to look at them. Regarding the score, once I am over the current set of errors (open issues), I will deal with the logging. |
|
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
|
@janiversen what's the status with the async |
|
Sorry for the delay in responding, I was occupied with the change in “state of alert” here in Spain, which are slowly moving back to a somewhat normal life. The async code is waiting for a new version from pymodbus, I am working on an alternative that bypasses the communication part of pymodbus, but it is only moving slowly forward. I prefer if it is not much work, that you convert to sync and we get it merged. When in future we make an async version I will make the needed changes for all components. |
|
@janiversen I was busy with other stuff too. But I will start working on it again. Converting my code shouldn't be much work. Also, I'll keep async versions. Later, either you could modify it or just ask me and I'll provide the files. |
|
Perfect, let me know when you want a review, so we can get this code merged, it is long overdue. |
|
@janiversen I still work on this. I didn't verify my latest changes manually. Also, I would love to include at least some unit tests, but I didn't grasp how existing tests are written. Tests for Modbus sensor are clear, but cover is more complicated. My main issue is that the tests in general are not well documented, and sometimes I have no clue what they're doing. However, this PR can be changed from draft again, and you guys can start reviewing my code. I can always include tests in a separate PR. Thanks! |
@janiversen - If I can help with testing of the async solution, please let me know. |
|
@janiversen I fixed a couple of issues, and tested the code manually. Now it's ready for review. Please take a look at it now. Thanks! |
|
Looks real good, ready to be merged from my side. Lets see if @MartinHjelmare is happy too. |
MartinHjelmare
left a comment
There was a problem hiding this comment.
Looks good! Some comments.
|
@MartinHjelmare I implemented changes according to your comments. Please check now. Thanks! |
|
@MartinHjelmare, @janiversen please take a look at the latest code.
CONFIG CHANGEDue to the change to move For a better demonstration, here's the original config: modbus:
- name: plc_01
type: tcp
host: 127.0.0.1
port: 5020And here's a new config. Note the modbus:
hubs:
- name: plc_01
type: tcp
host: 127.0.0.1
port: 5020
covers:
- name: plc_01_door
scan_interval: 1
hub: plc_01
slave: 1
coil: 0
device_class: door
status_register: 4
status_register_type: input
state_opening: 1
state_open: 2
state_closing: 3
state_closed: 4This config is very readable, but it's a breaking change. What's your suggestion on this? Perhaps I could introduce a backward compatibility. However, in such cases users cannot use the new WarningsWhen I run such a config, Home Assistant issues a warning. It's not critical and has no effect on the component. However, please take a look at the log output. 2020-07-03 17:40:51 WARNING (Recorder) [homeassistant.components.recorder] Event is not JSON serializable: <Event platform_discovered[L]: service=load_platform.cover, platform=modbus, discovered=[OrderedDict([('name', 'plc_01_door'), ('scan_interval', datetime.timedelta(seconds=1)), ('hub', 'plc_01'), ('slave', 1), ('coil', 0), ('device_class', 'door'), ('status_register', 4), ('status_register_type', 'input'), ('state_opening', 1), ('state_open', 2), ('state_closing', 3), ('state_closed', 4)])]>DEFAULT HUBUpdate: I created a separate PR to deal with this issue: #37546 Each modbus component has an optional Please advise on both issues. |
|
Finally, I updated this PR with some of the requested changes:
Please take a look at it, so we can finally start cleaning this PR. Thanks! |
|
LGTM. |
|
I would really not like to have/make a global change to the config of the whole modbus, for a couple of reasons:
|
The code as is implemented now doesn't break anything. It adds Modbus covers as an optional list inside hub definition (see updated description). Existing config should NOT be affected. Global config change makes sense, but it can be postponed. However, we should do it at some point, because maintenance and coding new features is harder. |
|
Yes a global change surely makes sense, but it must be timed !! I saw your config did not break the existing ones, sorry for not mentioning that. It would be real nice to get PR merged. |
|
Cover is new, so how can this be a breaking change? |
|
That's stale. |
|
@MartinHjelmare thanks! What's the next step? Should I squash the commits before we merge it? |
MartinHjelmare
left a comment
There was a problem hiding this comment.
Sorry, this old comment hadn't been addressed.
|
No, we'll squash when we merge. |
* Add Modbus cover * Fix improper commands written for Modbus cover via coil * Make changes per review comments * Fix default hub not defined Since support for multiple hubs was added, the default hub option was not implemented correctly. Now I added necessary logic to make it work. First hub in a list will be used as a default hub. * Move Cover config under Modbus section * Revert setting up a default hub alias * Make hub mandatory for Cover * Add default scan interval * Read scan_interval from discovery info * Fix linter error * Use default scan interval from Cover platform * Handle polling for Modbus cover directly inside entity * Move covers under hub config * Fix for review comment * Call update() from Cover actuator methods * Fix time validation
* Add Modbus cover * Fix improper commands written for Modbus cover via coil * Make changes per review comments * Fix default hub not defined Since support for multiple hubs was added, the default hub option was not implemented correctly. Now I added necessary logic to make it work. First hub in a list will be used as a default hub. * Move Cover config under Modbus section * Revert setting up a default hub alias * Make hub mandatory for Cover * Add default scan interval * Read scan_interval from discovery info * Fix linter error * Use default scan interval from Cover platform * Handle polling for Modbus cover directly inside entity * Move covers under hub config * Fix for review comment * Call update() from Cover actuator methods * Fix time validation
|
@vzahradnik may I ask which modbus devices this integration works with on your end? I might be looking for a couple hundred of these. |
|
@makuser I use this integration with Controllino Mega, which is an industry-grade Arduino Mega. I have most of the logic there, and Home Assistant provides a frontend and automation logic to it. I also have some other Modbus devices, but even in this case the data goes through Controllino. It takes Modbus over TCP, and sends it as Modbus RTU over RS485 (serial). This solution works very well. I am thinking of writing a blog post about it. In the meantime, however, feel free to ask. |
Proposed change
This pull request adds a new Modbus entity - cover. At the moment, this implementation supports
open,closed,opening, andclosingstates.User can control the cover using a coil or a holding register. If a coil is used, we can't detect intermediary states like opening or closing. Therefore, an optional
status_registerattribute was defined, so that the cover state can be read from the register.If user decides to use holding register to control the cover, this register is also used for reading the states back. However, user can specify
status_registerwhich will take priority also in this case.To map register values to actual states, four optional attributes were defined (with reasonable default values). User can override any or all of the values, e.g.,
state_open=1, orstate_closing=3. If the cover is controlled by the holding register, thestate_openandstate_closedattributes are also used for writing into the register, and controlling the state of the cover.Configuration validation was adjusted, so that either
coilorregisteris specified. User needs to specify one of these attributes. If both or none of them are specified, a config error is logged.Type of change
Example entry for
configuration.yaml:Note: for more examples, please refer to the documentation PR. I provided several examples to make the usage clear to the user.
Additional information
Checklist
black --fast homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all..coveragerc.The integration reached or maintains the following Integration Quality Scale: