OpenWonderLabs / homebridge-switchbot

The Homebridge SwitchBot plugin allows you to access your SwitchBot Device(s) from HomeKit. Homebridge.
https://openwonderlabs.github.io/homebridge-switchbot/
ISC License
245 stars 53 forks source link

Bug: Bot not able to send BLE commands #1073

Open DKhen opened 1 month ago

DKhen commented 1 month ago

Describe the Bug

ive just installed Version 4.0.0, set up the bot from scratch but still receiving the Same error as in the old Issue.

Bot: Swotchbot failed BLEpushChanges with BLE Connection, Error Message: "Cannot read properties of undefined (reading 'press') "

To Reproduce

Expected Behavior

properties can be read and makes a press

Relevant Log Output


[10/12/2024, 11:00:38 AM] [SwitchBot] ID EBUG] Bot: Swotchbot (power, battery, de
viceMode) = BLE: (undefined, undefined, u
ndefined), current: (undefined, 100, press)

[10/12/2024, 11:00:38 AM] [SwitchBot] [D EBUG] Bot: Swotchbot Press Mode, On: fal se
[10/12/2024, 11:00:38 AM] [SwitchBot] [D EBUG] Bot: Swotchbot BatteryLevel: undef ined
[10/12/2024, 11:00:38 AM] [SwitchBot] [D EBUG] Bot: Swotchbot StatusLowBattery: 0 [10/12/2024, 11:00:38 AM] [SwitchBot] ID EBUG] Bot: Swotchbot updateHomeKitCharac teristics
[10/12/2024, 11:00:38 AM] [SwitchBot] ID EBUG] Bot: Swotchbot BatteryLevel: undef ined
[10/12/2024, 11:00:38 AM] [SwitchBot] [D EBUG] Bot: Swotchbot updateCharacteristi c StatusLowBattery: 0
[10/12/2024, 11:00:38 AM] [SwitchBot] ID EBUG] Bot: Swotchbot updateCharacteristi c On: false
[10/12/2024, 11:00:58 AM] [SwitchBot] ID
EBUG] Bot: Swotchbot value: true
[10/12/2024, 11:00:58 AM] [SwitchBot] [D EBUG] Bot: Swotchbot BLEpushChanges

[10/12/2024, 11:00:58 AM] [SwitchBot] [D
EBUG] Bot: Swotchbot value: true
[10/12/2024, 11:00:58 AM] [SwitchBot] [D EBUG] Bot: Swotchbot BLEpushChanges
[10/12/2024, 11:00:58 AM] [SwitchBot] [D EBUG] Bot: Swotchbot BLEpushChanges On:
true OnCached: false
[10/12/2024, 11:00:58 AM] [SwitchBot] [D EBUG] Bot: Swotchbot bleMac: c7:32:34:35
: 0b: 5c
[10/12/2024, 11:00:58 AM] [SwitchBot] ID
EBUG] Bot: Swotchbot Bot Mode: press [10/12/2024, 11:01:03 AM] [SwitchBot] St opped Scanning for SwitchBot BLE devices
[10/12/2024, 11:01:03 AM] [SwitchBot] BO
t: Swotchbot On: true
[10/12/2024, 11:01:03 AM] [SwitchBot] Bot: Swotchbot failed BLEpushChanges with
BLE Connection, Error Message: "Cannot read properties of undefined (reading 'press') "

Config for homebridge-switchbot


{
"name": "Switchbot",
"credentials": {
        "token": "x",
        "secret": "x",
        "notice": "Keep your Token & Secret a secret!"
    },
    "options": {
        "devices": [
            {
                "configDeviceName": "Swotchbot",
                "deviceId": "c7:32:34:35:0B:5C",
                "configDeviceType": "Bot",
                "connectionType": "BLE",
                "mode": "press",
                "doublePress": 1,
                "logging": "debug"
            }
        ]
    },
    "platform": "SwitchBot"
}

Screenshots

No response

Device and Model

Switchbot Bot with Firmware v6.6

Node.js Version

v20.10.0

NPM Version

10.2.3

Homebridge Version

v1.8.4

Homebridge Switchbot Plugin Version

v4.0.0

Homebridge Config UI X Plugin Version

v4.58.0

Operating System

Raspian / Portainer / homebridge Image

donavanbecker commented 1 month ago

Providing no config?

Also you have this installed on portainer. My guess is that that could be causing the issues.

DKhen commented 1 month ago

Sorry, it didnt show up, here it is:

{
"name": "Switchbot",
"credentials": {
        "token": "x",
        "secret": "x",
        "notice": "Keep your Token & Secret a secret!"
    },
    "options": {
        "devices": [
            {
                "configDeviceName": "Swotchbot",
                "deviceId": "c7:32:34:35:0B:5C",
                "configDeviceType": "Bot",
                "connectionType": "BLE",
                "mode": "press",
                "doublePress": 1,
                "logging": "debug"
            }
        ]
    },
    "platform": "SwitchBot"
}

The error also occurs if I use the Plugin outside of docker.

donavanbecker commented 1 month ago

Does everything work fine with OpenAPI?

donavanbecker commented 1 month ago

Update your deviceId to C73234350B5C

DKhen commented 1 month ago

Isnt OpenAPI exclusive to use with the Switchbot Bridge? I just got the bot.

Changed deviceId but no difference.

DKhen commented 1 month ago

New error Message: image

donavanbecker commented 1 month ago

Isnt OpenAPI exclusive to use with the Switchbot Bridge? I just got the bot.

Changed deviceId but no difference.

Yes you need a Hub to use bot with OpenAPI

donavanbecker commented 1 month ago

New error Message: image

This happens when the plugin cannot receive serviceData (BLE Data) from the device.

If you cannot push a command, I am not surprised that you weren't able to receive as well.

donavanbecker commented 1 month ago

The error also occurs if I use the Plugin outside of docker.

Have you installed all prerequisites of node-switchbot and noble.

DKhen commented 1 month ago

Yes I have, im trying also some scripts with noble with discovering bluetooth devices, and that seems to be working. Is there a discord where we could discuss this?

DKhen commented 1 month ago

directly from homebridge console:

const noble = require('@stoprocent/noble');

const targetAddress = 'c7:32:34:35:0b:5c';

noble.on('stateChange', (state) => {
    if (state === 'poweredOn') {
        console.log('Bluetooth is powered on. Starting scan...');
        noble.startScanning([], false);
    } else {
        console.log('Bluetooth is not powered on. Stopping scan...');
        noble.stopScanning();
    }
});

noble.on('discover', (peripheral) => {
    const discoveredAddress = peripheral.address.toLowerCase(); // Normalize to lowercase
    if (discoveredAddress === targetAddress) {
        const advertisement = peripheral.advertisement;
        const manufacturerData = advertisement.manufacturerData;

        let deviceName = 'Unknown';
        if (manufacturerData) {
            // Extract device-specific name from manufacturerData if localName is undefined
            deviceName = `SwitchBot_${manufacturerData.toString('hex').slice(0, 12)}`;
        }

       console.log(peripheral);
       console.log('Discovered target peripheral:');
       console.log(`  Name: ${deviceName}`);
       console.log(`  Address: ${peripheral.address}`);
       console.log(`  RSSI: ${peripheral.rssi}`);
       console.log(`  UUID: ${peripheral.uuid}`);
       console.log('  Advertisement:', advertisement);
}
});
Bluetooth is powered on. Starting scan...
<ref *1> Peripheral {
  _noble: Noble {
    initialized: true,
    address: 'e4:5f:01:a8:64:9f',
    _state: 'poweredOn',
    _bindings: NobleBindings {
      _state: 'poweredOn',
      _addresses: [Object],
      _addresseTypes: [Object],
      _connectable: [Object],
      _isExtended: false,
      scannable: [Object],
      _pendingConnectionUuid: null,
      _connectionQueue: [],
      _handles: {},
      _gatts: {},
      _aclStreams: {},
      _signalings: {},
      _hci: [Hci],
      _gap: [Gap],
      _events: [Object: null prototype],
      _eventsCount: 25,
      onSigIntBinded: [Function: bound ],
      _scanServiceUuids: []
    },
    _peripherals: {
      d4adfc01a646: [Peripheral],
      '7138c37152be': [Peripheral],
      '3e402754330d': [Peripheral],
      '54deca1759a9': [Peripheral],
      '4623a39224d8': [Peripheral],
      '6abada3773c8': [Peripheral],
      '57c75c6cb276': [Peripheral],
      c73234350b5c: [Circular *1]
    },
    _services: {
      d4adfc01a646: {},
      '7138c37152be': {},
      '3e402754330d': {},
      '54deca1759a9': {},
      '4623a39224d8': {},
      '6abada3773c8': {},
      '57c75c6cb276': {},
      c73234350b5c: {}
    },
    _characteristics: {
      d4adfc01a646: {},
      '7138c37152be': {},
      '3e402754330d': {},
      '54deca1759a9': {},
      '4623a39224d8': {},
      '6abada3773c8': {},
      '57c75c6cb276': {},
      c73234350b5c: {}
    },
    _descriptors: {
      d4adfc01a646: {},
      '7138c37152be': {},
      '3e402754330d': {},
      '54deca1759a9': {},
      '4623a39224d8': {},
      '6abada3773c8': {},
      '57c75c6cb276': {},
      c73234350b5c: {}
    },
    _discoveredPeripheralUUids: {
      d4adfc01a646: true,
      '7138c37152be': true,
      '3e402754330d': true,
      '54deca1759a9': true,
      '4623a39224d8': true,
      '6abada3773c8': true,
      '57c75c6cb276': true,
      c73234350b5c: true
    },
    _events: [Object: null prototype] {
      warning: [Function (anonymous)],
      newListener: [Function (anonymous)],
      stateChange: [Function (anonymous)],
      discover: [Function (anonymous)]
    },
    _eventsCount: 4,
    _allowDuplicates: false
  },
  id: 'c73234350b5c',
  uuid: 'c73234350b5c',
  address: 'c7:32:34:35:0b:5c',
  addressType: 'random',
  connectable: true,
  scannable: false,
  advertisement: {
    localName: undefined,
    txPowerLevel: undefined,
    manufacturerData: <Buffer 69 09 c7 32 34 35 0b 5c 10 2c>,
    serviceData: [ [Object] ],
    serviceUuids: [],
    solicitationServiceUuids: [],
    serviceSolicitationUuids: []
  },
  rssi: -32,
  services: null,
  mtu: null,
  state: 'disconnected'
}
Discovered target peripheral:
  Name: SwitchBot_6909c7323435
  Address: c7:32:34:35:0b:5c
  RSSI: -32
  UUID: c73234350b5c
  Advertisement: {
  localName: undefined,
  txPowerLevel: undefined,
  manufacturerData: <Buffer 69 09 c7 32 34 35 0b 5c 10 2c>,
  serviceData: [ { uuid: 'fd3d', data: <Buffer 48 40 e4 00> } ],
  serviceUuids: [],
  solicitationServiceUuids: [],
  serviceSolicitationUuids: []
}
DKhen commented 1 month ago

But if I try this using node-switchbot:

import { SwitchBotBLE } from 'node-switchbot';
import noble from '@stoprocent/noble';
const switchBotBLE = new SwitchBotBLE({ noble });

switchBotBLE.discover().then(() => {
  console.log('The discovery process was finished.');
});

switchBotBLE.discover({
  duration: 5000,
  quick: true
}).then((device_list) => {
 console.log(device_list);
}).catch((error) => {
  console.error(error);
});

i get

The discovery process was finished.
[]
[]
donavanbecker commented 1 month ago

My BLE control is also completely broken with 4.0

[10/14/2024, 2:23:26 PM] [@switchbot/homebridge-switchbot] This plugin generated a warning from the characteristic 'Target Position': characteristic value expected valid finite number and received "NaN" (number). See https://homebridge.io/w/JtMGR for more info.
[10/14/2024, 2:23:27 PM] [SwitchBot] Curtain3: LeftCurtain TypeError: Cannot read properties of undefined (reading 'runToPos')
[10/14/2024, 2:23:27 PM] [SwitchBot] Curtain3: LeftCurtain Retrying
[10/14/2024, 2:23:28 PM] [SwitchBot] Curtain3: LeftCurtain TypeError: Cannot read properties of undefined (reading 'runToPos')
[10/14/2024, 2:23:28 PM] [SwitchBot] Curtain3: LeftCurtain Retrying
[10/14/2024, 2:23:29 PM] [SwitchBot] Curtain3: LeftCurtain TypeError: Cannot read properties of undefined (reading 'runToPos')
[10/14/2024, 2:23:29 PM] [SwitchBot] Curtain3: LeftCurtain Retrying
[10/14/2024, 2:23:30 PM] [SwitchBot] Curtain3: LeftCurtain TypeError: Cannot read properties of undefined (reading 'runToPos')
[10/14/2024, 2:23:30 PM] [SwitchBot] Curtain3: LeftCurtain Retrying
[10/14/2024, 2:23:31 PM] [SwitchBot] Curtain3: LeftCurtain failed BLEpushChanges with BLE Connection, Error Message: "Cannot read properties of undefined (reading 'runToPos')"

