zwave-js / zwave-js-server

Apache License 2.0
143 stars 18 forks source link

Typescript types package for client #1189

Closed alexojegu closed 2 months ago

alexojegu commented 6 months ago

Would it be possible to have a Typescript types package for client?

Having Typescript types for incoming and outgoing messages could help develop other services based on zwave-js-server, for example a plugin for Homebridge.

I'm not sure if they could be generated automatically from the current source code.

raman325 commented 5 months ago

are you asking for this because you don't want to install the server if you just need the types? You can always add this package in devDependencies and then you will have access to all the types

alexojegu commented 5 months ago

Are you asking for this because you don't want to install the server if you just need the types?

Exactly, that's the reason.

You can always add this package in devDependencies and then you will have access to all the types

I tried, but I had problems with the enums. Quick example:

import { IncomingMessage } from "@zwave-js/server/dist/lib/incoming_message.js"
import { WebSocket } from "undici";

export class SocketClient {
    private socket: WebSocket;

    public constructor() {
        this.socket = new WebSocket("ws://192.168.1.5:3000");

        this.send({
            messageId: "initialize",
            command: "initialize",
            schemaVersion: 35
        })
    }

    public send(message: IncomingMessage): void {
        this.socket.send(JSON.stringify(message));
    }
}

Typescript error:

src/socketClient.ts:12:13 - error TS2322: Type '"initialize"' is not assignable to type 'ServerCommand | NodeCommand | ControllerCommand | DriverCommand | MulticastGroupCommand | BroadcastNodeCommand | EndpointCommand | UtilsCommand'.

12             command: "initialize",
               ~~~~~~~

  node_modules/@zwave-js/server/dist/lib/incoming_message.d.ts:13:5
    13     command: ServerCommand.startListening;
           ~~~~~~~
    The expected type comes from property 'command' which is declared here on type 'IncomingMessage'

Found 1 error.
alexojegu commented 5 months ago

Well, for now I am using my own types to incoming/outcoming messages (with several any).

But now I'm having problems with the schema version and the ZwaveState / NodeState types (I imagine ControllerState has the same problem, but I'm not using it):

import { ZwaveState } from "@zwave-js/server";

protected async handleStart(): Promise<void> {
  await this.sendMessage({
    messageId: "initialize",
    command: "initialize",
    schemaVersion: 35,
  });

  const response = await this.sendMessage({
    messageId: "start_listening",
    command: "start_listening",
  });

  this.discoverDevice(response.result.state);
}

private discoverDevice({ nodes }: ZwaveState): void {
  for (const node of nodes) {
    if (node.isControllerNode) {
      continue;
    }
  }
}

I can't find a way to select the type corresponding to the correct version of the schema, in this case 35:

src/zwavePlatform.ts:83:22 - error TS2339: Property 'isControllerNode' does not exist on type 'NodeState'.
  Property 'isControllerNode' does not exist on type 'NodeStateSchema0'.

83             if (node.isControllerNode) {
                        ~~~~~~~~~~~~~~~~

Found 1 error.

Any idea how to solve the problem?

raman325 commented 2 months ago

src/socketClient.ts:12:13 - error TS2322: Type '"initialize"' is not assignable to type 'ServerCommand | NodeCommand | ControllerCommand | DriverCommand | MulticastGroupCommand | BroadcastNodeCommand | EndpointCommand | UtilsCommand'.

I think once https://github.com/zwave-js/zwave-js-server/pull/1259 is merged, you can import ServerCommand and use ServerCommand.initialize directly

raman325 commented 2 months ago

and now it solves both issues