Giter Club home page Giter Club logo

nathankellenicki / node-poweredup Goto Github PK

View Code? Open in Web Editor NEW
459.0 459.0 58.0 3.29 MB

A Javascript module to interface with LEGO Powered Up components.

Home Page: https://nathankellenicki.github.io/node-poweredup/

License: MIT License

TypeScript 98.66% HTML 0.93% JavaScript 0.41%
boost controlplus duplo duplotrain lego legoboost legocontrolplus legoeducation legopoweredup legospikeprime legotechniccontrolplus legowedo2 nodejs poweredup spikeprime technic techniccontrolplus typescript wedo2

node-poweredup's People

Contributors

10on avatar aileo avatar churchs19 avatar david-colombo avatar debenben avatar dependabot[bot] avatar firien avatar highflying avatar jncraton avatar nathankellenicki avatar nutki avatar p8nut avatar sciguy16 avatar techi602 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-poweredup's Issues

Cannot find module

Hi

I having problems running the code, It errors with

internal/modules/cjs/loader.js:302
      throw err;
      ^

Error: Cannot find module '/Projects/train_controller/duplo-app_controller/dist/node/index-node.js'. Please verify that the package.json has a valid "main" entry
    at tryPackage (internal/modules/cjs/loader.js:294:19)
    at Function.Module._findPath (internal/modules/cjs/loader.js:525:18)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:781:27)
    at Function.Module._load (internal/modules/cjs/loader.js:687:27)
    at Module.require (internal/modules/cjs/loader.js:849:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Projects/train_controller/duplo-app_controller/test3/node.js:1:19)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32) {
  code: 'MODULE_NOT_FOUND',
  path: '/Projects/train_controller/duplo-app_controller/package.json',
  requestPath: '..'
}

I installed by doing the following

npm init -y
npm install node-poweredup --save
sudo node ./node.js

I am running OSX 10.14.5
It managed to make it work on my work machine running OSX 10.12

So it there something i need to change to make it run on 10.14

Any help would very much be appreciated

Cheers

James

Can't connect to Control+ hub

Hey Nathan!

First of all – super nice project. Thank you so much!
I tried to connect a Control+ hub on my MacBook with Node, but wasn't able to to do that. I'm running on MacOS 10.14.6 and Node 8.0.0/10.16.3/12.9.0 (none of them worked). Running DEBUG=* node ./example.js just says:

Scanning for Hubs...
  noble stateChange poweredOn +0ms
  poweredup Scanning started +0ms
  noble scanStart +1ms

and then nothing happens.

Interestingly, the connection works fine via the Web API.

Do you have an idea what I could try or where I could dig deeper?

Uncaught (in promise) DOMException

When using the browser version and connecting on a Android Pixel 2 in Chrome I'm getting the following error 'Uncaught (in promise) DOMException'. When connecting on a laptop it works.

Screenshot 2019-08-12 at 14 33 58

This relates to the following function:
writeToCharacteristic(uuid, data, callback) { this._queue = this._queue.then(() => this._characteristics[uuid].writeValue(data)).then(() => { if (callback) { callback(); } }); }

Getting error [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to write outside buffer bounds

Hello,

I just discovered today this very interesting project, but I'm having some trouble running it. I'm using Windows 10 and yesterday I managed to run successfully the project movehub-async . movehub-async has a narrower scope than this project; i.e. it works only with Lego Boost, whereas this project, node-poweredup, seems to support all devices using the Lego Wireless Protocol (LWP). I mention that I installed all noble prerequisites, including installing the WinUSB driver.

The first issue I got with both projects was:

Error: No compatible USB Bluetooth 4.0 device found!
    at BluetoothHciSocket.bindUser (D:\temp\test-js-ble2\node_modules\bluetooth-hci-socket\lib\usb.js:70:11)
    at BluetoothHciSocket.bindRaw (D:\temp\test-js-ble2\node_modules\bluetooth-hci-socket\lib\usb.js:28:8)
    at Hci.init (D:\temp\test-js-ble2\node_modules\noble-mac\node_modules\noble\lib\hci-socket\hci.js:101:35)
    at NobleBindings.init (D:\temp\test-js-ble2\node_modules\noble-mac\node_modules\noble\lib\hci-socket\bindings.js:82:13)
    at Noble.<anonymous> (D:\temp\test-js-ble2\node_modules\noble-mac\node_modules\noble\lib\noble.js:57:24)

Having an Intel Bluetooth module, I tried my luck (as some google results suggested) and I modified the file \node_modules\bluetooth-hci-socket\lib\usb.js; i.e. adding the signature of my bluetooth device, as seen in Device Manager. Something like:

    this._usbDevice = ... || usb.findByIds(0x8087, 0x0aaa);

After doing this, project node-movehub-async has ran successfully. However, in this project, the error was gone, but I get the following (cf. the title of this issue).

RangeError [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to write outside buffer bounds
    at boundsError (internal/buffer.js:51:11)
    at Buffer.readUInt8 (internal/buffer.js:141:5)
    at Hci.processCmdCompleteEvent (D:\temp\test-js-ble2\node_modules\noble-mac\node_modules\noble\lib\hci-socket\hci.js:566:25)
    at Hci.onSocketData (D:\temp\test-js-ble2\node_modules\noble-mac\node_modules\noble\lib\hci-socket\hci.js:461:12)
    at BluetoothHciSocket.emit (events.js:182:13)
    at BluetoothHciSocket.onHciEventEndpointData (D:\temp\test-js-ble2\node_modules\bluetooth-hci-socket\lib\usb.js:156:10)
    at InEndpoint.emit (events.js:182:13)
    at Transfer.transferDone (D:\temp\test-js-ble2\node_modules\usb\usb.js:441:9)

Have you got any hints? I'm kind of stuck.

Note: just modifying the usb.js file cf. above was theory is an illegal hack. I.e. I bypass the guard condition, but maybe then the lib may fail somewhere else, because my Bluetooth device is different than the ones already supported. E.g. with errors such as the one above. BUT, given the fact that it has actually worked for the other project, node-movehub-async, makes me hope that maybe there might be a solution.

Thanks in advance!
Cristian

Failing to get Duplo Train working

I'm trying this on RPi Zero W with

Raspbian Buster Lite
Minimal image based on Debian Buster
Version: September 2019
Release date: 2019-09-26
Kernel version: 4.19

(upgraded)

I had issues with nodejs and nmp earlier, so

pi@raspberrypi:~ $ wget https://nodejs.org/dist/latest-v11.x/node-v11.15.0-linux-armv6l.tar.gz
pi@raspberrypi:~ $ tar -xzf node-v11.15.0-linux-armv6l.tar.gz
pi@raspberrypi:~ $ cd node-v11.15.0-linux-armv6l/
pi@raspberrypi:~/node-v11.15.0-linux-armv6l $ sudo cp -R * /usr/
pi@raspberrypi:~/node-v11.15.0-linux-armv6l $ node -v
v11.15.0
pi@raspberrypi:~/node-v11.15.0-linux-armv6l $ npm -v
6.7.0
pi@raspberrypi:~ $ npm install node-poweredup

due to this issue

internal/modules/cjs/loader.js:670
    throw err;
    ^

Error: Cannot find module '/home/pi/node_modules/@abandonware/bluetooth-hci-socket/lib/binding/binding.node'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15)
    at Function.Module._load (internal/modules/cjs/loader.js:591:27)
    at Module.require (internal/modules/cjs/loader.js:723:19)
    at require (internal/modules/cjs/helpers.js:14:16)
    at Object.<anonymous> (/home/pi/node_modules/@abandonware/bluetooth-hci-socket/lib/native.js:6:15)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Module.require (internal/modules/cjs/loader.js:723:19)

I installed this manually:

pi@raspberrypi:~ $ npm install @abandonware/bluetooth-hci-socket

Using the modified (2nd line -> "DuploTrainBase()") example:

const PoweredUP = require("node-poweredup");
const poweredUP = new PoweredUP.DuploTrainBase();

poweredUP.on("discover", async (hub) => { // Wait to discover a Hub
    console.log(`Discovered ${hub.name}!`);

    await hub.connect(); // Connect to the Hub
    console.log("Connected");

    await hub.sleep(3000); // Sleep for 3 seconds before starting

    while (true) { // Repeat indefinitely
        console.log("Running motor B at speed 75");
        hub.setMotorSpeed("B", 75); // Start a motor attached to port B to run a 3/4 speed (75) indefinitely
        console.log("Running motor A at speed 100 for 2 seconds");
        await hub.setMotorSpeed("A", 100,  2000); // Run a motor attached to port A for 2 seconds at maximum speed (100) then stop
        await hub.sleep(1000); // Do nothing for 1 second
        console.log("Running motor A at speed -50 for 1 seconds");
        await hub.setMotorSpeed("A", -50,  1000); // Run a motor attached to port A for 1 second at 1/2 speed in reverse (-50) then stop
        await hub.sleep(1000); // Do nothing for 1 second
    }
});

poweredUP.scan(); // Start scanning for Hubs
console.log("Scanning for Hubs...");

I receive this error:

pi@raspberrypi:~ $ export DEBUG=*
pi@raspberrypi:~ $ node nodetest.js
/home/pi/node_modules/node-poweredup/dist/node/hub.js:38
        device.on("disconnect", () => {
               ^

TypeError: Cannot read property 'on' of undefined
    at new Hub (/home/pi/node_modules/node-poweredup/dist/node/hub.js:38:16)
    at new LPF2Hub (/home/pi/node_modules/node-poweredup/dist/node/lpf2hub.js:23:9)
    at new DuploTrainBase (/home/pi/node_modules/node-poweredup/dist/node/duplotrainbase.js:23:9)
    at Object.<anonymous> (/home/pi/nodetest.js:2:19)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    at internal/main/run_main_module.js:21:11

can't install on raspbian

Hi I can't install it on raspbian because it can't find the noble-mac.git. Below is the error received
code ENOGIT
npm ERR! Error while executing:
npm ERR! undefined ls-remote -h -t https://github.com/Timeular/noble-mac.git
npm ERR!
npm ERR! undefined
npm ERR! No git binary found in $PATH
npm ERR!
npm ERR! Failed using git.
npm ERR! Please check if you have git installed and in your PATH.

Can't move Spike Prime Large Motor

Hi,
First of all, I wanna thank you for your amazing work. It is really great to be able to use Lego Powered Up from node js and not from a Scratch-like interface on a smartphone ! :)

I have a Move Hub and a Spike Prime Large Motor, which I'm trying to use from a Raspberry Pi 3+ running Raspbian. The Move Hub itself is correctly detected and I've been able to control the A & B motors.

Yet I'm unable to use the Spike Prime Large Motor. It has to be noted that I got it from the #45680 set and not from the "main" set. Maybe it has something to do with the problem I'm facing.

I'm trying to run a simple test script:

poweredUP.on("discover", async (hub) => { // Wait to discover a Hub
    console.log(`Discovered ${hub.name}!`);
    await hub.connect(); // Connect to the Hub
    const motorC = await hub.waitForDeviceAtPort("C");
    console.log("Connected");
    console.log("Going to zero");
    motorC.gotoRealZero();
    console.log("going to 90 deg");
    motorC.gotoAngle(90) 
        .then(e => console.log(e)).catch(e => console.error(e));
    console.log(motorC.mode,motorC.type,motorC.connected,);
    process.exit();
});

Here's the output I get (with DEBUG=*) (I spare you the whole connection part, I might include it if you need it):

Connected
Going to zero
  lpf2hub Sent Message (LPF2_ALL) <Buffer 0a 00 41 02 03 01 00 00 00 01> +4ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 21 02 00> +1ms
going to 90 deg
  lpf2hub Sent Message (LPF2_ALL) <Buffer 0e 00 81 02 11 0d 5a 00 00 00 64 64 7f 03> +4ms
3 49 true  hci set scan enabled - writing: 010c20020001 +42ms
  hci disconnect - writing: 01060403400013 +1ms

I hope you can help. Thanks again!

setLEDColor strange behavior and connection method

I running your library on Raspberry 3 B+ (Raspbian os).
I have 4 Poweredup Hub, with 4 train motors connected to port A of each hub.

I put to power on all 4 hubs and start scanning with this portion of code:

let red_train = null;
let blue_train = null;
let green_train = null;
let yellow_train = null;
let iHubCount=0;

poweredUP.scan();
console.log("Start scan...");

poweredUP.on("discover", async (hub) => {
    await hub.connect();
    
    if (iHubCount==4){
        yellow_train=hub;
        yellow_train.sleep(500);
        yellow_train.setLEDColor(COLORS["yellow"]);
        iHubCount=5;
        //poweredUP.scan();
    }
    
    if (iHubCount==3){
        green_train=hub;
        green_train.sleep(500);
        green_train.setLEDColor(COLORS["green"]);
        iHubCount=4;
        //scan for new hub
        //poweredUP.scan();
    }
    
    if (iHubCount==1){
        blue_train=hub;
        blue_train.sleep(500);
        blue_train.setLEDColor(COLORS["blue"]);
        iHubCount=2;
        //scan for new hub
        //poweredUP.scan();
    }
    
    if (iHubCount==0){
        red_train=hub;
        red_train.sleep(500);
        red_train.setLEDColor(COLORS["red"]);
        iHubCount=1;
        //scan for new hub
        //poweredUP.scan();
    }
    
    //if (hub.name=="Gianluca"){
    //    hub.setLEDColor(9);
    //}
    
    console.log(`Connected to ${hub.name} (${hub.uuid})`);
    sLog += `Connected to ${hub.name} (${hub.uuid})\n`;

    //hub.on("disconnect", () => {
    //    console.log(`Hub ${hub.name} (${hub.uuid}) disconnected`);
    //    sLog += `Hub ${hub.name} (${hub.uuid}) disconnected\n`;
    //})
});

I want to assign a different color to each hub, in order of 'connect' event.
For first two hubs, the color are set right. For others hubs, remaining white.
If i set color, later, from another function, the LED color change correctly.
What i wrong?

Another question: what do you think is the best way to look forward to new hubs without first having to power on (all together) and then launch the scan?
I want to start scanning when Raspberry boot up and rest in waiting that 1, 2, 3 or 4 hubs, powered in different moments.

If you look the portion of the code i have try to call poweredUP.scan() after each hub connection.
it work, but sometime don't find the new hubs powered

Help

Hi there

this isn't strictly to do with node-poweredup but i was wondering if you could give me some pointers, I trying to make a bluetooth remote using espruino and seem to fine connect to a duple train but when i try to send the buffer command it doesn't appear to be doing anything

I using the Duplo train hub this command i am trying to send
[0x08, 0x00, 0x81, 0x01, 0x11, 0x51, 0x01, 0x05]

in your powered script i am try replicate hub.playSound(5)

this code is current using

function connect_train() {
  if (connected == 0) {
    NRF.connect("e0:7d:ea:0c:03:29").then(function(g) {
      console.log("Starting connecting2");
      gatt = g;
      return gatt.getPrimaryService("00001623-1212-efde-1623-785feabcd123");
    }).then(function(service) {
      return service.getCharacteristic("00001624-1212-efde-1623-785feabcd123");
    }).then(function(characteristic) {
      Characteristic_store = characteristic;
        return characteristic.readValue();
      }).then(value => {
        console.log(value);
    }).then(function() {
      console.log("Train Connected");
      connected = 1;
  });
  } else {
    gatt.disconnect();
    console.log("Train Disconnected");
    connected = 0;
  }
}

function send_message() {
  console.log("message = ", Characteristic_store);
  const sendvalue = new Uint8Array([0x08, 0x00, 0x81, 0x01, 0x11, 0x51, 0x01, 0x05]);
  Characteristic_store.writeValue(sendvalue)
  .then(_ => {
    console.log(sendvalue);
  });
}

any help would be greatly appreciated

Cheers

James

Duplo Train Base Speaker - way to play something besides built in sounds?

First of all, your library is fantastic. I got the Duplo Cargo Train for my kid, and I'm not sure which of us is having more fun. Thank you for the time you put into this, and for doing it in Typescript as well. That's made it much easier to figure out how to use it.

I've managed to train motor, and I can get the color data from the sensor, and I can play built in sounds. However, I couldn't tell if there is a way to send raw data to the speaker in such a way as to play anything else? Do you know if there is such a way, or know where I would look to find out what sort of data to send in a direct stream?

Many thanks again!

Running application without sudo

I have just started using this library (thanks so much for creating and sharing!) and I run into an issue: I am only able to connect to the Boost Move Hub when I run node with sudo. I tried to search for using Noble without sudo but couldn't find any results, which made me wonder if the elevated rights are a requirement from Noble or node-poweredup. Is there anyway I can use the library without elevated rights?

The reason I would like to use run as normal user account is to facilitate debugging in VS Code. I am running Elementary OS (Ubuntu 18.04).

Getting hub object if you know hub uuid

Is it possible to get hub object if you know hub uuid?

So you do something like that, where you can get hubUuid from params for example?

hub = PUPHub(hubUuid);
hub.setLEDColor(1);

Getting a port value on Control+ returns 1 byte of data

I have used your project as a guide to build out a full controller in .NET C#. The level of detail of your solution has been fantastic in unlocking the mysteries of the Control+ Hub. I have the Lego Liebherr 9800 which I am now controlling from my PC.

My only gotcha thus far is trying to get the rotations of a specific motor. I can reset the absolute position and go to an absolute position. All good.

The problem is this: when I do a Port Value request for port "A": 0x05, 0x00, 0x21, 0x00, 0x00, I then get a result of 0x05, 0x00, 0x45, 0x00, 0x3a. I am expecting 4 bytes of data but I am just getting 1 byte (0x3a in this case) which seems to echo the power I am applying to the port.

In your code, a nice "rotate" event fires when a motor is turned and returns 4 bytes of data. I think I am missing something...any little bit of guidance would be great! I don't see any place in your code where you are actually registering for this "rotate" event.

My end-game here is to do a calibration on the arm of the excavator just like Lego does in their app.

Spike Prime DeviceTypes

For info, the new external sensors/motors may be of interest:

//existing internal ids also used in Spike
VOLTAGE = 20,
CURRENT = 21,
RGB_LIGHT = 23,
CONTROL_PLUS_ACCELEROMETER = 57,
CONTROL_PLUS_GYRO = 58,
CONTROL_PLUS_TILT = 59,

//new Spike internal ids
SPIKE_LED_MATRIX = 25;
RGB_SENSOR = 64;

//new external devices
SPIKE_MEDIUM_MOTOR = 48,
SPIKE_LARGE_MOTOR = 49,
SPIKE_COLOR = 61;
SPIKE_DISTANCE = 62;
SPIKE_FORCE = 63;

//not released but mentioned often within spike app
SPIKE_SMALL_MOTOR = 65;

The new devices are all well documented here:
https://education.lego.com/en-us/support/spike-prime/technical-specifications?fbclid=IwAR2ZrltttwUkGmztKrA5RVGJr99Z80A_OsZ8bV6bruQSQMNh3nRk4HVLUSA

Steam train motor wont run

I can connect to my steam train just fine and event set the LED colors but when trying to run the motor with hub.setMotorSpeed("A", 50); I get:

(node:3827) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Port A does not exist on this Hub type

Is "A" not the correct port for the motor on the steam train? It seems to be wat is used in all the examples...

Can't control duplo train.

Hy Everyone,
I am currently trying to control a duplo train (10875) but it seem that i am stuck when i wait to get the motor.
currently the promise of waitForDeviceByType never resolve.
Do you have any idea where that can come from ?

here is the code i use:

const PoweredUP = require("node-poweredup");
const poweredUP = new PoweredUP.PoweredUP();

console.log("Looking for Hubs...");

poweredUP.on("discover", async (hub) => {

    await hub.connect();
    if (hub instanceof PoweredUP.DuploTrainBase) {
        console.log('train')
        let train = hub;
        console.log("await Motor")
        let motor = await train.waitForDeviceByType(PoweredUP.Consts.DeviceType.DUPLO_TRAIN_BASE_MOTOR);
        console.log(motor)
    }
});

poweredUP.scan();

thanks for your help.

hub.uuid changes | Unique identifier

Disclaimer: I may not be directly related to this module.

Using the same build of my app over two urls (localhost / 127.0.0.1), the same PUP Hub get different uuid.

From what I observed, doing multiple re-connection between both url, the uuid persists per url.

Any idea of a persitent way to identify hub ?

Bad color detection

I installed the Boost color sensor and found it doesn't seem to work work for me, it doesn't register all colors. Also it seems to me the light emitted from the sensor is weaker than when it's connected to the Boost set, when connected to the Boost set it does register all colors as was expected. I've replaced the batteries, but to no avail. I'm testing in quite low light conditions.

Motor don't run...

I have one Smart Hub and one train motor from LEGO City Train.
I haved used Raspberry 3 B+ with last Raspbian version.
After installed Noble Library (https://github.com/noble/noble), and Node-Poweredup, i have activate the BT and execute the example to start/stop motor for 2 second with this command:
node lego.js

The Led on Smart Hub becomes fixed, but the motor (connected to port A) don't start.

The console report:
noble warning: unknown peripheral 90842b00420c
noble warning: unknown peripheral 90842b00420c
noble: unknown peripheral null connected!
noble: unknown peripheral null connected!
noble: unknown peripheral null connected!

What am I doing wrong?

Discussion surrounding a new paradigm for talking to attached devices

Something which has been on my mind for a while (which recently came up in a not-entirely-unrelated issue) has been a new paradigm for talking to devices attached to hubs.

Problem Space

Here are a few examples of the current design, and where it falls short.

hub.setMotorSpeed("A", 50);

This method allows you to start running the motor attached to port "A" at a speed 50 constantly. It does no checking against the type of device actually attached to the port, and therefore may or may not work. For example, it will work just fine with an attached light (setting the brightness to half), but will fail against a color sensor.

If device type checking would be added, it would be a lengthy list of compatible devices, which could potentially get out of date as new devices are added.

Similarly:

hub.setLightBrightness("A", 50);

Pretty much does the same as the above, but with less logic. For example setMotorSpeed() changes the underlying command depending on the attached motor and hub combination. However this doesn't - so it may set a motor running at half speed, it may not.

This method is used for rotating a tacho motor to a specified angle:

hub.setMotorAngle("A", 50, 100);

It won't work against non-tacho motors, so a device type check is done at the start of the method (see above comment). As new devices are released with this capability, the method needs to be changed to add more devices to the device check. A similar problem exists with setAbsoluteSpeed().

Another example is for setting the color of the LED on the hub. This is done like so:

hub.setLEDColor(Consts.Color.PINK);

However the color of the LED on attached color sensor can also be changed, which this library doesn't support at the moment. Were it to support it, what would the solution be? Do we add an optional port argument to the method? Or do we create an entirely new method named something along the lines of setLEDColorOnColorSensor()? Neither seem ideal.

Current Proposal

Having thought about this for a little while, an approach that keeps coming to me is to create an individual class for each device, such as SimpleMotor, TrainMotor, BoostMotor, Light, DistanceSensor, TiltSensor, etc.

When one is attached to a hub, an "attach" event is emitted as normal, however instead of having the type id as a parameter, it would contain an instance of the device class, like so:

hub.on("attach", (port, device) => {
    console.log(`Device attached - port ${port}, type ${device.type}`);
    if (device instanceof Light) {
        const light = device;
        light.setBrightness(50); // Set half brightness
    } else if (device instanceof BoostMotor) {
        const motor = device;
        motor.rotateByAngle(66, 100); // Rotate by 66 degrees at full speed
    }
});

Or, you could retrieve the device from the hub:

hub.getDeviceAtPort("A").setBrightness(50); // Assuming the device on port A is a light

Having an individual class for each device or device type would also allow greater control of the various modes each device supports, which while already supported by this library through the subscribe method, is not at all bug free.

For example, the following examples could be implemented:

colorSensor.enableProximityMode();

Which would result in proximity events being emitted. Or:

colorSensor.enableCountMode();

Which would result in count events being emitted.

Or even combining them (and subsequently separating them) using the ability of the LEGO Wireless Protocol to combine modes:

colorSensor.enableProximityMode();
colorSensor.enableCountMode();

Which could result in both events being emitted, or even a new combined event (proximityAndCount) with the values of both.

And then:

colorSensor.disableCountMode();

Dynamically reverting to proximity events only.

Closing

This solution doesn't solve all problems, and could be quite tricky to implement. For example taking care to prevent modes being combined that can't be combined. However any further thoughts or suggestions by anyone is interested is welcome. :)

(cc'ing previous participants @nutki, @aileo, @dlech)

Port infos on Control+ hub not always available

I'm implementing a react based remote control app using node-poweredup:
https://brick-remote.ractive.ch
I'm testing and developing this with the Control+ hubs.

The issue is that when a hub is connected, its port infos are not always available.

In this example ports A, B and D are connected, but port A never shows any info, port B most of the time and port D almost always:

I'm getting the port info with hub.getPortDeviceType(port) (see here) after a call to await hub.connect() (see here).
The ports that are identified as "unkown" also don't get sensor messages. While e..g port B gets "rotate" events, port A does not.

Steering the motors on those ports although works and e.g. a motor on port A that is recognized as "unknown" can be successfully controlled by calling hub.setMotorSpeed("A", 50) (see here).

Any ideas what is wrong here so that the port infos are not correctly set after the hub is connected?

The source code of the app can be found here and started locally with yarn start dev. Debug logging is currently enabled (see here).

Support for Power Functions

Now that Power Functions can be support via use of the color sensor I was thinking about having a go at adding support here - does anyone have any documentation that may help me? Or any ideas on where to start!

Thanks in advance.

Disconnect event not firing when hub turned off

I'm trying to display the powered up network topology graphically, but when I turn off a hub there is no event that fires to indicate that a hub has disappeared. Based on my reading of the code it looks like there should be a disconnect event, but I don't see it. Is there a way to be notified of hub disconnection?

BOOST_TACHO_MOTOR and setAbsolutePosition

I have an 88008 V46 connected to a Boost Move Hub, and I am able to set it to absolute angles with the Lego Powered Up app. This library disallows this as unsupported, since the motor reports as BOOST_TACHO_MOTOR. To test, I hacked up boostmovehub.js to see if it would work if allowed. For me at least, it worked fine.

Maybe this is supported but the library just doesn't know it.

Unable to connect multiple Hubs on Raspberry Pi 3 B v2

I am trying to connect multiple hubs on a Raspberry Pi 3 B v2. I'm using a cut down sample script to debug with no success:

const PoweredUP = require("node-poweredup");
const poweredUP = new PoweredUP.PoweredUP();
poweredUP.on("discover", async (hub) => {
    console.log(`Discovered ${hub.name}!`);
    await hub.connect();
    console.log(`Connected to ${hub.name}`);
});
poweredUP.scan();
console.log("Scanning for Hubs...");

The first device connects, but no more are detected:

root@rasp1:/home/pi/stash/lego-layout/apps/state# node ./dist/test.js
Scanning for Hubs...
Discovered Storage!
Connected to Storage

If I run the same thing on my Macbook I can connect to multiple devices:

$ node ./dist/test.js 
Scanning for Hubs...
Discovered Storage!
Discovered Tunnel Approac!
Connected to Storage
Connected to Tunnel Approac
Discovered Station Depart!
Discovered Station Approa!
Connected to Station Depart
Discovered Station!
Connected to Station Approa
Connected to Station

I have double checked that I have installed the correct dependencies on the Raspberry Pi.

I'm guessing this is a problem more with noble rather than node-poweredup - any suggestions?

[Question] Rotation - how to interpret the numbers?

Hey there,

I was confused about the information the "rotation angle of Motor x" in the Boost-App provided, so I tried to check out, whether I could besser Information using this API.

But do be honest, I am still puzzled. Could you provide more insight about the number that the "rotation" event it emitting?

I was expecting a number in degrees, but instead I get really high numbers and after rotating the motor I do not get the same numbers again, although the motor/tacho was positioned back to the original position.

I hope you can help me out.

Thanks.

Attach event emitted only if autoSubscribe

Code from hub.ts, line 280 to 289, only emit the attach event only if autoSubscribe is true :

if (this.autoSubscribe) {
    this._activatePortDevice(port.value, type, this._getModeForDeviceType(type), 0x00);
    /**
     * Emits when a motor or sensor is attached to the Hub.
     * @event Hub#attach
     * @param {string} port
     * @param {DeviceType} type
     */
    this.emit("attach", port.id, type);
}

While detach event is emitted whatever the value of autoSubscribe.
As there is no possible subscribe to get back attach events, I wonder if it should emit them in any case ?

UnhandledPromiseRejectionWarning with Vernie Roaming Example

I always get the same UnhandledPromiseRejectionWarning when using the vernie_roaming.js example. Here is the full output:

$ >  node app.js
Looking for Vernie...
Connected to Vernie! Battery level: 100
(node:50807) UnhandledPromiseRejectionWarning: Error: Angle rotation is only available when using a Boost Tacho Motor, Boost Move Hub Motor, Control+ Medium Motor, or Control+ Large Motor
    at BoostMoveHub.setMotorAngle (/path/lego-boost/node_modules/node-poweredup/dist/node/boostmovehub.js:172:19)
    at turnHeadRight (/path/lego-boost/app.js:29:18)
    at /path/lego-boost/app.js:52:15
    at new Promise (<anonymous>)
    at scan (/path/lego-boost/app.js:47:12)
    at Timeout._onTimeout (/path/lego-boost/app.js:129:80)
(node:50807) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:50807) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

What's strange about it: Vernie starts to move backwards in the beginning and then without hitting anything the exception is thrown. I am using the standard LEGO Boost Set with nothing else.

I am using macOS 10.14.6 and node 12.6.0.

Scanning for Hubs with 88006 and CSR8510

The LED on my Bluetooth dongle will light up when I use bluetoothctl or gatttool (which successfully drives the Lego motors).

But when I run the example code it waits at "Scanning for Hubs..." forever and the LED on the dongle stays dark.

Maybe it's because the USB dongle has 2 Controllers, Any ideas how to make node-poweredup try more than the first Controller?

ColorAndDistance example for Duplo train

I understand that the duplo train hub can emit both color AND distance information, but so far all I’ve managed to see is the “color” event. If I try instead to subscribe to “colorAndDistance” on the hub then it never seems to fire. From my cursory looking at the code, the Duplo color sensor only seems to operate in one mode and only seems to edit the “color” event. It’s likely that I’m missing something obvious since I’m quite new to this library/ecosystem.

Help: Won't connect to raspberry pi 3

I have the simple example script work totally fine on my mac, but when I try on my rpi, it just sits on Scanning for Hubs....
When I run sudo hcitool lescan it surely enough finds 90:84:2B:17:8A:5B Smart Hub, so I'm kind of puzzled. Can anyone help point me in the right direction?
Thanks

Impossible to disconnect

hi
when i disconnect the hub
poweredUp remove the hub
but the legohub is still connected to my computer.
i use this.poweredUP.getConnectedHubByUUID(decodeURIComponent(uuid)).disconnect()

i m under angular and i use your library.
MacOS 10.14.6
i do not have any worries with speed or change led or connect to.

Use in TypeScript application

Is it possible for me to easily use the node-poweredup library in a TS application?

Some superfluous information on why I ask:
After doing some playing around in and with the sample JS applications, I had intended to use the node-poweredup package in a TS application as I am not that familiar with vanilla JS.
After getting started the first thing I noticed was that the .on() was not recognized on the PoweredUp class. I then noticed that PoweredUp is extending EventEmitter which is the class i suspected contains the .on() method. From there I realized that NPM had not installed events package. I installed it manually, however when building the application it still fails on this .on() due to not being able to find a value for Promise.

Seeing the library works fine in a JS application, I suspect that dev packages are missing but don't actually provide functionality, purely the interface definitions. And I fear I will continue to run into these missing interfaces if I use node-poweredup in a TS application, making the attempt not worth the effort.

jetson nano, ubuntu 18, npm install

npm install node-poweredup --save

[email protected] install /home/bb8/www/controller/node_modules/usb
prebuild-install --verbose || node-gyp rebuild

prebuild-install info begin Prebuild-install version 5.3.3
prebuild-install info looking for cached prebuild @ /home/bb8/.npm/_prebuilds/31517a-usb-v1.6.2-node-v57-linux-arm64.tar.gz
prebuild-install http request GET https://github.com/tessel/node-usb/releases/download/v1.6.2/usb-v1.6.2-node-v57-linux-arm64.tar.gz
prebuild-install http 404 https://github.com/tessel/node-usb/releases/download/v1.6.2/usb-v1.6.2-node-v57-linux-arm64.tar.gz
prebuild-install WARN install No prebuilt binaries found (target=8.17.0 runtime=node arch=arm64 libc= platform=linux)
make: Entering directory '/home/bb8/www/controller/node_modules/usb/build'
CC(target) Release/obj.target/libusb/libusb/libusb/core.o
CC(target) Release/obj.target/libusb/libusb/libusb/descriptor.o
CC(target) Release/obj.target/libusb/libusb/libusb/hotplug.o
CC(target) Release/obj.target/libusb/libusb/libusb/io.o
CC(target) Release/obj.target/libusb/libusb/libusb/strerror.o
CC(target) Release/obj.target/libusb/libusb/libusb/sync.o
CC(target) Release/obj.target/libusb/libusb/libusb/os/poll_posix.o
CC(target) Release/obj.target/libusb/libusb/libusb/os/threads_posix.o
CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_usbfs.o
CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_udev.o
AR(target) Release/obj.target/usb.a
COPY Release/usb.a
CXX(target) Release/obj.target/usb_bindings/src/node_usb.o
../src/node_usb.cc: In function ‘void handleHotplug(std::pair<libusb_device*, libusb_hotplug_event>)’:
../src/node_usb.cc:151:58: warning: ‘v8::Localv8::Value Nan::MakeCallback(v8::Localv8::Object, const char*, int, v8::Localv8::Value)’ is deprecated [-Wdeprecated-declaration]
Nan::MakeCallback(Nan::New(hotplugThis), "emit", 2, argv);
^
In file included from ../src/helpers.h:3:0,
from ../src/node_usb.h:21,
from ../src/node_usb.cc:1:
../node_modules/nan/nan.h:1001:46: note: declared here
NAN_DEPRECATED inline v8::Localv8::Value MakeCallback(
^~~~~~~~~~~~
CXX(target) Release/obj.target/usb_bindings/src/device.o
../src/device.cc: In static member function ‘static void Req::default_after(uv_work_t
)’:
../src/device.cc:237:64: warning: ‘v8::Localv8::Value Nan::MakeCallback(v8::Localv8::Object, v8::Localv8::Function, int, v8::Localv8::Value)’ is deprecated [-Wdeprecated-declarations]
Nan::MakeCallback(device, Nan::New(baton->callback), 1, argv);
^
In file included from ../src/helpers.h:3:0,
from ../src/node_usb.h:21,
from ../src/device.cc:1:
../node_modules/nan/nan.h:959:46: note: declared here
NAN_DEPRECATED inline v8::Localv8::Value MakeCallback(
^~~~~~~~~~~~
CXX(target) Release/obj.target/usb_bindings/src/transfer.o
../src/transfer.cc: In function ‘void handleCompletion(Transfer
)’:
../src/transfer.cc:126:72: warning: ‘v8::Localv8::Value Nan::MakeCallback(v8::Localv8::Object, v8::Localv8::Function, int, v8::Localv8::Value*)’ is deprecated [-Wdeprecated-declarations]
Nan::MakeCallback(self->handle(), Nan::New(self->v8callback), 3, argv);
^
In file included from ../src/helpers.h:3:0,
from ../src/node_usb.h:21,
from ../src/transfer.cc:1:
../node_modules/nan/nan.h:959:46: note: declared here
NAN_DEPRECATED inline v8::Localv8::Value MakeCallback(
^~~~~~~~~~~~
SOLINK_MODULE(target) Release/obj.target/usb_bindings.node
COPY Release/usb_bindings.node
make: Leaving directory '/home/bb8/www/controller/node_modules/usb/build'

@abandonware/[email protected] install /home/bb8/www/controller/node_modules/@abandonware/bluetooth-hci-socket
node-pre-gyp install --fallback-to-build

node-pre-gyp WARN Using needle for node-pre-gyp https download
node-pre-gyp WARN Tried to download(404): https://github.com/abandonware/node-bluetooth-hci-socket/releases/download/0.5.3-5/binding-0.5.3-5-node-v57-linux-arm64.tar.gz
node-pre-gyp WARN Pre-built binaries not found for @abandonware/[email protected] and [email protected] (node-v57 ABI, glibc) (falling back to source compile with node-gyp)
make: Entering directory '/home/bb8/www/controller/node_modules/@abandonware/bluetooth-hci-socket/build'
CXX(target) Release/obj.target/binding/src/BluetoothHciSocket.o
SOLINK_MODULE(target) Release/obj.target/binding.node
COPY Release/binding.node
COPY /home/bb8/www/controller/node_modules/@abandonware/bluetooth-hci-socket/lib/binding/binding.node
TOUCH Release/obj.target/action_after_build.stamp
make: Leaving directory '/home/bb8/www/controller/node_modules/@abandonware/bluetooth-hci-socket/build'

@abandonware/[email protected] install /home/bb8/www/controller/node_modules/@abandonware/noble
node-gyp rebuild

make: Entering directory '/home/bb8/www/controller/node_modules/@abandonware/noble/build'
SOLINK_MODULE(target) Release/obj.target/noble.node
COPY Release/noble.node
make: Leaving directory '/home/bb8/www/controller/node_modules/@abandonware/noble/build'
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

  • [email protected]
    added 305 packages from 220 contributors and audited 686 packages in 44.431s

4 packages are looking for funding
run npm fund for details

found 1 moderate severity vulnerability
run npm audit fix to fix them, or npm audit for details

Boost Hub and setMotorAngle gives error but works

Hi,

first of all, I was really happy when I found this library you made!

I have a LEGO Boost Hub and want to rotate the hub motor by a certain degree. So I try setMotorAngle but I get this error: Angle rotation is only available when using a Boost Tacho Motor or Boost Move Hub Motor. This is due a if statement checking the type on the portObj used. However, there is only one line in the whole code base settning that property on a port, in the contructor of Port. And there it's set to UNKNOWN. So the if will never be fulfilled.

If I just remove the if regarding portObj.type in the setMotorAngle method in BoostMoveHub all works as intended.

What is the idea here, that the port type should perhaps be added to the port constructor? Or should it be set later by the hub object? Or should the if in fact be removed? Or…

Using 1.9.1.

Thank you!

Is there a way to save the absolute position reference point on the Control+ Hub?

I am working on a calibration routine for the Control+ Hub and when I reset the absolute position, I would like that to "stick" between power cycles of the Hub. Not sure that can be saved in the hub or whether I should handle it in my application.

Currently, when the Control+ Hub is powered up, the current position of the motor becomes the reference point (absolute position zero).

subscribe/unsubscribe usage

I'm trying to figure it out what subscribe/unsubscribe functions are doing?

For color sensor I'm using hub.on("color"), could I use subscribe/unsubscribe for color sensor, or are this functions used for some other use-case/device

Also just saw that you will implement power off https://www.eurobricks.com/forum/index.php?/forums/topic/162288-powered-up-a-tear-down/&page=13&tab=comments#comment-3068973 I was just thinking how could I do that, since if you disconnect you are automatically connected back

Can't connect in ts application

Hi,

I created a Ionic application where I try to connect to a hub.
I implemented the plugin in ts instead of js, however it gets stuck on "Scanning for Hubs" and the promise never resolve.

import { Component, OnInit } from '@angular/core';
import { PoweredUP } from 'node_modules/node-poweredup/dist/node/poweredup-browser';

@Component({
  selector: 'app-poweredup',
  templateUrl: './poweredup.component.html',
  styleUrls: ['./poweredup.component.scss'],
})
export class PoweredupComponent implements OnInit {
  constructor(public poweredUP: PoweredUP) {}

  ngOnInit() {
    this.poweredUP.on('discover', async (hub) => {
      // Wait to discover a Hub
      console.log(`Discovered ${hub.name}!`);
      await hub.connect(); // Connect to the Hub
      console.log('Connected');
    });
  }

  scan() {
    this.poweredUP.scan().then();
    console.log('Scanning for Hubs...');
  }
}

I searched in the async _discoveryEventHandler(server) function of poweredup-bowser.js to see where the scanning stop, and i found out that the event handler never goes through this line :

if (isLPF2Hub) {
     hubType = await this._determineLPF2HubType(device);
}

The eventHandler seems to be stuck here and I can't find a solution. Any idea?

Does not connect to the hub?

Hi,

I have the cargo train, I'm trying to connect my raspberrypi with the hub to control the train.
I'm trying the Node.js Sample Usage, but it stay at Scanning for Hubs. I'm new with Node Js, im not sure how could I solved that problem?

Thanks

Question : Get Hub's LED color

Hello,

First, thank you for this awesome project.
I was wondering if there is a way to get the current colors of the hub built-in LED ?

Thank you.
Léo

Pup remote voltage sensor

Upon connection the pup hub reports the following internal devices as new port connections

 [15, 0, 4, 50, 1, 23, 0, 0, 0, 0, 16, 0, 0, 0, 16]
 [15, 0, 4, 59, 1, 21, 0, 2, 0, 0, 0, 2, 0, 0, 0]
 [15, 0, 4, 60, 1, 20, 0, 2, 0, 0, 0, 2, 0, 0, 0]

port 0x32 device 0x17 (rgb led)
port 0x3B device 0x15 (current sensor)
port 0x3C device 0x14 (voltage sensor)

However the pup remote reports

 [15, 0, 4, 0, 1, 55, 0, 0, 0, 0, 16, 0, 0, 0, 16]
 [15, 0, 4, 1, 1, 55, 0, 0, 0, 0, 16, 0, 0, 0, 16]
 [15, 0, 4, 52, 1, 23, 0, 0, 0, 0, 16, 0, 0, 0, 16]
 [15, 0, 4, 59, 1, 20, 0, 2, 0, 0, 0, 2, 0, 0, 0]
 [15, 0, 4, 60, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16]

port 0x00 device 0x37 (remote buttons)
port 0x01 device 0x37 (remote buttons)
port 0x34 device 0x17 (rgb LED)
port 0x3B device 0x14 (voltage sensor)
port 0x3C device 0x38 (unknown different sensor)

Note the 0x14 voltage sensor is on different ports.

Therefore assuming internal port 0x3C is always going to be voltage in _parseSensorMessage is not correct. The internal sensors should really be programmatically 'attached' to their port in exactly the same way that external devices are attached to a port - the necessary 'new device' notification is transmitted by the hub when the initial connection is made.

Using boost color and distance sensor in mode 1 returns distance as color

I tried to subscribe to a color and distance sensor on a PUP hub on port A using this code (based on the web_bluetooth example):

const poweredUP = new PoweredUP.PoweredUP();
poweredUP.autoSubscribe = false;
poweredUP.on("discover", async (hub) => { // Wait to discover hubs
    await hub.connect(); // Connect to hub
    log(`Connected to ${hub.name}!`);
    hub.sleep(1000)
    hub.subscribe('A', 1);
    hub.on('distance', (port, ...values) => log(`distance on A: ${ JSON.stringify(values) }`));
    hub.on('color', (port, ...values) => log(`color on A: ${ JSON.stringify(values) }`));
    hub.on('colorAndDistance', (port, ...values) => log(`colorAndDistance on A: ${ JSON.stringify(values) }`));
});

And I get this output when I get the sensor closer to an obstacle:

Connected to PoweredUp!
color on A: [10]
distance on A: [null]
colorAndDistance on A: [10,null]
color on A: [9]
distance on A: [null]
colorAndDistance on A: [9,null]
color on A: [8]
distance on A: [null]
colorAndDistance on A: [8,null]
color on A: [7]
distance on A: [null]
colorAndDistance on A: [7,null]
color on A: [6]
distance on A: [null]
colorAndDistance on A: [6,null]
color on A: [5]
distance on A: [null]
colorAndDistance on A: [5,null]
color on A: [4]
distance on A: [null]
colorAndDistance on A: [4,null]
color on A: [2]
distance on A: [null]
colorAndDistance on A: [2,null]
color on A: [3]
distance on A: [null]
colorAndDistance on A: [3,null]
color on A: [2]
distance on A: [null]
colorAndDistance on A: [2,null]

Message structure depends on device mode and I don't think message contains the device mode.
I think it should be relevant to store mode in port informations to handle this. If others thinks the same I can work on a PR.

multiple discover event listeners on repeated scans calls

I am tinkering with a web app to control some Duplo trains. I want it to handle multiple trains and be robust enough to deal with them powering on and off. (My thought was to have this running on a Pi Zero 24/7)

The scan function for PoweredUP stops scanning after a discovery. Calling scan again seems to add duplicate event listeners for the Noble discover event. Was it not designed for the scan to start and stop?

  • Is there a reason you stop scanning (???)
  • Would you accept a PR to handle start/stops?

thanks for making this project

Scan interrupt when a tentative to connect to a device

Hi,
I am making some test with this library, my goal is to connect on a Raspberry Pi multiple train and multiple remote.

When I try and adapt the examples, I have the following problem: the scan for new hubs/remotes stop once a device is discovered and the connection is initiated.

I have this following test :

const PoweredUP = require("node-poweredup");
const poweredUP = new PoweredUP.PoweredUP();

poweredUP.on("discover", async (hub) => { // Wait to discover a Hub
  
  console.log(`##############################`)
  console.log(`Discovered ${hub.name}!`);
  
  if( hub instanceof PoweredUP.PUPRemote ){
    console.log("~~ Powered UP Remote ~~")
    await hub.connect(); // Connect to the Hub
    console.log("Connected");
    await hub.sleep(3000);
    
    if(hub.name.indexOf("Remote Grey") > -1){
      await hub.setLEDColor(PoweredUP.Consts.Color.WHITE);
    } else if(hub.name.indexOf("Remote Blue") > -1){
      await hub.setLEDColor(PoweredUP.Consts.Color.BLUE);
    } else if(hub.name.indexOf("Remote Red") > -1){
      await hub.setLEDColor(PoweredUP.Consts.Color.RED);
    } else if(hub.name.indexOf("Remote Green") > -1){
      await hub.setLEDColor(PoweredUP.Consts.Color.GREEN);
    }
  }

});
poweredUP.scan(); // Start scanning for Hubs
console.log("Scanning for Hubs...");

Which will just color the LED of the remote depending of the name of the remote.

When I just turn on one remote, this one is connected and the LED changes color. If I turn on another remote, this remote is never discoverer.

If I turn all my remote at the same time when no other device is connected, all the remote are discovered and the connection to all the remote is made (and the LEDs' color will change).

Of course, same with standard trains hub. When one hub is connected, scan is interrupted and no more hub nor remote can be discovered.

When I disconnect the attached device, the scan restart and new devices can be discovered.

I had a look to the log (DEBUG=* node scanners.js) and it seems that the Noble library decide to stop scanning after the connection is enabled. After a look to the code, I don't see why it decide to stop scanning without the stop command.

Here is the (long) log:

root@rpi-indoor:~/nfslocal/dev/puptest# DEBUG=* node scanners.js
Scanning for Hubs...
  hci setting filter to: 1600000020c10000000000400000 +0ms
  hci set event mask - writing: 01010c08fffffbff07f8bf3d +4ms
  hci set le event mask - writing: 010120081f00000000000000 +1ms
  hci read local version - writing: 01011000 +2ms
  hci write LE host supported - writing: 016d0c020100 +1ms
  hci read LE host supported - writing: 016c0c00 +1ms
  hci read bd addr - writing: 01091000 +1ms
  hci onSocketData: 040e0401010c00 +6ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 3073 +1ms
  hci           status = 0 +1ms
  hci           result =  +0ms
  hci onSocketData: 040e0401012000 +2ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8193 +1ms
  hci           status = 0 +0ms
  hci           result =  +0ms
  hci onSocketData: 040e0c010110000922010931011961 +1ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 4097 +1ms
  hci           status = 0 +0ms
  hci           result = 0922010931011961 +0ms
  hci set scan enabled - writing: 010c20020001 +1ms
  hci set scan parameters - writing: 010b200701100010000000 +2ms
  hci onSocketData: 040e04016d0c00 +1ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +0ms
  hci           cmd = 3181 +1ms
  hci           status = 0 +0ms
  hci           result =  +0ms
  hci onSocketData: 040e06016c0c000100 +1ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +0ms
  hci           cmd = 3180 +1ms
  hci           status = 0 +0ms
  hci           result = 0100 +0ms
  hci                   le = 1 +1ms
  hci                   simul = 0 +0ms
  hci onSocketData: 040e0a01091000be65feeb27b8 +0ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 4105 +0ms
  hci           status = 0 +1ms
  hci           result = be65feeb27b8 +0ms
  hci address = b8:27:eb:fe:65:be +0ms
  noble addressChange b8:27:eb:fe:65:be +0ms
  hci onSocketData: 040e04010c200c +2ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8204 +1ms
  hci           status = 12 +0ms
  hci           result =  +0ms
  hci onSocketData: 040e04010b2000 +1ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8203 +0ms
  hci           status = 0 +0ms
  hci           result =  +1ms
  noble stateChange poweredOn +5ms
  poweredup Scanning started +0ms
  hci set scan enabled - writing: 010c20020001 +3ms
  hci set scan parameters - writing: 010b200701100010000000 +1ms
  hci set scan enabled - writing: 010c20020101 +0ms
  hci onSocketData: 040e04010c200c +1ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8204 +0ms
  hci           status = 12 +0ms
  hci           result =  +1ms
  hci onSocketData: 040e04010b2000 +0ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +1ms
  hci           cmd = 8203 +0ms
  hci           status = 0 +0ms
  hci           result =  +0ms
  hci onSocketData: 040e04010c2000 +1ms
  hci   event type = 4 +0ms
  hci   sub event type = 14 +1ms
  hci           cmd = 8204 +0ms
  hci           status = 0 +0ms
  hci           result =  +0ms
  noble scanStart +11ms
  hci onSocketData: 043e2b02010000a4aa6732daa41f020106110723d1bcea5f782316deef12122316000009ff970300420a006100b8 +2s
  hci   event type = 4 +1ms
  hci   sub event type = 62 +0ms
  hci           LE meta event type = 2 +0ms
  hci           LE meta event status = 1 +0ms
  hci           LE meta event data = 0000a4aa6732daa41f020106110723d1bcea5f782316deef12122316000009ff970300420a006100b8 +1ms
  hci                   type = 0 +2ms
  hci                   address = a4:da:32:67:aa:a4 +0ms
  hci                   address type = public +0ms
  hci                   eir = 020106110723d1bcea5f782316deef12122316000009ff970300420a006100 +1ms
  hci                   rssi = -72 +1ms
  gap advertisement = {"manufacturerData":{"type":"Buffer","data":[151,3,0,66,10,0,97,0]},"serviceData":[],"serviceUuids":["000016231212efde1623785feabcd123"],"solicitationServiceUuids":[],"serviceSolicitationUuids":[]} +0ms
  hci onSocketData: 043e2a02010400a4aa6732daa41e140952656d6f746520426c75650000000000000000051210002000020a00b7 +6ms
  hci   event type = 4 +1ms
  hci   sub event type = 62 +1ms
  hci           LE meta event type = 2 +0ms
  hci           LE meta event status = 1 +1ms
  hci           LE meta event data = 0400a4aa6732daa41e140952656d6f746520426c75650000000000000000051210002000020a00b7 +0ms
  hci                   type = 4 +2ms
  hci                   address = a4:da:32:67:aa:a4 +0ms
  hci                   address type = public +1ms
  hci                   eir = 140952656d6f746520426c75650000000000000000051210002000020a00 +0ms
  hci                   rssi = -73 +1ms
  gap advertisement = {"localName":"Remote Blue\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","txPowerLevel":0,"manufacturerData":{"type":"Buffer","data":[151,3,0,66,10,0,97,0]},"serviceData":[],"serviceUuids":["000016231212efde1623785feabcd123"],"solicitationServiceUuids":[],"serviceSolicitationUuids":[]} +10ms
  pupremote Discovered Powered UP Remote +0ms
  poweredup Hub a4da3267aaa4 discovered +3s
##############################
Discovered Remote Blue!
~~ Powered UP Remote ~~
  pupremote Connecting to Powered UP Remote +1s
  hci create le conn - writing: 010d2019600030000000a4aa6732daa40006000c000000c80004000600 +1s
  hci onSocketData: 040f0400010d20 +4ms
  hci   event type = 4 +1ms
  hci   sub event type = 15 +0ms
  hci           status = 0 +1ms
  hci           cmd = 8205 +0ms
  hci onSocketData: 043e13010040000000a4aa6732daa40c000000c80000 +42ms
  hci   event type = 4 +1ms
  hci   sub event type = 62 +1ms
  hci           LE meta event type = 1 +0ms
  hci           LE meta event status = 0 +1ms
  hci           LE meta event data = 40000000a4aa6732daa40c000000c80000 +0ms
  hci                   handle = 64 +2ms
  hci                   role = 0 +1ms
  hci                   address type = public +0ms
  hci                   address = a4:da:32:67:aa:a4 +1ms
  hci                   interval = 15 +0ms
  hci                   latency = 0 +1ms
  hci                   supervision timeout = 2000 +0ms
  hci                   master clock accuracy = 0 +1ms
  att a4:da:32:67:aa:a4: write: 020001 +0ms
  hci write acl data pkt - writing: 024000070003000400020001 +19ms
  hci onSocketData: 011620024000 +6ms
  hci   event type = 1 +1ms
  hci           cmd = 8214 +0ms
  hci           data len = 2 +1ms
  hci onSocketData: 040f0400011620 +1ms
  hci   event type = 4 +1ms
  hci   sub event type = 15 +1ms
  hci           status = 0 +0ms
  hci           cmd = 8214 +1ms
  hci onSocketData: 010c20020000 +1ms
  hci   event type = 1 +0ms
  hci           cmd = 8204 +1ms
  hci           data len = 2 +0ms
  hci                   LE enable scan command +1ms
  hci                   enable scanning = false +0ms
  hci                   filter duplicates = false +1ms
  noble scanStop +4s
  hci onSocketData: 040e0e0116200000000000000000000000 +4ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8214 +1ms
  hci           status = 0 +0ms
  hci           result = 00000000000000000000 +1ms
  hci onSocketData: 040e04010c2000 +1ms
  hci   event type = 4 +1ms
  hci   sub event type = 14 +0ms
  hci           cmd = 8204 +1ms
  hci           status = 0 +0ms
  hci           result =  +1ms
  hci onSocketData: 043e0c040040000100000000000000 +1ms
  hci   event type = 4 +0ms
  hci   sub event type = 62 +1ms
  hci           LE meta event type = 4 +0ms
  hci           LE meta event status = 0 +1ms
  hci           LE meta event data = 40000100000000000000 +0ms
  hci onSocketData: 024020070003000400031700 +2ms
  hci   event type = 2 +1ms
  hci           cid = 4 +0ms
  hci           handle = 64 +1ms
  hci           data = 031700 +0ms
  att a4:da:32:67:aa:a4: read: 031700 +39ms
  att a4:da:32:67:aa:a4: new MTU is 23 +1ms
  att a4:da:32:67:aa:a4: write: 100100ffff0028 +1ms
  hci write acl data pkt - writing: 0240000b0007000400100100ffff0028 +7ms
  hci onSocketData: 02402012000e0004001106010007000018080008000118 +21ms
  hci   event type = 2 +0ms
  hci           cid = 4 +1ms
  hci           handle = 64 +0ms
  hci           data = 1106010007000018080008000118 +0ms
  att a4:da:32:67:aa:a4: read: 1106010007000018080008000118 +25ms
  att a4:da:32:67:aa:a4: write: 100900ffff0028 +1ms
  hci write acl data pkt - writing: 0240000b0007000400100900ffff0028 +3ms
  hci onSocketData: 0240201a001600040011140900ffff23d1bcea5f782316deef121223160000 +27ms
  hci   event type = 2 +0ms
  hci           cid = 4 +0ms
  hci           handle = 64 +1ms
  hci           data = 11140900ffff23d1bcea5f782316deef121223160000 +0ms
  att a4:da:32:67:aa:a4: read: 11140900ffff23d1bcea5f782316deef121223160000 +29ms
  bledevice Service/characteristic discovery started +0ms
  att a4:da:32:67:aa:a4: write: 080900ffff0328 +4ms
  hci write acl data pkt - writing: 0240000b0007000400080900ffff0328 +5ms
  hci onSocketData: 0240201b001700040009150a001c0b0023d1bcea5f782316deef121224160000 +24ms
  hci   event type = 2 +0ms
  hci           cid = 4 +0ms
  hci           handle = 64 +0ms
  hci           data = 09150a001c0b0023d1bcea5f782316deef121224160000 +1ms
  att a4:da:32:67:aa:a4: read: 09150a001c0b0023d1bcea5f782316deef121224160000 +26ms
  att a4:da:32:67:aa:a4: write: 080c00ffff0328 +2ms
  hci write acl data pkt - writing: 0240000b0007000400080c00ffff0328 +4ms
  hci onSocketData: 02402009000500040001080c000a +24ms
  hci   event type = 2 +1ms
  hci           cid = 4 +0ms
  hci           handle = 64 +0ms
  hci           data = 01080c000a +0ms
  att a4:da:32:67:aa:a4: read: 01080c000a +27ms
  bledevice Service/characteristic discovery finished +59ms
  att a4:da:32:67:aa:a4: write: 080a00ffff0229 +3ms
  hci write acl data pkt - writing: 0240000b0007000400080a00ffff0229 +4ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 0a 00 41 3b 00 01 00 00 00 01> +0ms
  hci onSocketData: 0240200a000600040009040c000000 +25ms
  hci   event type = 2 +0ms
  hci           cid = 4 +1ms
  hci           handle = 64 +0ms
  hci           data = 09040c000000 +0ms
  att a4:da:32:67:aa:a4: read: 09040c000000 +27ms
  att a4:da:32:67:aa:a4: write: 120b000a00413b000100000001 +1ms
  hci write acl data pkt - writing: 02400011000d000400120b000a00413b000100000001 +2ms
  hci onSocketData: 02402005000100040013 +27ms
  hci   event type = 2 +0ms
  hci           cid = 4 +0ms
  hci           handle = 64 +1ms
  hci           data = 13 +0ms
  att a4:da:32:67:aa:a4: read: 13 +29ms
  att a4:da:32:67:aa:a4: write: 120c000100 +1ms
  hci write acl data pkt - writing: 024000090005000400120c000100 +2ms
  hci onSocketData: 02402005000100040013 +27ms
  hci   event type = 2 +0ms
  hci           cid = 4 +0ms
  hci           handle = 64 +0ms
  hci           data = 13 +1ms
  att a4:da:32:67:aa:a4: read: 13 +29ms
  hci onSocketData: 02402011000d0004001b0b000a00473b000100000001 +14ms
  hci   event type = 2 +0ms
  hci           cid = 4 +1ms
  hci           handle = 64 +0ms
  hci           data = 1b0b000a00473b000100000001 +0ms
  lpf2hub Received Message (LPF2_ALL) <Buffer 0a 00 47 3b 00 01 00 00 00 01> +102ms
  hci onSocketData: 0240201600120004001b0b000f0004000137000000001000000010 +3ms
  hci   event type = 2 +0ms
  hci           cid = 4 +0ms
  hci           handle = 64 +1ms
  hci           data = 1b0b000f0004000137000000001000000010 +0ms
  lpf2hub Received Message (LPF2_ALL) <Buffer 0f 00 04 00 01 37 00 00 00 00 10 00 00 00 10> +3ms
  lpf2hubmodeinfo Port 00, type 0037 (POWERED_UP_REMOTE_BUTTON) +0ms
  lpf2hubmodeinfo Port 00, hardware version 1.0.00.0000, software version 1.0.00.0000 +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 21 00 01> +3ms
  att a4:da:32:67:aa:a4: write: 120b000500210001 +24ms
  hci write acl data pkt - writing: 0240000c0008000400120b000500210001 +6ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 21 00 02> +2ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 0a 00 41 00 00 01 00 00 00 01> +2ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 02 02> +3ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 03 05> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 04 05> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 05 02> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 06 02> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 01 0d 05> +0ms
  poweredup Hub a4da3267aaa4 connected +367ms
  pupremote Connect completed +362ms
Connected
  hci onSocketData: 0240201600120004001b0b000f0004010137000000001000000010 +12ms
  hci   event type = 2 +0ms
  hci           cid = 4 +1ms
  hci           handle = 64 +0ms
  hci           data = 1b0b000f0004010137000000001000000010 +0ms
  lpf2hub Received Message (LPF2_ALL) <Buffer 0f 00 04 01 01 37 00 00 00 00 10 00 00 00 10> +5ms
  lpf2hubmodeinfo Port 01, type 0037 (POWERED_UP_REMOTE_BUTTON) +17ms
  lpf2hubmodeinfo Port 01, hardware version 1.0.00.0000, software version 1.0.00.0000 +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 21 01 01> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 05 00 21 01 02> +1ms
  lpf2hub Sent Message (LPF2_ALL) <Buffer 0a 00 41 01 00 01 00 00 00 01> +1ms

I am doing my test on a Raspberry Pi 3 and a Raspberry Pi 0 with the integrated Bluetooth.
Latest Raspbian (Raspbian GNU/Linux 10 (buster))
Node: v12.13.1 for the RPi3, v11.15.0 for the RPi0
"node-poweredup": "^4.3.0"
I can give the full node dependencies if required.

I hope you will be able to give me a hint.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.