Betree / magicblue

💡 Unofficial Python API to control Magic Blue bulbs over Bluetooth
MIT License
100 stars 23 forks source link

Multiple bulbs setup #27

Closed Betree closed 6 years ago

Betree commented 7 years ago

This question is often asked, how many bulbs can we handle at the same time ? There's no theoretical limit in this library, but maybe in bluepy ?

Any feedback on the subject would be welcome. I've personally ordered two more bulbs so I'll be able to check that in a few weeks.

mouth4war commented 7 years ago

For what it's worth, I have 5 of these bulbs and can't get more than 3 to work at a time. What I've found by using gatttool is that the flag "-t random" is needed for these bulbs to work.

I'm able to connect to all the bulbs with gatttool but not magicblueshell (exceptions are thrown for 2 bulbs of the 5 - ERROR:magicblue.magicblueshell:Unexpected error with command "connect...). The other 3 connect using magicblueshell just fine (INFO:magicblue.magicblueshell:Connected).

The exception seems to be coming from blue.py using addr type Public instead of Random. bluepy.btle.BTLEException Failed to connect to peripheral XXXXXX, addr type: public

The function def _figure_addr_type needs to have a check for v8 and setting addr type to random. I have made this change locally and now I'm able to connect to all 5 bulbs. Now, HomeAssistant is still not able to connect to those two, so IDK what's up with that. Magicblueshell connects but HA doesn't.

For reference, I have all 5 v8 bulbs. The ones that don't work have MAC starting with F1 and F6.

Betree commented 7 years ago

@mouth4war This is really interesting. My setup is 2xv10 (public address type) and 1xv7 (random address type, same as your v8).

I've made some changes in experiments/multi-bulbs (commit 52fa1f093678bcc026ebac096ea857420b44c88d) to be able to use magicblueshell with multiple bulbs at the same time, which makes testing easier.

The two v10 react pretty well, everything went fine. But when I try to use the v7 at the same time as the two other, it randomly disconnects - maybe a conflict when using public and random at the same time.

But regarding your problem, my v7 bulb mac address starts with c7, the two others with f8. Maybe some of you v8 are using public and other random address type. If so, we should put this code @StevenLooman wrote before version checking :

# try using mac_address
if mac_address is not None:
    mac_address_num = int(mac_address.replace(':', ''), 16)
    if mac_address_num & 0xF00000000000 == 0xF00000000000:
        return btle.ADDR_TYPE_PUBLIC

The reason it works from magicblueshell but not HA must be that when calling connect from magicblueshell, it also scans the device address type and pass it to magicbluelib.

Can you try connecting to the bulb that have a MAC starting with F using public address type ?

Betree commented 7 years ago

The official android app also bugs when I try to use both types (v7/v10) at the same time.

StevenLooman commented 7 years ago

