Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update quickstart example so the code does not fail with "Failed to initialize the driver: undefined is not a function" #2077

Closed
AlCalzone opened this issue Mar 15, 2021 · 6 comments · Fixed by #2079

Comments

@AlCalzone
Copy link
Member

@esteban-uo unfortunately, the log is not enough to figure out where the error is coming from. Can you edit one file and try again?
node_modules/zwave-js/build/lib/driver/Driver.js, edit line 431:

-                    message = `Failed to initialize the driver: ${e instanceof Error ? e.message : String(e)}`;
+                    message = `Failed to initialize the driver: ${e instanceof Error ? e.stack : String(e)}`;

This should give us an idea what is happening.

@AlCalzone AlCalzone added bug Something isn't working waiting for info ⏳ labels Mar 15, 2021
@esteban-uo
Copy link

thanks a lot! @AlCalzone

the stacktrace is now:

11:58:38.355 DRIVER   Failed to initialize the driver: TypeError: undefined is not a function
                          at Map.forEach (<anonymous>)
                          at Driver.<anonymous> (/usr/src/app/test.js:26:29)
                          at Object.onceWrapper (node:events:484:28)
                          at Driver.emit (node:events:378:20)
                          at Driver.EventEmitter.emit (node:domain:470:12)
                          at Driver.initializeControllerAndNodes (/usr/src/app/node_modules/zwave-js
                      /src/lib/driver/Driver.ts:836:8)
                          at Immediate.<anonymous> (/usr/src/app/node_modules/zwave-js/src/lib/drive
                      r/Driver.ts:731:5)
ZWaveError: Failed to initialize the driver: TypeError: undefined is not a function
    at Map.forEach (<anonymous>)
    at Driver.<anonymous> (/usr/src/app/test.js:26:29)
    at Object.onceWrapper (node:events:484:28)
    at Driver.emit (node:events:378:20)
    at Driver.EventEmitter.emit (node:domain:470:12)
    at Driver.initializeControllerAndNodes (/usr/src/app/node_modules/zwave-js/src/lib/driver/Driver.ts:836:8)
    at Immediate.<anonymous> (/usr/src/app/node_modules/zwave-js/src/lib/driver/Driver.ts:731:5)
    at Immediate.<anonymous> (/usr/src/app/node_modules/zwave-js/src/lib/driver/Driver.ts:747:6) {
  code: 5,
  context: undefined,
  transactionSource: undefined
}

@esteban-uo
Copy link

esteban-uo commented Mar 15, 2021

@AlCalzone I think the issue is that I misunderstood the quick-start example:

// ...
driver.controller.nodes.forEach(
        // e.g. add event handlers to all known nodes
    );

    // When a node is marked as ready, it is safe to control it
    const node = driver.controller.nodes.get(2);
    node.once("ready", async () => {
        // e.g. perform a BasicCC::Set with target value 50
        await node.commandClasses.Basic.set(50);
    });
// ...

Seems to be even when the event ready is fired, it doesn't mean the nodes are ready, so the .nodes is still undefined... so I just commented out that and after I ran:

    driver.once("driver ready", () => {
    /*
    Now the controller interview is complete. This means we know which nodes
    are included in the network, but they might not be ready yet.
    The node interview will continue in the background.
    */

    console.log(driver.controller.nodes)

    // driver.controller.nodes.forEach(
    //     // e.g. add event handlers to all known nodes
    // );

    // // After a node was interviewed, it is safe to control it
    // const node = driver.controller.nodes.get(2);
    // node.once("interview completed", async () => {
    //     // e.g. perform a BasicCC::Set with target value 50
    //     await node.commandClasses.Basic.set(50);
    // });
});

now it looks better

12:10:15.709 DRIVER « [RES] [GetRoutingInfo]
                        node ids: 1
12:10:16.027 CNTRLR « [Node 002]   node neighbors received: 1
12:10:16.060 CNTRLR   [Node 002] Interview stage completed: Neighbors
12:10:16.077 CNTRLR   [Node 002] Interview completed
12:10:16.114 CNTRLR   [Node 002] The node is ready to be used
12:10:16.141 CNTRLR   All nodes are ready to be used

@AlCalzone
Copy link
Member Author

Hmm, that shouldn't be. Your code gets executed when the driver ready event is emitted. The driver itself uses controller.nodes in the very next line and does not crash:

grafik

@AlCalzone
Copy link
Member Author

So I just tested with a slight variant of the quick start code:

const { Driver } = require("zwave-js");

// Tell the driver which serial port to use
const driver = new Driver("COM5");
// You must add a handler for the error event before starting the driver
driver.on("error", (e) => {
	// Do something with it
	console.error(e);
});
// Listen for the driver ready event before doing anything with the driver
driver.once("driver ready", () => {
	/*
    Now the controller interview is complete. This means we know which nodes
    are included in the network, but they might not be ready yet.
    The node interview will continue in the background.
    */

	driver.controller.nodes.forEach(
		// e.g. add event handlers to all known nodes
		(node) => {
			console.log(node.id);
		},
	);

	// When a node is marked as ready, it is safe to control it
	const node = driver.controller.nodes.get(7);
	node.once("ready", async () => {
		// e.g. perform a BasicCC::Set with target value 50
		await node.commandClasses.Basic.set(50);
	});
});
// Start the driver. To await this method, put this line into an async method
void driver.start();

and that runs fine for me. I guess there's else something you did wrong.

@AlCalzone AlCalzone added working as intended ✔ and removed bug Something isn't working labels Mar 15, 2021
@esteban-uo
Copy link

esteban-uo commented Mar 15, 2021

@AlCalzone looks good actually!

because I just copy paste the quick start, the forEach handler should must have always a function...

[1,2,3].forEach()
Uncaught TypeError: undefined is not a function
    at Array.forEach (<anonymous>)
  driver.controller.nodes.forEach((node) => {
    console.log(node)
  });

doing so, then is ok... shame on me! maybe for other dummies might be helpful to update the docu at least that part?

Anyway, thanks a lot! <3

@AlCalzone
Copy link
Member Author

I guess we could at least show the boilerplate for the callback function.

@AlCalzone AlCalzone changed the title Failed to initialize the driver: undefined is not a function Update quickstart example so the code does not fail with "Failed to initialize the driver: undefined is not a function" Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants