jfarmer08 / homebridge-wyze-smart-home

Wyze Smart Home plugin for Homebridge.
MIT License
103 stars 17 forks source link

Issue Due to Wyze Bolt I Believe #94

Closed shpress closed 1 year ago

shpress commented 1 year ago

This is the error I am getting and the reason I think I am getting it is because I have a Wyze Bolt installed which is Bluetooth only and does not connect to wifi. How Can i go about fixing this?

TypeError: Cannot convert undefined or null to object at Function.keys () at WyzeLock.lockGetProperty (/volume1/homebridge/node_modules/homebridge-wyze-smart-home/src/accessories/WyzeAccessory.js:422:32) at processTicksAndRejections (node:internal/process/task_queues:96:5) [4/13/2023, 7:34:01 AM] [Wyze] Child bridge process ended [4/13/2023, 7:34:01 AM] [Wyze] Process Ended. Code: 1, Signal: null [4/13/2023, 7:34:08 AM] [Wyze] Restarting Process... [4/13/2023, 7:34:08 AM] [Wyze] Launched child bridge with PID 25144 [4/13/2023, 7:34:08 AM] Registering platform 'homebridge-wyze-smart-home.WyzeSmartHome' [4/13/2023, 7:34:08 AM] [Wyze] Loaded homebridge-wyze-smart-home v0.5.26 child bridge successfully [4/13/2023, 7:34:08 AM] Loaded 5 cached accessories from cachedAccessories.0ED47E47B76E. [4/13/2023, 7:34:08 AM] [homebridge-wyze-smart-home] This plugin generated a warning from the characteristic 'Current Door State': Characteristic not in required or optional characteristic section for service ContactSensor. Adding anyway.. See https://homebridge.io/w/JtMGR for more info. [4/13/2023, 7:34:09 AM] Homebridge v1.6.0 (HAP v0.11.0) (Wyze) is running on port 35760.

/volume1/homebridge/node_modules/homebridge-wyze-smart-home/src/accessories/WyzeAccessory.js:422 const prop_keypad = Object.keys(lockKeypadProperties)

github-actions[bot] commented 1 year ago

Message that will be displayed on users' first issue

cwong-archy commented 1 year ago

i can confirm. same issue. once i have the device added it broke homebridge. works fine after removing from wyze app

[4/16/2023, 7:54:02 PM] [homebridge-wyze-smart-home] This plugin generated a warning from the characteristic 'On': characteristic value expected boolean and received undefined. See https://homebridge.io/w/JtMGR for more info.
[4/16/2023, 7:54:02 PM] TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at WyzeLock.lockGetProperty (/usr/lib/node_modules/homebridge-wyze-smart-home/src/accessories/WyzeAccessory.js:422:32)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
[4/16/2023, 7:54:02 PM] Got SIGTERM, shutting down Homebridge...
HewittJC commented 1 year ago

I had the same issue as well and was able to more or less confirm it is indeed the Lock Bolt causing the issue.

I basically just wrapped the offending Lock logic in some dummy error handling and that seems to let the child bridge start. I am however having some issues getting my HomeKit to add the bridge but I don't have any reason to think thats related quite yet. Turned out to be a firewall rule so this does appear to work for me!

Here is the snippet of code that I edited:

    const prop_keypad = []
    var printError = function(error, explicit) {
      console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
    }   
    try {
      //console.log(undefined.name);
      const prop_keypad = Object.keys(lockKeypadProperties)
    } catch (e) {
      if (e instanceof TypeError) {
        printError(e, true);
      } else {
        printError(e, false);
      }   
    }   

    //const prop_keypad = Object.keys(lockKeypadProperties)
    //if (prop_keypad === null) {
    //  const prop_keypad = []
    //} 

    for (const element of prop_keypad) {
      const prop = element
      switch (prop ) { 
        case "power":
          this.homeKitAccessory.context.device_params.keypadPower = lockKeypadProperties[prop]
          continue
        case "onoff_line":
          this.homeKitAccessory.context.device_params.keypadOnoff_line = lockKeypadProperties[prop]
          continue
      }   
    }   

    try {
      let lockKeypadProp = propertyList.device.keypad.hardware_info
      const prop_keypadProp = Object.keys(lockKeypadProp)
      for (const element of prop_keypadProp) {
        const prop = element
        switch (prop ) { 
          case "mac":
            this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
            continue
        }   
      }   
    } catch (e) {
      if (e instanceof TypeError) {
        printError(e, true);
      } else {
        printError(e, false);
      }   
    }   

    //let lockKeypadProp = propertyList.device.keypad.hardware_info
    //const prop_keypadProp = Object.keys(lockKeypadProp)
    //for (const element of prop_keypadProp) {
    //  const prop = element
    //  switch (prop ) {
    //    case "mac":
    //      this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
    //      continue
    //  }
    //} 
    this.updating = false
  }

I left the original code intact as comments. I am by no means a JavaScript developer, so if there is a better/cleaner way to do this please let me know!

cwong-archy commented 1 year ago

I had the same issue as well and was able to more or less confirm it is indeed the Lock Bolt causing the issue.

I basically just wrapped the offending Lock logic in some dummy error handling and that seems to let the child bridge start. ~I am however having some issues getting my HomeKit to add the bridge but I don't have any reason to think thats related quite yet.~ Turned out to be a firewall rule so this does appear to work for me!

Here is the snippet of code that I edited:

    const prop_keypad = []
    var printError = function(error, explicit) {
      console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
    }   
    try {
      //console.log(undefined.name);
      const prop_keypad = Object.keys(lockKeypadProperties)
    } catch (e) {
      if (e instanceof TypeError) {
        printError(e, true);
      } else {
        printError(e, false);
      }   
    }   

    //const prop_keypad = Object.keys(lockKeypadProperties)
    //if (prop_keypad === null) {
    //  const prop_keypad = []
    //} 

    for (const element of prop_keypad) {
      const prop = element
      switch (prop ) { 
        case "power":
          this.homeKitAccessory.context.device_params.keypadPower = lockKeypadProperties[prop]
          continue
        case "onoff_line":
          this.homeKitAccessory.context.device_params.keypadOnoff_line = lockKeypadProperties[prop]
          continue
      }   
    }   

    try {
      let lockKeypadProp = propertyList.device.keypad.hardware_info
      const prop_keypadProp = Object.keys(lockKeypadProp)
      for (const element of prop_keypadProp) {
        const prop = element
        switch (prop ) { 
          case "mac":
            this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
            continue
        }   
      }   
    } catch (e) {
      if (e instanceof TypeError) {
        printError(e, true);
      } else {
        printError(e, false);
      }   
    }   

    //let lockKeypadProp = propertyList.device.keypad.hardware_info
    //const prop_keypadProp = Object.keys(lockKeypadProp)
    //for (const element of prop_keypadProp) {
    //  const prop = element
    //  switch (prop ) {
    //    case "mac":
    //      this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
    //      continue
    //  }
    //} 
    this.updating = false
  }

I left the original code intact as comments. I am by no means a JavaScript developer, so if there is a better/cleaner way to do this please let me know!

hey @HewittJC thanks for the code. i made the changes and it seems to work...

seeing this -

[EXPLICIT] TypeError: Cannot convert undefined or null to object
[EXPLICIT] TypeError: Cannot read properties of undefined (reading 'hardware_info')

but thats fine with me as long as its working. :P

just in case anyone else want to make the change, i made the edit in /usr/lib/node_modules/homebridge-wyze-smart-home/src/accessories/WyzeAccessory.js

heres the diff -

──── sudo diff WyzeAccessory.js WyzeAccessory.js-original
422,437c422
<     // const prop_keypad = Object.keys(lockKeypadProperties)
<     const prop_keypad = []
<     var printError = function(error, explicit) {
<       console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
<     }
<     try {
<       //console.log(undefined.name);
<       const prop_keypad = Object.keys(lockKeypadProperties)
<     } catch (e) {
<       if (e instanceof TypeError) {
<         printError(e, true);
<       } else {
<         printError(e, false);
<       }
<     }
<
---
>     const prop_keypad = Object.keys(lockKeypadProperties)
449,465c434,441
<
<     try {
<       let lockKeypadProp = propertyList.device.keypad.hardware_info
<       const prop_keypadProp = Object.keys(lockKeypadProp)
<       for (const element of prop_keypadProp) {
<         const prop = element
<         switch (prop ) {
<           case "mac":
<             this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
<             continue
<         }
<       }
<     } catch (e) {
<       if (e instanceof TypeError) {
<         printError(e, true);
<       } else {
<         printError(e, false);
---
>     let lockKeypadProp = propertyList.device.keypad.hardware_info
>     const prop_keypadProp = Object.keys(lockKeypadProp)
>     for (const element of prop_keypadProp) {
>       const prop = element
>       switch (prop ) {
>         case "mac":
>           this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
>           continue
467,477c443
<     }
<     // let lockKeypadProp = propertyList.device.keypad.hardware_info
<     // const prop_keypadProp = Object.keys(lockKeypadProp)
<     // for (const element of prop_keypadProp) {
<     //   const prop = element
<     //   switch (prop ) {
<     //     case "mac":
<     //       this.homeKitAccessory.context.device_params.keypadMac = lockKeypadProp[prop]
<     //       continue
<     //   }
<     // }
---
>     }
HewittJC commented 1 year ago

@cwong-archy those are just the printError statements from within the try/catch blocks. Its just printing the errors out so that they aren't made totally silent.

Glad to help!