My mac address check is probably not complete or even invalid. The check I added worked for my bulbs (v10) and the one or articles about hacking the bulbs (can't remember which versions those were.) If you have/know something better...

Your best bet if so specify a version when connecting.

For the CLI: Please be aware that a new version of bluepy has been released. I noticed it can now take an entry from the scanner and automatically choose public/private.

mouth4war commented 7 years ago

I fixed the HA issue by copying the magicbluelib file to the deps folder (it maintains a local copy). So with RANDOM, I'm able to connect to all 5 bulbs with magicblueshell and HA both.

mouth4war commented 7 years ago

An update after observing the bulbs over a few days. They behave erratically in terms of maintaining a connection. Different bulbs become unresponsive and cannot connect in magicblueshell at different times. Wait for a second or two and retry and viola, you're connected. Some "broken pipe" exceptions pop up from time to time.

Examples:

connect 1 ERROR:magicblue.magicblueshell:Unexpected error with command "connect 1": Failed to connect to peripheral c1:d4:bf:XX:XX:XX, addr type: random connect 1 INFO:magicblue.magicblueshell:Connected turn off

Bye ! Exception ignored in: <bound method Peripheral.del of <bluepy.btle.Peripheral object at 0x7648baf0>> Traceback (most recent call last): File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 520, in del self.disconnect() File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 416, in disconnect self._writeCmd("disc\n") File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 268, in _writeCmd self._helper.stdin.flush() BrokenPipeError: [Errno 32] Broken pipe

I do remember similar behaviour in the android app. So maybe it's a v8 bulb thing. How is the performance of the later bulbs for you guys? Are they consistent and responsive?

Betree commented 7 years ago

They do disconnect often, though v10 is more stable than v7 in my case.

However I found that using @StevenLooman's fork of the homeassistant component works really well as it now automatically reconnects and doesn't lock the all thing; from the user point of view it's transparent.

Another thing I noticed : the range for it to work properly is pretty short and very sensitive to obstacles.

mouth4war commented 7 years ago

Thanks for those tips! HA is not throwing up exceptions after switching to that fork. Bulbs seem more responsive, so far.

I might just add 3 more of these to my room setup, despite white-only yeelights being around the same price. I prefer the aesthetics of this bulb more than the yeelight. I know I'll probably regret this!

StevenLooman commented 7 years ago

My 3 v10s are also not 100% stable. Not from home assistant and not from the magicblue CLI or libs, although the CLI appears to be a bit more stable. All this is tried on a Raspberry PI 3.

Be sure to upgrade to the latest version of bluepy, that might further improve stability.

To be honest, if you want something (more) stable, you might want to choose another platform. I do have a (white-only) yeelight, but the light is very unnatural and unpleasant. I have no experience with the Philips HUE platform, or any of the compatible blubs.

mouth4war commented 7 years ago

I'm a lot happier with the performance with your HA component fork, Steven. They are not 100% but almost 99% reliable now. I ordered 3 more to complete my living room setup so I'll have 8 of these in my living room.

I'm partial to ball/globe shaped bulbs so the yeelights and hues look unappealing to me. I can use them in lamps where the bulb isnt exposed, though.

OT: I also have 5 of Philips/Xiaomi WW hubless step-less dimming globe-shaped bulbs (220v) that work with the MiHome app and look great too. Wish these could be included in HA but it looks like they can't.

StevenLooman commented 7 years ago

Great! I'm curious to know how which versions you'll get and how they work.

For the Xiami bulbs, interesting. I have no experience with Xiaomi hardware, but am curious how these will work. I am guessing via bluetooth as well, but probably using another protocol.

There are some articles about the magicblue bulbs, on how to sniff the bluetooth traffic. Maybe you can do this and figure out any specifics from the used protocol.

mouth4war commented 7 years ago

So I got 3 v10 bulbs in the mail today. Plugged them in and tried magicblueshell and then adding to HASS.

They work fine, so far. Though HASS scenes take a while to set since the bulbs are sent commands one-by-one, so they respond one-by-one.

EDIT: So there's an exception showing up in the HASS log that's making HASS unresponsive. Once the exception happens, HASS logs show repeated failed attempts (timeouts) at updating the lights by fluxer. Is it coming from the library or the HASS component?

2017-08-01 18:55:04 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved Traceback (most recent call last): File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step result = coro.throw(exc) File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/core.py", line 1025, in _event_to_service_call yield from service_handler.func(service_call) File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/components/light/init.py", line 279, in async_handle_light_service yield from light.async_turn_on(params) File "/usr/lib/python3.4/asyncio/futures.py", line 388, in iter yield self # This tells Task to wait for completion. File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup value = future.result() File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result raise self._exception File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run result = self.fn(*self.args, *self.kwargs) File "/home/homeassistant/.homeassistant/custom_components/light/magicbluelight.py", line 58, in wrapper vals = func(self, args, kwargs) File "/home/homeassistant/.homeassistant/custom_components/light/magicbluelight.py", line 178, in turn_on self._light.set_color(self._rgb) File "/srv/homeassistant/lib/python3.4/site-packages/magicblue/magicbluelib.py", line 39, in wrapper return func(self, *args, **kwargs) File "/srv/homeassistant/lib/python3.4/site-packages/magicblue/magicbluelib.py", line 198, in set_color self._send_characteristic.write(msg) File "/srv/homeassistant/lib/python3.4/site-packages/magicblue/magicbluelib.py", line 284, in _send_characteristic uuid=UUID_CHARACTERISTIC_WRITE) File "/srv/homeassistant/lib/python3.4/site-packages/bluepy/btle.py", line 467, in getCharacteristics rsp = self._getResp('find') File "/srv/homeassistant/lib/python3.4/site-packages/bluepy/btle.py", line 369, in _getResp resp = self._waitResp(wantType + ['ntfy', 'ind'], timeout) File "/srv/homeassistant/lib/python3.4/site-packages/bluepy/btle.py", line 325, in _waitResp self._stopHelper() File "/srv/homeassistant/lib/python3.4/site-packages/bluepy/btle.py", line 255, in _stopHelper self._helper.stdin.flush() BrokenPipeError: [Errno 32] Broken pipe 2017-08-01 19:00:20 WARNING (MainThread) [homeassistant.helpers.entity] Update of light.chandelier_2 is taking over 10 seconds 2017-08-01 19:00:20 WARNING (MainThread) [homeassistant.helpers.entity] Update of switch.fluxer is taking over 10 seconds 2017-08-01 19:00:41 WARNING (MainThread) [homeassistant.components.light] Updating magicbluelight light took longer than the scheduled update interval 0:00:30 2017-08-01 19:00:41 WARNING (MainThread) [homeassistant.components.switch] Updating flux switch took longer than the scheduled update interval 0:00:30 2017-08-01 19:01:12 WARNING (MainThread) [homeassistant.components.light] Updating magicbluelight light took longer than the scheduled update interval 0:00:30 2017-08-01 19:01:12 WARNING (MainThread) [homeassistant.components.switch] Updating flux switch took longer than the scheduled update interval 0:00:30 2017-08-01 19:01:43 WARNING (MainThread) [homeassistant.components.light] Updating magicbluelight light took longer than the scheduled update interval 0:00:30

StevenLooman commented 7 years ago

The update should be happening in a separate thread and the MainThread should not get hung up on this. As soon as I have more time I'll look into this.

Betree commented 6 years ago

Closing this as 0.5 release allows for multiple bulbs usage in magicblueshell.

We probably have improvements and optimizations to do in the lib too but we'll open specific issues for them.