This seems to be a carryover of this: #1007 (comment)

Please delete from this issue and open a new issue as this is for Curtains

DKhen commented 4 weeks ago

@donavanbecker using noble, i managed to send the trigger command to the bot, eventually this might help you with finding the error? i have tbh struggle to see through this project 😅

const noble = require('@abandonware/noble');
const targetAddress = 'c7:32:34:35:0b:5c';

noble.on('stateChange', (state) => {
    if (state === 'poweredOn') {
        console.log('Bluetooth is powered on. Starting scan...');
        noble.startScanning([], false);
    } else {
        console.log('Bluetooth is not powered on. Stopping scan...');
        noble.stopScanning();
    }
});

noble.on('discover', (peripheral) => {
    const discoveredAddress = peripheral.address.toLowerCase();
    if (discoveredAddress === targetAddress) {
        console.log('Discovered target peripheral:', peripheral.advertisement);

        console.log('Attempting to connect...');
        peripheral.connect((error) => {
            if (error) {
                console.error('Failed to connect:', error);
                return;
            }
            console.log('Connected to the device.');

            // Add a small delay before interacting
            setTimeout(() => {
                sendCommandToSwitchBot(peripheral);
            }, 1000); // Delay for 1 second
        });

        // Handle disconnect
        peripheral.once('disconnect', (error) => {
            if (error) {
                console.error('Disconnected due to error:', error);
            } else {
                console.log('Peripheral disconnected');
            }
        });
    }
});

function sendCommandToSwitchBot(peripheral) {
    peripheral.discoverAllServicesAndCharacteristics((error, services, characteristics) => {
        if (error) {
            console.error('Error discovering services/characteristics:', error);
            return;
        }

        console.log('Successfully discovered services and characteristics.');

        // Interact with the custom characteristics
        characteristics.forEach((characteristic) => {
            if (characteristic.uuid === 'cba20003224d11e69fb80002a5d5c51b' ||
                characteristic.uuid === 'cba20002224d11e69fb80002a5d5c51b') {

                console.log('Interacting with SwitchBot Bot characteristic.');

                // Attempt to read the characteristic first
                characteristic.read((error, data) => {
                    if (error) {
                        console.error('Error reading characteristic:', error);
                    } else {
                        console.log('Characteristic read data:', data);

                        // Now attempt to send the press command
                        const command = Buffer.from([0x57, 0x01, 0x00]); // Example press command
                        characteristic.write(command, false, (error) => {
                            if (error) {
                                console.error('Error writing to characteristic:', error);
                            } else {
                                console.log('Command sent to SwitchBot Bot!');
                            }
                        });
                    }
                });
            }
        });
    });
}
donavanbecker commented 4 weeks ago

Thanks @DKhen! When I have time I will take a look. But if you want to open a PR to make it better, by all means.

DKhen commented 4 weeks ago

oh that was no critism for your project, its just my own stupidness lol :D i will give it a try, but im sure in mean time you already fixed it haha

donavanbecker commented 4 weeks ago

I wasn't taking it as critism. I self taught myself how to code.... so it probably could be better ha.

DKhen commented 4 weeks ago

Ah okay nice, in fact i develop with php, but I find it hardly to get into typescript especially with such huge projects

donavanbecker commented 3 weeks ago

@DKhen are you on the homebridge discord server?

DKhen commented 3 weeks ago

Not yet, you got a link somewhere?

donavanbecker commented 3 weeks ago

You can find it right here:

Homebridge UI: Community