Skip to content

External Components - sensor.py - partially initialized module 'esphome.components.sensor' has no attribute 'sensor_schema' #5323

Description

@DEADSEC-SECURITY

The problem

Hi guys, I'm trying to develop my own custom component so I can have esphome use a BLE device I own but when I compile I get an error from sensor.py on my component.

sensor.py

import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, esp32_ble_tracker
from esphome.const import (
    CONF_MAC_ADDRESS,
    CONF_BATTERY_LEVEL,
    UNIT_PERCENT,
    DEVICE_CLASS_BATTERY,
    STATE_CLASS_MEASUREMENT,
    CONF_ID
)

DEPENDENCIES = ["esp32_ble_tracker"]

pill_dispenser_ns = cg.esphome_ns.namespace("pill_dispenser")
PillDispenser = pill_dispenser_ns.class_(
    "PillDispenser", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
)

CONFIG_SCHEMA = (
    cv.Schema(
        {
            cv.GenerateID(): cv.declare_id(PillDispenser),
            cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
            cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
                unit_of_measurement=UNIT_PERCENT,
                accuracy_decimals=0,
                device_class=DEVICE_CLASS_BATTERY,
                state_class=STATE_CLASS_MEASUREMENT,
            )
        }
    )
    .extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
    .extend(cv.COMPONENT_SCHEMA)
)


async def to_code(config):
    var = cg.new_Pvariable(config[CONF_ID])
    await cg.register_component(var, config)
    await esp32_ble_tracker.register_ble_device(var, config)

    cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))

    if CONF_BATTERY_LEVEL in config:
        sens = await sensor.new_sensor(config[CONF_BATTERY_LEVEL])
        cg.add(var.set_battery(sens))

File structure

Screenshot 2023-12-31 194509

Which version of ESPHome has the issue?

2023.12.5

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2023.12.4

What platform are you using?

ESP32-IDF

Board

ESP32

Component causing the issue

Custom Component

Example YAML snippet

esphome:
  name: xxx
  friendly_name: xxx

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    version: recommended

external_components:
  - source:
      type: local
      path: my_components/dose_control

esp32_ble_tracker:

ble_client:
  - mac_address: A6:C0:82:01:17:72
    id: dispenser
        
sensor:
  - platform: ble_client
    type: characteristic
    ble_client_id: dispenser
    name: "Temperature Sensor 32bit float"
    device_class: "temperature"
    lambda: |-
      return *((float*)(&x[0]));

Anything in the logs that might be useful for us?

INFO ESPHome 2023.12.5
INFO Reading configuration /config/esphome/grandmother-pill-dispenser.yaml...
ERROR Unable to load component sensor:
Traceback (most recent call last):
  File "/esphome/esphome/loader.py", line 169, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/config/esphome/my_components/dose_control/sensor.py", line 25, in <module>
    cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
                                     ^^^^^^^^^^^^^^^^^^^^
AttributeError: partially initialized module 'esphome.components.sensor' has no attribute 'sensor_schema' (most likely due to a circular import)
Failed config

sensor: [source <unicode string>:58]
  
  Component not found: sensor.
  - platform: ble_client
    type: characteristic
    ble_client_id: dispenser
    name: Temperature Sensor 32bit float
    device_class: temperature
    lambda: return *((float*)(&x[0]));

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions