I’m developing a component that can control multiple brands and models of same kind devices. Currently the component works great with one small exception - all classes for all devices as hardcoded in a single file, which is pain in the *ss when it comes to readability and maintenance, so I’ve created a sub-directory with empty __init__.py
inside it and I split all the classes in separate .py
files in the same sub-directory I mentioned above. The question is how to dynamically load in climate.py
the classes from that sub-directory by having class name, as string value, coming from the platform config entry in configuration.yaml
(like brand: 'Panasonic'
)? File structure and config entry are shown at the end of the topic.
Next snippet works, but it is not dynamic …
from .heatpumps.panasonic import Panasonic
Next snippet produces error: “No module named heatpumps”
The error is only in hass.io . When I run same code with same file structure locally on my PC it works fine.
# climate.py
import importlib
# module = importlib.import_module('.' + brand.lower(), 'heatpumps') #error here
module = importlib.import_module('.panasonic', 'heatpumps') #error here
# heatpump_class = getattr(module, brand)
heatpump_class = getattr(module, 'Panasonic')
ac = heatpump_class()
Other things I tried with no success:
module = importlib.import_module('.panasonic', '.heatpumps') # No module named '.heatpumps'
module = importlib.import_module('heatpumps.panasonic') # No module named 'heatpumps'
module = importlib.import_module('.heatpumps.panasonic') # No module named '.heatpumps'
module = importlib.import_module('irclimate.heatpumps.panasonic') # No module named 'irclimate'
File hierarchy:
custom_components
(dir)
|_ irclimate
(dir)
|_ __init__.py
|_ climate.py
|_ const.py
|_ manifest.json
|_ reproduce_state.py
|_ heatpumps
(dir)
|_ __init__.py
|_ acprotocol.py
|_ panasonic.py
|_ fujitsu.py
|_ daewoo.py
|_ etc …
Example ‘panasonic.py’:
class Panasonic:
pass
Example configuration.yaml
entry:
- platform: irclimate
name: Panasonic Air Conditioner
target_sensor: sensor.temp_feel
min_temp: 16
max_temp: 30
ac_mode: true
target_temp: 26
cold_tolerance: 0
hot_tolerance: 0
min_cycle_duration:
seconds: 5
keep_alive:
minutes: 3
initial_operation_mode: "off"
away_temp: 24
precision: 1.0
topic: "cmnd/blaster/irsend"
brand: "Panasonic"
send_action:
service: script.ir_raw
data:
data: 'send'
room: kitchen