Skip to content

Add support for notification streams #226

@robbinjanssen

Description

@robbinjanssen

Both WD5 and WD4 have support for notification streams. Basically this is a HTTP GET call that is kept-alive and keeps receiving JSON updates about thermostats.

  1. Where do we put this code, ojmicroline.py is currently responsible for data-fetching, however since both WD4 and WD5 are pretty different (1 call vs 3 calls), im not sure where to put it. @adamjernst any suggestions?
  2. Then we need to figure out what HA requires for these push updates. I think we need to implement something like registration for listeners and callbacks to those listeners?

For WD5 this is a POC:

async def get_stream_connection(
    self, 
    session_id: str,
    session: ClientSession
) -> Any:
    async with async_timeout.timeout(30):
        # Negotiate
        url = URL.build(
            scheme="https", 
            host=self.host, 
            path="/ocd5notification/negotiate",
            query={"clientProtocol": "1.3"}
        )
        
        response = await session.request(method="GET", url=url, ssl=True)
        response.raise_for_status()

        data = json.loads(await response.text());
        connectionId = data['ConnectionId']
        connectionToken = data['ConnectionToken']
    
        # Start
        url = URL.build(
            scheme="https", 
            host=self.host, 
            path="/ocd5notification/send",
            query={
                "transport": "serverSentEvents",
                "connectionToken": connectionToken,
                "connectionId": connectionId,
            },
        )

        response = await session.request(
            method="POST",
            url=url, 
            headers={"Content-Type": "application/x-www-form-urlencoded"}, 
            data=f"data={session_id}",
            ssl=True
        )
        response.raise_for_status()

        # Connect to stream
        url = URL.build(
            scheme="https", 
            host=self.host, 
            path="/ocd5notification/connect",
            query={
                "transport": "serverSentEvents",
                "connectionToken": connectionToken,
                "connectionId": connectionId,
            },
        )

        response = await session.request(method="GET", url=url, headers={"Accept":"text/event-stream"}, ssl=True)
        response.raise_for_status()

        async for line in response.content:
            data = line.decode('ascii').strip()
            if (data == ""):
                continue

            data = data[6:]
            if data != 'initialized':
                data = json.loads(data)
            
            if "M" not in data:
                continue
            
            for event in data["M"]:
                print(json.dumps(event, indent=2))

Metadata

Metadata

Assignees

No one assigned

    Labels

    new-featureNew features or options.no-staleThis issue or PR is exempted from the stable bot.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions