mmakaay / esphome-xiaomi_bslamp2

ESPHome integration for the Xiaomi Mijia Bedside Lamp v2.
Other
205 stars 49 forks source link

[BUG] Can't import the external component #65

Closed shokwaav closed 2 years ago

shokwaav commented 2 years ago

Describe the bug A clear and concise description of what the bug is.

I'm getting an error with importing the component on validating the esphome firmware.

ERROR Unable to import component xiaomi_bslamp2.light:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
ERROR Unable to import component xiaomi_bslamp2.text_sensor:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
ERROR Unable to import component xiaomi_bslamp2.output:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
ERROR Unable to import component xiaomi_bslamp2.binary_sensor:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
ERROR Unable to import component xiaomi_bslamp2.binary_sensor:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
ERROR Unable to import component xiaomi_bslamp2.sensor:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 162, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/config/esphome/.esphome/external_components/d1d49d2c/components/xiaomi_bslamp2/__init__.py", line 6, in <module>
    from esphome.components.i2c import I2CComponent, I2CDevice
ImportError: cannot import name 'I2CComponent' from 'esphome.components.i2c' (/esphome/esphome/components/i2c/__init__.py)
Failed config

Here is my .yaml file:

substitutions:
  name: bedside-lamp
  friendly_name: Bedside Lamp
  transition_length: 500ms

  # Component identifiers.
  prefix: bedside_lamp
  id_light: ${prefix}
  id_light_mode: ${prefix}_light_mode
  id_power_button: ${prefix}_power_button
  id_color_button: ${prefix}_color_button
  id_slider_level: ${prefix}_slider_level
  id_front_panel_illumination: ${prefix}_front_panel_illumination

# --------------------------------------------------------------------------
# Use your own preferences for these components.
# --------------------------------------------------------------------------

wifi:
  ssid: "xxxx"
  password: "xxxxx"

  # Enable fallback hotspot (for captive portal) in case wifi connection fails
  ap:
    ssid: "ESPHome $friendly_name"
    password: "Password-For-Connecting-To-Captive-Portal"

captive_portal:

api:
  # Disable the reboot timeout. By default, the lamp reboots after 15
  # minutes without any client connections (e.g. when home assistant is off
  # line, or when the WiFi is broken). Reboots are annoying though, because
  # the RGBWW LEDs will turn off during the reboot, causing the light to
  # flicker.
  reboot_timeout: 0s

ota:
  password: "123456"

# The log level can be raised when needed for debugging the firmware. For
# production, a low log level is recommended. Mainly because high volume log
# output might interfere with the API/WiFi connection stability. So when
# raising the log level, beware that you might see dropped connections from
# Home Assistant and the network log viewer.
logger:
    level: WARN

# --------------------------------------------------------------------------
# Configuration specific for the Xiaomi Mijia Bedside Lamp 2.
# This is just an example. You can of course modify it for your own needs.
# --------------------------------------------------------------------------

# Retrieve the code for the xiaomi_bslamp2 platform from GitHub.
external_components:
  - source:
      type: git
      url: https://github.com/mmakaay/esphome-xiaomi_bslamp2
      ref: main
    refresh: 60s

# A special platform package is used for enabling unicore and disabling the
# efuse mac crc check. These two changes are required for the ESP32-WROOM-32D
# chip that is used in the lamp.
esphome:
  name: ${name}
  platform: ESP32
  board: esp32doit-devkit-v1
  platformio_options:
    platform: espressif32@3.2.0
    platform_packages: |-
      framework-arduinoespressif32 @ https://github.com/mmakaay/arduino-esp32-unicore-no-mac-crc#v1.0.6

# This component controls the LED lights of the lamp.
light:
  - platform: xiaomi_bslamp2
    id: ${id_light}
    name: ${friendly_name} RGBWW Light
    default_transition_length: ${transition_length}
    # When the brightness is changed, then update the level indicator
    # on the front panel accordingly. In night light mode, turn off
    # the front panel illumination.
    on_brightness:
      - if:
          condition:
            text_sensor.state:
                id: ${id_light_mode}
                state: night
          then:
            - output.set_level:
                id: ${id_front_panel_illumination}
                level: 0
          else:
            - output.set_level:
                id: ${id_front_panel_illumination}
                level: !lambda return x;
    # You can use any effects that you like. These are just examples.
    effects:
      - random:
          name: "Slow Random"
          transition_length: 30s
          update_interval: 30s
      - random:
          name: "Fast Random"
          transition_length: 3s
          update_interval: 3s
    # You can define one or more groups of presets. These presets can
    # be activated using various "preset.activate" action options.
    # The presets can for example be used to mimic the behavior of the
    # original firmware (tapping the color button = go to next preset,
    # holding the color button = switch between RGB and white light mode).
    # These bindings have been setup below, using the binary_sensor for
    # the color button.
    presets:
      rgb:
        red:         { red: 100%, green: 0%,   blue: 0%   }
        green:       { red: 0%,   green: 100%, blue: 0%   }
        blue:        { red: 0%,   green: 0%,   blue: 100% }
        yellow:      { red: 100%, green: 100%, blue: 0%   }
        purple:      { red: 100%, green: 0%,   blue: 100% }
        randomize:   { effect: Fast Random                }
      white:
        cold:        { color_temperature: 153 mireds      }
        chilly:      { color_temperature: 275 mireds      }
        luke:        { color_temperature: 400 mireds      }
        warm:        { color_temperature: 588 mireds      }

