cogito/esphome_dev/esphome/components/msa3xx/__init__.py

189 lines
5.3 KiB
Python

from esphome import automation
import esphome.codegen as cg
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import (
CONF_CALIBRATION,
CONF_ID,
CONF_MIRROR_X,
CONF_MIRROR_Y,
CONF_OFFSET_X,
CONF_OFFSET_Y,
CONF_OFFSET_Z,
CONF_RANGE,
CONF_RESOLUTION,
CONF_SWAP_XY,
CONF_TRANSFORM,
CONF_TYPE,
)
CODEOWNERS = ["@latonita"]
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
CONF_MSA3XX_ID = "msa3xx_id"
CONF_MIRROR_Z = "mirror_z"
CONF_ON_ACTIVE = "on_active"
CONF_ON_DOUBLE_TAP = "on_double_tap"
CONF_ON_FREEFALL = "on_freefall"
CONF_ON_ORIENTATION = "on_orientation"
CONF_ON_TAP = "on_tap"
MODEL_MSA301 = "MSA301"
MODEL_MSA311 = "MSA311"
msa3xx_ns = cg.esphome_ns.namespace("msa3xx")
MSA3xxComponent = msa3xx_ns.class_(
"MSA3xxComponent", cg.PollingComponent, i2c.I2CDevice
)
MSAModels = msa3xx_ns.enum("Model", True)
MSA_MODELS = {
MODEL_MSA301: MSAModels.MSA301,
MODEL_MSA311: MSAModels.MSA311,
}
MSARange = msa3xx_ns.enum("Range", True)
MSA_RANGES = {
"2G": MSARange.RANGE_2G,
"4G": MSARange.RANGE_4G,
"8G": MSARange.RANGE_8G,
"16G": MSARange.RANGE_16G,
}
MSAResolution = msa3xx_ns.enum("Resolution", True)
RESOLUTIONS_MSA301 = {
14: MSAResolution.RES_14BIT,
12: MSAResolution.RES_12BIT,
10: MSAResolution.RES_10BIT,
8: MSAResolution.RES_8BIT,
}
RESOLUTIONS_MSA311 = {
12: MSAResolution.RES_12BIT,
}
_COMMON_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(MSA3xxComponent),
cv.Optional(CONF_RANGE, default="2G"): cv.enum(MSA_RANGES, upper=True),
cv.Optional(CONF_CALIBRATION): cv.Schema(
{
cv.Optional(CONF_OFFSET_X, default=0): cv.float_range(
min=-4.5, max=4.5
),
cv.Optional(CONF_OFFSET_Y, default=0): cv.float_range(
min=-4.5, max=4.5
),
cv.Optional(CONF_OFFSET_Z, default=0): cv.float_range(
min=-4.5, max=4.5
),
}
),
cv.Optional(CONF_TRANSFORM): cv.Schema(
{
cv.Optional(CONF_MIRROR_X, default=False): cv.boolean,
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
cv.Optional(CONF_MIRROR_Z, default=False): cv.boolean,
cv.Optional(CONF_SWAP_XY, default=False): cv.boolean,
}
),
cv.Optional(CONF_ON_ACTIVE): automation.validate_automation(single=True),
cv.Optional(CONF_ON_TAP): automation.validate_automation(single=True),
cv.Optional(CONF_ON_DOUBLE_TAP): automation.validate_automation(single=True),
cv.Optional(CONF_ON_FREEFALL): automation.validate_automation(single=True),
cv.Optional(CONF_ON_ORIENTATION): automation.validate_automation(single=True),
}
).extend(cv.polling_component_schema("10s"))
CONFIG_SCHEMA = cv.typed_schema(
{
MODEL_MSA301: _COMMON_SCHEMA.extend(
{
cv.Optional(CONF_RESOLUTION, default=14): cv.enum(RESOLUTIONS_MSA301),
}
).extend(i2c.i2c_device_schema(0x26)),
MODEL_MSA311: _COMMON_SCHEMA.extend(
{
cv.Optional(CONF_RESOLUTION, default=12): cv.enum(RESOLUTIONS_MSA311),
}
).extend(i2c.i2c_device_schema(0x62)),
},
upper=True,
enum=MSA_MODELS,
)
MSA_SENSOR_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_MSA3XX_ID): cv.use_id(MSA3xxComponent),
}
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
cg.add(var.set_model(config[CONF_TYPE]))
cg.add(var.set_range(MSA_RANGES[config[CONF_RANGE]]))
cg.add(var.set_resolution(RESOLUTIONS_MSA301[config[CONF_RESOLUTION]]))
if transform := config.get(CONF_TRANSFORM):
cg.add(
var.set_transform(
transform[CONF_MIRROR_X],
transform[CONF_MIRROR_Y],
transform[CONF_MIRROR_Z],
transform[CONF_SWAP_XY],
)
)
if calibration_config := config.get(CONF_CALIBRATION):
cg.add(
var.set_offset(
calibration_config[CONF_OFFSET_X],
calibration_config[CONF_OFFSET_Y],
calibration_config[CONF_OFFSET_Z],
)
)
# Triggers secton
if CONF_ON_ORIENTATION in config:
await automation.build_automation(
var.get_orientation_trigger(),
[],
config[CONF_ON_ORIENTATION],
)
if CONF_ON_TAP in config:
await automation.build_automation(
var.get_tap_trigger(),
[],
config[CONF_ON_TAP],
)
if CONF_ON_DOUBLE_TAP in config:
await automation.build_automation(
var.get_double_tap_trigger(),
[],
config[CONF_ON_DOUBLE_TAP],
)
if CONF_ON_ACTIVE in config:
await automation.build_automation(
var.get_active_trigger(),
[],
config[CONF_ON_ACTIVE],
)
if CONF_ON_FREEFALL in config:
await automation.build_automation(
var.get_freefall_trigger(),
[],
config[CONF_ON_FREEFALL],
)