Thanks, do I need to use a corodinator or just call the function (method?)
I tried calling the function directly for the switch.py, I added:
from .api import post_data
def turn_on(self, **_kwargs):
"""Turn on device"""
api.post_data(self.parameter, "ON")
def turn_off(self, **_kwargs):
"""Turn off device"""
api.post_data(self.parameter, "OFF")
But this just broke the switch, so I must have it wrong?
Edit: just found the error, it cant import api.post_data
ImportError: cannot import name âpost_dataâ from âcustom_components.msp_integration_requests_example.apiâ (/config/custom_components/msp_integration_requests_example/api.py)
You cannot just call the post data directly like this when it is part of a class. Your code will be erroring for a slightly different reason in that you have imported post_data but you are calling api.post_ data instead of just post_data. But for the reason above, it would not work anyway and would error when you used your switch.
Access to your instantiated api class exists in your coordinator.
Iâm sending this which seems to work let me test yours:
r = requests.post(f"http://{self.host}/{path}", f"{parameter}={value}", timeout=10)
Doesnât like your data=data
Errors:
TypeError: a bytes-like object is required, not âstrâ
I do note using my f"{parameter}={value}" the switches works, but they change ON->OFF->ON after toggling to ON
Is there someway to force the API to read after switch toggles?
Tried this, doesnât fix it, self.coordinator.api.get_data(âapiâ) the:
ON->OFF->ON after toggling to ON similar for offâŚ
Note the actual device is not doing this, it changes to the correct position immediately, and does not change, itâs just the Home Assistant GUI.
Seems like a timing thing, if I toggle the switch just before the API reads it doesnât do it.
Need to figure out how to get the coordinator to update its values after a change of switch positions.
to force an immediate update as some of the other methods try to batch and wait a while before doing an update which gives you the switch behaviour as you see.
Just doing some clean up and wondering why the sensors are not getting created with correct unique name, they get the name like:
sensor.battery_soh
Shouldnât they have a unique name like below?
eg sensor.DOMAIN-Master-battery_soh
@property
def unique_id(self) -> str:
"""Return unique id."""
# All entities must have a unique id. Think carefully what you want this to be as
# changing it later will cause HA to create new entities.
return (f"{DOMAIN}-{self.coordinator.get_api_data_value("role")}-{self.parameter}")
You can do this how you think and is very much based on what your device/api is.
I wouldnât necessarily include your domain name but often it makes sense to include the device name. I assume you have amended the device_info property or are at least happy with it as it is?
There is actually a nice function in HA to add the device name to your entity name by setting
_attr_has_entity_name = True
in your entity class. Ie.
class ExampleBaseSensor(CoordinatorEntity, SensorEntity):
"""Implementation of a sensor."""
_attr_has_entity_name = True
def __init__(self, coordinator: ExampleCoordinator, parameter_name: str) -> None:
"""Initialise sensor."""
super().__init__(coordinator)
self.parameter = parameter_name
self.parameter_value = coordinator.get_api_data_value(self.parameter)
I think you may need to remove and re-add for it to recreate these entities with their new ids.
Also, you have not changed the unique id property, which is fine, but if you have multiple devices you want to add, this will not generate unique ids. Again, as per the comments, think about this and structure how you see fit.
Edit: sorry was having a thick moment and now get what youre asking. No, unique_id does not define the entity_id. I know! Unique id is a hidden id in the entity registry. Entity id is generated based on the entity name with the caveat that HA will also do some other things re generating the entity id based on the attribute mentioned above and also translations keys and adding numbers to the end if not unique etc.
I was browsing them and have some suggestions/questions. Not sure if this is the best place to mention them, but anyways
There is this comment:
# If you have created any custom services, they need to be removed here too.
I understood from some discussions on Discord a while back that nowadays it is preferred to just register the services when the integration gets loaded (I think it was in async_setup) and not remove them. Unfortunately I donât recall the details of the reason for this.
A bit of a nitpick, but there are some comments in the fan.py that mention lights which is a bit confusing.
Is there a specific reason to use requests in the examples?
When using aiohttp or httpx would avoid the need for wrapping the calls in async_add_executor_job all the time.
I think you can simplify the async_unload_entry by adding the updatelistener like below so it will be unloaded with the entry without additional code in the async_unload_entry.
Iâll lok into the custom services comment as not aware of this. I do know however, that the example doesnât actually unload them anyway. It was on my to fix list.
Great, will fix fan comments.
In terms of using requests, it was more about using a sync library as many libraries out there for integration to IOT are sync and it demonstrates how to use these in HA. Obviously, it doesnt actually use the requests methods and uses non blocking mock api methods so desnt need to run on a thread.
And yes, good point about unloading listeners, will amend that.
Can you please provide some guidance or an example that uses a serial connection to talk to the device? I have a large number of devices that communicate with serial that I have written commercial drivers for other automation platforms in the past and I would like to take a stab at porting those over to home assistant but the documentation (in general, not yours) is very limited, very confusing, seems to assume youâre a 12th tier python ninja (sorry, Iâm on programming language number 35 or 40 with python, the lines get blurry and its hard to be that in depth). I have serial controlled PDUs for example, that seems like an incredibly easy integration to write. I have a python class built that will authenticate to the PDUs and grab sensor data and control the state of the outlets. I was expecting it to be trivial to integrate but I donât even know where to get started. I have written it with queues and asyncio (aioserial) so its fully non blocking but I donât know where to insert my event loop. Looking at the main docs it seems to indicate that IO should only occur in the update function. Specifically it says âAll data has to be fetched inside the update method and cached on the entityâ, does that mean I launch a loop and serial read/write coroutines from within the update? I am very confused. I have only found two serial integrations and Iâm struggling to reverse engineer them as they are written completely differently from each other and from the way you have written these examples. They also seem to require serial to ethernet adapters. It kind of astounds me that there are so few examples given the massive number of serial controlled av devices out there. A fully commented working example would go miles to help me out. I can provide my python code but didnât want to dump a big chunk of code thatâs off topic into the thread.
Sure. Let me look at this for you. If you could post a link to your api that would really help (as guessing your api is handling all serial io and this is more about using that in HA?).