# This text sensor propagates the currently active light mode.
# The possible light modes are: "off", "rgb", "white" and "night".
# By setting the name, the text_sensor will show up as an entity
# for the lamp in Home Assistant.
text_sensor:
  - platform: xiaomi_bslamp2
    name: ${friendly_name} Light Mode
    id: ${id_light_mode}

# This float output controls the front panel illumination + level indicator.
# Value 0.0 turns off the illumination. Other values (up to 1.0) turn on
# the illumination and set the level indicator to the requested level.
output:
  - platform: xiaomi_bslamp2
    id: ${id_front_panel_illumination}

# Binary sensors can be created for handling front panel touch / release
# events. To specify what part of the front panel to look at, the "for"
# parameter can be set to: "POWER_BUTTON", "COLOR_BUTTON" or "SLIDER".
binary_sensor:
  # When tapping the power button, toggle the light.
  # When holding the power button, turn on night light mode.
  - platform: xiaomi_bslamp2
    id: ${id_power_button}
    for: POWER_BUTTON
    on_multi_click:
    - timing:
        - ON for at most 0.8s
      then:
        - light.toggle: ${id_light}
    - timing:
        - ON for at least 0.8s
      then:
        - light.turn_on:
            id: ${id_light}
            brightness: 1%

  # When tapping the color button, acivate the next preset.
  # When holding the color button, activate the next preset group.
  - platform: xiaomi_bslamp2
    id: ${id_color_button}
    for: COLOR_BUTTON
    on_multi_click:
      - timing:
          - ON for at most 0.6s
        then:
          - preset.activate:
              next: preset
      - timing:
          - ON for at least 0.6s
        then:
          - preset.activate:
              next: group

# This sensor component publishes touch events for the front panel slider.
# The published value represents the level at which the slider was touched.
# By default, values range from 0.01 to 1.00 (in 20 steps). This range can
# be modified using the "range_from" and "range_to" parameters.
sensor:
  # When the slider is touched, update the brightness.
  # Brightness 0.01 initiates the light night mode, which has already
  # been handled above (by holding the power button). Therefore, brightness
  # starts from 0.02 here, to not trigger night mode using the slider.
  - platform: xiaomi_bslamp2
    id: ${id_slider_level}
    range_from: 0.02
    on_value:
      then:
        - light.turn_on:
            id: ${id_light}
            brightness: !lambda return x;

I'm using ESPHome v2021.10.3

shokwaav commented 2 years ago

Oh never mind, seems I use the example.yaml from the dev version.

It seems the main branch hasn't been updated yet?

mmakaay commented 2 years ago

It seems the main branch hasn't been updated yet?

The main branch was becoming a bit hard to maintain, because I often have new stable changes ready, while ESPHome has not yet moved forward. When I pushed new code to main, it would break things for users that use old ESPHome versions. So instead, the main branch is now "dev", on which I always work against ESPHome "dev", Once I get to a stable release, I branch to a release branch, for example "release/2021.10.0" for the current stable release.

So in fact, the "main" branch could be considered stale now. I won't remove it yet though, to not bother people that are still using it.

shokwaav commented 2 years ago

So in fact, the "main" branch could be considered stale now. I won't remove it yet though, to not bother people that are still using it.

I see - I think I got it confused because I clicked the example.yaml in the main branch instead of following the link int he readme.

Would it be possible to change the name of the "main" branch example.yaml name so it would be less confusing?

mmakaay commented 2 years ago

Not really, because "main" is what's referenced in the existing configs that make use of it. What was changed however, is the default branch for the repository. If you browse to https://github.com/mmakaay/esphome-xiaomi_bslamp2 , then you will see that dev is selected as the default branch. So via that route you should get the most recent data.

In time, I certainly want to get rid of the main branch completely, possibly by renaming it to legacy or so, but at this point I think it's too soon for that.