Thanks - I suspected it might be. From my testing, Javascript handles web sockets differently. It doesn’t need to “talk” to the server at the “user level” (or is doing so behind the scenes)… A ping/pong seems to be sufficient.
Here’s a more complete Python example if you want to try it.
# WS client example
# Listens to broadcast events from the Ezlo hub
import asyncio
import websockets
async def wsListener():
uri = "ws://192.168.1.176:17000/"
while True:
async with websockets.connect(uri) as websocket:
greeting = await websocket.recv()
print ("Hub says: " + greeting)
await asyncio.sleep(0.5)
def startListener():
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(wsListener())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
loop.close()
def main():
print ("Starting hub listener")
startListener()
# The main entry point for our app.
if __name__ == '__main__':
main()
I’ll give it a go later. My test on an insecure channel with anonymous access just concluded at over 20 hours continuous with no data moving other than ping/pong. I wonder if this is something specific to the Python implementation, because I can confirm by my own network monitoring that there’s no other data on channel (nothing going on “behind the scenes”). I’m also going to try it with my Lua WS implementation (LuWS) and see what happens. Stay tuned.
Thanks - I can’t tell (yet) if it’s a Python “issue” or a Javascript “feature”. With Python you have to send user-level requests to keep the connection alive (even with ping/pong) but with Javascript a ping/pong alone appears to be sufficient.
I really wish you could search the results in the API Tool. Or they would change the results output so the friendly device names are displayed first.
I have 102 devices on my Ezlo Plus and trying to find one particular device in that list, to then try and find its _id for say the “Switch” item is a nightmare.
I just finished about a 45 minute run on your code with no disconnect/stall. I was running on Ubuntu 20.04.2 (under VMWare) with Python 3.8.10, websockets 9.1, asyncio 3.4.3. I’ve just started another test with more careful timing measurement. The hub is dead quiet (no activity/testing/development going on during these tests) other than a single manipulation of a switch at the start to make it send a ui_broadcast to confirm the app is actually connected.
Interesting… it definitely disconnects (freezes on my end), unless I add a hub-level query. Difficult one to track down… be curious what other users get if they try it.
In general request with filter by deviceId looks like this:
{
"method": "hub.items.list",
"id": "_ID_",
"params": {
"deviceIds": [
"deviceId0",
"deviceId1"
]
}
}
We have 3 types of entities representing physical devices: logical devices, items, device settings.
Logical device is just a container with functionality. The functionality of the device is represented by items and settings. As usual, items are enough for typical device managing; settings are used for deeper customization.
Physical device can have several functionalities under the hood (E.g. sensor device with motion sensor and the smoke sensor inside or multichannel plug with several outputs; etc…). So we split these sub functionalities: physical device can be divided into several logical devices. Each included physical device has a root logical device, other logical devices are children. Look at the field “parentDeviceId”. It’s empty for root and not empty for children.
Each logical device contains a set of functionality representing by items (each logical device has one or more items). Take the field “deviceId” to match the item to the device. Once again: an item is a simple but holistic element of the functionality (switch, sensor, thermostat setpoint, doorlock state, etc…), the logical device can have a set of items. The principle is the same for device settings (except that only the root logical device has settings).
If the user of firmware API just has started his application, he should request hub.devices.list, hub.items.list, hub.device.settings.list and build own UI model depend on his application purposes. Then it’s not necessary to request all these things each time, better listen to broadcasts.
Re: “If the user of firmware API just has started his application, he should request hub.devices.list, hub.items.list, hub.device.settings.list and build own UI model depend on his application purposes. Then it’s not necessary to request all these things each time, better listen to broadcasts.”