project-chip / connectedhomeip

Matter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.
https://buildwithmatter.com
Apache License 2.0
7.25k stars 1.93k forks source link

[Feature] [chip-tool] send web socket on interactive server mode #32478

Open mmt-10 opened 4 months ago

mmt-10 commented 4 months ago

Feature description

Hi,

I would like chip-tool to send the information of the subscribe cluster it received via web socket.

Execute ./chip-tool interactive server. Set onoff subscribe on-off 5 10 <node id> 1 via web socket.

chip-tool shows received data from cluster's subscribed message. However, chip-tool did not send received message via web socket.

Platform

core

Platform Version(s)

No response

Anything else?

No response

Chapoly1305 commented 4 months ago

same here, looking for a solution, or a workaround

PokersKun commented 4 months ago

Also looking at this, any solutions? @vivien-apple @bzbarsky-apple

bzbarsky-apple commented 4 months ago

Someone would have to write code for this.

Chapoly1305 commented 4 months ago

It's quite complex to add feature into the project itself, but I think it might be possible to create a workaround. The chiptool can use trace parameter to generate a live json file, maybe we can setup a separated ws server to publish periodic messages until officially supported. Maybe a Python script to consume the content of the json file?

PhLuReh commented 3 weeks ago

I think current implementation is more or less not thought to be asynchronous (which would in fact be supported by websocket). But the implementation allows for an empty (or numeric only for specifying a timeout in s) message, which will be used as async call. So if results are reported (for example by the registered subscriptions), those will be returned by the next read after async call.

This is my exemplary Python implementation, which is hopefully helpful:

async def recv(websocket):
    while True:
        # send async call
        await websocket.send("")
        # wait for response
        msg = await websocket.recv()
        now = datetime.now()
        default = True
        try:
            data = json.loads(msg)
            # if result was json and contains results
            if "results" in data:
                for res in data["results"]:
                    # if it was a change of an attribute value. print it
                    if "endpointId" in res:
                        print(f"[{now}] endpoint {res['endpointId']}: {res['attributeId']}={res['value']}")
                        default = False
        except Exception:
            pass
        if default:
            print(f"{msg}")

Having a timeout set in the async call also enables to receive logs and failures. But I also resulted in some Segmentation Fault over time (10-20s).

mmt-10 commented 1 week ago

@PhLuReh

Thank you for your solution. Our member tried your solution.

We make 2 websocket interfaces as below; for Sending command (input only) ws://localhost:9002 for Subscribe command (listen only) ws://localhost:9003

Then, Segmentation Fault disappeared.