From d4855e2f1cfb649e6627f5336a87c963cff1ce07 Mon Sep 17 00:00:00 2001 From: Artem Sheremet Date: Mon, 5 Jan 2026 20:53:51 +0000 Subject: [PATCH] Update to esphome 2025.12, use its cc1101 --- blinds.yaml | 5 +- components/cc1101/README.md | 2 - components/cc1101/__init__.py | 406 --------- components/cc1101/cc1101.cpp | 1194 -------------------------- components/cc1101/cc1101.h | 125 --- components/cc1101/cc1101defs.h | 693 --------------- components/cc1101/cc1101pa.h | 684 --------------- components/cc1101/cc1101sub.h | 57 -- components/cc1101/number/__init__.py | 204 ----- components/cc1101/number/number.h | 51 -- components/cc1101/select/__init__.py | 178 ---- components/cc1101/select/select.h | 34 - components/cc1101/switch/__init__.py | 78 -- components/cc1101/switch/switch.h | 22 - components/cc1101/text/__init__.py | 133 --- components/cc1101/text/text.h | 18 - components/nuki_lock/__init__.py | 0 components/nuki_lock/lock.py | 282 ------ components/nuki_lock/nuki_lock.cpp | 543 ------------ components/nuki_lock/nuki_lock.h | 145 ---- components/somfy/somfy.cpp | 2 +- components/syslog/syslog.cpp | 25 +- components/syslog/syslog.h | 4 +- flake.lock | 6 +- templates/syslog.yaml | 1 + 25 files changed, 23 insertions(+), 4869 deletions(-) delete mode 100644 components/cc1101/README.md delete mode 100644 components/cc1101/__init__.py delete mode 100644 components/cc1101/cc1101.cpp delete mode 100644 components/cc1101/cc1101.h delete mode 100644 components/cc1101/cc1101defs.h delete mode 100644 components/cc1101/cc1101pa.h delete mode 100644 components/cc1101/cc1101sub.h delete mode 100644 components/cc1101/number/__init__.py delete mode 100644 components/cc1101/number/number.h delete mode 100644 components/cc1101/select/__init__.py delete mode 100644 components/cc1101/select/select.h delete mode 100644 components/cc1101/switch/__init__.py delete mode 100644 components/cc1101/switch/switch.h delete mode 100644 components/cc1101/text/__init__.py delete mode 100644 components/cc1101/text/text.h delete mode 100644 components/nuki_lock/__init__.py delete mode 100644 components/nuki_lock/lock.py delete mode 100644 components/nuki_lock/nuki_lock.cpp delete mode 100644 components/nuki_lock/nuki_lock.h diff --git a/blinds.yaml b/blinds.yaml index 101c373..902e9d3 100644 --- a/blinds.yaml +++ b/blinds.yaml @@ -31,8 +31,7 @@ spi: cc1101: id: transceiver cs_pin: 13 - tuner: - frequency: 433340 + frequency: 433.34MHz remote_transmitter: pin: 4 @@ -43,7 +42,7 @@ remote_transmitter: - cc1101.begin_tx: transceiver on_complete: then: - - cc1101.end_tx: transceiver + - cc1101.set_idle: transceiver cover: - name: "Office window" diff --git a/components/cc1101/README.md b/components/cc1101/README.md deleted file mode 100644 index 319e76d..0000000 --- a/components/cc1101/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is a snapshot of https://github.com/esphome/esphome/pull/6300 that is -confirmed to work with our hardware. diff --git a/components/cc1101/__init__.py b/components/cc1101/__init__.py deleted file mode 100644 index f832e64..0000000 --- a/components/cc1101/__init__.py +++ /dev/null @@ -1,406 +0,0 @@ -from esphome import automation, pins -from esphome.automation import maybe_simple_id -import esphome.codegen as cg -from esphome.components import ( - binary_sensor, - remote_base, - sensor, - spi, - text_sensor, - voltage_sampler, -) -import esphome.config_validation as cv -from esphome.const import ( - CONF_CHANNEL, - CONF_CODE, - CONF_FREQUENCY, - CONF_ID, - CONF_PROTOCOL, - CONF_SENSOR, - CONF_TEMPERATURE, - CONF_WAIT_TIME, - # DEVICE_CLASS_FREQUENCY, - DEVICE_CLASS_SIGNAL_STRENGTH, - DEVICE_CLASS_TEMPERATURE, - ENTITY_CATEGORY_DIAGNOSTIC, - ICON_CHIP, - STATE_CLASS_MEASUREMENT, - UNIT_CELSIUS, - UNIT_DECIBEL_MILLIWATT, - UNIT_EMPTY, -) - -CODEOWNERS = ["@gabest11"] -DEPENDENCIES = ["spi"] -AUTO_LOAD = [ - "remote_base", - "voltage_sampler", - "sensor", - "binary_sensor", - "text_sensor", - "number", - "switch", - "select", - "text", -] -MULTI_CONF = True -UNIT_MEGA_HERTZ = "MHz" -UNIT_KILO_HERTZ = "kHz" -UNIT_MILLI_VOLT = "mV" -UNIT_MICRO_AMPERE = "mA" -UNIT_DECIBEL_MICRO_VOLT = "dBuV" - -ns = cg.esphome_ns.namespace("cc1101") -CC1101Component = ns.class_("CC1101Component", cg.PollingComponent, spi.SPIDevice) - -CONF_CC1101_ID = "cc1101_id" - -CONF_GDO0_PIN = "gdo0_pin" -CONF_GDO0_ADC_ID = "gdo0_adc_id" -CONF_OUTPUT_POWER = "output_power" -CONF_RX_ATTENUATION = "rx_attenuation" -CONF_DC_BLOCKING_FILTER = "dc_blocking_filter" - -# tuner -CONF_TUNER = "tuner" -# CONF_FREQUENCY = "frequency" -CONF_IF_FREQUENCY = "if_frequency" -CONF_BANDWIDTH = "bandwidth" -# CONF_CHANNEL = "channel" -CONF_CHANNEL_SPACING = "channel_spacing" -CONF_FSK_DEVIATION = "fsk_deviation" -CONF_MSK_DEVIATION = "msk_deviation" -CONF_SYMBOL_RATE = "symbol_rate" -CONF_SYNC_MODE = "sync_mode" -CONF_CARRIER_SENSE_ABOVE_THRESHOLD = "carrier_sense_above_threshold" -CONF_MODULATION = "modulation" - -# agc -CONF_AGC = "agc" -CONF_MAGN_TARGET = "magn_target" -CONF_MAX_LNA_GAIN = "max_lna_gain" -CONF_MAX_DVGA_GAIN = "max_dvga_gain" -CONF_CARRIER_SENSE_ABS_THR = "carrier_sense_abs_thr" -CONF_CARRIER_SENSE_REL_THR = "carrier_sense_rel_thr" -CONF_LNA_PRIORITY = "lna_priority" -CONF_FILTER_LENGTH_FSK_MSK = "filter_length_fsk_msk" -CONF_FILTER_LENGTH_ASK_OOK = "filter_length_ask_ook" -CONF_FREEZE = "freeze" -CONF_HYST_LEVEL = "hyst_level" - -# sensor -CONF_CHIP_ID = "chip_id" -CONF_RSSI = "rssi" -CONF_LQI = "lqi" -# CONF_TEMPERATURE = "temperature" - -SyncMode = ns.enum("SyncMode", True) -SYNC_MODE = { - "None": SyncMode.SYNC_MODE_NONE, - "15/16": SyncMode.SYNC_MODE_15_16, - "16/16": SyncMode.SYNC_MODE_16_16, - "30/32": SyncMode.SYNC_MODE_30_32, -} - -Modulation = ns.enum("Modulation", True) -MODULATION = { - "2-FSK": Modulation.MODULATION_2_FSK, - "GFSK": Modulation.MODULATION_GFSK, - "UNUSED 2": Modulation.MODULATION_UNUSED_2, - "ASK/OOK": Modulation.MODULATION_ASK_OOK, - "4-FSK": Modulation.MODULATION_4_FSK, - "UNUSED 5": Modulation.MODULATION_UNUSED_5, - "UNUSED 6": Modulation.MODULATION_UNUSED_6, - "MSK": Modulation.MODULATION_MSK, -} - -RxAttenuation = ns.enum("RxAttenuation", True) -RX_ATTENUATION = { - "0dB": RxAttenuation.RX_ATTENUATION_0DB, - "6dB": RxAttenuation.RX_ATTENUATION_6DB, - "12dB": RxAttenuation.RX_ATTENUATION_12DB, - "18dB": RxAttenuation.RX_ATTENUATION_18DB, -} - -MagnTarget = ns.enum("MagnTarget", True) -MAGN_TARGET = { - "24dB": MagnTarget.MAGN_TARGET_24DB, - "27dB": MagnTarget.MAGN_TARGET_27DB, - "30dB": MagnTarget.MAGN_TARGET_30DB, - "33dB": MagnTarget.MAGN_TARGET_33DB, - "36dB": MagnTarget.MAGN_TARGET_36DB, - "38dB": MagnTarget.MAGN_TARGET_38DB, - "40dB": MagnTarget.MAGN_TARGET_40DB, - "42dB": MagnTarget.MAGN_TARGET_42DB, -} - -MaxLnaGain = ns.enum("MaxLnaGain", True) -MAX_LNA_GAIN = { - "Default": MaxLnaGain.MAX_LNA_GAIN_DEFAULT, - "2.6dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_2P6DB, - "6.1dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_6P1DB, - "7.4dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_7P4DB, - "9.2dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_9P2DB, - "11.5dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_11P5DB, - "14.6dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_14P6DB, - "17.1dB": MaxLnaGain.MAX_LNA_GAIN_MINUS_17P1DB, -} - -MaxDvgaGain = ns.enum("MaxDvgaGain", True) -MAX_DVGA_GAIN = { - "Default": MaxDvgaGain.MAX_DVGA_GAIN_DEFAULT, - "-1": MaxDvgaGain.MAX_DVGA_GAIN_MINUS_1, - "-2": MaxDvgaGain.MAX_DVGA_GAIN_MINUS_2, - "-3": MaxDvgaGain.MAX_DVGA_GAIN_MINUS_3, -} - -CarrierSenseRelThr = ns.enum("CarrierSenseRelThr", True) -CARRIER_SENSE_REL_THR = { - "Default": CarrierSenseRelThr.CARRIER_SENSE_REL_THR_DEFAULT, - "+6dB": CarrierSenseRelThr.CARRIER_SENSE_REL_THR_PLUS_6DB, - "+10dB": CarrierSenseRelThr.CARRIER_SENSE_REL_THR_PLUS_10DB, - "+14dB": CarrierSenseRelThr.CARRIER_SENSE_REL_THR_PLUS_14DB, -} - -FilterLengthFskMsk = ns.enum("FilterLengthFskMsk", True) -FILTER_LENGTH_FSK_MSK = { - "8": FilterLengthFskMsk.FILTER_LENGTH_8, - "16": FilterLengthFskMsk.FILTER_LENGTH_16, - "32": FilterLengthFskMsk.FILTER_LENGTH_32, - "64": FilterLengthFskMsk.FILTER_LENGTH_64, -} - -FilterLengthAskOok = ns.enum("FilterLengthAskOok", True) -FILTER_LENGTH_ASK_OOK = { - "4dB": FilterLengthAskOok.FILTER_LENGTH_4DB, - "8dB": FilterLengthAskOok.FILTER_LENGTH_8DB, - "12dB": FilterLengthAskOok.FILTER_LENGTH_12DB, - "16dB": FilterLengthAskOok.FILTER_LENGTH_16DB, -} - -Freeze = ns.enum("Freeze", True) -FREEZE = { - "Default": Freeze.AGC_FREEZE_DEFAULT, - "On Sync": Freeze.AGC_FREEZE_ON_SYNC, - "Analog Only": Freeze.AGC_FREEZE_ANALOG_ONLY, - "Analog And Digital": Freeze.AGC_FREEZE_ANALOG_AND_DIGITAL, -} - -WaitTime = ns.enum("WaitTime", True) -WAIT_TIME = { - "8": WaitTime.WAIT_TIME_8_SAMPLES, - "16": WaitTime.WAIT_TIME_16_SAMPLES, - "24": WaitTime.WAIT_TIME_24_SAMPLES, - "32": WaitTime.WAIT_TIME_32_SAMPLES, -} - -HystLevel = ns.enum("HystLevel", True) -HYST_LEVEL = { - "None": HystLevel.HYST_LEVEL_NONE, - "Low": HystLevel.HYST_LEVEL_LOW, - "Medium": HystLevel.HYST_LEVEL_MEDIUM, - "High": HystLevel.HYST_LEVEL_HIGH, -} - -TYPES = { - None: { - CONF_OUTPUT_POWER: [cv.float_range(-70, 11)], - CONF_RX_ATTENUATION: [cv.enum(RX_ATTENUATION)], - CONF_DC_BLOCKING_FILTER: [cv.boolean], - }, - CONF_TUNER: { - CONF_FREQUENCY: [cv.float_range(300000, 928000)], - CONF_IF_FREQUENCY: [cv.float_range(25, 788)], - CONF_BANDWIDTH: [cv.float_range(58, 812)], - CONF_CHANNEL: [cv.uint8_t], - CONF_CHANNEL_SPACING: [cv.float_range(25, 405)], - CONF_FSK_DEVIATION: [cv.float_range(1.5, 381)], - CONF_MSK_DEVIATION: [cv.int_range(1, 8)], - CONF_SYMBOL_RATE: [cv.float_range(600, 500000)], - CONF_SYNC_MODE: [cv.enum(SYNC_MODE)], - CONF_CARRIER_SENSE_ABOVE_THRESHOLD: [cv.boolean], - CONF_MODULATION: [cv.enum(MODULATION)], - }, - CONF_AGC: { - CONF_MAGN_TARGET: [cv.enum(MAGN_TARGET)], - CONF_MAX_LNA_GAIN: [cv.enum(MAX_LNA_GAIN)], - CONF_MAX_DVGA_GAIN: [cv.enum(MAX_DVGA_GAIN)], - CONF_CARRIER_SENSE_ABS_THR: [cv.int_range(-8, 7)], - CONF_CARRIER_SENSE_REL_THR: [cv.enum(CARRIER_SENSE_REL_THR)], - CONF_LNA_PRIORITY: [cv.boolean], - CONF_FILTER_LENGTH_FSK_MSK: [cv.enum(FILTER_LENGTH_FSK_MSK)], - CONF_FILTER_LENGTH_ASK_OOK: [cv.enum(FILTER_LENGTH_ASK_OOK)], - CONF_FREEZE: [cv.enum(FREEZE)], - CONF_WAIT_TIME: [cv.enum(WAIT_TIME)], - CONF_HYST_LEVEL: [cv.enum(HYST_LEVEL)], - }, - CONF_SENSOR: { - CONF_CHIP_ID: [ - text_sensor.text_sensor_schema( - # unit_of_measurement=UNIT_, - # accuracy_decimals=3, - # device_class=DEVICE_CLASS_, - # state_class=STATE_CLASS_MEASUREMENT, - entity_category=ENTITY_CATEGORY_DIAGNOSTIC, - icon=ICON_CHIP, - ), - "text_sensor", - ], - CONF_RSSI: [ - sensor.sensor_schema( - unit_of_measurement=UNIT_DECIBEL_MILLIWATT, - accuracy_decimals=0, - device_class=DEVICE_CLASS_SIGNAL_STRENGTH, - state_class=STATE_CLASS_MEASUREMENT, - entity_category=ENTITY_CATEGORY_DIAGNOSTIC, - # icon=ICON_CHIP, - ), - "sensor", - ], - CONF_LQI: [ - sensor.sensor_schema( - unit_of_measurement=UNIT_EMPTY, - accuracy_decimals=0, - # device_class=DEVICE_CLASS_SIGNAL_STRENGTH, - state_class=STATE_CLASS_MEASUREMENT, - entity_category=ENTITY_CATEGORY_DIAGNOSTIC, - # icon=ICON_CHIP, - ), - "sensor", - ], - CONF_TEMPERATURE: [ - sensor.sensor_schema( - unit_of_measurement=UNIT_CELSIUS, - accuracy_decimals=1, - device_class=DEVICE_CLASS_TEMPERATURE, - state_class=STATE_CLASS_MEASUREMENT, - entity_category=ENTITY_CATEGORY_DIAGNOSTIC, - # icon=ICON_CHIP, - ), - "sensor", - ], - }, -} - -CONFIG_SCHEMA = ( - cv.Schema( - { - cv.GenerateID(): cv.declare_id(CC1101Component), - cv.Optional(CONF_GDO0_PIN): cv.All(pins.internal_gpio_output_pin_schema), - cv.Optional(CONF_GDO0_ADC_ID): cv.use_id(voltage_sampler.VoltageSampler), - } - ) - .extend( - {cv.Optional(k): v[0] for k, v in TYPES[None].items()}, - { - cv.Optional(CONF_TUNER): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_TUNER].items()} - ), - cv.Optional(CONF_AGC): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_AGC].items()} - ), - cv.Optional(CONF_SENSOR): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_SENSOR].items()} - ), - }, - ) - .extend(cv.polling_component_schema("60s")) - .extend(spi.spi_device_schema(cs_pin_required=True)) -) - -CC1101_COMPONENT_SCHEMA = cv.Schema( - { - cv.GenerateID(CONF_CC1101_ID): cv.use_id(CC1101Component), - } -) - - -async def for_each_conf(config, types, callback): - for section in types: - if section is not None and section not in config: - continue - c = config[section] if section is not None else config - for type, args in types[section].items(): - if type not in c: - continue - setter = "set_" - if section is not None and section != CONF_SENSOR: - setter += section + "_" - setter += type - # print(setter + "(" + repr(c[type]) + ")") - await callback(c[type], args[1:], setter) - - -async def to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) - await cg.register_component(var, config) - await spi.register_spi_device(var, config) - if CONF_GDO0_PIN in config: - gdo0_pin = await cg.gpio_pin_expression(config[CONF_GDO0_PIN]) - cg.add(var.set_config_gdo0_pin(gdo0_pin)) - if CONF_GDO0_ADC_ID in config: - gdo0_adc_id = await cg.get_variable(config[CONF_GDO0_ADC_ID]) - cg.add(var.set_config_gdo0_adc_pin(gdo0_adc_id)) - - async def set_var(c, args, setter): - if len(args) > 0: - s = None - if args[0] == "sensor": - s = await sensor.new_sensor(c) - elif args[0] == "binary_sensor": - s = await binary_sensor.new_binary_sensor(c) - elif args[0] == "text_sensor": - s = await text_sensor.new_text_sensor(c) - if s is not None: - cg.add(getattr(var, setter + "_" + args[0])(s)) - else: - cg.add(getattr(var, setter)(c)) - - await for_each_conf(config, TYPES, set_var) - - -BeginTxAction = ns.class_("BeginTxAction", automation.Action) -EndTxAction = ns.class_("EndTxAction", automation.Action) - -CC1101_ACTION_SCHEMA = maybe_simple_id( - { - cv.GenerateID(CONF_ID): cv.use_id(CC1101Component), - } -) - - -@automation.register_action("cc1101.begin_tx", BeginTxAction, CC1101_ACTION_SCHEMA) -@automation.register_action("cc1101.end_tx", EndTxAction, CC1101_ACTION_SCHEMA) -async def cc1101_action_to_code(config, action_id, template_arg, args): - var = cg.new_Pvariable(action_id, template_arg) - await cg.register_parented(var, config[CONF_ID]) - return var - - -CC1101RawAction = ns.class_("CC1101RawAction", remote_base.RCSwitchRawAction) - -CC1101_TRANSMIT_SCHEMA = ( - cv.Schema( - { - cv.GenerateID(CONF_CC1101_ID): cv.use_id(CC1101Component), - } - ) - .extend(remote_base.REMOTE_TRANSMITTABLE_SCHEMA) - .extend(remote_base.RC_SWITCH_RAW_SCHEMA) - .extend(remote_base.RC_SWITCH_TRANSMITTER) -) - - -@remote_base.register_action( - "rc_switch_raw_cc1101", CC1101RawAction, CC1101_TRANSMIT_SCHEMA -) -async def rc_switch_raw_cc1101_action(var, config, args): - proto = await cg.templatable( - config[CONF_PROTOCOL], - args, - remote_base.RCSwitchBase, - to_exp=remote_base.build_rc_switch_protocol, - ) - cg.add(var.set_protocol(proto)) - cg.add(var.set_code(await cg.templatable(config[CONF_CODE], args, cg.std_string))) - await cg.register_parented(var, config[CONF_CC1101_ID]) diff --git a/components/cc1101/cc1101.cpp b/components/cc1101/cc1101.cpp deleted file mode 100644 index 283567f..0000000 --- a/components/cc1101/cc1101.cpp +++ /dev/null @@ -1,1194 +0,0 @@ -#include "cc1101.h" -#include "cc1101pa.h" -#include "esphome/core/helpers.h" -#include "esphome/core/log.h" -#include -#include -#include - -namespace esphome { -namespace cc1101 { - -static const char *const TAG = "cc1101"; - -CC1101Component::CC1101Component() { - this->gdo0_ = nullptr; - this->gdo0_adc_ = nullptr; - this->reset_ = false; - this->output_power_requested_ = OUTPUT_POWER_MAX; - this->output_power_effective_ = OUTPUT_POWER_MAX; - memset(this->pa_table_, 0, sizeof(pa_table_)); - memset(&this->state_, 0, sizeof(this->state_)); - - // datasheet defaults (non-listed fields are zero) - - this->state_.GDO2_CFG = 0x29; - this->state_.GDO1_CFG = 0x2E; - this->state_.GDO0_CFG = 0x3F; - this->state_.FIFO_THR = 7; - this->state_.SYNC1 = 0xD3; - this->state_.SYNC0 = 0x91; - this->state_.PKTLEN = 0xFF; - this->state_.APPEND_STATUS = 1; - this->state_.LENGTH_CONFIG = 1; - this->state_.CRC_EN = 1; - this->state_.WHITE_DATA = 1; - this->state_.FREQ_IF = 0x0F; - this->state_.FREQ2 = 0x1E; - this->state_.FREQ1 = 0xC4; - this->state_.FREQ0 = 0xEC; - this->state_.DRATE_E = 0x0C; - this->state_.CHANBW_E = 0x02; - this->state_.DRATE_M = 0x22; - this->state_.SYNC_MODE = 2; - this->state_.CHANSPC_E = 2; - this->state_.NUM_PREAMBLE = 2; - this->state_.CHANSPC_M = 0xF8; - this->state_.DEVIATION_M = 7; - this->state_.DEVIATION_E = 4; - this->state_.RX_TIME = 7; - this->state_.CCA_MODE = 3; - this->state_.PO_TIMEOUT = 1; - this->state_.FOC_LIMIT = 2; - this->state_.FOC_POST_K = 1; - this->state_.FOC_PRE_K = 2; - this->state_.FOC_BS_CS_GATE = 1; - this->state_.BS_POST_KP = 1; - this->state_.BS_POST_KI = 1; - this->state_.BS_PRE_KP = 2; - this->state_.BS_PRE_KI = 1; - this->state_.MAGN_TARGET = 3; - this->state_.AGC_LNA_PRIORITY = 1; - this->state_.FILTER_LENGTH = 1; - this->state_.WAIT_TIME = 1; - this->state_.HYST_LEVEL = 2; - this->state_.WOREVT1 = 0x87; - this->state_.WOREVT0 = 0x6B; - this->state_.RC_CAL = 1; - this->state_.EVENT1 = 7; - this->state_.RC_PD = 1; - this->state_.MIX_CURRENT = 2; - this->state_.LODIV_BUF_CURRENT_RX = 1; - this->state_.LNA2MIX_CURRENT = 1; - this->state_.LNA_CURRENT = 1; - this->state_.LODIV_BUF_CURRENT_TX = 1; - this->state_.FSCAL3_LO = 9; - this->state_.CHP_CURR_CAL_EN = 2; - this->state_.FSCAL3_HI = 2; - this->state_.FSCAL2 = 0x0A; - this->state_.FSCAL1 = 0x20; - this->state_.FSCAL0 = 0x0D; - this->state_.RCCTRL1 = 0x41; - this->state_.FSTEST = 0x59; - this->state_.PTEST = 0x7F; - this->state_.AGCTEST = 0x3F; - this->state_.TEST2 = 0x88; - this->state_.TEST1 = 0x31; - this->state_.TEST0_LO = 1; - this->state_.VCO_SEL_CAL_EN = 1; - this->state_.TEST0_HI = 2; - - // old settings which make no sense to me - - /* - // MDMCFG1 - this->state_.NUM_PREAMBLE = 0; // ? - this->state_.PO_TIMEOUT = 2; // Approx. 149 – 155 μs - // FOCCFG - this->state_.FOC_BS_CS_GATE = 0; // ? - // BSCFG - this->state_.BS_PRE_KP = 1; // ? - // FSCAL3 - this->state_.FSCAL3_HI = 3; // ? - // FSCAL2 - this->state_.VCO_CORE_H_EN = 1; // Choose high (1) / low (0) VCO ? - // FSCAL1 - this->state_.FSCAL1 = 0; // ? - // FSCAL0 - this->state_.FSCAL0 = 31; // ? - // TEST0 - this->state_.VCO_SEL_CAL_EN = 0; // ? - */ - - // old settings that kinda make sense - - // TODO: this->set_mode_(false) - - // IOCFGx - this->state_.GDO2_CFG = 0x0D; // Async serial output (TODO: enum) - this->state_.GDO0_CFG = 0x0D; - - // PKTCTRL0 - // Setting PKTCTRL0.PKT_FORMAT to 3 enables asynchronous serial mode. In TX, the - // GDO0 pin is used for data input (TX data). Data output can be on GDO0, GDO1, or - // GDO2. This is set by the IOCFG0.GDO0_CFG, IOCFG1.GDO1_CFG - // and IOCFG2.GDO2_CFG fields. - this->state_.PKT_FORMAT = 3; // (TODO: enum) - // With PKTCTRL0.LENGTH_CONFIG=2, the packet length is set to infinite and transmission - // and reception will continue until turned off manually. As described in the next section, - // this can be used to support packet formats with different length configuration than natively - // supported by CC1101 - this->state_.LENGTH_CONFIG = 2; // (TODO: enum) - - // MDMCFG0 (TODO: this->set_..) - this->state_.FS_AUTOCAL = 1; // When going from IDLE to RX or TX (or FSTXON) - - this->set_tuner_frequency(433920); - this->set_tuner_if_frequency(153); - this->set_tuner_bandwidth(203); - this->set_tuner_channel(0); - this->set_tuner_channel_spacing(200); - this->set_tuner_symbol_rate(5000); - this->set_tuner_sync_mode(SyncMode::SYNC_MODE_NONE); - this->set_tuner_carrier_sense_above_threshold(true); - this->set_tuner_modulation(Modulation::MODULATION_ASK_OOK); - // this->set_tuner_fsk_deviation(47.607f); - // this->set_tuner_msk_deviation(0); - this->set_agc_magn_target(MagnTarget::MAGN_TARGET_42DB); // ? - this->set_agc_max_lna_gain(MaxLnaGain::MAX_LNA_GAIN_DEFAULT); - this->set_agc_max_dvga_gain(MaxDvgaGain::MAX_DVGA_GAIN_MINUS_3); // ? - this->set_agc_lna_priority(false); // ? - this->set_agc_wait_time(WaitTime::WAIT_TIME_32_SAMPLES); // ? -} - -// overrides - -void CC1101Component::setup() { - if (this->gdo0_ != nullptr) { -#ifdef USE_ESP8266 - // ESP8266 GDO0 generally input, switched to output for TX - // ESP32 GDO0 output, GDO2 input - // if there is an ADC, GDO0 is input only while reading temperature - this->gdo0_->setup(); - this->gdo0_->pin_mode(gpio::FLAG_INPUT); -#endif - } - - // datasheet 19.1.2 - - this->cs_->digital_write(true); - delayMicroseconds(1); - this->cs_->digital_write(false); - delayMicroseconds(1); - this->cs_->digital_write(true); - delayMicroseconds(41); - this->cs_->digital_write(false); - delayMicroseconds(5000); - - this->spi_setup(); - - // reset - - this->send_(Command::RES); - - // Read part number and version - - this->read_(Register::PARTNUM); - this->read_(Register::VERSION); - - if (this->state_.VERSION == 0) { - mark_failed(); - ESP_LOGE(TAG, "Failed to reset CC1101 modem. Check connection."); - return; - } - - char buff[32] = {0}; - snprintf(buff, sizeof(buff), "%02X%02X", this->state_.PARTNUM, this->state_.VERSION); - this->chip_id_ = buff; - - ESP_LOGD(TAG, "%s was found", this->chip_id_.c_str()); - - for (uint8_t i = 0; i <= 0x2E; i++) { - this->write_((Register) i); - } - - this->write_(Register::PATABLE, this->pa_table_, sizeof(this->pa_table_)); - - ESP_LOGV(TAG, "verify"); - - for (uint8_t i = 0; i <= 0x2E; i++) { - uint8_t old_value = this->regs_[i]; - this->read_((Register) i); - ESP_LOGV(TAG, "[%d] %02X vs %02X%s", i, old_value, this->regs_[i], old_value != this->regs_[i] ? " ***" : ""); - } - - this->send_(Command::RX); - - this->publish_output_power(); - this->publish_rx_attenuation(); - this->publish_dc_blocking_filter(); - this->publish_tuner_frequency(); - this->publish_tuner_if_frequency(); - this->publish_tuner_bandwidth(); - this->publish_tuner_channel(); - this->publish_tuner_channel_spacing(); - this->publish_tuner_fsk_deviation(); - this->publish_tuner_msk_deviation(); - this->publish_tuner_symbol_rate(); - this->publish_tuner_sync_mode(); - this->publish_tuner_carrier_sense_above_threshold(); - this->publish_tuner_modulation(); - this->publish_agc_magn_target(); - this->publish_agc_max_lna_gain(); - this->publish_agc_max_dvga_gain(); - this->publish_agc_carrier_sense_abs_thr(); - this->publish_agc_carrier_sense_rel_thr(); - this->publish_agc_lna_priority(); - this->publish_agc_filter_length_fsk_msk(); - this->publish_agc_filter_length_ask_ook(); - this->publish_agc_freeze(); - this->publish_agc_wait_time(); - this->publish_agc_hyst_level(); - - this->publish_chip_id_text_sensor(); - this->publish_rssi_sensor(); - this->publish_lqi_sensor(); - this->publish_temperature_sensor(); -} - -void CC1101Component::dump_config() { - ESP_LOGCONFIG(TAG, "CC1101: "); - // LOG_SPI_DEVICE(this); - if (this->is_failed()) { - ESP_LOGE(TAG, "failed!"); - } - ESP_LOGCONFIG(TAG, " Chip: %s", this->chip_id_.c_str()); - ESP_LOGCONFIG(TAG, " Tuner:"); - ESP_LOGCONFIG(TAG, " Output Power: %.1f dBm", this->get_output_power()); - ESP_LOGCONFIG(TAG, " Rx Attenuation: %d dB", (int) this->get_rx_attenuation() * 6); - ESP_LOGCONFIG(TAG, " DC Blocking Filter: %d", (int) this->get_dc_blocking_filter()); - ESP_LOGCONFIG(TAG, " Frequency: %d KHz", (int) this->get_tuner_frequency()); - ESP_LOGCONFIG(TAG, " IF Frequency: %d KHz", (int) this->get_tuner_if_frequency()); - ESP_LOGCONFIG(TAG, " Bandwith: %d KHz", (int) this->get_tuner_bandwidth()); - ESP_LOGCONFIG(TAG, " Channel: %d", (int) this->get_tuner_channel()); - ESP_LOGCONFIG(TAG, " Channel Spacing: %d KHz", (int) this->get_tuner_channel_spacing()); - ESP_LOGCONFIG(TAG, " FSK Deviation: %d KHz", (int) this->get_tuner_fsk_deviation()); - ESP_LOGCONFIG(TAG, " MSK Deviation: %d KHz", (int) this->get_tuner_msk_deviation()); - ESP_LOGCONFIG(TAG, " Symbol Rate: %d Baud", (int) this->get_tuner_symbol_rate()); - ESP_LOGCONFIG(TAG, " Sync Mode: %d", (int) this->get_tuner_sync_mode()); - ESP_LOGCONFIG(TAG, " Carrier Sense Above Threshold: %d", (int) this->get_tuner_carrier_sense_above_threshold()); - ESP_LOGCONFIG(TAG, " Modulation: %d", (int) this->get_tuner_modulation()); - // TODO: ...and everything else... - LOG_PIN(" CS Pin: ", this->cs_); - LOG_PIN(" GDO0: ", this->gdo0_); - LOG_TEXT_SENSOR(" ", "Chip ID", this->chip_id_text_sensor_); - LOG_SENSOR(" ", "RSSI", this->rssi_sensor_); - LOG_SENSOR(" ", "LQI", this->lqi_sensor_); - LOG_SENSOR(" ", "Temperature sensor", this->temperature_sensor_); - LOG_UPDATE_INTERVAL(this); -} - -void CC1101Component::update() { - this->read_(Register::RSSI); - this->publish_rssi_sensor(); - - this->read_(Register::LQI); - this->publish_lqi_sensor(); - - if (this->gdo0_ != nullptr && this->gdo0_adc_ != nullptr) { - // TODO: read temperature if possible - this->publish_temperature_sensor(); - } -} - -void CC1101Component::loop() {} - -// actions - -void CC1101Component::begin_tx() { - this->send_(Command::TX); - - if (this->gdo0_ != nullptr) { -#ifdef USE_ESP8266 -#ifdef USE_ARDUINO - noInterrupts(); // NOLINT -#else // USE_ESP_IDF - portDISABLE_INTERRUPTS() -#endif - this->gdo0_->pin_mode(gpio::FLAG_OUTPUT); -#endif - } -} - -void CC1101Component::end_tx() { - if (this->gdo0_ != nullptr) { -#ifdef USE_ESP8266 -#ifdef USE_ARDUINO - interrupts(); // NOLINT -#else // USE_ESP_IDF - portENABLE_INTERRUPTS() -#endif - this->gdo0_->pin_mode(gpio::FLAG_INPUT); -#endif - } - - this->send_(Command::RX); -} - -// protected - -void CC1101Component::strobe_(Command cmd) { - uint8_t index = (uint8_t) cmd; - if (cmd < Command::RES || cmd > Command::NOP) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return; - } - - if (!this->reset_) { - if (this->get_component_state() & COMPONENT_STATE_LOOP) { - ESP_LOGE(TAG, "%s(0x%02X) device was not reset", __func__, index); - return; - } - } - - this->enable(); - this->write_byte(index); - this->disable(); - - ESP_LOGV(TAG, "%s(0x%02X)", __func__, index); -} - -void CC1101Component::write_(Register reg) { - uint8_t index = (uint8_t) reg; - if (reg > Register::TEST0 || reg == Register::FSTEST || reg == Register::AGCTEST) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return; - } - - if (!this->reset_) { - if (this->get_component_state() & COMPONENT_STATE_LOOP) { - ESP_LOGE(TAG, "%s(0x%02X) device was not reset", __func__, index); - return; - } - } - - uint8_t value = this->regs_[index]; - - this->enable(); - this->write_byte(index); - this->transfer_array(&value, 1); - this->disable(); - - ESP_LOGV(TAG, "%s(0x%02X) = 0x%02X", __func__, index, this->regs_[index]); -} - -void CC1101Component::write_(Register reg, uint8_t value) { - uint8_t index = (uint8_t) reg; - if (reg > Register::TEST0 || reg == Register::FSTEST || reg == Register::AGCTEST) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return; - } - - this->regs_[index] = value; - this->write_(reg); -} - -void CC1101Component::write_(Register reg, uint8_t *buffer, size_t length) { - uint8_t index = (uint8_t) reg; - if (reg != Register::PATABLE && reg != Register::FIFO) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return; - } - - if (!this->reset_) { - if (this->get_component_state() & COMPONENT_STATE_LOOP) { - ESP_LOGE(TAG, "%s(0x%02X) device was not reset", __func__, index); - return; - } - } - - this->enable(); - this->write_byte(index | BUS_WRITE | BUS_BURST); - this->transfer_array(buffer, length); - this->disable(); - - ESP_LOGV(TAG, "%s(0x%02X) %zu", __func__, index, length); -} - -bool CC1101Component::read_(Register reg) { - uint8_t index = (uint8_t) reg; - if (reg > Register::RCCTRL0_STATUS) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return false; - } - - this->enable(); - this->write_byte(index | BUS_READ | BUS_BURST); - this->regs_[index] = this->transfer_byte(0); - this->disable(); - - return true; -} - -bool CC1101Component::read_(Register reg, uint8_t *buffer, size_t length) { - uint8_t index = (uint8_t) reg; - if (reg != Register::PATABLE && reg != Register::FIFO) { - ESP_LOGE(TAG, "%s(0x%02X) invalid register address", __func__, index); - return false; - } - - this->enable(); - this->write_byte(index | BUS_READ | BUS_BURST); - this->read_array(buffer, length); - this->disable(); - - return true; -} - -void CC1101Component::send_(Command cmd) { - if (cmd == Command::TX || cmd == Command::RX || cmd == Command::PWD) { - this->send_(Command::IDLE); - } - - ESP_LOGV(TAG, "%s(0x%02X)", __func__, (uint8_t) cmd); - - this->strobe_(cmd); - this->wait_(cmd); - - if (cmd == Command::RES) { - this->reset_ = true; - } -} - -bool CC1101Component::wait_(Command cmd) { - uint32_t start = millis(); - while ((millis() - start) < 1000) { - this->read_(Register::MARCSTATE); - State s = (State) this->state_.MARC_STATE; - if (cmd == Command::IDLE || cmd == Command::RES) { - if (s == State::IDLE) - return true; - } else if (cmd == Command::RX) { - if (s == State::RX || s == State::RX_END || s == State::RXTX_SWITCH) - return true; - } else if (cmd == Command::TX) { - if (s == State::TX || s == State::TX_END || s == State::TXRX_SWITCH) - return true; - } else { - return true; // else if TODO - } - delayMicroseconds(1); - } - mark_failed(); - ESP_LOGE(TAG, "CC1101 modem wait state timeout. Check connection."); - return false; -} - -// config - -template T GET_ENUM_LAST(T value) { return T::LAST; } - -#define CHECK_ENUM(value) \ - if ((value) >= GET_ENUM_LAST(value)) { \ - ESP_LOGE(TAG, "%s(%d) invalid", __func__, (int) (value)); \ - return; \ - } - -#define CHECK_FLOAT_RANGE(value, min_value, max_value) \ - if ((value) < (min_value) || (value) > (max_value)) { \ - ESP_LOGE(TAG, "%s(%.2f) invalid (%.2f - %.2f)", __func__, value, min_value, max_value); \ - return; \ - } - -#define CHECK_INT_RANGE(value, min_value, max_value) \ - if ((value) < (min_value) || (value) > (max_value)) { \ - ESP_LOGE(TAG, "%s(%d) invalid (%d - %d)", __func__, (int) (value), (int) (min_value), (int) (max_value)); \ - return; \ - } - -#define CHECK_TEXT_RANGE(value, max_size) \ - if ((value).size() > (max_size)) { \ - ESP_LOGW(TAG, "%s(%s) trimmed (max %d characters)", __func__, (value).c_str(), max_size); \ - (value).resize(max_size); \ - } - -/* -static int mapint(int x, int in_min, int in_max, int out_min, int out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - -static int32_t mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} -*/ - -static void split_float(float value, int mbits, uint8_t &e, uint32_t &m) { - if (value < 0) { - ESP_LOGE(TAG, "split_float(%f, %d): positive values only", value, mbits); - } - - int e_tmp; - float m_tmp = std::frexp(value, &e_tmp); - - if (e_tmp <= mbits) { - ESP_LOGW(TAG, "split_float(%f, %d): exponent would be negative, set to minimum", value, mbits); - e = 0; - m = 0; - return; - } - - // frexp returns 2^e * 0.m - // but we want the original 2^e * 1.m format with the hidden bit - - e = (uint8_t) (e_tmp - mbits - 1); - m = (uint32_t) ((m_tmp * 2 - 1) * (1 << (mbits + 1)) + 1) >> 1; - - // mantissa might overflow due to rounding, even the datasheet recommends this: - // "If DRATE_M is rounded to the nearest integer and becomes 256, - // increment DRATE_E and use DRATE_M = 0." - - if (m == (1 << mbits)) { - e = e + 1; - m = 0; - } -} - -void CC1101Component::set_output_power(float value) { - CHECK_FLOAT_RANGE(value, OUTPUT_POWER_MIN, OUTPUT_POWER_MAX) - - this->output_power_requested_ = value; - - int freq = (int) this->get_tuner_frequency(); - Modulation modulation = this->get_tuner_modulation(); - uint8_t a = 0xC0; - - if (freq >= 300000 && freq <= 348000) { - a = PowerTable::find(PA_TABLE_315, sizeof(PA_TABLE_315) / sizeof(PA_TABLE_315[0]), value); - } else if (freq >= 378000 && freq <= 464000) { - a = PowerTable::find(PA_TABLE_433, sizeof(PA_TABLE_433) / sizeof(PA_TABLE_433[0]), value); - } else if (freq >= 779000 && freq < 900000) { - a = PowerTable::find(PA_TABLE_868, sizeof(PA_TABLE_868) / sizeof(PA_TABLE_868[0]), value); - } else if (freq >= 900000 && freq <= 928000) { - a = PowerTable::find(PA_TABLE_915, sizeof(PA_TABLE_915) / sizeof(PA_TABLE_915[0]), value); - } else { - ESP_LOGE(TAG, "frequency out of range: %d", freq); - } - - if (modulation == Modulation::MODULATION_ASK_OOK) { - this->pa_table_[0] = 0; - this->pa_table_[1] = a; - } else { - this->pa_table_[0] = a; - this->pa_table_[1] = 0; - } - - this->output_power_effective_ = value; - - ESP_LOGD(TAG, "set_output_power(%.1f) %d", value, a); - - this->publish_output_power(); - - if (!this->reset_) { - return; - } - - this->write_(Register::PATABLE, this->pa_table_, sizeof(this->pa_table_)); -} - -float CC1101Component::get_output_power() { return this->output_power_effective_; } - -void CC1101Component::set_rx_attenuation(RxAttenuation value) { - CHECK_ENUM(value) - - this->state_.CLOSE_IN_RX = (uint8_t) value; - - ESP_LOGD(TAG, "set_rx_attenuation(%d)", (int) value); - - this->publish_rx_attenuation(); - - if (!this->reset_) { - return; - } - - this->write_(Register::FIFOTHR); -} - -RxAttenuation CC1101Component::get_rx_attenuation() { return (RxAttenuation) this->state_.CLOSE_IN_RX; } - -void CC1101Component::set_dc_blocking_filter(bool value) { - this->state_.DEM_DCFILT_OFF = value ? 0 : 1; // inverted logic, 0 is Enable - - ESP_LOGD(TAG, "set_dc_blocking_filter(%d)", value ? 1 : 0); - - this->publish_dc_blocking_filter(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG2); -} - -bool CC1101Component::get_dc_blocking_filter() { return this->state_.DEM_DCFILT_OFF == 0; } - -// tuner_* - -void CC1101Component::set_tuner_frequency(float value) { - CHECK_FLOAT_RANGE(value, FREQUENCY_MIN, FREQUENCY_MAX) - - // strange frequencies like 360MHz also seem to work, not sure about the quality - - int freq = (int) (value * (1 << 16) / XTAL_FREQUENCY); - - this->state_.FREQ2 = (uint8_t) (freq >> 16); - this->state_.FREQ1 = (uint8_t) (freq >> 8); - this->state_.FREQ0 = (uint8_t) freq; - - this->set_output_power(this->output_power_requested_); // frequency and modulation dependent - - ESP_LOGD(TAG, "set_tuner_frequency(%f) FREQ = %02X%02X%02X", value, this->state_.FREQ2, this->state_.FREQ1, - this->state_.FREQ0); - - this->publish_tuner_frequency(); - - if (!this->reset_) { - return; - } - - // If any frequency programming register is altered when the frequency synthesizer is - // running, the synthesizer may give an undesired response. Hence, the frequency - // programming should only be updated when the radio is in the IDLE state. - - // TODO: this may also apply when setting other registers - // channel (CHANNR.CHAN) - // channel_spacing (MDMCFG1.CHANSPC_*) - // if_frequency (FSCTRL1.FREQ_IF) - - this->send_(Command::IDLE); - - this->write_(Register::FREQ2); - this->write_(Register::FREQ1); - this->write_(Register::FREQ0); - - // calibration - /* - if (freq >= 300000 && freq <= 348000) { - this->write_(Register::FSCTRL0, (uint8_t) mapint(freq, 300000, 348000, 24, 28)); - - if (freq < 322880) { - this->write_(Register::TEST0, 0x0B); - } else { - this->write_(Register::TEST0, 0x09); - this->read_(Register::FSCAL2); - if(this->state_.VCO_CORE_H_EN == 0) { - this->state_.VCO_CORE_H_EN = 1; - this->write_(Register::FSCAL2); - } - } - } else if (freq >= 378000 && freq <= 464000) { - this->write_(Register::FSCTRL0, (uint8_t) mapint(freq, 378000, 464000, 31, 38)); - - if (freq < 430500) { - this->write_(Register::TEST0, 0x0B); - } else { - this->write_(Register::TEST0, 0x09); - this->read_(Register::FSCAL2); - if(this->state_.VCO_CORE_H_EN == 0) { - this->state_.VCO_CORE_H_EN = 1; - this->write_(Register::FSCAL2); - } - } - } else if (freq >= 779000 && freq < 900000) { - this->write_(Register::FSCTRL0, (uint8_t) mapint(freq, 779000, 899000, 65, 76)); - - if (freq < 861000) { - this->write_(Register::TEST0, 0x0B); - } else { - this->write_(Register::TEST0, 0x09); - this->read_(Register::FSCAL2); - if(this->state_.VCO_CORE_H_EN == 0) { - this->state_.VCO_CORE_H_EN = 1; - this->write_(Register::FSCAL2); - } - } - } else if (freq >= 900000 && freq <= 928000) { - this->write_(Register::FSCTRL0, (uint8_t) mapint(freq, 900000, 928000, 77, 79)); - //if (freq < ) { - // this->write_(Register::TEST0, 0x0B); - //} else { - // this->write_(Register::TEST0, 0x09); - this->read_(Register::FSCAL2); - if(this->state_.VCO_CORE_H_EN == 0) { - this->state_.VCO_CORE_H_EN = 1; - this->write_(Register::FSCAL2); - } - //} - } - */ - - this->send_(Command::RX); -} - -float CC1101Component::get_tuner_frequency() { - uint32_t freq = 0; - freq |= (uint32_t) this->state_.FREQ2 << 16; - freq |= (uint32_t) this->state_.FREQ1 << 8; - freq |= (uint32_t) this->state_.FREQ0; - return roundf((float) XTAL_FREQUENCY * freq / (1 << 16)); -} - -void CC1101Component::set_tuner_if_frequency(float value) { - CHECK_FLOAT_RANGE(value, IF_FREQUENCY_MIN, IF_FREQUENCY_MAX) - - this->state_.FREQ_IF = value * (1 << 10) / XTAL_FREQUENCY; - - ESP_LOGD(TAG, "set_tuner_if_frequency(%f)", value); - - this->publish_tuner_if_frequency(); - - if (!this->reset_) { - return; - } - - this->write_(Register::FSCTRL1); -} - -float CC1101Component::get_tuner_if_frequency() { return XTAL_FREQUENCY * this->state_.FREQ_IF / (1 << 10); } - -void CC1101Component::set_tuner_bandwidth(float value) { - CHECK_FLOAT_RANGE(value, BANDWIDTH_MIN, BANDWIDTH_MAX) - - uint8_t e; - uint32_t m; - split_float(XTAL_FREQUENCY / (value * 8), 2, e, m); - this->state_.CHANBW_E = (uint8_t) e; - this->state_.CHANBW_M = (uint8_t) m; - - ESP_LOGD(TAG, "set_tuner_bandwidth(%f) CHANBW_E = %d CHANBW_M = %d", value, this->state_.CHANBW_E, - this->state_.CHANBW_M); - - this->publish_tuner_bandwidth(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG4); -} - -float CC1101Component::get_tuner_bandwidth() { - float chanbw = (float) (4 + this->state_.CHANBW_M) * (1 << this->state_.CHANBW_E); - return roundf(XTAL_FREQUENCY / (8 * chanbw)); -} - -void CC1101Component::set_tuner_channel(uint8_t value) { - this->state_.CHANNR = (uint8_t) value; - - ESP_LOGD(TAG, "set_tuner_channel(%d)", (int) value); - - this->publish_tuner_channel(); - - if (!this->reset_) { - return; - } - - this->write_(Register::CHANNR); -} - -uint8_t CC1101Component::get_tuner_channel() { return (uint8_t) this->state_.CHANNR; } - -void CC1101Component::set_tuner_channel_spacing(float value) { - CHECK_FLOAT_RANGE(value, CHANNEL_SPACING_MIN, CHANNEL_SPACING_MAX) - - uint8_t e; - uint32_t m; - split_float(value * (1 << 18) / XTAL_FREQUENCY, 8, e, m); - this->state_.CHANSPC_E = (uint8_t) e; - this->state_.CHANSPC_M = (uint8_t) m; - - ESP_LOGD(TAG, "set_tuner_channel_spacing(%f) CHANSPC_E = %d CHANSPC_M = %d", value, this->state_.CHANSPC_E, - this->state_.CHANSPC_M); - - this->publish_tuner_channel_spacing(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG1); - this->write_(Register::MDMCFG0); -} - -float CC1101Component::get_tuner_channel_spacing() { - float chanspc = (float) (256 + this->state_.CHANSPC_M) * (1 << this->state_.CHANSPC_E); - return XTAL_FREQUENCY * chanspc / (1 << 18); -} - -void CC1101Component::set_tuner_fsk_deviation(float value) { - CHECK_FLOAT_RANGE(value, FSK_DEVIATION_MIN, FSK_DEVIATION_MAX) - - uint8_t e; - uint32_t m; - split_float(value * (1 << 17) / XTAL_FREQUENCY, 3, e, m); - this->state_.DEVIATION_E = (uint8_t) e; - this->state_.DEVIATION_M = (uint8_t) m; - - ESP_LOGD(TAG, "set_tuner_fsk_deviation(%f) DEVIATION_E = %d DEVIATION_M = %d", value, this->state_.DEVIATION_E, - this->state_.DEVIATION_M); - - this->publish_tuner_fsk_deviation(); - - if (!this->reset_) { - return; - } - - this->write_(Register::DEVIATN); -} - -float CC1101Component::get_tuner_fsk_deviation() { - float deviation = (float) (8 + this->state_.DEVIATION_M) * (1 << this->state_.DEVIATION_E); - return XTAL_FREQUENCY * deviation / (1 << 17); -} - -void CC1101Component::set_tuner_msk_deviation(uint8_t value) { - CHECK_INT_RANGE(value, MSK_DEVIATION_MIN, MSK_DEVIATION_MAX) - - this->state_.DEVIATION_E = 0; - this->state_.DEVIATION_M = value - 1; // Specifies the fraction of symbol period (1/8-8/8) - - ESP_LOGD(TAG, "set_tuner_msk_deviation(%d)", value); - - this->publish_tuner_msk_deviation(); - - if (!this->reset_) { - return; - } - - this->write_(Register::DEVIATN); -} - -uint8_t CC1101Component::get_tuner_msk_deviation() { return this->state_.DEVIATION_M + 1; } - -void CC1101Component::set_tuner_symbol_rate(float value) { - CHECK_FLOAT_RANGE(value, SYMBOL_RATE_MIN, SYMBOL_RATE_MAX) - - uint8_t e; - uint32_t m; - split_float(value * (1 << 28) / (XTAL_FREQUENCY * 1000), 8, e, m); - this->state_.DRATE_E = (uint8_t) e; - this->state_.DRATE_M = (uint8_t) m; - - ESP_LOGD(TAG, "set_tuner_symbol_rate(%f) CHANBW_E = %d CHANBW_M = %d", value, this->state_.DRATE_E, - this->state_.DRATE_M); - - this->publish_tuner_symbol_rate(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG4); - this->write_(Register::MDMCFG3); -} - -float CC1101Component::get_tuner_symbol_rate() { - float drate = (float) (256 + this->state_.DRATE_M) * (1 << this->state_.DRATE_E); - return (XTAL_FREQUENCY * 1000) * drate / (1 << 28); -} - -void CC1101Component::set_tuner_sync_mode(SyncMode value) { - CHECK_ENUM(value) - - this->state_.SYNC_MODE = (uint8_t) value; - - ESP_LOGD(TAG, "set_tuner_sync_mode(%d)", (int) value); - - this->publish_tuner_sync_mode(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG2); -} - -SyncMode CC1101Component::get_tuner_sync_mode() { return (SyncMode) this->state_.SYNC_MODE; } - -void CC1101Component::set_tuner_carrier_sense_above_threshold(bool value) { - this->state_.CARRIER_SENSE_ABOVE_THRESHOLD = value ? 1 : 0; - - ESP_LOGD(TAG, "set_tuner_carrier_sense_above_threshold(%d)", value ? 1 : 0); - - this->publish_tuner_carrier_sense_above_threshold(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG2); -} - -bool CC1101Component::get_tuner_carrier_sense_above_threshold() { - return this->state_.CARRIER_SENSE_ABOVE_THRESHOLD == 1; -} - -void CC1101Component::set_tuner_modulation(Modulation value) { - CHECK_ENUM(value) - - this->state_.MOD_FORMAT = (uint8_t) value; - // In OOK/ASK mode, this selects the PATABLE index to use when transmitting a ‘1’. - // PATABLE index zero is used in OOK/ASK when transmitting a ‘0’. - this->state_.PA_POWER = value == Modulation::MODULATION_ASK_OOK ? 1 : 0; - - this->set_output_power(this->output_power_requested_); // frequency and modulation dependent - - ESP_LOGD(TAG, "set_tuner_modulation(%d)", (int) value); - - this->publish_tuner_modulation(); - - if (!this->reset_) { - return; - } - - this->write_(Register::MDMCFG2); - this->write_(Register::FREND0); -} - -Modulation CC1101Component::get_tuner_modulation() { return (Modulation) this->state_.MOD_FORMAT; } - -// agc_* - -void CC1101Component::set_agc_magn_target(MagnTarget value) { - CHECK_ENUM(value) - - this->state_.MAGN_TARGET = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_magn_target(%d)", (int) value); - - this->publish_agc_magn_target(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL2); -} - -MagnTarget CC1101Component::get_agc_magn_target() { return (MagnTarget) this->state_.MAGN_TARGET; } - -void CC1101Component::set_agc_max_lna_gain(MaxLnaGain value) { - CHECK_ENUM(value) - - this->state_.MAX_LNA_GAIN = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_max_lna_gain(%d)", (int) value); - - this->publish_agc_max_lna_gain(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL2); -} - -MaxLnaGain CC1101Component::get_agc_max_lna_gain() { return (MaxLnaGain) this->state_.MAX_LNA_GAIN; } - -void CC1101Component::set_agc_max_dvga_gain(MaxDvgaGain value) { - CHECK_ENUM(value) - - this->state_.MAX_DVGA_GAIN = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_max_dvga_gain(%d)", (int) value); - - this->publish_agc_max_dvga_gain(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL2); -} - -MaxDvgaGain CC1101Component::get_agc_max_dvga_gain() { return (MaxDvgaGain) this->state_.MAX_DVGA_GAIN; } - -void CC1101Component::set_agc_carrier_sense_abs_thr(int8_t value) { - CHECK_INT_RANGE(value, CARRIER_SENSE_ABS_THR_MIN, CARRIER_SENSE_ABS_THR_MAX) - - this->state_.CARRIER_SENSE_ABS_THR = (uint8_t) (value & 0b1111); - - ESP_LOGD(TAG, "set_agc_carrier_sense_abs_thr(%d)", (int) value); - - this->publish_agc_carrier_sense_abs_thr(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL1); -} - -int8_t CC1101Component::get_agc_carrier_sense_abs_thr() { - return (int8_t) (this->state_.CARRIER_SENSE_ABS_THR << 4) >> 4; -} - -void CC1101Component::set_agc_carrier_sense_rel_thr(CarrierSenseRelThr value) { - CHECK_ENUM(value) - - this->state_.CARRIER_SENSE_REL_THR = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_agc_carrier_sense_rel_thr(%d)", (int) value); - - this->publish_agc_carrier_sense_rel_thr(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL1); -} - -CarrierSenseRelThr CC1101Component::get_agc_carrier_sense_rel_thr() { - return (CarrierSenseRelThr) this->state_.CARRIER_SENSE_REL_THR; -} - -void CC1101Component::set_agc_lna_priority(bool value) { - this->state_.AGC_LNA_PRIORITY = value ? 1 : 0; - - ESP_LOGD(TAG, "set_agc_lna_priority(%d)", value ? 1 : 0); - - this->publish_agc_lna_priority(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL1); -} - -bool CC1101Component::get_agc_lna_priority() { return this->state_.AGC_LNA_PRIORITY == 1; } - -void CC1101Component::set_agc_filter_length_fsk_msk(FilterLengthFskMsk value) { - CHECK_ENUM(value) - - this->state_.FILTER_LENGTH = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_filter_length_fsk_msk(%d)", (int) value); - - this->publish_agc_filter_length_fsk_msk(); - this->publish_agc_filter_length_ask_ook(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL0); -} - -FilterLengthFskMsk CC1101Component::get_agc_filter_length_fsk_msk() { - return (FilterLengthFskMsk) this->state_.FILTER_LENGTH; -} - -void CC1101Component::set_agc_filter_length_ask_ook(FilterLengthAskOok value) { - CHECK_ENUM(value) - - this->state_.FILTER_LENGTH = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_filter_length_ask_ook(%d)", (int) value); - - this->publish_agc_filter_length_ask_ook(); - this->publish_agc_filter_length_fsk_msk(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL0); -} - -FilterLengthAskOok CC1101Component::get_agc_filter_length_ask_ook() { - return (FilterLengthAskOok) this->state_.FILTER_LENGTH; -} - -void CC1101Component::set_agc_freeze(Freeze value) { - CHECK_ENUM(value) - - this->state_.AGC_FREEZE = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_freeze(%d)", (int) value); - - this->publish_agc_freeze(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL0); -} - -Freeze CC1101Component::get_agc_freeze() { return (Freeze) this->state_.AGC_FREEZE; } - -void CC1101Component::set_agc_wait_time(WaitTime value) { - CHECK_ENUM(value) - - this->state_.WAIT_TIME = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_wait_time(%d)", (int) value); - - this->publish_agc_wait_time(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL0); -} - -WaitTime CC1101Component::get_agc_wait_time() { return (WaitTime) this->state_.WAIT_TIME; } - -void CC1101Component::set_agc_hyst_level(HystLevel value) { - CHECK_ENUM(value) - - this->state_.HYST_LEVEL = (uint8_t) value; - - ESP_LOGD(TAG, "set_agc_hyst_level(%d)", (int) value); - - this->publish_agc_hyst_level(); - - if (!this->reset_) { - return; - } - - this->write_(Register::AGCCTRL0); -} - -HystLevel CC1101Component::get_agc_hyst_level() { return (HystLevel) this->state_.HYST_LEVEL; } - -// sensors - -std::string CC1101Component::get_chip_id_text_sensor() { return this->chip_id_; } - -float CC1101Component::get_rssi_sensor() { return (float) this->state_.RSSI / 2 - 74; } - -float CC1101Component::get_lqi_sensor() { return (float) this->state_.LQI_EST; } - -float CC1101Component::get_temperature_sensor() { return (float) 0; } // TODO - -template void CC1101Component::publish_(S *s, T state) { - if (s != nullptr) { - if (!s->has_state() || s->state != state) { - s->publish_state(state); - } - } -} - -void CC1101Component::publish_switch_(switch_::Switch *s, bool state) { - if (s != nullptr) { - if (s->state != state) { // ? - s->publish_state(state); - } - } -} - -void CC1101Component::publish_select_(select::Select *s, size_t index) { - if (s != nullptr) { - if (auto state = s->at(index)) { - if (!s->has_state() || s->state != *state) { - s->publish_state(*state); - } - } - } -} - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/cc1101.h b/components/cc1101/cc1101.h deleted file mode 100644 index 418c41a..0000000 --- a/components/cc1101/cc1101.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "esphome/core/component.h" -#include "esphome/core/automation.h" -#include "esphome/components/spi/spi.h" -#include "esphome/components/remote_base/rc_switch_protocol.h" -#include "esphome/components/voltage_sampler/voltage_sampler.h" -#include "esphome/components/sensor/sensor.h" -#include "esphome/components/binary_sensor/binary_sensor.h" -#include "esphome/components/text_sensor/text_sensor.h" -#include "esphome/components/number/number.h" -#include "esphome/components/switch/switch.h" -#include "esphome/components/select/select.h" -#include "esphome/components/text/text.h" -#include -#include "cc1101defs.h" -#include "cc1101sub.h" - -namespace esphome { -namespace cc1101 { - -class CC1101Component : public PollingComponent, - public spi::SPIDevice { - public: - CC1101Component(); - - void set_config_gdo0_pin(InternalGPIOPin *pin) { gdo0_ = pin; } - void set_config_gdo0_adc_pin(voltage_sampler::VoltageSampler *pin) { gdo0_adc_ = pin; } - - void setup() override; - void dump_config() override; - void update() override; - void loop() override; - - void begin_tx(); - void end_tx(); - - CC1101_SUB_NUMBER(output_power, float) - CC1101_SUB_SELECT(rx_attenuation, RxAttenuation) - CC1101_SUB_SWITCH(dc_blocking_filter) - // TODO: CC1101_SUB_SWITCH(manchester) - CC1101_SUB_NUMBER(tuner_frequency, float) - CC1101_SUB_NUMBER(tuner_if_frequency, float) - CC1101_SUB_NUMBER(tuner_bandwidth, float) - CC1101_SUB_NUMBER(tuner_channel, uint8_t) - CC1101_SUB_NUMBER(tuner_channel_spacing, float) - CC1101_SUB_NUMBER(tuner_fsk_deviation, float) - CC1101_SUB_NUMBER(tuner_msk_deviation, uint8_t) - CC1101_SUB_NUMBER(tuner_symbol_rate, float) - CC1101_SUB_SELECT(tuner_sync_mode, SyncMode) - CC1101_SUB_SWITCH(tuner_carrier_sense_above_threshold) - CC1101_SUB_SELECT(tuner_modulation, Modulation) - CC1101_SUB_SELECT(agc_magn_target, MagnTarget) - CC1101_SUB_SELECT(agc_max_lna_gain, MaxLnaGain) - CC1101_SUB_SELECT(agc_max_dvga_gain, MaxDvgaGain) - CC1101_SUB_NUMBER(agc_carrier_sense_abs_thr, int8_t) - CC1101_SUB_SELECT(agc_carrier_sense_rel_thr, CarrierSenseRelThr) - CC1101_SUB_SWITCH(agc_lna_priority) - CC1101_SUB_SELECT(agc_filter_length_fsk_msk, FilterLengthFskMsk) - CC1101_SUB_SELECT(agc_filter_length_ask_ook, FilterLengthAskOok) - CC1101_SUB_SELECT(agc_freeze, Freeze) - CC1101_SUB_SELECT(agc_wait_time, WaitTime) - CC1101_SUB_SELECT(agc_hyst_level, HystLevel) - CC1101_SUB_TEXT_SENSOR(chip_id) - // TODO: PARTNUM - // TODO: VERSION - CC1101_SUB_SENSOR(rssi) - CC1101_SUB_SENSOR(lqi) - // TODO: CRC OK - CC1101_SUB_SENSOR(temperature) - - protected: - InternalGPIOPin *gdo0_; - voltage_sampler::VoltageSampler *gdo0_adc_; - std::string chip_id_; - bool reset_; - float output_power_requested_; - float output_power_effective_; - uint8_t pa_table_[8]; - union { - struct CC1101State state_; - uint8_t regs_[sizeof(struct CC1101State) / sizeof(uint8_t)]; - }; - - void strobe_(Command cmd); - void write_(Register reg); - void write_(Register reg, uint8_t value); - void write_(Register reg, uint8_t *buffer, size_t length); - bool read_(Register reg); - bool read_(Register reg, uint8_t *buffer, size_t length); - // bool send_data_(const uint8_t* data, size_t length); - void send_(Command cmd); - bool wait_(Command cmd); - - template void publish_(S *s, T state); - // template specialization here in the header is not supported by the compiler - void publish_switch_(switch_::Switch *s, bool state); - void publish_select_(select::Select *s, size_t index); -}; - -template class BeginTxAction : public Action, public Parented { - public: - void play(Ts... x) override { this->parent_->begin_tx(); } -}; - -template class EndTxAction : public Action, public Parented { - public: - void play(Ts... x) override { this->parent_->end_tx(); } -}; - -template -class CC1101RawAction : public remote_base::RCSwitchRawAction, public Parented { - protected: - void play(Ts... x) override { - this->parent_->begin_tx(); - remote_base::RCSwitchRawAction::play(x...); - this->parent_->end_tx(); - } - - public: -}; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/cc1101defs.h b/components/cc1101/cc1101defs.h deleted file mode 100644 index e46d6c8..0000000 --- a/components/cc1101/cc1101defs.h +++ /dev/null @@ -1,693 +0,0 @@ -#pragma once - -#include - -namespace esphome { -namespace cc1101 { - -static constexpr float XTAL_FREQUENCY = 26000; -static constexpr float OUTPUT_POWER_MIN = -30; -static constexpr float OUTPUT_POWER_MAX = 11; -static constexpr float FREQUENCY_MIN = 300000; -static constexpr float FREQUENCY_MAX = 928000; -static constexpr float IF_FREQUENCY_MIN = 25; -static constexpr float IF_FREQUENCY_MAX = 788; -static constexpr float BANDWIDTH_MIN = 58; -static constexpr float BANDWIDTH_MAX = 812; -static constexpr uint8_t CHANNEL_MIN = 0; -static constexpr uint8_t CHANNEL_MAX = 255; -static constexpr float CHANNEL_SPACING_MIN = 25; -static constexpr float CHANNEL_SPACING_MAX = 405; -static constexpr float FSK_DEVIATION_MIN = 1.5f; -static constexpr float FSK_DEVIATION_MAX = 381; -static constexpr uint8_t MSK_DEVIATION_MIN = 1; -static constexpr uint8_t MSK_DEVIATION_MAX = 8; -static constexpr float SYMBOL_RATE_MIN = 600; -static constexpr float SYMBOL_RATE_MAX = 500000; -static constexpr int8_t CARRIER_SENSE_ABS_THR_MIN = -8; -static constexpr int8_t CARRIER_SENSE_ABS_THR_MAX = 7; - -static constexpr uint8_t BUS_BURST = 0x40; -static constexpr uint8_t BUS_READ = 0x80; -static constexpr uint8_t BUS_WRITE = 0x00; -static constexpr uint8_t BYTES_IN_RXFIFO = 0x7F; // byte number in RXfifo - -enum class Register : uint8_t { - IOCFG2, // GDO2 output pin configuration - IOCFG1, // GDO1 output pin configuration - IOCFG0, // GDO0 output pin configuration - FIFOTHR, // RX FIFO and TX FIFO thresholds - SYNC1, // Sync word, high INT8U - SYNC0, // Sync word, low INT8U - PKTLEN, // Packet length - PKTCTRL1, // Packet automation control - PKTCTRL0, // Packet automation control - ADDR, // Device address - CHANNR, // Channel number - FSCTRL1, // Frequency synthesizer control - FSCTRL0, // Frequency synthesizer control - FREQ2, // Frequency control word, high INT8U - FREQ1, // Frequency control word, middle INT8U - FREQ0, // Frequency control word, low INT8U - MDMCFG4, // Modem configuration - MDMCFG3, // Modem configuration - MDMCFG2, // Modem configuration - MDMCFG1, // Modem configuration - MDMCFG0, // Modem configuration - DEVIATN, // Modem deviation setting - MCSM2, // Main Radio Control State Machine configuration - MCSM1, // Main Radio Control State Machine configuration - MCSM0, // Main Radio Control State Machine configuration - FOCCFG, // Frequency Offset Compensation configuration - BSCFG, // Bit Synchronization configuration - AGCCTRL2, // AGC control - AGCCTRL1, // AGC control - AGCCTRL0, // AGC control - WOREVT1, // High INT8U Event 0 timeout - WOREVT0, // Low INT8U Event 0 timeout - WORCTRL, // Wake On Radio control - FREND1, // Front end RX configuration - FREND0, // Front end TX configuration - FSCAL3, // Frequency synthesizer calibration - FSCAL2, // Frequency synthesizer calibration - FSCAL1, // Frequency synthesizer calibration - FSCAL0, // Frequency synthesizer calibration - RCCTRL1, // RC oscillator configuration - RCCTRL0, // RC oscillator configuration - FSTEST, // Frequency synthesizer calibration control - PTEST, // Production test - AGCTEST, // AGC test - TEST2, // Various test settings - TEST1, // Various test settings - TEST0, // Various test settings - UNUSED, - PARTNUM, - VERSION, - FREQEST, - LQI, - RSSI, - MARCSTATE, - WORTIME1, - WORTIME0, - PKTSTATUS, - VCO_VC_DAC, - TXBYTES, - RXBYTES, - RCCTRL1_STATUS, - RCCTRL0_STATUS, - PATABLE, - FIFO, -}; - -enum class Command : uint8_t { - RES = 0x30, // Reset chip. - FSTXON, // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). - // If in RX/TX: Go to a wait state where only the synthesizer is - // running (for quick RX / TX turnaround). - XOFF, // Turn off crystal oscillator. - CAL, // Calibrate frequency synthesizer and turn it off - // (enables quick start). - RX, // Enable RX. Perform calibration first if coming from IDLE and - // MCSM0.FS_AUTOCAL=1. - TX, // In IDLE state: Enable TX. Perform calibration first if - // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled: - // Only go to TX if channel is clear. - IDLE, // Exit RX / TX, turn off frequency synthesizer and exit - // Wake-On-Radio mode if applicable. - AFC, // Perform AFC adjustment of the frequency synthesizer - WOR, // Start automatic RX polling sequence (Wake-on-Radio) - PWD, // Enter power down mode when CSn goes high. - FRX, // Flush the RX FIFO buffer. - FTX, // Flush the TX FIFO buffer. - WORRST, // Reset real time clock. - NOP, // No operation. May be used to pad strobe commands to two - // INT8Us for simpler software. -}; - -enum class State : uint8_t { - SLEEP, - IDLE, - XOFF, - VCOON_MC, - REGON_MC, - MANCAL, - VCOON, - REGON, - STARTCAL, - BWBOOST, - FS_LOCK, - IFADCON, - ENDCAL, - RX, - RX_END, - RX_RST, - TXRX_SWITCH, - RXFIFO_OVERFLOW, - FSTXON, - TX, - TX_END, - RXTX_SWITCH, - TXFIFO_UNDERFLOW, -}; - -enum class RxAttenuation : uint8_t { - RX_ATTENUATION_0DB, - RX_ATTENUATION_6DB, - RX_ATTENUATION_12DB, - RX_ATTENUATION_18DB, - LAST, -}; - -// MDMCFG2 - -enum class SyncMode : uint8_t { - SYNC_MODE_NONE, - SYNC_MODE_15_16, - SYNC_MODE_16_16, - SYNC_MODE_30_32, - LAST, -}; - -enum class Modulation : uint8_t { - MODULATION_2_FSK, - MODULATION_GFSK, - MODULATION_UNUSED_2, - MODULATION_ASK_OOK, - MODULATION_4_FSK, - MODULATION_UNUSED_5, - MODULATION_UNUSED_6, - MODULATION_MSK, - LAST, -}; - -// AGCCTRL2 - -enum class MagnTarget : uint8_t { - MAGN_TARGET_24DB, - MAGN_TARGET_27DB, - MAGN_TARGET_30DB, - MAGN_TARGET_33DB, - MAGN_TARGET_36DB, - MAGN_TARGET_38DB, - MAGN_TARGET_40DB, - MAGN_TARGET_42DB, - LAST, -}; - -enum class MaxLnaGain : uint8_t { - MAX_LNA_GAIN_DEFAULT, - MAX_LNA_GAIN_MINUS_2P6DB, - MAX_LNA_GAIN_MINUS_6P1DB, - MAX_LNA_GAIN_MINUS_7P4DB, - MAX_LNA_GAIN_MINUS_9P2DB, - MAX_LNA_GAIN_MINUS_11P5DB, - MAX_LNA_GAIN_MINUS_14P6DB, - MAX_LNA_GAIN_MINUS_17P1DB, - LAST, -}; - -enum class MaxDvgaGain : uint8_t { - MAX_DVGA_GAIN_DEFAULT, - MAX_DVGA_GAIN_MINUS_1, - MAX_DVGA_GAIN_MINUS_2, - MAX_DVGA_GAIN_MINUS_3, - LAST, -}; - -// AGCCTRL1 - -// CARRIER_SENSE_ABS_THR => number -7..+7, -8 is disabled - -enum class CarrierSenseRelThr : uint8_t { - CARRIER_SENSE_REL_THR_DEFAULT, - CARRIER_SENSE_REL_THR_PLUS_6DB, - CARRIER_SENSE_REL_THR_PLUS_10DB, - CARRIER_SENSE_REL_THR_PLUS_14DB, - LAST, -}; - -// AGC_LNA_PRIORITY => switch - -// AGCCTRL0 - -enum class FilterLengthFskMsk : uint8_t { - FILTER_LENGTH_8DB, - FILTER_LENGTH_16DB, - FILTER_LENGTH_32DB, - FILTER_LENGTH_64DB, - LAST, -}; - -enum class FilterLengthAskOok : uint8_t { - FILTER_LENGTH_4DB, - FILTER_LENGTH_8DB, - FILTER_LENGTH_12DB, - FILTER_LENGTH_16DB, - LAST, -}; - -enum class Freeze : uint8_t { - FREEZE_DEFAULT, - FREEZE_ON_SYNC, - FREEZE_ANALOG_ONLY, - FREEZE_ANALOG_AND_DIGITAL, - LAST, -}; - -enum class WaitTime : uint8_t { - WAIT_TIME_8_SAMPLES, - WAIT_TIME_16_SAMPLES, - WAIT_TIME_24_SAMPLES, - WAIT_TIME_32_SAMPLES, - LAST, -}; - -enum class HystLevel : uint8_t { - HYST_LEVEL_NONE, - HYST_LEVEL_LOW, - HYST_LEVEL_MEDIUM, - HYST_LEVEL_HIGH, - LAST, -}; - -// - -struct CC1101State { - // 0x00 - union { - uint8_t IOCFG2; - struct { - uint8_t GDO2_CFG : 6; - uint8_t GDO2_INV : 1; - uint8_t : 1; - }; - }; - // 0x01 - union { - uint8_t IOCFG1; - struct { - uint8_t GDO1_CFG : 6; - uint8_t GDO1_INV : 1; - uint8_t GDO_DS : 1; // GDO, not GD0 - }; - }; - // 0x02 - union { - uint8_t IOCFG0; - struct { - uint8_t GDO0_CFG : 6; - uint8_t GDO0_INV : 1; - uint8_t TEMP_SENSOR_ENABLE : 1; - }; - }; - // 0x03 - union { - uint8_t FIFOTHR; - struct { - uint8_t FIFO_THR : 4; - uint8_t CLOSE_IN_RX : 2; // RxAttenuation - uint8_t ADC_RETENTION : 1; - uint8_t : 1; - }; - }; - // 0x04 - uint8_t SYNC1; - // 0x05 - uint8_t SYNC0; - // 0x06 - uint8_t PKTLEN; - // 0x07 - union { - uint8_t PKTCTRL1; - struct { - uint8_t ADR_CHK : 2; - uint8_t APPEND_STATUS : 1; - uint8_t CRC_AUTOFLUSH : 1; - uint8_t : 1; - uint8_t PQT : 3; - }; - }; - // 0x08 - union { - uint8_t PKTCTRL0; - struct { - uint8_t LENGTH_CONFIG : 2; - uint8_t CRC_EN : 1; - uint8_t : 1; - uint8_t PKT_FORMAT : 2; - uint8_t WHITE_DATA : 1; - uint8_t : 1; - }; - }; - // 0x09 - uint8_t ADDR; - // 0x0A - uint8_t CHANNR; - // 0x0B - union { - uint8_t FSCTRL1; - struct { - uint8_t FREQ_IF : 5; - uint8_t RESERVED : 1; // hm? - uint8_t : 2; - }; - }; - // 0x0C - uint8_t FSCTRL0; - // 0x0D - uint8_t FREQ2; // [7:6] always zero - // 0x0E - uint8_t FREQ1; - // 0x0F - uint8_t FREQ0; - // 0x10 - union { - uint8_t MDMCFG4; - struct { - uint8_t DRATE_E : 4; - uint8_t CHANBW_M : 2; - uint8_t CHANBW_E : 2; - }; - }; - // 0x11 - union { - uint8_t MDMCFG3; - struct { - uint8_t DRATE_M : 8; - }; - }; - // 0x12 - union { - uint8_t MDMCFG2; - struct { - uint8_t SYNC_MODE : 2; - uint8_t CARRIER_SENSE_ABOVE_THRESHOLD : 1; - uint8_t MANCHESTER_EN : 1; - uint8_t MOD_FORMAT : 3; // Modulation - uint8_t DEM_DCFILT_OFF : 1; - }; - }; - // 0x13 - union { - uint8_t MDMCFG1; - struct { - uint8_t CHANSPC_E : 2; - uint8_t : 2; - uint8_t NUM_PREAMBLE : 3; - uint8_t FEC_EN : 1; - }; - }; - // 0x14 - union { - uint8_t MDMCFG0; - struct { - uint8_t CHANSPC_M : 8; - }; - }; - // 0x15 - union { - uint8_t DEVIATN; - struct { - uint8_t DEVIATION_M : 3; - uint8_t : 1; - uint8_t DEVIATION_E : 3; - uint8_t : 1; - }; - }; - // 0x16 - union { - uint8_t MCSM2; - struct { - uint8_t RX_TIME : 3; - uint8_t RX_TIME_QUAL : 1; - uint8_t RX_TIME_RSSI : 1; - uint8_t : 3; - }; - }; - // 0x17 - union { - uint8_t MCSM1; - struct { - uint8_t TXOFF_MODE : 2; - uint8_t RXOFF_MODE : 2; - uint8_t CCA_MODE : 2; - uint8_t : 2; - }; - }; - // 0x18 - union { - uint8_t MCSM0; - struct { - uint8_t XOSC_FORCE_ON : 1; - uint8_t PIN_CTRL_EN : 1; - uint8_t PO_TIMEOUT : 2; - uint8_t FS_AUTOCAL : 2; - uint8_t : 2; - }; - }; - // 0x19 - union { - uint8_t FOCCFG; - struct { - uint8_t FOC_LIMIT : 2; - uint8_t FOC_POST_K : 1; - uint8_t FOC_PRE_K : 2; - uint8_t FOC_BS_CS_GATE : 1; - uint8_t : 2; - }; - }; - // 0x1A - union { - uint8_t BSCFG; - struct { - uint8_t BS_LIMIT : 2; - uint8_t BS_POST_KP : 1; - uint8_t BS_POST_KI : 1; - uint8_t BS_PRE_KP : 2; - uint8_t BS_PRE_KI : 2; - }; - }; - // 0x1B - union { - uint8_t AGCCTRL2; - struct { - uint8_t MAGN_TARGET : 3; // MagnTarget - uint8_t MAX_LNA_GAIN : 3; // MaxLnaGain - uint8_t MAX_DVGA_GAIN : 2; // MaxDvgaGain - }; - }; - // 0x1C - union { - uint8_t AGCCTRL1; - struct { - uint8_t CARRIER_SENSE_ABS_THR : 4; - uint8_t CARRIER_SENSE_REL_THR : 2; // CarrierSenseRelThr - uint8_t AGC_LNA_PRIORITY : 1; - uint8_t : 1; - }; - }; - // 0x1D - union { - uint8_t AGCCTRL0; - struct { - uint8_t FILTER_LENGTH : 2; // FilterLengthFskMsk or FilterLengthAskOok - uint8_t AGC_FREEZE : 2; // Freeze - uint8_t WAIT_TIME : 2; // WaitTime - uint8_t HYST_LEVEL : 2; // HystLevel - }; - }; - // 0x1E - uint8_t WOREVT1; - // 0x1F - uint8_t WOREVT0; - // 0x20 - union { - uint8_t WORCTRL; - struct { - uint8_t WOR_RES : 2; - uint8_t : 1; - uint8_t RC_CAL : 1; - uint8_t EVENT1 : 3; - uint8_t RC_PD : 1; - }; - }; - // 0x21 - union { - uint8_t FREND1; - struct { - uint8_t MIX_CURRENT : 2; - uint8_t LODIV_BUF_CURRENT_RX : 2; - uint8_t LNA2MIX_CURRENT : 2; - uint8_t LNA_CURRENT : 2; - }; - }; - // 0x22 - union { - uint8_t FREND0; - struct { - uint8_t PA_POWER : 3; - uint8_t : 1; - uint8_t LODIV_BUF_CURRENT_TX : 2; - uint8_t : 2; - }; - }; - // 0x23 - union { - uint8_t FSCAL3; - struct { - uint8_t FSCAL3_LO : 4; - uint8_t CHP_CURR_CAL_EN : 2; // Disable charge pump calibration stage when 0. - uint8_t FSCAL3_HI : 2; - }; - }; - // 0x24 - union { - // uint8_t FSCAL2; - struct { - uint8_t FSCAL2 : 5; - uint8_t VCO_CORE_H_EN : 1; - uint8_t : 2; - }; - }; - // 0x25 - union { - // uint8_t FSCAL1; - struct { - uint8_t FSCAL1 : 6; - uint8_t : 2; - }; - }; - // 0x26 - union { - // uint8_t FSCAL0; - struct { - uint8_t FSCAL0 : 7; - uint8_t : 1; - }; - }; - // 0x27 - union { - // uint8_t RCCTRL1; - struct { - uint8_t RCCTRL1 : 7; - uint8_t : 1; - }; - }; - // 0x28 - union { - // uint8_t RCCTRL0; - struct { - uint8_t RCCTRL0 : 7; - uint8_t : 1; - }; - }; - // 0x29 - uint8_t FSTEST; - // 0x2A - uint8_t PTEST; - // 0x2B - uint8_t AGCTEST; - // 0x2C - uint8_t TEST2; - // 0x2D - uint8_t TEST1; - // 0x2E - union { - uint8_t TEST0; - struct { - uint8_t TEST0_LO : 1; - uint8_t VCO_SEL_CAL_EN : 1; // Enable VCO selection calibration stage when 1 - uint8_t TEST0_HI : 6; - }; - }; - // 0x2F - uint8_t REG_2F; - // 0x30 - uint8_t PARTNUM; - // 0x31 - uint8_t VERSION; - // 0x32 - union { - uint8_t FREQEST; - struct { - int8_t FREQOFF_EST : 8; - }; - }; - // 0x33 - union { - uint8_t LQI; - struct { - uint8_t LQI_EST : 7; - uint8_t LQI_CRC_OK : 1; - }; - }; - // 0x34 - int8_t RSSI; - // 0x35 - union { - // uint8_t MARCSTATE; - struct { - uint8_t MARC_STATE : 5; // State - uint8_t : 3; - }; - }; - // 0x36 - uint8_t WORTIME1; - // 0x37 - uint8_t WORTIME0; - // 0x38 - union { - uint8_t PKTSTATUS; - struct { - uint8_t GDO0 : 1; - uint8_t : 1; - uint8_t GDO2 : 1; - uint8_t SFD : 1; - uint8_t CCA : 1; - uint8_t PQT_REACHED : 1; - uint8_t CS : 1; - uint8_t CRC_OK : 1; // same as LQI_CRC_OK? - }; - }; - // 0x39 - uint8_t VCO_VC_DAC; - // 0x3A - union { - uint8_t TXBYTES; - struct { - uint8_t NUM_TXBYTES : 7; - uint8_t TXFIFO_UNDERFLOW : 1; - }; - }; - // 0x3B - union { - uint8_t RXBYTES; - struct { - uint8_t NUM_RXBYTES : 7; - uint8_t RXFIFO_OVERFLOW : 1; - }; - }; - // 0x3C - union { - // uint8_t RCCTRL1_STATUS; - struct { - uint8_t RCCTRL1_STATUS : 7; - uint8_t : 1; - }; - }; - // 0x3D - union { - // uint8_t RCCTRL0_STATUS; - struct { - uint8_t RCCTRL0_STATUS : 7; - uint8_t : 1; - }; - }; - // 0x3E - uint8_t REG_3E; - // 0x3F - uint8_t REG_3F; -}; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/cc1101pa.h b/components/cc1101/cc1101pa.h deleted file mode 100644 index ffe38f0..0000000 --- a/components/cc1101/cc1101pa.h +++ /dev/null @@ -1,684 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace esphome { -namespace cc1101 { - -// CC1101 Design Note DN013 - -// The typical CC1101 output power levels and current consumption for the different PATABLE -// register settings are given in Table 1for 315 MHz, in Table 2 for 433 MHz, in Table 3 for 868 -// MHz, and in Table 4 for 915 MHz. It is however not recommended to use the PATABLE -// register settings from 0x61 to 0x6F for CC1101. - -struct PowerTableItem { - uint8_t value; - uint8_t dbm_diff; // starts from 12.0, diff to previous entry, scaled by 10 -}; - -struct PowerTable { - public: - static float find(const PowerTableItem *items, size_t count, float &dbm_target) { - int dbmi = 120; - int dbmi_target = (int) std::lround(dbm_target * 10); - for (size_t i = 0; i < count; i++) { - dbmi -= items[i].dbm_diff; - if (dbmi_target >= dbmi) { - if (items[i].value >= 0x61 && items[i].value <= 0x6F) - continue; // see note in the commend above - dbm_target = (float) dbmi / 10; - return items[i].value; - } - } - dbm_target = -30; - return 0x03; - } -}; - -// filtered tables to save memory -// - at least 1dBm difference -// - 0x61 - 0x6F removed -// - no values below -30dBm - -static const PowerTableItem PA_TABLE_315[] = { - {0xC0, 14}, // C0 10.6 -35.3 -44.4 -57.8 -53.8 -58.3 -57.2 -57.8 -56.7 28.5 - {0xC3, 10}, // C3 9.6 -39.2 -45.3 -59.0 -54.2 -59.0 -57.5 -58.3 -57.2 26.2 - {0xC6, 11}, // C6 8.5 -43.2 -46.3 -59.2 -54.7 -59.1 -57.7 -58.3 -57.4 24.4 - {0xC9, 10}, // C9 7.5 -47.0 -47.3 -58.9 -55.0 -59.0 -57.9 -58.4 -57.5 23.0 - {0x81, 12}, // 81 6.3 -49.2 -45.7 -57.3 -53.6 -59.0 -56.0 -56.5 -57.5 19.5 - {0x85, 13}, // 85 5.0 -51.0 -47.2 -59.8 -54.2 -59.0 -56.9 -57.9 -58.0 18.3 - {0x88, 11}, // 88 3.9 -46.6 -48.1 -60.0 -55.0 -58.9 -57.5 -58.2 -58.2 17.4 - {0xCF, 11}, // CF 2.8 -49.8 -51.3 -57.6 -56.8 -59.1 -58.4 -58.1 -58.3 18.0 - {0x8D, 11}, // 8D 1.7 -43.8 -49.5 -58.9 -56.3 -58.8 -58.2 -58.4 -58.5 15.8 - {0x50, 10}, // 50 0.7 -59.2 -51.2 -59.0 -56.5 -59.0 -58.3 -58.3 -58.2 15.3 - {0x40, 10}, // 40 -0.3 -58.2 -52.1 -59.4 -56.9 -59.0 -58.4 -58.4 -58.3 14.7 - {0x3D, 10}, // 3D -1.3 -54.4 -48.4 -59.8 -57.5 -58.9 -58.3 -58.5 -58.5 19.3 - {0x55, 10}, // 55 -2.3 -56.7 -53.6 -59.7 -57.5 -59.1 -58.7 -58.4 -58.4 13.7 - {0x39, 11}, // 39 -3.4 -50.9 -49.5 -59.8 -58.0 -59.0 -58.5 -58.4 -58.4 16.8 - {0x2B, 15}, // 2B -4.9 -51.2 -50.4 -59.9 -58.0 -58.9 -58.7 -58.3 -58.4 15.6 - {0x29, 16}, // 29 -6.5 -51.8 -51.6 -59.9 -58.4 -59.0 -58.8 -58.3 -58.3 14.7 - {0x28, 10}, // 28 -7.5 -52.2 -52.5 -60.0 -58.6 -59.0 -58.8 -58.2 -58.4 14.3 - {0x27, 11}, // 27 -8.6 -52.9 -53.1 -60.0 -58.8 -59.1 -58.8 -58.3 -58.5 13.9 - {0x26, 12}, // 26 -9.8 -53.6 -54.3 -60.1 -58.7 -59.0 -58.7 -58.4 -58.4 13.4 - {0x25, 13}, // 25 -11.1 -54.3 -55.5 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 13.0 - {0x33, 11}, // 33 -12.2 -55.0 -56.3 -60.0 -58.7 -59.0 -58.9 -58.4 -58.4 12.8 - {0x1F, 11}, // 1F -13.3 -55.6 -57.2 -60.0 -58.8 -58.9 -58.9 -58.3 -58.4 12.4 - {0x1D, 12}, // 1D -14.5 -56.0 -58.0 -60.0 -58.8 -59.1 -58.7 -58.4 -58.5 12.1 - {0x32, 11}, // 32 -15.6 -56.9 -58.8 -59.9 -58.8 -59.0 -58.8 -58.3 -58.5 12.2 - {0x1A, 10}, // 1A -16.6 -57.3 -59.5 -59.9 -58.8 -59.1 -58.8 -58.4 -58.4 11.8 - {0x18, 19}, // 18 -18.5 -57.8 -60.3 -60.0 -58.8 -59.0 -58.9 -58.2 -58.5 11.6 - {0x17, 11}, // 17 -19.6 -58.7 -60.9 -60.0 -58.7 -58.9 -58.9 -58.5 -58.4 11.4 - {0x0C, 11}, // C -20.7 -59.4 -61.1 -60.0 -58.8 -59.1 -58.9 -58.4 -58.3 11.3 - {0x0A, 15}, // A -22.2 -59.9 -61.9 -60.0 -58.9 -59.0 -58.9 -58.4 -58.5 11.2 - {0x08, 18}, // 8 -24.0 -60.5 -62.5 -60.0 -58.7 -59.1 -58.8 -58.3 -58.5 11.1 - {0x07, 11}, // 7 -25.1 -61.3 -62.9 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 11.0 - {0x06, 13}, // 6 -26.4 -61.6 -63.2 -60.1 -58.7 -59.0 -58.9 -58.5 -58.5 11.0 - {0x05, 13}, // 5 -27.7 -62.3 -63.4 -60.1 -58.7 -59.2 -58.8 -58.4 -58.5 10.9 - {0x04, 19}, // 4 -29.6 -62.7 -63.6 -59.9 -58.7 -59.0 -58.9 -58.4 -58.4 10.8 -}; - -static const PowerTableItem PA_TABLE_433[] = { - {0xC0, 21}, // C0 9.9 -43.4 -45.0 -53.9 -55.2 -55.8 -52.3 -55.6 29.1 - {0xC3, 11}, // C3 8.8 -49.3 -45.9 -55.9 -55.4 -57.2 -52.6 -57.5 26.9 - {0xC6, 10}, // C6 7.8 -56.2 -46.9 -56.9 -55.6 -58.2 -53.2 -57.9 25.2 - {0xC9, 10}, // C9 6.8 -56.1 -47.9 -57.3 -55.9 -58.5 -54.0 -56.9 23.8 - {0xCC, 10}, // CC 5.8 -52.8 -48.9 -57.0 -56.1 -58.4 -54.6 -56.2 22.6 - {0x85, 10}, // 85 4.8 -54.2 -53.0 -58.3 -55.0 -57.8 -56.8 -58.0 19.1 - {0x88, 12}, // 88 3.6 -56.2 -53.8 -58.3 -55.7 -58.1 -57.2 -58.2 18.2 - {0x8B, 13}, // 8B 2.3 -57.7 -54.5 -58.0 -56.3 -58.1 -57.5 -58.2 17.3 - {0x8E, 19}, // 8E 0.4 -58.0 -55.5 -57.8 -57.4 -58.2 -58.1 -58.4 16.2 - {0x40, 12}, // 40 -0.8 -59.7 -56.1 -58.2 -57.7 -58.4 -58.3 -58.2 15.4 - {0x3C, 13}, // 3C -2.1 -60.6 -57.3 -58.2 -58.0 -58.5 -58.4 -58.5 19.3 - {0x3A, 10}, // 3A -3.1 -59.5 -57.5 -58.3 -58.3 -58.6 -58.1 -58.6 18.1 - {0x8F, 15}, // 8F -4.6 -52.2 -57.7 -58.1 -58.8 -58.4 -58.7 -58.3 14.4 - {0x37, 10}, // 37 -5.6 -56.8 -58.3 -58.3 -58.8 -58.4 -58.5 -58.4 16.2 - {0x36, 12}, // 36 -6.8 -56.8 -58.9 -58.3 -58.8 -58.3 -58.5 -58.5 15.6 - {0x28, 10}, // 28 -7.8 -56.6 -59.0 -58.2 -59.0 -58.4 -58.5 -58.4 15.1 - {0x26, 21}, // 26 -9.9 -57.0 -59.4 -58.3 -59.0 -58.4 -58.7 -58.4 14.3 - {0x25, 15}, // 25 -11.4 -57.3 -59.7 -58.4 -59.0 -58.3 -58.7 -58.5 13.9 - {0x24, 19}, // 24 -13.3 -57.9 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 13.5 - {0x1E, 10}, // 1E -14.3 -58.4 -59.8 -58.2 -59.0 -58.4 -58.6 -58.6 13.2 - {0x1C, 12}, // 1C -15.5 -58.6 -59.9 -58.4 -58.8 -58.6 -58.8 -58.5 12.9 - {0x1A, 15}, // 1A -17.0 -59.4 -59.9 -58.3 -59.1 -58.5 -58.7 -58.4 12.7 - {0x18, 18}, // 18 -18.8 -60.2 -59.9 -58.2 -59.0 -58.5 -58.7 -58.6 12.5 - {0x17, 10}, // 17 -19.8 -60.6 -59.9 -58.2 -58.9 -58.4 -58.7 -58.4 12.4 - {0x0C, 12}, // C -21.0 -61.1 -59.9 -58.4 -59.0 -58.5 -58.7 -58.6 12.3 - {0x15, 15}, // 15 -22.5 -61.7 -60.0 -58.2 -59.1 -58.3 -58.6 -58.7 12.2 - {0x08, 18}, // 8 -24.3 -62.3 -59.9 -58.3 -59.0 -58.4 -58.8 -58.5 12.1 - {0x07, 10}, // 7 -25.3 -62.6 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 12.0 - {0x06, 12}, // 6 -26.5 -63.2 -59.9 -58.3 -58.9 -58.5 -58.6 -58.6 12.0 - {0x05, 14}, // 5 -27.9 -63.5 -59.8 -58.3 -59.1 -58.5 -58.7 -58.4 11.9 - {0x04, 16}, // 4 -29.5 -63.7 -59.9 -58.3 -58.9 -58.5 -58.5 -58.5 11.9 -}; - -static const PowerTableItem PA_TABLE_868[] = { - {0xC0, 13}, // C0 10.7 -35.1 -58.6 -58.6 -57.5 -50.0 34.2 - {0xC3, 11}, // C3 9.6 -41.5 -58.5 -58.3 -57.4 -54.4 31.6 - {0xC6, 11}, // C6 8.5 -47.7 -58.5 -58.3 -57.6 -55.0 29.5 - {0xC9, 10}, // C9 7.5 -44.4 -58.5 -58.5 -57.7 -53.6 27.8 - {0xCC, 10}, // CC 6.5 -40.6 -58.6 -58.4 -57.6 -52.5 26.3 - {0xCE, 10}, // CE 5.5 -38.5 -58.5 -58.4 -57.8 -52.2 25.0 - {0x84, 11}, // 84 4.4 -35.3 -58.7 -58.5 -57.8 -55.8 20.3 - {0x87, 10}, // 87 3.4 -39.4 -58.6 -58.6 -57.8 -55.7 19.5 - {0xCF, 10}, // CF 2.4 -36.6 -58.6 -58.4 -57.7 -53.6 22.0 - {0x8C, 13}, // 8C 1.1 -50.2 -58.6 -58.5 -57.7 -55.9 17.9 - {0x50, 14}, // 50 -0.3 -42.1 -58.5 -58.5 -57.6 -57.1 16.9 - {0x40, 12}, // 40 -1.5 -43.2 -58.5 -58.7 -57.7 -57.2 16.1 - {0x3F, 11}, // 3F -2.6 -53.7 -58.6 -58.5 -57.8 -57.5 21.4 - {0x55, 10}, // 55 -3.6 -44.9 -58.6 -58.4 -57.8 -57.5 15.0 - {0x57, 12}, // 57 -4.8 -46.0 -58.6 -58.5 -57.6 -57.4 14.5 - {0x8F, 12}, // 8F -6.0 -51.6 -58.5 -58.6 -57.7 -57.1 15.0 - {0x2A, 14}, // 2A -7.4 -49.3 -58.5 -58.6 -57.7 -57.4 16.2 - {0x28, 16}, // 28 -9.0 -49.0 -58.5 -58.6 -57.7 -57.4 15.4 - {0x26, 20}, // 26 -11.0 -49.2 -58.5 -58.5 -57.7 -57.4 14.6 - {0x25, 15}, // 25 -12.5 -49.5 -58.6 -58.6 -57.8 -57.3 14.1 - {0x24, 18}, // 24 -14.3 -50.2 -58.5 -58.4 -57.8 -57.4 13.7 - {0x1D, 14}, // 1D -15.7 -50.7 -58.6 -58.6 -57.8 -57.5 13.3 - {0x1B, 13}, // 1B -17.0 -51.3 -58.5 -58.4 -57.7 -57.5 13.1 - {0x19, 16}, // 19 -18.6 -52.0 -58.6 -58.5 -57.8 -57.5 12.9 - {0x22, 10}, // 22 -19.6 -52.5 -58.5 -58.6 -57.7 -57.4 12.9 - {0x0D, 15}, // D -21.1 -53.3 -58.6 -58.6 -57.8 -57.4 12.6 - {0x0B, 12}, // B -22.3 -53.9 -58.6 -58.5 -57.8 -57.4 12.5 - {0x09, 15}, // 9 -23.8 -54.7 -58.5 -58.5 -57.8 -57.5 12.4 - {0x21, 10}, // 21 -24.8 -55.1 -58.5 -58.5 -57.7 -57.5 12.5 - {0x13, 17}, // 13 -26.5 -55.9 -58.6 -58.5 -57.6 -57.6 12.3 - {0x05, 12}, // 5 -27.7 -56.4 -58.4 -58.4 -57.7 -57.5 12.2 - {0x12, 12}, // 12 -28.9 -57.1 -58.4 -58.5 -57.7 -57.3 12.2 -}; - -static const PowerTableItem PA_TABLE_915[] = { - {0xC0, 26}, // C0 9.4 -33.5 -58.5 -58.4 -55.8 -32.6 31.8 - {0xC3, 11}, // C3 8.3 -41.5 -58.6 -58.4 -56.3 -38.0 29.3 - {0xC6, 11}, // C6 7.2 -42.5 -58.5 -58.4 -56.7 -40.5 27.4 - {0xC9, 10}, // C9 6.2 -37.6 -58.6 -58.4 -57.2 -38.8 25.9 - {0xCD, 12}, // CD 5.0 -34.2 -58.6 -58.5 -57.5 -37.3 24.3 - {0x84, 11}, // 84 3.9 -32.0 -58.6 -58.4 -57.7 -40.1 19.7 - {0x87, 10}, // 87 2.9 -36.5 -58.4 -58.5 -57.7 -39.6 18.9 - {0x8A, 11}, // 8A 1.8 -42.2 -58.5 -58.4 -57.7 -39.6 18.1 - {0x8D, 13}, // 8D 0.5 -46.8 -58.5 -58.5 -57.7 -40.4 17.3 - {0x8E, 11}, // 8E -0.6 -46.6 -58.5 -58.5 -57.8 -41.1 16.7 - {0x51, 10}, // 51 -1.6 -38.7 -58.4 -58.5 -57.7 -46.9 16.0 - {0x3E, 11}, // 3E -2.7 -50.0 -58.5 -58.4 -57.6 -55.3 20.7 - {0x3B, 11}, // 3B -3.8 -50.7 -58.6 -58.4 -57.6 -55.2 18.9 - {0x39, 13}, // 39 -5.1 -50.0 -58.5 -58.5 -57.6 -54.0 17.7 - {0x2B, 13}, // 2B -6.4 -47.6 -58.4 -58.4 -57.8 -52.1 16.5 - {0x36, 15}, // 36 -7.9 -46.9 -58.5 -58.4 -57.7 -51.2 15.8 - {0x35, 14}, // 35 -9.3 -46.7 -58.6 -58.4 -57.7 -50.7 15.2 - {0x26, 16}, // 26 -10.9 -47.0 -58.6 -58.4 -57.8 -50.9 14.5 - {0x25, 14}, // 25 -12.3 -47.2 -58.6 -58.3 -57.7 -51.0 14.1 - {0x24, 18}, // 24 -14.1 -48.1 -58.4 -58.4 -57.8 -51.4 13.7 - {0x1D, 14}, // 1D -15.5 -48.7 -58.4 -58.5 -57.7 -51.9 13.2 - {0x1B, 13}, // 1B -16.8 -49.3 -58.6 -58.4 -57.8 -52.3 13.0 - {0x19, 15}, // 19 -18.3 -50.2 -58.5 -58.5 -57.6 -52.8 12.8 - {0x18, 10}, // 18 -19.3 -50.6 -58.5 -58.5 -57.7 -53.1 12.7 - {0x17, 10}, // 17 -20.3 -51.2 -58.6 -58.5 -57.8 -53.1 12.6 - {0x0C, 11}, // C -21.4 -51.8 -58.4 -58.5 -57.7 -53.4 12.5 - {0x0A, 13}, // A -22.7 -52.6 -58.5 -58.4 -57.7 -53.6 12.4 - {0x08, 16}, // 8 -24.3 -53.6 -58.4 -58.4 -57.6 -54.1 12.3 - {0x13, 19}, // 13 -26.2 -54.6 -58.4 -58.5 -57.7 -54.3 12.2 - {0x05, 11}, // 5 -27.3 -55.3 -58.4 -58.4 -57.8 -54.5 12.1 - {0x12, 13}, // 12 -28.6 -55.9 -58.6 -58.5 -57.7 -54.7 12.1 - {0x03, 12}, // 3 -29.8 -56.9 -58.5 -58.4 -57.7 -54.7 12.0 -}; -/* -static const PowerTableItem PA_TABLE_315_FULL[] = { - {0xC0, 4}, // C0 10.6 -35.3 -44.4 -57.8 -53.8 -58.3 -57.2 -57.8 -56.7 28.5 - {0xC1, 2}, // C1 10.3 -36.6 -44.7 -58.4 -54.0 -58.5 -57.4 -58.0 -56.8 27.6 - {0xC2, 4}, // C2 9.9 -37.8 -45.0 -58.8 -54.1 -59.0 -57.3 -58.3 -56.9 26.9 - {0xC3, 3}, // C3 9.6 -39.2 -45.3 -59.0 -54.2 -59.0 -57.5 -58.3 -57.2 26.2 - {0xC4, 4}, // C4 9.2 -40.5 -45.7 -59.1 -54.5 -58.9 -57.5 -58.4 -57.2 25.6 - {0xC5, 3}, // C5 8.8 -41.9 -46.0 -59.2 -54.6 -58.9 -57.6 -58.4 -57.3 25.0 - {0xC6, 3}, // C6 8.5 -43.2 -46.3 -59.2 -54.7 -59.1 -57.7 -58.3 -57.4 24.4 - {0xC7, 3}, // C7 8.2 -44.5 -46.6 -59.2 -55.0 -59.1 -57.9 -58.3 -57.3 23.9 - {0xC8, 2}, // C8 7.9 -45.7 -47.0 -59.1 -55.0 -59.1 -57.9 -58.4 -57.3 23.4 - {0xC9, 4}, // C9 7.5 -47.0 -47.3 -58.9 -55.0 -59.0 -57.9 -58.4 -57.5 23.0 - {0xCA, 2}, // CA 7.2 -48.0 -47.7 -58.8 -55.0 -59.0 -57.8 -58.4 -57.7 22.5 - {0xCB, 2}, // CB 6.9 -49.1 -47.9 -58.7 -55.4 -58.9 -58.1 -58.3 -57.6 22.1 - {0xCC, 3}, // CC 6.6 -50.0 -48.3 -58.7 -55.3 -59.0 -58.1 -58.4 -57.8 21.7 - {0x80, 0}, // 80 6.6 -46.9 -45.4 -56.3 -53.7 -59.0 -55.8 -56.3 -57.5 19.8 - {0x81, 2}, // 81 6.3 -49.2 -45.7 -57.3 -53.6 -59.0 -56.0 -56.5 -57.5 19.5 - {0xCD, 0}, // CD 6.3 -50.9 -48.6 -58.4 -55.5 -58.9 -58.0 -58.1 -57.8 21.3 - {0x82, 2}, // 82 6.0 -52.0 -46.2 -58.1 -53.8 -58.9 -56.4 -57.1 -57.7 19.2 - {0x83, 2}, // 83 5.8 -53.7 -46.5 -58.7 -53.8 -59.0 -56.6 -57.3 -57.8 18.9 - {0xCE, 2}, // CE 5.6 -51.9 -49.2 -58.2 -55.5 -58.9 -58.1 -58.3 -57.9 20.6 - {0x84, 1}, // 84 5.4 -53.0 -46.8 -59.5 -54.0 -59.0 -56.9 -57.5 -57.8 18.6 - {0x85, 4}, // 85 5.0 -51.0 -47.2 -59.8 -54.2 -59.0 -56.9 -57.9 -58.0 18.3 - {0x86, 2}, // 86 4.7 -49.3 -47.5 -60.0 -54.4 -59.0 -57.1 -58.0 -58.1 18.0 - {0x87, 4}, // 87 4.3 -47.8 -47.8 -60.0 -54.6 -59.0 -57.2 -58.2 -58.1 17.7 - {0x88, 3}, // 88 3.9 -46.6 -48.1 -60.0 -55.0 -58.9 -57.5 -58.2 -58.2 17.4 - {0x89, 3}, // 89 3.5 -45.8 -48.4 -59.9 -55.2 -58.9 -57.7 -58.3 -58.3 17.0 - {0x8A, 3}, // 8A 3.1 -45.0 -48.7 -59.9 -55.3 -59.0 -57.8 -58.2 -58.3 16.7 - {0xCF, 3}, // CF 2.8 -49.8 -51.3 -57.6 -56.8 -59.1 -58.4 -58.1 -58.3 18.0 - {0x8B, 0}, // 8B 2.7 -44.5 -48.9 -59.6 -55.8 -58.9 -57.7 -58.5 -58.3 16.4 - {0x8C, 5}, // 8C 2.2 -44.1 -49.2 -59.0 -56.1 -58.9 -57.9 -58.3 -58.4 16.1 - {0x8D, 5}, // 8D 1.7 -43.8 -49.5 -58.9 -56.3 -58.8 -58.2 -58.4 -58.5 15.8 - {0x50, 10}, // 50 0.7 -59.2 -51.2 -59.0 -56.5 -59.0 -58.3 -58.3 -58.2 15.3 - {0x8E, 0}, // 8E 0.6 -43.7 -50.0 -58.7 -56.7 -58.9 -58.3 -58.3 -58.5 15.2 - {0x60, 0}, // 60 0.5 -59.9 -51.3 -59.0 -56.6 -59.1 -58.2 -58.4 -58.4 15.2 - {0x51, 4}, // 51 0.1 -58.9 -51.6 -59.2 -56.8 -59.0 -58.4 -58.5 -58.4 15.0 - {0x61, 2}, // 61 -0.1 -59.3 -51.7 -59.2 -56.7 -59.0 -58.5 -58.4 -58.4 14.8 - {0x40, 1}, // 40 -0.3 -58.2 -52.1 -59.4 -56.9 -59.0 -58.4 -58.4 -58.3 14.7 - {0x52, 2}, // 52 -0.5 -58.2 -52.1 -59.3 -56.7 -58.8 -58.4 -58.4 -58.5 14.6 - {0x62, 1}, // 62 -0.7 -58.8 -52.3 -59.3 -57.0 -59.0 -58.4 -58.4 -58.3 14.5 - {0x3F, 1}, // 3F -0.8 -57.0 -48.3 -59.9 -57.3 -59.1 -58.3 -58.4 -58.5 20.5 - {0x3E, 1}, // 3E -1.0 -55.9 -48.4 -59.8 -57.4 -59.1 -58.4 -58.5 -58.3 19.9 - {0x53, 1}, // 53 -1.1 -57.6 -52.7 -59.3 -57.1 -59.1 -58.6 -58.4 -58.4 14.3 - {0x3D, 1}, // 3D -1.3 -54.4 -48.4 -59.8 -57.5 -58.9 -58.3 -58.5 -58.5 19.3 - {0x63, 0}, // 63 -1.3 -58.0 -52.8 -59.5 -57.3 -59.1 -58.5 -58.3 -58.4 14.2 - {0x3C, 3}, // 3C -1.7 -53.2 -48.6 -59.9 -57.6 -59.0 -58.4 -58.4 -58.5 18.6 - {0x54, 0}, // 54 -1.7 -57.2 -53.2 -59.3 -57.3 -59.0 -58.5 -58.3 -58.4 14.0 - {0x64, 1}, // 64 -1.9 -57.4 -53.3 -59.5 -57.4 -59.0 -58.5 -58.2 -58.3 13.9 - {0x3B, 2}, // 3B -2.1 -52.2 -48.7 -59.8 -57.7 -59.2 -58.5 -58.4 -58.5 18.0 - {0x55, 1}, // 55 -2.3 -56.7 -53.6 -59.7 -57.5 -59.1 -58.7 -58.4 -58.4 13.7 - {0x65, 2}, // 65 -2.5 -57.1 -53.7 -59.7 -57.7 -59.0 -58.7 -58.4 -58.4 13.7 - {0x2F, 1}, // 2F -2.6 -51.5 -48.7 -60.0 -57.9 -59.0 -58.4 -58.3 -58.3 17.3 - {0x3A, 1}, // 3A -2.7 -51.4 -49.1 -59.8 -57.8 -59.1 -58.5 -58.4 -58.4 17.4 - {0x56, 2}, // 56 -3.0 -56.6 -54.1 -59.7 -57.7 -58.9 -58.8 -58.4 -58.5 13.5 - {0x2E, 1}, // 2E -3.1 -51.3 -49.1 -60.0 -57.9 -59.0 -58.6 -58.3 -58.4 16.9 - {0x66, 0}, // 66 -3.1 -56.9 -54.3 -59.7 -57.8 -58.9 -58.8 -58.4 -58.4 13.4 - {0x39, 2}, // 39 -3.4 -50.9 -49.5 -59.8 -58.0 -59.0 -58.5 -58.4 -58.4 16.8 - {0x57, 1}, // 57 -3.5 -56.6 -54.4 -59.8 -57.9 -59.0 -58.7 -58.3 -58.4 13.3 - {0x2D, 1}, // 2D -3.6 -51.1 -49.4 -60.0 -58.1 -59.1 -58.6 -58.5 -58.4 16.4 - {0x67, 1}, // 67 -3.7 -56.8 -54.7 -59.9 -58.0 -59.0 -58.8 -58.4 -58.3 13.2 - {0x8F, 5}, // 8F -4.2 -45.9 -52.6 -58.4 -58.5 -59.0 -58.8 -58.3 -58.6 13.3 - {0x2C, 0}, // 2C -4.2 -51.0 -49.8 -60.0 -58.0 -59.0 -58.6 -58.4 -58.4 16.0 - {0x38, 0}, // 38 -4.3 -50.7 -50.2 -59.8 -58.0 -59.0 -58.6 -58.3 -58.5 16.1 - {0x68, 0}, // 68 -4.3 -56.9 -55.1 -59.7 -58.0 -59.0 -58.9 -58.5 -58.5 13.0 - {0x2B, 6}, // 2B -4.9 -51.2 -50.4 -59.9 -58.0 -58.9 -58.7 -58.3 -58.4 15.6 - {0x69, 0}, // 69 -4.9 -56.9 -55.5 -59.9 -58.3 -59.1 -58.9 -58.3 -58.5 12.8 - {0x37, 5}, // 37 -5.4 -51.3 -50.5 -60.0 -58.3 -59.1 -58.7 -58.4 -58.4 15.4 - {0x6A, 0}, // 6A -5.5 -56.9 -56.1 -59.8 -58.3 -59.0 -58.8 -58.4 -58.5 12.6 - {0x2A, 2}, // 2A -5.7 -51.5 -51.1 -60.0 -58.4 -59.1 -58.7 -58.3 -58.6 15.2 - {0x6B, 3}, // 6B -6.1 -57.0 -56.5 -59.9 -58.5 -59.0 -58.9 -58.3 -58.6 12.5 - {0x29, 4}, // 29 -6.5 -51.8 -51.6 -59.9 -58.4 -59.0 -58.8 -58.3 -58.3 14.7 - {0x6C, 2}, // 6C -6.7 -57.0 -57.0 -59.9 -58.5 -59.1 -58.9 -58.5 -58.4 12.3 - {0x36, 0}, // 36 -6.7 -51.9 -51.5 -60.0 -58.2 -59.0 -58.8 -58.4 -58.4 14.7 - {0x6D, 5}, // 6D -7.2 -57.3 -57.1 -60.0 -58.6 -58.9 -58.8 -58.4 -58.3 12.2 - {0x28, 2}, // 28 -7.5 -52.2 -52.5 -60.0 -58.6 -59.0 -58.8 -58.2 -58.4 14.3 - {0x35, 5}, // 35 -8.1 -52.7 -52.7 -60.0 -58.7 -59.0 -58.9 -58.3 -58.5 14.1 - {0x6E, 3}, // 6E -8.4 -58.0 -57.9 -60.0 -58.6 -59.1 -58.9 -58.3 -58.5 11.9 - {0x27, 1}, // 27 -8.6 -52.9 -53.1 -60.0 -58.8 -59.1 -58.8 -58.3 -58.5 13.9 - {0x26, 12}, // 26 -9.8 -53.6 -54.3 -60.1 -58.7 -59.0 -58.7 -58.4 -58.4 13.4 - {0x34, 0}, // 34 -9.9 -53.7 -54.4 -59.9 -58.8 -59.0 -58.7 -58.3 -58.4 13.5 - {0x25, 11}, // 25 -11.1 -54.3 -55.5 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 13.0 - {0x33, 10}, // 33 -12.2 -55.0 -56.3 -60.0 -58.7 -59.0 -58.9 -58.4 -58.4 12.8 - {0x24, 8}, // 24 -13.0 -55.4 -56.9 -60.1 -58.7 -59.1 -59.0 -58.3 -58.5 12.6 - {0x6F, 1}, // 6F -13.2 -58.3 -60.7 -59.8 -58.7 -59.1 -58.9 -58.3 -58.5 11.2 - {0x1F, 1}, // 1F -13.3 -55.6 -57.2 -60.0 -58.8 -58.9 -58.9 -58.3 -58.4 12.4 - {0x1E, 5}, // 1E -13.9 -55.8 -57.4 -60.0 -58.6 -59.1 -58.9 -58.4 -58.5 12.2 - {0x1D, 5}, // 1D -14.5 -56.0 -58.0 -60.0 -58.8 -59.1 -58.7 -58.4 -58.5 12.1 - {0x1C, 6}, // 1C -15.2 -56.3 -58.3 -60.1 -58.9 -58.9 -58.8 -58.3 -58.4 12.0 - {0x23, 2}, // 23 -15.4 -56.8 -58.3 -60.1 -58.7 -59.0 -58.8 -58.3 -58.5 12.1 - {0x32, 1}, // 32 -15.6 -56.9 -58.8 -59.9 -58.8 -59.0 -58.8 -58.3 -58.5 12.2 - {0x1B, 3}, // 1B -15.9 -56.8 -58.9 -60.0 -58.8 -59.1 -58.7 -58.5 -58.5 11.9 - {0x1A, 7}, // 1A -16.6 -57.3 -59.5 -59.9 -58.8 -59.1 -58.8 -58.4 -58.4 11.8 - {0x19, 8}, // 19 -17.5 -57.5 -59.6 -60.0 -58.7 -59.0 -58.9 -58.3 -58.5 11.7 - {0x18, 10}, // 18 -18.5 -57.8 -60.3 -60.0 -58.8 -59.0 -58.9 -58.2 -58.5 11.6 - {0x22, 3}, // 22 -18.8 -58.4 -60.6 -59.9 -58.7 -59.1 -58.9 -58.5 -58.5 11.7 - {0x0F, 0}, // F -18.8 -58.3 -60.5 -59.8 -58.7 -59.1 -58.9 -58.2 -58.4 11.5 - {0x0E, 5}, // E -19.4 -58.6 -60.9 -59.9 -58.6 -58.9 -58.9 -58.3 -58.5 11.4 - {0x17, 2}, // 17 -19.6 -58.7 -60.9 -60.0 -58.7 -58.9 -58.9 -58.5 -58.4 11.4 - {0x0D, 3}, // D -20.0 -58.8 -61.0 -60.0 -58.8 -59.0 -58.8 -58.5 -58.4 11.4 - {0x0C, 6}, // C -20.7 -59.4 -61.1 -60.0 -58.8 -59.1 -58.9 -58.4 -58.3 11.3 - {0x16, 1}, // 16 -20.9 -59.4 -61.4 -59.9 -58.8 -59.1 -58.9 -58.4 -58.3 11.3 - {0x31, 4}, // 31 -21.3 -59.2 -61.5 -60.0 -58.6 -59.1 -58.9 -58.3 -58.5 11.5 - {0x0B, 0}, // B -21.4 -59.3 -61.8 -60.0 -58.8 -58.9 -58.9 -58.4 -58.5 11.3 - {0x0A, 8}, // A -22.2 -59.9 -61.9 -60.0 -58.9 -59.0 -58.9 -58.4 -58.5 11.2 - {0x15, 1}, // 15 -22.4 -59.9 -62.3 -60.1 -58.6 -59.1 -59.1 -58.3 -58.4 11.2 - {0x09, 6}, // 9 -23.0 -60.3 -62.0 -59.9 -58.7 -59.0 -58.8 -58.4 -58.5 11.1 - {0x08, 10}, // 8 -24.0 -60.5 -62.5 -60.0 -58.7 -59.1 -58.8 -58.3 -58.5 11.1 - {0x14, 3}, // 14 -24.3 -60.6 -62.7 -60.0 -58.9 -59.2 -58.9 -58.2 -58.4 11.1 - {0x21, 1}, // 21 -24.5 -60.7 -62.4 -59.9 -58.9 -58.9 -58.8 -58.3 -58.5 11.2 - {0x07, 6}, // 7 -25.1 -61.3 -62.9 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 11.0 - {0x06, 12}, // 6 -26.4 -61.6 -63.2 -60.1 -58.7 -59.0 -58.9 -58.5 -58.5 11.0 - {0x13, 2}, // 13 -26.6 -61.8 -63.1 -59.9 -58.7 -59.1 -58.8 -58.4 -58.6 11.0 - {0x05, 10}, // 5 -27.7 -62.3 -63.4 -60.1 -58.7 -59.2 -58.8 -58.4 -58.5 10.9 - {0x04, 19}, // 4 -29.6 -62.7 -63.6 -59.9 -58.7 -59.0 -58.9 -58.4 -58.4 10.8 - {0x12, 1}, // 12 -29.8 -62.8 -63.5 -60.0 -58.7 -59.1 -58.8 -58.3 -58.6 10.9 - {0x03, 18}, // 3 -31.7 -63.4 -63.9 -60.1 -58.8 -59.1 -58.7 -58.3 -58.5 10.8 - {0x02, 29}, // 2 -34.6 -64.0 -64.0 -59.9 -58.7 -58.9 -58.8 -58.4 -58.6 10.7 - {0x11, 0}, // 11 -34.6 -64.0 -64.0 -59.9 -58.7 -59.0 -58.9 -58.3 -58.4 10.8 - {0x01, 36}, // 1 -38.3 -64.9 -63.9 -60.0 -58.9 -58.9 -58.9 -58.4 -58.5 10.7 - {0x10, 29}, // 10 -41.2 -65.3 -64.0 -59.9 -58.6 -59.0 -58.9 -58.4 -58.5 10.6 - {0x30, 0}, // 30 -41.3 -65.5 -63.9 -60.0 -58.7 -59.1 -58.8 -58.4 -58.6 10.9 - {0x20, 0}, // 20 -41.3 -65.3 -64.0 -60.1 -58.8 -59.1 -58.9 -58.4 -58.3 10.8 - {0x00, 225}, // 0 -63.8 -65.4 -64.0 -59.9 -58.9 -58.9 -58.8 -58.3 -58.5 10.3 -}; - -static const PowerTableItem PA_TABLE_433_FULL[] = { - {0xC0, 10}, // C0 9.9 -43.4 -45.0 -53.9 -55.2 -55.8 -52.3 -55.6 29.1 - {0xC1, 4}, // C1 9.5 -45.2 -45.3 -54.6 -55.2 -56.5 -52.5 -56.5 28.3 - {0xC2, 3}, // C2 9.2 -47.1 -45.5 -55.2 -55.1 -56.9 -52.4 -57.1 27.6 - {0xC3, 3}, // C3 8.8 -49.3 -45.9 -55.9 -55.4 -57.2 -52.6 -57.5 26.9 - {0xC4, 3}, // C4 8.5 -51.8 -46.2 -56.3 -55.3 -57.7 -52.9 -57.9 26.3 - {0xC5, 4}, // C5 8.1 -54.6 -46.5 -56.6 -55.4 -58.1 -53.2 -57.9 25.7 - {0xC6, 2}, // C6 7.8 -56.2 -46.9 -56.9 -55.6 -58.2 -53.2 -57.9 25.2 - {0xC7, 3}, // C7 7.4 -57.0 -47.2 -57.0 -55.7 -58.3 -53.5 -57.6 24.7 - {0xC8, 3}, // C8 7.1 -57.4 -47.6 -57.2 -55.9 -58.4 -53.5 -57.2 24.2 - {0xC9, 2}, // C9 6.8 -56.1 -47.9 -57.3 -55.9 -58.5 -54.0 -56.9 23.8 - {0xCA, 3}, // CA 6.4 -54.9 -48.3 -57.2 -56.1 -58.6 -54.2 -56.7 23.4 - {0x80, 1}, // 80 6.3 -50.3 -51.7 -57.7 -53.8 -56.4 -56.3 -57.1 20.6 - {0xCB, 2}, // CB 6.1 -53.8 -48.6 -57.0 -56.1 -58.5 -54.3 -56.7 23.0 - {0x81, 0}, // 81 6.0 -51.4 -52.0 -58.0 -54.0 -56.6 -56.1 -57.4 20.3 - {0xCC, 2}, // CC 5.8 -52.8 -48.9 -57.0 -56.1 -58.4 -54.6 -56.2 22.6 - {0x82, 0}, // 82 5.8 -52.3 -52.1 -58.2 -54.2 -57.0 -56.3 -57.5 20.0 - {0xCD, 2}, // CD 5.5 -52.1 -49.2 -56.9 -56.2 -58.2 -54.8 -56.2 22.3 - {0x83, 0}, // 83 5.5 -53.0 -52.5 -58.3 -54.4 -57.4 -56.4 -57.8 19.7 - {0x84, 4}, // 84 5.1 -53.7 -52.9 -58.1 -54.6 -57.5 -56.6 -57.9 19.4 - {0xCE, 1}, // CE 4.9 -50.6 -49.9 -56.6 -56.3 -58.4 -55.4 -55.8 21.6 - {0x85, 1}, // 85 4.8 -54.2 -53.0 -58.3 -55.0 -57.8 -56.8 -58.0 19.1 - {0x86, 3}, // 86 4.4 -54.9 -53.1 -58.2 -55.1 -57.8 -56.9 -58.1 18.8 - {0x87, 4}, // 87 4.0 -55.6 -53.5 -58.2 -55.3 -58.1 -56.9 -58.2 18.5 - {0x88, 3}, // 88 3.6 -56.2 -53.8 -58.3 -55.7 -58.1 -57.2 -58.2 18.2 - {0x89, 3}, // 89 3.2 -56.8 -53.9 -58.2 -55.8 -58.1 -57.3 -58.0 17.9 - {0x8A, 4}, // 8A 2.8 -57.4 -54.1 -58.2 -56.0 -58.3 -57.7 -58.1 17.6 - {0x8B, 5}, // 8B 2.3 -57.7 -54.5 -58.0 -56.3 -58.1 -57.5 -58.2 17.3 - {0xCF, 2}, // CF 2.0 -48.3 -52.4 -56.0 -57.0 -57.7 -57.3 -56.4 19.3 - {0x8C, 1}, // 8C 1.9 -58.2 -54.7 -58.1 -56.7 -58.3 -58.0 -58.2 17.1 - {0x8D, 5}, // 8D 1.4 -58.4 -54.9 -58.0 -56.8 -58.2 -58.2 -58.1 16.8 - {0x8E, 9}, // 8E 0.4 -58.0 -55.5 -57.8 -57.4 -58.2 -58.1 -58.4 16.2 - {0x50, 0}, // 50 0.4 -59.0 -55.2 -58.2 -57.4 -58.4 -57.8 -58.4 16.0 - {0x60, 3}, // 60 0.1 -59.1 -55.4 -58.1 -57.4 -58.4 -57.7 -58.3 15.9 - {0x51, 4}, // 51 -0.3 -59.2 -55.8 -58.2 -57.5 -58.4 -57.9 -58.3 15.7 - {0x61, 2}, // 61 -0.5 -59.3 -55.8 -58.2 -57.8 -58.3 -58.1 -58.3 15.6 - {0x40, 3}, // 40 -0.8 -59.7 -56.1 -58.2 -57.7 -58.4 -58.3 -58.2 15.4 - {0x52, 0}, // 52 -0.9 -59.6 -56.1 -58.3 -57.7 -58.3 -58.3 -58.3 15.3 - {0x3F, 2}, // 3F -1.1 -61.3 -56.9 -58.2 -57.9 -58.5 -58.2 -58.6 21.1 - {0x62, 0}, // 62 -1.1 -59.6 -56.2 -58.2 -57.8 -58.4 -58.2 -58.3 15.3 - {0x3E, 2}, // 3E -1.4 -61.4 -57.0 -58.3 -57.9 -58.5 -58.2 -58.5 20.5 - {0x53, 1}, // 53 -1.5 -59.7 -56.5 -58.3 -57.9 -58.4 -58.1 -58.3 15.0 - {0x3D, 1}, // 3D -1.7 -61.1 -57.2 -58.3 -57.9 -58.6 -58.3 -58.5 19.9 - {0x63, 0}, // 63 -1.7 -59.8 -56.7 -58.3 -57.9 -58.4 -58.4 -58.3 15.0 - {0x3C, 4}, // 3C -2.1 -60.6 -57.3 -58.2 -58.0 -58.5 -58.4 -58.5 19.3 - {0x54, 1}, // 54 -2.2 -60.0 -56.8 -58.3 -58.1 -58.5 -58.4 -58.5 14.8 - {0x64, 0}, // 64 -2.3 -60.1 -57.0 -58.2 -58.2 -58.5 -58.6 -58.5 14.7 - {0x3B, 2}, // 3B -2.5 -60.4 -57.5 -58.3 -58.1 -58.5 -58.2 -58.5 18.7 - {0x55, 2}, // 55 -2.8 -60.3 -57.2 -58.3 -58.2 -58.3 -58.4 -58.6 14.5 - {0x65, 1}, // 65 -2.9 -60.2 -57.2 -58.3 -58.3 -58.4 -58.4 -58.4 14.5 - {0x2F, 1}, // 2F -3.0 -58.4 -57.6 -58.3 -58.1 -58.6 -58.4 -58.5 17.9 - {0x3A, 1}, // 3A -3.1 -59.5 -57.5 -58.3 -58.3 -58.6 -58.1 -58.6 18.1 - {0x56, 1}, // 56 -3.3 -60.2 -57.5 -58.4 -58.6 -58.5 -58.4 -58.3 14.3 - {0x2E, 2}, // 2E -3.5 -58.0 -57.8 -58.3 -58.4 -58.3 -58.3 -58.5 17.5 - {0x66, 0}, // 66 -3.5 -60.3 -57.6 -58.2 -58.4 -58.3 -58.5 -58.5 14.2 - {0x39, 2}, // 39 -3.8 -58.7 -57.8 -58.3 -58.3 -58.4 -58.4 -58.5 17.5 - {0x57, 2}, // 57 -4.0 -60.3 -57.7 -58.4 -58.4 -58.4 -58.7 -58.4 14.1 - {0x2D, 0}, // 2D -4.0 -57.6 -58.0 -58.2 -58.5 -58.4 -58.6 -58.5 17.1 - {0x67, 0}, // 67 -4.1 -60.1 -57.8 -58.1 -58.6 -58.4 -58.7 -58.6 14.0 - {0x8F, 5}, // 8F -4.6 -52.2 -57.7 -58.1 -58.8 -58.4 -58.7 -58.3 14.4 - {0x2C, 1}, // 2C -4.7 -57.4 -58.3 -58.3 -58.7 -58.5 -58.5 -58.5 16.7 - {0x38, 0}, // 38 -4.7 -58.2 -58.0 -58.3 -58.6 -58.4 -58.5 -58.5 16.9 - {0x68, 0}, // 68 -4.7 -60.4 -57.8 -58.4 -58.7 -58.4 -58.7 -58.5 13.8 - {0x2B, 5}, // 2B -5.3 -57.0 -58.7 -58.4 -58.6 -58.4 -58.5 -58.5 16.3 - {0x69, 0}, // 69 -5.3 -60.6 -58.4 -58.3 -58.8 -58.4 -58.7 -58.5 13.6 - {0x37, 2}, // 37 -5.6 -56.8 -58.3 -58.3 -58.8 -58.4 -58.5 -58.4 16.2 - {0x6A, 3}, // 6A -5.9 -60.8 -58.6 -58.3 -58.7 -58.5 -58.6 -58.5 13.5 - {0x2A, 0}, // 2A -6.0 -56.8 -58.6 -58.4 -58.8 -58.4 -58.6 -58.3 15.9 - {0x6B, 5}, // 6B -6.5 -60.5 -58.9 -58.3 -58.6 -58.5 -58.7 -58.3 13.3 - {0x36, 2}, // 36 -6.8 -56.8 -58.9 -58.3 -58.8 -58.3 -58.5 -58.5 15.6 - {0x29, 1}, // 29 -6.9 -56.7 -58.9 -58.1 -58.6 -58.5 -58.6 -58.5 15.5 - {0x6C, 1}, // 6C -7.1 -60.5 -58.9 -58.2 -58.9 -58.5 -58.6 -58.6 13.2 - {0x6D, 6}, // 6D -7.7 -60.4 -59.2 -58.4 -59.0 -58.5 -58.6 -58.5 13.0 - {0x28, 0}, // 28 -7.8 -56.6 -59.0 -58.2 -59.0 -58.4 -58.5 -58.4 15.1 - {0x35, 5}, // 35 -8.3 -56.8 -59.1 -58.4 -58.9 -58.5 -58.6 -58.5 15.0 - {0x27, 3}, // 27 -8.7 -56.8 -59.2 -58.2 -58.9 -58.5 -58.6 -58.4 14.7 - {0x6E, 2}, // 6E -8.9 -60.2 -59.3 -58.3 -58.8 -58.5 -58.7 -58.5 12.8 - {0x26, 10}, // 26 -9.9 -57.0 -59.4 -58.3 -59.0 -58.4 -58.7 -58.4 14.3 - {0x34, 1}, // 34 -10.1 -57.0 -59.4 -58.4 -58.9 -58.3 -58.7 -58.5 14.4 - {0x25, 13}, // 25 -11.4 -57.3 -59.7 -58.4 -59.0 -58.3 -58.7 -58.5 13.9 - {0x33, 9}, // 33 -12.3 -57.8 -59.8 -58.4 -58.9 -58.3 -58.7 -58.6 13.8 - {0x24, 10}, // 24 -13.3 -57.9 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 13.5 - {0x1F, 3}, // 1F -13.7 -57.9 -59.9 -58.4 -59.0 -58.5 -58.7 -58.5 13.3 - {0x1E, 6}, // 1E -14.3 -58.4 -59.8 -58.2 -59.0 -58.4 -58.6 -58.6 13.2 - {0x1D, 5}, // 1D -14.9 -58.6 -59.8 -58.3 -59.0 -58.5 -58.7 -58.5 13.1 - {0x6F, 5}, // 6F -15.5 -59.1 -59.9 -58.3 -59.1 -58.5 -58.7 -58.6 12.4 - {0x1C, 0}, // 1C -15.5 -58.6 -59.9 -58.4 -58.8 -58.6 -58.8 -58.5 12.9 - {0x23, 0}, // 23 -15.6 -59.0 -59.9 -58.1 -59.0 -58.4 -58.6 -58.5 13.1 - {0x32, 0}, // 32 -15.7 -59.0 -59.8 -58.2 -58.8 -58.5 -58.6 -58.5 13.1 - {0x1B, 5}, // 1B -16.2 -59.1 -59.9 -58.3 -59.0 -58.5 -58.6 -58.4 12.8 - {0x1A, 8}, // 1A -17.0 -59.4 -59.9 -58.3 -59.1 -58.5 -58.7 -58.4 12.7 - {0x19, 8}, // 19 -17.8 -59.7 -59.9 -58.3 -59.0 -58.4 -58.6 -58.5 12.6 - {0x18, 10}, // 18 -18.8 -60.2 -59.9 -58.2 -59.0 -58.5 -58.7 -58.6 12.5 - {0x22, 1}, // 22 -19.0 -60.4 -59.9 -58.3 -59.0 -58.5 -58.6 -58.5 12.6 - {0x0F, 3}, // F -19.3 -60.4 -59.8 -58.4 -59.0 -58.6 -58.6 -58.5 12.4 - {0x17, 5}, // 17 -19.8 -60.6 -59.9 -58.2 -58.9 -58.4 -58.7 -58.4 12.4 - {0x0E, 0}, // E -19.8 -60.5 -59.9 -58.3 -59.1 -58.5 -58.8 -58.6 12.4 - {0x0D, 5}, // D -20.4 -60.7 -60.0 -58.4 -59.0 -58.5 -58.5 -58.5 12.3 - {0x0C, 6}, // C -21.0 -61.1 -59.9 -58.4 -59.0 -58.5 -58.7 -58.6 12.3 - {0x16, 0}, // 16 -21.0 -61.2 -59.9 -58.3 -59.1 -58.5 -58.7 -58.4 12.3 - {0x31, 3}, // 31 -21.3 -61.3 -60.0 -58.3 -59.0 -58.5 -58.7 -58.5 12.5 - {0x0B, 3}, // B -21.7 -61.3 -59.9 -58.2 -58.9 -58.5 -58.8 -58.4 12.2 - {0x15, 8}, // 15 -22.5 -61.7 -60.0 -58.2 -59.1 -58.3 -58.6 -58.7 12.2 - {0x0A, 0}, // A -22.5 -61.8 -60.0 -58.2 -58.9 -58.6 -58.6 -58.6 12.2 - {0x09, 8}, // 9 -23.3 -61.8 -60.0 -58.2 -59.0 -58.6 -58.6 -58.4 12.1 - {0x08, 10}, // 8 -24.3 -62.3 -59.9 -58.3 -59.0 -58.4 -58.8 -58.5 12.1 - {0x14, 0}, // 14 -24.3 -62.1 -59.9 -58.4 -59.1 -58.5 -58.7 -58.5 12.1 - {0x21, 1}, // 21 -24.5 -62.4 -59.9 -58.3 -59.1 -58.4 -58.6 -58.4 12.2 - {0x07, 8}, // 7 -25.3 -62.6 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 12.0 - {0x06, 11}, // 6 -26.5 -63.2 -59.9 -58.3 -58.9 -58.5 -58.6 -58.6 12.0 - {0x13, 0}, // 13 -26.5 -63.0 -59.8 -58.3 -59.0 -58.4 -58.7 -58.4 12.0 - {0x05, 13}, // 5 -27.9 -63.5 -59.8 -58.3 -59.1 -58.5 -58.7 -58.4 11.9 - {0x04, 16}, // 4 -29.5 -63.7 -59.9 -58.3 -58.9 -58.5 -58.5 -58.5 11.9 - {0x12, 1}, // 12 -29.6 -63.6 -59.7 -58.3 -59.1 -58.6 -58.6 -58.5 11.9 - {0x03, 17}, // 3 -31.4 -64.2 -60.1 -58.4 -59.0 -58.6 -58.8 -58.6 11.8 - {0x11, 23}, // 11 -33.8 -64.3 -59.9 -58.3 -58.9 -58.6 -58.6 -58.5 11.8 - {0x02, 0}, // 2 -33.8 -64.4 -59.9 -58.3 -59.1 -58.4 -58.8 -58.6 11.7 - {0x01, 27}, // 1 -36.5 -64.2 -59.9 -58.4 -59.0 -58.6 -58.6 -58.5 11.7 - {0x10, 17}, // 10 -38.3 -64.4 -59.9 -58.4 -59.0 -58.5 -58.8 -58.5 11.7 - {0x20, 0}, // 20 -38.3 -64.6 -59.9 -58.3 -59.0 -58.6 -58.7 -58.5 11.8 - {0x30, 1}, // 30 -38.4 -64.4 -59.9 -58.3 -59.1 -58.5 -58.7 -58.6 11.9 - {0x00, 243}, // 0 -62.7 -64.5 -59.8 -58.2 -58.9 -58.5 -58.7 -58.6 11.3 -}; - -static const PowerTableItem PA_TABLE_868_FULL[] = { - {0xC0, 3}, // C0 10.7 -35.1 -58.6 -58.6 -57.5 -50.0 34.2 - {0xC1, 3}, // C1 10.3 -37.0 -58.5 -58.6 -57.5 -51.4 33.3 - {0xC2, 3}, // C2 10.0 -39.2 -58.3 -58.5 -57.4 -53.2 32.4 - {0xC3, 4}, // C3 9.6 -41.5 -58.5 -58.3 -57.4 -54.4 31.6 - {0xC4, 4}, // C4 9.2 -44.0 -58.6 -58.5 -57.4 -55.2 30.9 - {0xC5, 2}, // C5 8.9 -46.2 -58.5 -58.6 -57.6 -55.4 30.2 - {0xC6, 4}, // C6 8.5 -47.7 -58.5 -58.3 -57.6 -55.0 29.5 - {0xC7, 3}, // C7 8.2 -47.3 -58.5 -58.5 -57.7 -54.5 28.9 - {0xC8, 3}, // C8 7.8 -45.9 -58.5 -58.4 -57.7 -54.1 28.3 - {0xC9, 2}, // C9 7.5 -44.4 -58.5 -58.5 -57.7 -53.6 27.8 - {0xCA, 2}, // CA 7.2 -42.9 -58.6 -58.4 -57.6 -53.2 27.3 - {0xCB, 4}, // CB 6.8 -41.7 -58.5 -58.4 -57.8 -52.8 26.8 - {0xCC, 2}, // CC 6.5 -40.6 -58.6 -58.4 -57.6 -52.5 26.3 - {0xCD, 2}, // CD 6.2 -39.8 -58.4 -58.6 -57.6 -52.3 25.9 - {0xCE, 7}, // CE 5.5 -38.5 -58.5 -58.4 -57.8 -52.2 25.0 - {0x80, 2}, // 80 5.2 -31.9 -58.5 -58.4 -57.8 -56.2 21.2 - {0x81, 2}, // 81 5.0 -32.6 -58.5 -58.6 -57.8 -56.2 21.0 - {0x82, 2}, // 82 4.8 -33.4 -58.4 -58.4 -57.7 -56.2 20.8 - {0x83, 2}, // 83 4.6 -34.3 -58.4 -58.5 -57.7 -56.1 20.5 - {0x84, 1}, // 84 4.4 -35.3 -58.7 -58.5 -57.8 -55.8 20.3 - {0x85, 3}, // 85 4.1 -36.5 -58.7 -58.6 -57.7 -55.8 20.0 - {0x86, 3}, // 86 3.7 -37.8 -58.6 -58.5 -57.8 -55.8 19.7 - {0x87, 3}, // 87 3.4 -39.4 -58.6 -58.6 -57.8 -55.7 19.5 - {0x88, 3}, // 88 3.0 -41.0 -58.5 -58.5 -57.7 -55.7 19.1 - {0x89, 3}, // 89 2.6 -43.0 -58.5 -58.6 -57.6 -55.8 18.8 - {0xCF, 2}, // CF 2.4 -36.6 -58.6 -58.4 -57.7 -53.6 22.0 - {0x8A, 2}, // 8A 2.1 -45.1 -58.5 -58.5 -57.6 -55.8 18.5 - {0x8B, 4}, // 8B 1.7 -47.5 -58.5 -58.4 -57.8 -55.8 18.2 - {0x8C, 5}, // 8C 1.1 -50.2 -58.6 -58.5 -57.7 -55.9 17.9 - {0x8D, 5}, // 8D 0.6 -52.6 -58.5 -58.5 -57.8 -55.8 17.6 - {0x50, 9}, // 50 -0.3 -42.1 -58.5 -58.5 -57.6 -57.1 16.9 - {0x60, 2}, // 60 -0.5 -42.3 -58.6 -58.5 -57.6 -57.2 16.8 - {0x8E, 0}, // 8E -0.5 -55.5 -58.5 -58.6 -57.7 -56.2 17.0 - {0x51, 4}, // 51 -0.9 -42.6 -58.6 -58.6 -57.6 -57.1 16.5 - {0x61, 2}, // 61 -1.1 -42.8 -58.3 -58.5 -57.6 -57.1 16.4 - {0x40, 3}, // 40 -1.5 -43.2 -58.5 -58.7 -57.7 -57.2 16.1 - {0x52, 1}, // 52 -1.6 -43.2 -58.5 -58.5 -57.7 -57.2 16.1 - {0x62, 1}, // 62 -1.8 -43.2 -58.4 -58.6 -57.7 -57.0 16.0 - {0x53, 4}, // 53 -2.3 -43.7 -58.6 -58.6 -57.7 -57.2 15.7 - {0x63, 1}, // 63 -2.4 -43.8 -58.6 -58.4 -57.6 -57.1 15.6 - {0x3F, 2}, // 3F -2.6 -53.7 -58.6 -58.5 -57.8 -57.5 21.4 - {0x3E, 1}, // 3E -2.8 -54.2 -58.6 -58.5 -57.7 -57.5 20.8 - {0x54, 1}, // 54 -2.9 -44.4 -58.5 -58.6 -57.8 -57.4 15.3 - {0x64, 2}, // 64 -3.1 -44.3 -58.6 -58.6 -57.7 -57.4 15.3 - {0x3D, 1}, // 3D -3.2 -54.7 -58.6 -58.5 -57.7 -57.5 20.2 - {0x3C, 2}, // 3C -3.5 -55.0 -58.6 -58.5 -57.7 -57.5 19.6 - {0x55, 1}, // 55 -3.6 -44.9 -58.6 -58.4 -57.8 -57.5 15.0 - {0x65, 1}, // 65 -3.7 -44.9 -58.6 -58.5 -57.7 -57.5 15.0 - {0x3B, 2}, // 3B -4.0 -55.0 -58.5 -58.5 -57.7 -57.3 19.0 - {0x56, 2}, // 56 -4.2 -45.4 -58.5 -58.5 -57.7 -57.5 14.7 - {0x66, 2}, // 66 -4.4 -45.4 -58.5 -58.5 -57.7 -57.4 14.7 - {0x2F, 0}, // 2F -4.5 -52.6 -58.6 -58.6 -57.6 -57.4 18.2 - {0x3A, 0}, // 3A -4.5 -54.1 -58.6 -58.5 -57.8 -57.5 18.4 - {0x57, 2}, // 57 -4.8 -46.0 -58.6 -58.5 -57.6 -57.4 14.5 - {0x2E, 1}, // 2E -4.9 -51.8 -58.6 -58.4 -57.7 -57.4 17.8 - {0x67, 0}, // 67 -5.0 -46.0 -58.5 -58.5 -57.8 -57.5 14.4 - {0x39, 2}, // 39 -5.2 -52.9 -58.6 -58.6 -57.7 -57.5 17.8 - {0x2D, 2}, // 2D -5.5 -50.9 -58.6 -58.5 -57.7 -57.4 17.4 - {0x68, 2}, // 68 -5.7 -46.6 -58.5 -58.5 -57.7 -57.5 14.2 - {0x8F, 2}, // 8F -6.0 -51.6 -58.5 -58.6 -57.7 -57.1 15.0 - {0x2C, 0}, // 2C -6.0 -50.3 -58.6 -58.5 -57.7 -57.3 17.0 - {0x38, 0}, // 38 -6.1 -51.8 -58.6 -58.5 -57.7 -57.3 17.1 - {0x69, 2}, // 69 -6.3 -47.3 -58.4 -58.6 -57.6 -57.5 14.0 - {0x2B, 4}, // 2B -6.7 -49.8 -58.5 -58.5 -57.7 -57.5 16.6 - {0x6A, 2}, // 6A -6.9 -48.1 -58.6 -58.5 -57.7 -57.5 13.8 - {0x37, 0}, // 37 -6.9 -49.5 -58.5 -58.5 -57.6 -57.3 16.4 - {0x2A, 5}, // 2A -7.4 -49.3 -58.5 -58.6 -57.7 -57.4 16.2 - {0x6B, 0}, // 6B -7.5 -49.5 -58.5 -58.6 -57.7 -57.4 13.8 - {0x36, 5}, // 36 -8.1 -49.0 -58.5 -58.5 -57.7 -57.3 15.8 - {0x29, 0}, // 29 -8.2 -49.1 -58.6 -58.5 -57.8 -57.4 15.8 - {0x6C, 5}, // 6C -8.7 -52.2 -58.6 -58.5 -57.6 -57.4 14.0 - {0x28, 3}, // 28 -9.0 -49.0 -58.5 -58.6 -57.7 -57.4 15.4 - {0x35, 4}, // 35 -9.4 -48.9 -58.5 -58.5 -57.8 -57.3 15.2 - {0x27, 4}, // 27 -9.8 -49.0 -58.5 -58.5 -57.7 -57.3 15.0 - {0x26, 11}, // 26 -11.0 -49.2 -58.5 -58.5 -57.7 -57.4 14.6 - {0x34, 0}, // 34 -11.1 -49.2 -58.6 -58.6 -57.7 -57.3 14.6 - {0x25, 14}, // 25 -12.5 -49.5 -58.6 -58.6 -57.8 -57.3 14.1 - {0x33, 8}, // 33 -13.3 -49.7 -58.6 -58.5 -57.8 -57.5 14.0 - {0x24, 10}, // 24 -14.3 -50.2 -58.5 -58.4 -57.8 -57.4 13.7 - {0x6D, 1}, // 6D -14.5 -55.3 -58.6 -58.5 -57.7 -57.5 14.7 - {0x1F, 0}, // 1F -14.6 -50.3 -58.6 -58.6 -57.7 -57.5 13.5 - {0x1E, 5}, // 1E -15.1 -50.6 -58.6 -58.5 -57.6 -57.4 13.4 - {0x1D, 5}, // 1D -15.7 -50.7 -58.6 -58.6 -57.8 -57.5 13.3 - {0x1C, 6}, // 1C -16.4 -51.1 -58.6 -58.4 -57.6 -57.3 13.2 - {0x23, 1}, // 23 -16.5 -51.0 -58.6 -58.6 -57.8 -57.4 13.3 - {0x32, 0}, // 32 -16.5 -51.0 -58.6 -58.5 -57.7 -57.4 13.4 - {0x1B, 5}, // 1B -17.0 -51.3 -58.5 -58.4 -57.7 -57.5 13.1 - {0x1A, 8}, // 1A -17.8 -51.6 -58.6 -58.5 -57.7 -57.3 13.0 - {0x19, 8}, // 19 -18.6 -52.0 -58.6 -58.5 -57.8 -57.5 12.9 - {0x18, 8}, // 18 -19.5 -52.6 -58.5 -58.5 -57.8 -57.4 12.8 - {0x22, 1}, // 22 -19.6 -52.5 -58.5 -58.6 -57.7 -57.4 12.9 - {0x0F, 3}, // F -20.0 -52.8 -58.5 -58.5 -57.7 -57.6 12.7 - {0x0E, 5}, // E -20.5 -53.0 -58.5 -58.6 -57.7 -57.6 12.7 - {0x17, 0}, // 17 -20.5 -52.9 -58.6 -58.6 -57.7 -57.5 12.7 - {0x0D, 6}, // D -21.1 -53.3 -58.6 -58.6 -57.8 -57.4 12.6 - {0x0C, 5}, // C -21.7 -53.6 -58.6 -58.5 -57.7 -57.5 12.6 - {0x16, 0}, // 16 -21.7 -53.6 -58.5 -58.6 -57.6 -57.5 12.6 - {0x31, 1}, // 31 -21.9 -53.7 -58.5 -58.4 -57.8 -57.3 12.8 - {0x0B, 4}, // B -22.3 -53.9 -58.6 -58.5 -57.8 -57.4 12.5 - {0x0A, 6}, // A -23.0 -54.3 -58.6 -58.5 -57.8 -57.4 12.5 - {0x15, 0}, // 15 -23.0 -54.3 -58.5 -58.5 -57.8 -57.4 12.5 - {0x09, 8}, // 9 -23.8 -54.7 -58.5 -58.5 -57.8 -57.5 12.4 - {0x08, 8}, // 8 -24.6 -55.0 -58.6 -58.6 -57.7 -57.6 12.3 - {0x14, 0}, // 14 -24.7 -55.0 -58.5 -58.5 -57.7 -57.5 12.4 - {0x21, 1}, // 21 -24.8 -55.1 -58.5 -58.5 -57.7 -57.5 12.5 - {0x07, 6}, // 7 -25.5 -55.4 -58.6 -58.5 -57.7 -57.5 12.3 - {0x13, 10}, // 13 -26.5 -55.9 -58.6 -58.5 -57.6 -57.6 12.3 - {0x06, 0}, // 6 -26.5 -55.9 -58.5 -58.5 -57.6 -57.5 12.2 - {0x05, 11}, // 5 -27.7 -56.4 -58.4 -58.4 -57.7 -57.5 12.2 - {0x12, 11}, // 12 -28.9 -57.1 -58.4 -58.5 -57.7 -57.3 12.2 - {0x04, 0}, // 4 -28.9 -57.0 -58.6 -58.4 -57.7 -57.5 12.1 - {0x03, 13}, // 3 -30.2 -57.3 -58.5 -58.5 -57.7 -57.5 12.1 - {0x02, 15}, // 2 -31.7 -57.9 -58.5 -58.5 -57.7 -57.3 12.0 - {0x11, 0}, // 11 -31.7 -58.0 -58.5 -58.5 -57.8 -57.3 12.1 - {0x01, 14}, // 1 -33.1 -58.4 -58.6 -58.5 -57.8 -57.5 12.0 - {0x10, 10}, // 10 -34.1 -58.2 -58.7 -58.3 -57.7 -57.5 11.9 - {0x20, 0}, // 20 -34.1 -58.2 -58.5 -58.5 -57.7 -57.5 12.1 - {0x30, 1}, // 30 -34.2 -58.4 -58.6 -58.5 -57.8 -57.5 12.2 - {0x6E, 115}, // 6E -45.8 -57.9 -58.6 -58.5 -57.7 -57.5 16.1 - {0x00, 135}, // 0 -59.3 -58.3 -58.4 -58.5 -57.8 -57.4 11.3 - {0x6F, 99}, // 6F -69.2 -58.2 -58.5 -58.4 -57.6 -57.4 10.8 -}; - -static const PowerTableItem PA_TABLE_915_FULL[] = { - {0xC0, 15}, // C0 9.4 -33.5 -58.5 -58.4 -55.8 -32.6 31.8 - {0xC1, 4}, // C1 9.0 -35.9 -58.3 -58.5 -56.1 -34.4 30.9 - {0xC2, 4}, // C2 8.6 -38.6 -58.5 -58.4 -56.1 -36.2 30.0 - {0xC3, 2}, // C3 8.3 -41.5 -58.6 -58.4 -56.3 -38.0 29.3 - {0xC4, 4}, // C4 7.9 -43.6 -58.5 -58.4 -56.5 -39.6 28.6 - {0xC5, 3}, // C5 7.6 -43.9 -58.5 -58.5 -56.7 -40.5 28.0 - {0xC6, 3}, // C6 7.2 -42.5 -58.5 -58.4 -56.7 -40.5 27.4 - {0xC7, 2}, // C7 6.9 -40.7 -58.5 -58.5 -56.8 -40.0 26.9 - {0xC8, 3}, // C8 6.6 -39.0 -58.5 -58.4 -56.9 -39.4 26.4 - {0xC9, 3}, // C9 6.2 -37.6 -58.6 -58.4 -57.2 -38.8 25.9 - {0xCA, 2}, // CA 5.9 -36.5 -58.6 -58.4 -57.3 -38.2 25.5 - {0xCB, 3}, // CB 5.6 -35.6 -58.4 -58.4 -57.3 -37.8 25.1 - {0xCC, 2}, // CC 5.3 -34.8 -58.6 -58.3 -57.3 -37.5 24.7 - {0xCD, 2}, // CD 5.0 -34.2 -58.6 -58.5 -57.5 -37.3 24.3 - {0x80, 0}, // 80 4.9 -27.8 -58.5 -58.4 -57.7 -40.6 20.7 - {0x81, 2}, // 81 4.7 -28.7 -58.4 -58.5 -57.7 -40.6 20.5 - {0x82, 2}, // 82 4.5 -29.6 -58.5 -58.4 -57.7 -40.5 20.2 - {0xCE, 2}, // CE 4.3 -33.2 -58.5 -58.3 -57.5 -37.2 23.7 - {0x83, 0}, // 83 4.2 -30.7 -58.5 -58.4 -57.7 -40.4 20.0 - {0x84, 3}, // 84 3.9 -32.0 -58.6 -58.4 -57.7 -40.1 19.7 - {0x85, 2}, // 85 3.6 -33.3 -58.5 -58.5 -57.8 -39.9 19.4 - {0x86, 3}, // 86 3.3 -34.8 -58.5 -58.5 -57.6 -39.8 19.2 - {0x87, 3}, // 87 2.9 -36.5 -58.4 -58.5 -57.7 -39.6 18.9 - {0x88, 3}, // 88 2.5 -38.3 -58.6 -58.4 -57.8 -39.5 18.6 - {0x89, 2}, // 89 2.2 -40.2 -58.6 -58.5 -57.6 -39.6 18.3 - {0x8A, 4}, // 8A 1.8 -42.2 -58.5 -58.4 -57.7 -39.6 18.1 - {0xCF, 1}, // CF 1.6 -31.3 -58.7 -58.3 -57.6 -40.0 21.4 - {0x8B, 3}, // 8B 1.3 -44.0 -58.5 -58.4 -57.7 -39.8 17.8 - {0x8C, 4}, // 8C 0.9 -45.8 -58.4 -58.4 -57.6 -40.0 17.5 - {0x8D, 4}, // 8D 0.5 -46.8 -58.5 -58.5 -57.7 -40.4 17.3 - {0x8E, 11}, // 8E -0.6 -46.6 -58.5 -58.5 -57.8 -41.1 16.7 - {0x50, 3}, // 50 -0.9 -37.9 -58.5 -58.5 -57.8 -45.9 16.5 - {0x60, 2}, // 60 -1.1 -38.0 -58.4 -58.4 -57.7 -46.1 16.4 - {0x51, 5}, // 51 -1.6 -38.7 -58.4 -58.5 -57.7 -46.9 16.0 - {0x61, 1}, // 61 -1.8 -38.7 -58.5 -58.4 -57.7 -47.0 15.9 - {0x40, 3}, // 40 -2.1 -39.4 -58.6 -58.5 -57.7 -47.5 15.7 - {0x52, 1}, // 52 -2.2 -39.3 -58.5 -58.4 -57.7 -47.4 15.6 - {0x62, 1}, // 62 -2.4 -39.4 -58.5 -58.5 -57.8 -47.6 15.6 - {0x3F, 1}, // 3F -2.5 -49.6 -58.4 -58.4 -57.6 -55.1 21.3 - {0x3E, 2}, // 3E -2.7 -50.0 -58.5 -58.4 -57.6 -55.3 20.7 - {0x53, 1}, // 53 -2.9 -40.1 -58.5 -58.4 -57.8 -47.7 15.3 - {0x3D, 1}, // 3D -3.0 -50.3 -58.4 -58.5 -57.7 -55.2 20.1 - {0x63, 0}, // 63 -3.0 -40.1 -58.4 -58.4 -57.8 -47.7 15.2 - {0x3C, 3}, // 3C -3.4 -50.7 -58.4 -58.5 -57.7 -55.3 19.5 - {0x54, 1}, // 54 -3.5 -40.8 -58.5 -58.5 -57.7 -48.0 15.0 - {0x64, 2}, // 64 -3.7 -40.8 -58.5 -58.5 -57.6 -48.1 14.9 - {0x3B, 0}, // 3B -3.8 -50.7 -58.6 -58.4 -57.6 -55.2 18.9 - {0x55, 2}, // 55 -4.1 -41.6 -58.5 -58.4 -57.7 -49.2 14.7 - {0x2F, 1}, // 2F -4.2 -50.3 -58.5 -58.4 -57.7 -54.1 18.1 - {0x65, 0}, // 65 -4.3 -41.6 -58.6 -58.4 -57.6 -49.2 14.6 - {0x3A, 1}, // 3A -4.4 -50.5 -58.6 -58.4 -57.7 -54.8 18.3 - {0x2E, 2}, // 2E -4.7 -49.4 -58.5 -58.4 -57.7 -53.6 17.7 - {0x56, 0}, // 56 -4.7 -42.3 -58.5 -58.5 -57.8 -50.5 14.4 - {0x66, 2}, // 66 -4.9 -42.3 -58.5 -58.4 -57.7 -50.6 14.4 - {0x39, 1}, // 39 -5.1 -50.0 -58.5 -58.5 -57.6 -54.0 17.7 - {0x2D, 1}, // 2D -5.2 -48.8 -58.5 -58.4 -57.7 -53.0 17.3 - {0x57, 2}, // 57 -5.4 -43.1 -58.6 -58.4 -57.8 -51.9 14.2 - {0x67, 1}, // 67 -5.6 -43.1 -58.5 -58.4 -57.8 -52.1 14.1 - {0x8F, 1}, // 8F -5.7 -46.0 -58.6 -58.4 -57.6 -45.5 14.9 - {0x2C, 0}, // 2C -5.8 -48.1 -58.5 -58.4 -57.7 -52.4 16.9 - {0x38, 1}, // 38 -5.9 -49.2 -58.6 -58.4 -57.7 -53.3 17.1 - {0x68, 2}, // 68 -6.2 -43.9 -58.5 -58.5 -57.6 -51.6 13.9 - {0x2B, 2}, // 2B -6.4 -47.6 -58.4 -58.4 -57.8 -52.1 16.5 - {0x37, 2}, // 37 -6.7 -47.4 -58.6 -58.4 -57.7 -51.7 16.4 - {0x69, 0}, // 69 -6.8 -44.9 -58.5 -58.4 -57.7 -51.8 13.8 - {0x2A, 4}, // 2A -7.2 -47.2 -58.6 -58.4 -57.8 -51.6 16.1 - {0x6A, 2}, // 6A -7.4 -46.2 -58.5 -58.4 -57.9 -53.1 13.7 - {0x36, 5}, // 36 -7.9 -46.9 -58.5 -58.4 -57.7 -51.2 15.8 - {0x29, 0}, // 29 -8.0 -47.0 -58.6 -58.4 -57.8 -51.2 15.7 - {0x6B, 4}, // 6B -8.4 -49.0 -58.5 -58.4 -57.8 -55.4 13.9 - {0x28, 4}, // 28 -8.8 -46.8 -58.4 -58.5 -57.6 -50.9 15.3 - {0x35, 5}, // 35 -9.3 -46.7 -58.6 -58.4 -57.7 -50.7 15.2 - {0x27, 3}, // 27 -9.7 -46.7 -58.5 -58.4 -57.6 -50.7 14.9 - {0x26, 12}, // 26 -10.9 -47.0 -58.6 -58.4 -57.8 -50.9 14.5 - {0x34, 0}, // 34 -10.9 -47.0 -58.5 -58.4 -57.8 -50.8 14.5 - {0x25, 14}, // 25 -12.3 -47.2 -58.6 -58.3 -57.7 -51.0 14.1 - {0x6C, 0}, // 6C -12.4 -54.4 -58.6 -58.4 -57.8 -55.3 14.6 - {0x33, 6}, // 33 -13.1 -47.6 -58.5 -58.4 -57.8 -51.2 14.0 - {0x24, 10}, // 24 -14.1 -48.1 -58.4 -58.4 -57.8 -51.4 13.7 - {0x1F, 3}, // 1F -14.4 -48.2 -58.5 -58.4 -57.7 -51.5 13.5 - {0x1E, 5}, // 1E -14.9 -48.4 -58.5 -58.4 -57.8 -51.7 13.4 - {0x1D, 5}, // 1D -15.5 -48.7 -58.4 -58.5 -57.7 -51.9 13.2 - {0x1C, 6}, // 1C -16.1 -49.0 -58.4 -58.4 -57.7 -52.2 13.1 - {0x23, 1}, // 23 -16.3 -49.1 -58.4 -58.5 -57.8 -51.9 13.3 - {0x32, 0}, // 32 -16.4 -49.0 -58.5 -58.5 -57.7 -52.0 13.3 - {0x1B, 4}, // 1B -16.8 -49.3 -58.6 -58.4 -57.8 -52.3 13.0 - {0x1A, 6}, // 1A -17.5 -49.7 -58.5 -58.4 -57.8 -52.6 12.9 - {0x19, 8}, // 19 -18.3 -50.2 -58.5 -58.5 -57.6 -52.8 12.8 - {0x18, 10}, // 18 -19.3 -50.6 -58.5 -58.5 -57.7 -53.1 12.7 - {0x22, 0}, // 22 -19.4 -50.7 -58.5 -58.5 -57.8 -53.1 12.8 - {0x0F, 3}, // F -19.7 -50.9 -58.5 -58.5 -57.7 -52.9 12.6 - {0x0E, 5}, // E -20.2 -51.2 -58.6 -58.5 -57.8 -53.3 12.6 - {0x17, 1}, // 17 -20.3 -51.2 -58.6 -58.5 -57.8 -53.1 12.6 - {0x0D, 5}, // D -20.8 -51.4 -58.5 -58.5 -57.8 -53.2 12.5 - {0x0C, 5}, // C -21.4 -51.8 -58.4 -58.5 -57.7 -53.4 12.5 - {0x16, 0}, // 16 -21.4 -51.9 -58.5 -58.5 -57.7 -53.4 12.5 - {0x31, 3}, // 31 -21.7 -52.0 -58.5 -58.4 -57.8 -53.4 12.7 - {0x0B, 3}, // B -22.0 -52.2 -58.5 -58.4 -57.9 -53.6 12.4 - {0x0A, 6}, // A -22.7 -52.6 -58.5 -58.4 -57.7 -53.6 12.4 - {0x15, 1}, // 15 -22.8 -52.7 -58.5 -58.4 -57.8 -53.6 12.4 - {0x09, 6}, // 9 -23.5 -53.1 -58.5 -58.5 -57.7 -54.0 12.3 - {0x6D, 3}, // 6D -23.8 -50.2 -58.5 -58.4 -57.6 -55.3 15.5 - {0x08, 5}, // 8 -24.3 -53.6 -58.4 -58.4 -57.6 -54.1 12.3 - {0x14, 0}, // 14 -24.4 -53.7 -58.6 -58.4 -57.8 -53.9 12.3 - {0x21, 2}, // 21 -24.6 -53.6 -58.6 -58.4 -57.8 -53.9 12.4 - {0x07, 5}, // 7 -25.2 -54.1 -58.6 -58.4 -57.7 -54.0 12.2 - {0x13, 10}, // 13 -26.2 -54.6 -58.4 -58.5 -57.7 -54.3 12.2 - {0x06, 0}, // 6 -26.2 -54.6 -58.5 -58.3 -57.7 -54.3 12.2 - {0x05, 11}, // 5 -27.3 -55.3 -58.4 -58.4 -57.8 -54.5 12.1 - {0x12, 13}, // 12 -28.6 -55.9 -58.6 -58.5 -57.7 -54.7 12.1 - {0x04, 0}, // 4 -28.6 -56.1 -58.5 -58.4 -57.8 -54.5 12.0 - {0x03, 11}, // 3 -29.8 -56.9 -58.5 -58.4 -57.7 -54.7 12.0 - {0x02, 13}, // 2 -31.2 -57.5 -58.4 -58.4 -57.9 -54.7 11.9 - {0x11, 1}, // 11 -31.3 -57.6 -58.6 -58.3 -57.8 -54.7 12.0 - {0x01, 14}, // 1 -32.7 -58.4 -58.4 -58.4 -57.7 -54.7 11.9 - {0x10, 8}, // 10 -33.6 -58.6 -58.5 -58.3 -57.8 -54.8 11.9 - {0x20, 1}, // 20 -33.7 -58.6 -58.5 -58.3 -57.9 -54.6 12.0 - {0x30, 0}, // 30 -33.7 -58.5 -58.5 -58.4 -57.7 -54.9 12.1 - {0x00, 245}, // 0 -58.2 -58.5 -58.6 -58.3 -57.6 -54.1 11.2 - {0x6E, 62}, // 6E -64.5 -58.8 -58.5 -58.4 -57.7 -55.5 16.0 - {0x6F, 52}, // 6F -69.7 -58.6 -58.6 -58.4 -57.7 -55.3 10.7 -}; -*/ -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/cc1101sub.h b/components/cc1101/cc1101sub.h deleted file mode 100644 index 5012f3c..0000000 --- a/components/cc1101/cc1101sub.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -namespace esphome { -namespace cc1101 { - -#ifndef SUB_TEXT -#define SUB_TEXT(name) \ - protected: \ - text::Text *name##_text_{nullptr}; \ -\ - public: \ - void set_##name##_text(text::Text *text) { this->name##_text_ = text; } -#endif - -#define CC1101_SUB_NUMBER(name, type) \ - SUB_NUMBER(name) \ - void publish_##name() { this->publish_(this->name##_number_, (float) this->get_##name()); } \ - void set_##name(type value); \ - type get_##name(); - -#define CC1101_SUB_SWITCH(name) \ - SUB_SWITCH(name) \ - void publish_##name() { this->publish_switch_(this->name##_switch_, this->get_##name()); } \ - void set_##name(bool value); \ - bool get_##name(); - -#define CC1101_SUB_SELECT(name, type) \ - SUB_SELECT(name) \ - void publish_##name() { this->publish_select_(this->name##_select_, (size_t) this->get_##name()); } \ - void set_##name(type value); \ - type get_##name(); - -#define CC1101_SUB_TEXT(name) \ - SUB_TEXT(name) \ - void publish_##name() { this->publish_(this->name##_text_, this->get_##name()); } \ - void set_##name(const std::string &value); \ - std::string get_##name(); - -#define CC1101_SUB_SENSOR(name) \ - SUB_SENSOR(name) \ - void publish_##name##_sensor() { this->publish_(this->name##_sensor_, (float) this->get_##name##_sensor()); } \ - float get_##name##_sensor(); - -#define CC1101_SUB_BINARY_SENSOR(name) \ - SUB_BINARY_SENSOR(name) \ - void publish_##name##_binary_sensor() { \ - this->publish_(this->name##_binary_sensor_, this->get_##name##_binary_sensor()); \ - } \ - bool get_##name##_binary_sensor(); - -#define CC1101_SUB_TEXT_SENSOR(name) \ - SUB_TEXT_SENSOR(name) \ - void publish_##name##_text_sensor() { this->publish_(this->name##_text_sensor_, this->get_##name##_text_sensor()); } \ - std::string get_##name##_text_sensor(); - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/number/__init__.py b/components/cc1101/number/__init__.py deleted file mode 100644 index beaf838..0000000 --- a/components/cc1101/number/__init__.py +++ /dev/null @@ -1,204 +0,0 @@ -import esphome.codegen as cg -from esphome.components import number -import esphome.config_validation as cv -from esphome.const import ( - CONF_CHANNEL, - CONF_FREQUENCY, - CONF_MODE, - DEVICE_CLASS_FREQUENCY, - DEVICE_CLASS_SIGNAL_STRENGTH, - ENTITY_CATEGORY_CONFIG, - UNIT_DECIBEL, - UNIT_DECIBEL_MILLIWATT, -) - -from .. import ( - CC1101_COMPONENT_SCHEMA, - CONF_AGC, - CONF_BANDWIDTH, - CONF_CARRIER_SENSE_ABS_THR, - CONF_CC1101_ID, - CONF_CHANNEL_SPACING, - CONF_FSK_DEVIATION, - CONF_IF_FREQUENCY, - CONF_MSK_DEVIATION, - CONF_OUTPUT_POWER, - CONF_SYMBOL_RATE, - CONF_TUNER, - UNIT_KILO_HERTZ, - for_each_conf, - ns, -) - -NumberMode = number.NumberMode - -OutputPowerNumber = ns.class_("OutputPowerNumber", number.Number) -TunerFrequencyNumber = ns.class_("TunerFrequencyNumber", number.Number) -TunerIfFrequencyNumber = ns.class_("TunerIfFrequencyNumber", number.Number) -TunerBandwidthNumber = ns.class_("TunerBandwidthNumber", number.Number) -TunerChannelNumber = ns.class_("TunerChannelNumber", number.Number) -TunerChannelSpacingNumber = ns.class_("TunerChannelSpacingNumber", number.Number) -TunerFskDeviationNumber = ns.class_("TunerFskDeviationNumber", number.Number) -TunerMskDeviationNumber = ns.class_("TunerMskDeviationNumber", number.Number) -TunerSymbolRateNumber = ns.class_("TunerSymbolRateNumber", number.Number) -AgcCarrierSenseAbsThrNumber = ns.class_("AgcCarrierSenseAbsThrNumber", number.Number) - -TYPES = { - None: { - CONF_OUTPUT_POWER: [ - number.number_schema( - OutputPowerNumber, - unit_of_measurement=UNIT_DECIBEL_MILLIWATT, - device_class=DEVICE_CLASS_SIGNAL_STRENGTH, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.OUTPUT_POWER_MIN, - ns.OUTPUT_POWER_MAX, - 0.1, - NumberMode.NUMBER_MODE_SLIDER, - ], - }, - CONF_TUNER: { - CONF_FREQUENCY: [ - number.number_schema( - TunerFrequencyNumber, - unit_of_measurement=UNIT_KILO_HERTZ, - device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.FREQUENCY_MIN, - ns.FREQUENCY_MAX, - 1, - ], - CONF_IF_FREQUENCY: [ - number.number_schema( - TunerIfFrequencyNumber, - unit_of_measurement=UNIT_KILO_HERTZ, - device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.IF_FREQUENCY_MIN, - ns.IF_FREQUENCY_MAX, - 0.001, - ], - CONF_BANDWIDTH: [ - number.number_schema( - TunerBandwidthNumber, - unit_of_measurement=UNIT_KILO_HERTZ, - device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.BANDWIDTH_MIN, - ns.BANDWIDTH_MAX, - 0.001, - ], - CONF_CHANNEL: [ - number.number_schema( - TunerChannelNumber, - # unit_of_measurement=, - # device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.CHANNEL_MIN, - ns.CHANNEL_MAX, - 1, - # NumberMode.NUMBER_MODE_BOX, - ], - CONF_CHANNEL_SPACING: [ - number.number_schema( - TunerChannelSpacingNumber, - unit_of_measurement=UNIT_KILO_HERTZ, - device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.CHANNEL_SPACING_MIN, - ns.CHANNEL_SPACING_MAX, - 0.001, - ], - CONF_FSK_DEVIATION: [ - number.number_schema( - TunerFskDeviationNumber, - unit_of_measurement=UNIT_KILO_HERTZ, - device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.FSK_DEVIATION_MIN, - ns.FSK_DEVIATION_MAX, - 0.001, - ], - CONF_MSK_DEVIATION: [ - number.number_schema( - TunerMskDeviationNumber, - # unit_of_measurement=, - # device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.MSK_DEVIATION_MIN, - ns.MSK_DEVIATION_MAX, - 1, - ], - CONF_SYMBOL_RATE: [ - number.number_schema( - TunerSymbolRateNumber, - # unit_of_measurement=, - # device_class=DEVICE_CLASS_FREQUENCY, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.SYMBOL_RATE_MIN, - ns.SYMBOL_RATE_MAX, - 1, - ], - }, - CONF_AGC: { - CONF_CARRIER_SENSE_ABS_THR: [ - number.number_schema( - AgcCarrierSenseAbsThrNumber, - unit_of_measurement=UNIT_DECIBEL, - device_class=DEVICE_CLASS_SIGNAL_STRENGTH, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ns.CARRIER_SENSE_ABS_THR_MIN, - ns.CARRIER_SENSE_ABS_THR_MAX, - 1, - ], - }, -} - -CONFIG_SCHEMA = CC1101_COMPONENT_SCHEMA.extend( - {cv.Optional(k): v[0] for k, v in TYPES[None].items()}, - { - cv.Optional(CONF_TUNER): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_TUNER].items()} - ), - cv.Optional(CONF_AGC): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_AGC].items()} - ), - }, -) - - -async def to_code(config): - parent = await cg.get_variable(config[CONF_CC1101_ID]) - - async def new_number(c, args, setter): - # only override mode when it's set to auto in user config - if CONF_MODE not in c or c[CONF_MODE] == NumberMode.NUMBER_MODE_AUTO: - if len(args) > 3 and args[3] is not None: - c[CONF_MODE] = args[3] - n = await number.new_number( - c, min_value=args[0], max_value=args[1], step=args[2] - ) - await cg.register_parented(n, parent) - cg.add(getattr(parent, setter + "_number")(n)) - - await for_each_conf(config, TYPES, new_number) diff --git a/components/cc1101/number/number.h b/components/cc1101/number/number.h deleted file mode 100644 index befb816..0000000 --- a/components/cc1101/number/number.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "esphome/components/number/number.h" -#include "../cc1101.h" -#include - -namespace esphome { -namespace cc1101 { - -// maybe there is a way to specialize type dependent member pointers - -template -class NumberFloat : public number::Number, public Parented { - protected: - void control(float value) override { - this->publish_state(value); - (this->parent_->*F)(value); - } -}; - -template -class NumberUInt8 : public number::Number, public Parented { - protected: - void control(float value) override { - this->publish_state(value); - (this->parent_->*F)((uint8_t) lround(value)); - } -}; - -template -class NumberInt8 : public number::Number, public Parented { - protected: - void control(float value) override { - this->publish_state(value); - (this->parent_->*F)((int8_t) lround(value)); - } -}; - -using OutputPowerNumber = NumberFloat<&CC1101Component::set_output_power>; -using TunerFrequencyNumber = NumberFloat<&CC1101Component::set_tuner_frequency>; -using TunerIfFrequencyNumber = NumberFloat<&CC1101Component::set_tuner_if_frequency>; -using TunerBandwidthNumber = NumberFloat<&CC1101Component::set_tuner_bandwidth>; -using TunerChannelNumber = NumberUInt8<&CC1101Component::set_tuner_channel>; -using TunerChannelSpacingNumber = NumberFloat<&CC1101Component::set_tuner_channel_spacing>; -using TunerFskDeviationNumber = NumberFloat<&CC1101Component::set_tuner_fsk_deviation>; -using TunerMskDeviationNumber = NumberUInt8<&CC1101Component::set_tuner_msk_deviation>; -using TunerSymbolRateNumber = NumberFloat<&CC1101Component::set_tuner_symbol_rate>; -using AgcCarrierSenseAbsThrNumber = NumberInt8<&CC1101Component::set_agc_carrier_sense_abs_thr>; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/select/__init__.py b/components/cc1101/select/__init__.py deleted file mode 100644 index 0e1ac46..0000000 --- a/components/cc1101/select/__init__.py +++ /dev/null @@ -1,178 +0,0 @@ -import esphome.codegen as cg -from esphome.components import select -import esphome.config_validation as cv -from esphome.const import CONF_WAIT_TIME, ENTITY_CATEGORY_CONFIG - -from .. import ( - CARRIER_SENSE_REL_THR, - CC1101_COMPONENT_SCHEMA, - CONF_AGC, - CONF_CARRIER_SENSE_REL_THR, - CONF_CC1101_ID, - CONF_FILTER_LENGTH_ASK_OOK, - CONF_FILTER_LENGTH_FSK_MSK, - CONF_FREEZE, - CONF_HYST_LEVEL, - CONF_MAGN_TARGET, - CONF_MAX_DVGA_GAIN, - CONF_MAX_LNA_GAIN, - CONF_MODULATION, - CONF_RX_ATTENUATION, - CONF_SYNC_MODE, - CONF_TUNER, - FILTER_LENGTH_ASK_OOK, - FILTER_LENGTH_FSK_MSK, - FREEZE, - HYST_LEVEL, - MAGN_TARGET, - MAX_DVGA_GAIN, - MAX_LNA_GAIN, - MODULATION, - RX_ATTENUATION, - SYNC_MODE, - WAIT_TIME, - for_each_conf, - ns, -) - -RxAttenuationSelect = ns.class_("RxAttenuationSelect", select.Select) -TunerSyncModeSelect = ns.class_("TunerSyncModeSelect", select.Select) -TunerModulationSelect = ns.class_("TunerModulationSelect", select.Select) -AgcMagnTargetSelect = ns.class_("AgcMagnTargetSelect", select.Select) -AgcMaxLnaGainSelect = ns.class_("AgcMaxLnaGainSelect", select.Select) -AgcMaxDvgaGainSelect = ns.class_("AgcMaxDvgaGainSelect", select.Select) -AgcCarrierSenseRelThrSelect = ns.class_("AgcCarrierSenseRelThrSelect", select.Select) -AgcFilterLengthFskMskSelect = ns.class_("AgcFilterLengthFskMskSelect", select.Select) -AgcFilterLengthAskOokSelect = ns.class_("AgcFilterLengthAskOokSelect", select.Select) -AgcFreezeSelect = ns.class_("AgcFreezeSelect", select.Select) -AgcWaitTimeSelect = ns.class_("AgcWaitTimeSelect", select.Select) -AgcHystLevelSelect = ns.class_("AgcHystLevelSelect", select.Select) - - -TYPES = { - None: { - CONF_RX_ATTENUATION: [ - select.select_schema( - RxAttenuationSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - RX_ATTENUATION, - ], - }, - CONF_TUNER: { - CONF_SYNC_MODE: [ - select.select_schema( - TunerSyncModeSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - SYNC_MODE, - ], - CONF_MODULATION: [ - select.select_schema( - TunerModulationSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - MODULATION, - ], - }, - CONF_AGC: { - CONF_MAGN_TARGET: [ - select.select_schema( - AgcMagnTargetSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - MAGN_TARGET, - ], - CONF_MAX_LNA_GAIN: [ - select.select_schema( - AgcMaxLnaGainSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - MAX_LNA_GAIN, - ], - CONF_MAX_DVGA_GAIN: [ - select.select_schema( - AgcMaxDvgaGainSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - MAX_DVGA_GAIN, - ], - CONF_CARRIER_SENSE_REL_THR: [ - select.select_schema( - AgcCarrierSenseRelThrSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - CARRIER_SENSE_REL_THR, - ], - CONF_FILTER_LENGTH_FSK_MSK: [ - select.select_schema( - AgcFilterLengthFskMskSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - FILTER_LENGTH_FSK_MSK, - ], - CONF_FILTER_LENGTH_ASK_OOK: [ - select.select_schema( - AgcFilterLengthAskOokSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - FILTER_LENGTH_ASK_OOK, - ], - CONF_FREEZE: [ - select.select_schema( - AgcFreezeSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - FREEZE, - ], - CONF_WAIT_TIME: [ - select.select_schema( - AgcWaitTimeSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - WAIT_TIME, - ], - CONF_HYST_LEVEL: [ - select.select_schema( - AgcHystLevelSelect, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - HYST_LEVEL, - ], - }, -} - -CONFIG_SCHEMA = CC1101_COMPONENT_SCHEMA.extend( - {cv.Optional(k): v[0] for k, v in TYPES[None].items()}, - { - cv.Optional(CONF_TUNER): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_TUNER].items()} - ), - cv.Optional(CONF_AGC): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_AGC].items()} - ), - }, -) - - -async def to_code(config): - parent = await cg.get_variable(config[CONF_CC1101_ID]) - - async def new_select(c, args, setter): - s = await select.new_select(c, options=list(args[0].keys())) - await cg.register_parented(s, parent) - cg.add(getattr(parent, setter + "_select")(s)) - - await for_each_conf(config, TYPES, new_select) diff --git a/components/cc1101/select/select.h b/components/cc1101/select/select.h deleted file mode 100644 index b091d09..0000000 --- a/components/cc1101/select/select.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "esphome/components/select/select.h" -#include "../cc1101.h" - -namespace esphome { -namespace cc1101 { - -template -class Select : public select::Select, public Parented { - protected: - void control(const std::string &value) override { - this->publish_state(value); - if (auto index = this->active_index()) { - (this->parent_->*F)((T) *index); - } - } -}; - -using RxAttenuationSelect = Select; -using TunerSyncModeSelect = Select; -using TunerModulationSelect = Select; -using AgcMagnTargetSelect = Select; -using AgcMaxLnaGainSelect = Select; -using AgcMaxDvgaGainSelect = Select; -using AgcCarrierSenseRelThrSelect = Select; -using AgcFilterLengthFskMskSelect = Select; -using AgcFilterLengthAskOokSelect = Select; -using AgcFreezeSelect = Select; -using AgcWaitTimeSelect = Select; -using AgcHystLevelSelect = Select; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/switch/__init__.py b/components/cc1101/switch/__init__.py deleted file mode 100644 index ad7ff57..0000000 --- a/components/cc1101/switch/__init__.py +++ /dev/null @@ -1,78 +0,0 @@ -import esphome.codegen as cg -from esphome.components import switch -import esphome.config_validation as cv -from esphome.const import DEVICE_CLASS_SWITCH, ENTITY_CATEGORY_CONFIG - -from .. import ( - CC1101_COMPONENT_SCHEMA, - CONF_AGC, - CONF_CARRIER_SENSE_ABOVE_THRESHOLD, - CONF_CC1101_ID, - CONF_DC_BLOCKING_FILTER, - CONF_LNA_PRIORITY, - CONF_TUNER, - for_each_conf, - ns, -) - -DcBlockingFilterSwitch = ns.class_("DcBlockingFilterSwitch", switch.Switch) -CarrierSenseAboveThresholdSwitch = ns.class_( - "CarrierSenseAboveThresholdSwitch", switch.Switch -) -AgcLnaPrioritySwitch = ns.class_("AgcLnaPrioritySwitch", switch.Switch) - -TYPES = { - None: { - CONF_DC_BLOCKING_FILTER: [ - switch.switch_schema( - DcBlockingFilterSwitch, - device_class=DEVICE_CLASS_SWITCH, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ], - }, - CONF_TUNER: { - CONF_CARRIER_SENSE_ABOVE_THRESHOLD: [ - switch.switch_schema( - CarrierSenseAboveThresholdSwitch, - device_class=DEVICE_CLASS_SWITCH, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ], - }, - CONF_AGC: { - CONF_LNA_PRIORITY: [ - switch.switch_schema( - AgcLnaPrioritySwitch, - device_class=DEVICE_CLASS_SWITCH, - entity_category=ENTITY_CATEGORY_CONFIG, - # icon=ICON_, - ), - ], - }, -} - -CONFIG_SCHEMA = CC1101_COMPONENT_SCHEMA.extend( - {cv.Optional(k): v[0] for k, v in TYPES[None].items()}, - { - cv.Optional(CONF_TUNER): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_TUNER].items()} - ), - cv.Optional(CONF_AGC): cv.Schema( - {cv.Optional(k): v[0] for k, v in TYPES[CONF_AGC].items()} - ), - }, -) - - -async def to_code(config): - parent = await cg.get_variable(config[CONF_CC1101_ID]) - - async def new_switch(c, args, setter): - s = await switch.new_switch(c) - await cg.register_parented(s, parent) - cg.add(getattr(parent, setter + "_switch")(s)) - - await for_each_conf(config, TYPES, new_switch) diff --git a/components/cc1101/switch/switch.h b/components/cc1101/switch/switch.h deleted file mode 100644 index 8af9b6a..0000000 --- a/components/cc1101/switch/switch.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "esphome/components/switch/switch.h" -#include "../cc1101.h" - -namespace esphome { -namespace cc1101 { - -template class Switch : public switch_::Switch, public Parented { - protected: - void write_state(bool value) override { - this->publish_state(value); - (this->parent_->*F)(value); - } -}; - -using DcBlockingFilterSwitch = Switch<&CC1101Component::set_dc_blocking_filter>; -using CarrierSenseAboveThresholdSwitch = Switch<&CC1101Component::set_tuner_carrier_sense_above_threshold>; -using AgcLnaPrioritySwitch = Switch<&CC1101Component::set_agc_lna_priority>; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/cc1101/text/__init__.py b/components/cc1101/text/__init__.py deleted file mode 100644 index 7091620..0000000 --- a/components/cc1101/text/__init__.py +++ /dev/null @@ -1,133 +0,0 @@ -from typing import Optional - -import esphome.codegen as cg -from esphome.components import mqtt, text, web_server -import esphome.config_validation as cv -from esphome.const import ( - CONF_ENTITY_CATEGORY, - CONF_ICON, - CONF_ID, - CONF_MQTT_ID, - CONF_WEB_SERVER, - ENTITY_CATEGORY_CONFIG, -) -from esphome.core import CORE -from esphome.cpp_generator import MockObjClass -from esphome.cpp_helpers import setup_entity - -from .. import CC1101_COMPONENT_SCHEMA, CONF_CC1101_ID, for_each_conf, ns - -CONF_DUMMY_TEXT = "dummy_text" -ICON_FORMAT_TEXT = "mdi:format-text" - -DummyText = ns.class_("DummyText", text.Text) - -# The text component isn't implemented the same way as switch, select, number. -# It is not possible to create our own text platform as it is now, so I adopted -# the necessary code from those. - -_TEXT_SCHEMA = ( - cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA) - .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA) - .extend( - { - cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTTextComponent), - } - ) -) - -_UNDEF = object() - - -def text_schema( - class_: MockObjClass = _UNDEF, - *, - entity_category: str = _UNDEF, - device_class: str = _UNDEF, - icon: str = _UNDEF, -): - schema = _TEXT_SCHEMA - if class_ is not _UNDEF: - schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)}) - if entity_category is not _UNDEF: - schema = schema.extend( - { - cv.Optional( - CONF_ENTITY_CATEGORY, default=entity_category - ): cv.entity_category - } - ) - if icon is not _UNDEF: - schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon}) - return schema - - -TEXT_SCHEMA = text_schema() # for compatibility - - -async def setup_text_core_( - var, - config, - *, - min_length: Optional[int], - max_length: Optional[int], - pattern: Optional[str], -): - await setup_entity(var, config) - cg.add(var.traits.set_min_length(min_length)) - cg.add(var.traits.set_max_length(max_length)) - if pattern is not None: - cg.add(var.traits.set_pattern(pattern)) - - if (mqtt_id := config.get(CONF_MQTT_ID)) is not None: - mqtt_ = cg.new_Pvariable(mqtt_id, var) - await mqtt.register_mqtt_component(mqtt_, config) - - if web_server_config := config.get(CONF_WEB_SERVER): - await web_server.add_entity_config(var, web_server_config) - - -async def register_text( - var, - config, - min_length: Optional[int] = 0, - max_length: Optional[int] = 255, - pattern: Optional[str] = None, -): - if not CORE.has_id(config[CONF_ID]): - var = cg.Pvariable(config[CONF_ID], var) - cg.add(cg.App.register_text(var)) - await setup_text_core_( - var, config, min_length=min_length, max_length=max_length, pattern=pattern - ) - - -TYPES = { - None: { - CONF_DUMMY_TEXT: [ - text_schema( - DummyText, - entity_category=ENTITY_CATEGORY_CONFIG, - icon=ICON_FORMAT_TEXT, - ), - 0, - 64, - ] - }, -} - -CONFIG_SCHEMA = CC1101_COMPONENT_SCHEMA.extend( - {cv.Optional(k): v[0] for k, v in TYPES[None].items()}, -) - - -async def to_code(config): - parent = await cg.get_variable(config[CONF_CC1101_ID]) - - async def new_text(c, args, setter): - var = cg.new_Pvariable(c[CONF_ID]) - await register_text(var, c, min_length=args[0], max_length=args[1]) - await cg.register_parented(var, parent) - cg.add(getattr(parent, setter + "_text")(var)) - - await for_each_conf(config, TYPES, new_text) diff --git a/components/cc1101/text/text.h b/components/cc1101/text/text.h deleted file mode 100644 index 373f034..0000000 --- a/components/cc1101/text/text.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "esphome/components/text/text.h" -#include "../cc1101.h" - -namespace esphome { -namespace cc1101 { - -class DummyText : public text::Text, public Parented { - protected: - void control(const std::string &value) override { - this->publish_state(value); - // this->parent_->set_dummy_text(value); - } -}; - -} // namespace cc1101 -} // namespace esphome diff --git a/components/nuki_lock/__init__.py b/components/nuki_lock/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/components/nuki_lock/lock.py b/components/nuki_lock/lock.py deleted file mode 100644 index 6c53548..0000000 --- a/components/nuki_lock/lock.py +++ /dev/null @@ -1,282 +0,0 @@ -import esphome.codegen as cg -import esphome.config_validation as cv -import esphome.const as c -from esphome.components import lock, binary_sensor, text_sensor, sensor, button, time - -AUTO_LOAD = ["binary_sensor", "text_sensor", "sensor", "button"] - -CONF_PAIRED = "paired" -CONF_ERROR = "error" -CONF_BATTERY_CRITICAL = "battery_critical" -CONF_DOOR_CONTACT = "door_contact" -CONF_DOOR_CONTACT_SENSOR = "door_contact_sensor" -CONF_BEACON_RSSI = "beacon_rssi" -CONF_BEACON_LATENCY = "beacon_latency" -CONF_HEARTBEAT_LATENCY = "heartbeat_latency" -CONF_BEACON_BLE_ADDRESS = "beacon_ble_address" -CONF_LOCK_CURRENT_DATETIME = "lock_current_datetime" -CONF_TRIGGER = "trigger" -CONF_CONFIG_UPDATE_COUNT = "config_update_count" -CONF_LAST_ACTION = "last_action" -CONF_LAST_ACTION_TRIGGER = "last_action_trigger" -CONF_LAST_ACTION_COMPLETION_STATUS = "last_action_completion_status" -CONF_NIGHT_MODE_ACTIVE = "night_mode_active" -CONF_BATTERY_RESISTANCE = "battery_resistance" -CONF_LAST_ACTION_LOWEST_VOLTAGE = "last_action_lowest_voltage" -CONF_LAST_ACTION_START_VOLTAGE = "last_action_start_voltage" -CONF_LAST_ACTION_LOCK_DISTANCE = "last_action_lock_distance" -CONF_LAST_ACTION_START_TEMPERATURE = "last_action_start_temperature" -CONF_LAST_ACTION_BATTERY_DRAIN = "last_action_battery_drain" -CONF_LAST_ACTION_MAX_TURN_CURRENT = "last_action_max_turn_current" -CONF_REQUEST_BATTERY_REPORTS = "request_battery_reports" -CONF_RESTART_AFTER_BEACON_LATENCY = "restart_after_beacon_latency" -CONF_REQUEST_STATE = "request_state" -CONF_UNPAIR = "unpair" -CONF_TIME_SOURCE = "time_source" - -nuki_lock_ns = cg.esphome_ns.namespace("nuki_lock") -NukiLockComponent = nuki_lock_ns.class_("NukiLockComponent", lock.Lock, cg.PollingComponent) -RequestStateButton = nuki_lock_ns.class_("RequestStateButton", button.Button) -UnpairButton = nuki_lock_ns.class_("UnpairButton", button.Button) - -CONFIG_SCHEMA = lock.LOCK_SCHEMA.extend({ - cv.GenerateID(): cv.declare_id(NukiLockComponent), - - # Required sensors (if unconfigured, defaults are used). - cv.Optional(CONF_PAIRED, default={ - c.CONF_NAME: "Paired", - }): binary_sensor.binary_sensor_schema( - device_class=c.DEVICE_CLASS_CONNECTIVITY, - ), - cv.Optional(CONF_ERROR, default={ - c.CONF_NAME: "Error", - }): text_sensor.text_sensor_schema( - icon="mdi:alert", - ), - cv.Optional(CONF_BATTERY_CRITICAL, default={ - c.CONF_NAME: "Battery critical", - }): binary_sensor.binary_sensor_schema( - device_class=c.DEVICE_CLASS_BATTERY, - ), - cv.Optional(c.CONF_BATTERY_LEVEL, default={ - c.CONF_NAME: "Battery", - }): sensor.sensor_schema( - device_class=c.DEVICE_CLASS_BATTERY, - unit_of_measurement=c.UNIT_PERCENT, - ), - cv.Optional(CONF_DOOR_CONTACT, default={ - c.CONF_NAME: "Door contact", - }): binary_sensor.binary_sensor_schema( - device_class=c.DEVICE_CLASS_DOOR, - ), - cv.Optional(CONF_DOOR_CONTACT_SENSOR, default={ - c.CONF_NAME: "Door contact sensor", - }): text_sensor.text_sensor_schema(), - cv.Optional(CONF_TRIGGER, default={ - c.CONF_NAME: "Trigger", - }): text_sensor.text_sensor_schema(), - cv.Optional(CONF_NIGHT_MODE_ACTIVE, default={ - c.CONF_NAME: "Night mode active", - }): binary_sensor.binary_sensor_schema( - icon="mdi:weather-night", - ), - - # Optional sensors. - cv.Optional(CONF_BEACON_RSSI): sensor.sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - state_class=c.STATE_CLASS_MEASUREMENT, - device_class=c.DEVICE_CLASS_SIGNAL_STRENGTH, - unit_of_measurement=c.UNIT_DECIBEL_MILLIWATT, - ), - cv.Optional(CONF_BEACON_LATENCY): sensor.sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - state_class=c.STATE_CLASS_MEASUREMENT, - unit_of_measurement=c.UNIT_MILLISECOND, - ), - cv.Optional(CONF_HEARTBEAT_LATENCY): sensor.sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - state_class=c.STATE_CLASS_MEASUREMENT, - unit_of_measurement=c.UNIT_MILLISECOND, - ), - cv.Optional(CONF_BEACON_BLE_ADDRESS): text_sensor.text_sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - icon="mdi:bluetooth", - ), - cv.Optional(CONF_LOCK_CURRENT_DATETIME): text_sensor.text_sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - device_class=c.DEVICE_CLASS_TIMESTAMP, - ), - cv.Optional(CONF_CONFIG_UPDATE_COUNT): sensor.sensor_schema( - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - state_class=c.STATE_CLASS_TOTAL, - ), - cv.Optional(CONF_LAST_ACTION): text_sensor.text_sensor_schema(), - cv.Optional(CONF_LAST_ACTION_TRIGGER): text_sensor.text_sensor_schema(), - cv.Optional(CONF_LAST_ACTION_COMPLETION_STATUS): text_sensor.text_sensor_schema(), - - # Optional sensors - battery report. - cv.Optional(CONF_REQUEST_BATTERY_REPORTS, default=False): cv.boolean, - cv.Optional(c.CONF_BATTERY_VOLTAGE, default={ - c.CONF_NAME: "Battery voltage", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - device_class=c.DEVICE_CLASS_VOLTAGE, - unit_of_measurement=c.UNIT_VOLT, - accuracy_decimals=3, - ), - cv.Optional(CONF_BATTERY_RESISTANCE, default={ - c.CONF_NAME: "Battery resistance", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - unit_of_measurement=c.UNIT_OHM, - accuracy_decimals=3, - icon="mdi:resistor", - ), - cv.Optional(CONF_LAST_ACTION_LOWEST_VOLTAGE, default={ - c.CONF_NAME: "Last action lowest voltage", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - device_class=c.DEVICE_CLASS_VOLTAGE, - unit_of_measurement=c.UNIT_VOLT, - accuracy_decimals=3, - ), - cv.Optional(CONF_LAST_ACTION_START_VOLTAGE, default={ - c.CONF_NAME: "Last action start voltage", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - device_class=c.DEVICE_CLASS_VOLTAGE, - unit_of_measurement=c.UNIT_VOLT, - accuracy_decimals=3, - ), - cv.Optional(CONF_LAST_ACTION_LOCK_DISTANCE, default={ - c.CONF_NAME: "Last action lock distance", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - unit_of_measurement=c.UNIT_DEGREES, - icon="mdi:rotate-360", - ), - cv.Optional(CONF_LAST_ACTION_START_TEMPERATURE, default={ - c.CONF_NAME: "Last action start temperature", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - unit_of_measurement=c.UNIT_CELSIUS, - device_class=c.DEVICE_CLASS_TEMPERATURE, - ), - cv.Optional(CONF_LAST_ACTION_BATTERY_DRAIN, default={ - c.CONF_NAME: "Last action battery drain", - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - unit_of_measurement=c.UNIT_WATT_HOURS, - device_class=c.DEVICE_CLASS_ENERGY, - accuracy_decimals=5, - ), - cv.Optional(CONF_LAST_ACTION_MAX_TURN_CURRENT, default={ - c.CONF_NAME: "Last action max turn current", - c.CONF_DISABLED_BY_DEFAULT: True, # A few others, too. - }): sensor.sensor_schema( - state_class=c.STATE_CLASS_MEASUREMENT, - entity_category=c.ENTITY_CATEGORY_DIAGNOSTIC, - unit_of_measurement=c.UNIT_AMPERE, - device_class=c.DEVICE_CLASS_CURRENT, - accuracy_decimals=3, - ), - - # Configuration. - cv.Optional(CONF_RESTART_AFTER_BEACON_LATENCY, default="10min"): cv.positive_time_period_milliseconds, - - # Actions. - cv.Optional(CONF_REQUEST_STATE, default={ - c.CONF_NAME: "Request state", - }): button.button_schema(RequestStateButton, - entity_category=c.ENTITY_CATEGORY_CONFIG, - icon="mdi:refresh", - ), - cv.Optional(CONF_UNPAIR, default={ - c.CONF_NAME: "Unpair", - }): button.button_schema( - UnpairButton, - entity_category=c.ENTITY_CATEGORY_CONFIG, - icon="mdi:close", - ), - - # Time autoupdate. - cv.Optional(c.CONF_PIN): cv.positive_int, - cv.Optional(CONF_TIME_SOURCE): cv.use_id(time.RealTimeClock), -}).extend(cv.polling_component_schema("30min")) - -async def to_code(config): - var = cg.new_Pvariable(config[c.CONF_ID]) - await cg.register_component(var, config) - await lock.register_lock(var, config) - - request_state_button = await button.new_button(config[CONF_REQUEST_STATE]) - await cg.register_parented(request_state_button, config[c.CONF_ID]) - cg.add(var.set_request_state_button(request_state_button)) - - unpair_button = await button.new_button(config[CONF_UNPAIR]) - await cg.register_parented(unpair_button, config[c.CONF_ID]) - cg.add(var.set_request_state_button(unpair_button)) - - cg.add(var.set_paired_binary_sensor(await binary_sensor.new_binary_sensor(config[CONF_PAIRED]))) - cg.add(var.set_error_text_sensor(await text_sensor.new_text_sensor(config[CONF_ERROR]))) - cg.add(var.set_battery_critical_binary_sensor(await binary_sensor.new_binary_sensor(config[CONF_BATTERY_CRITICAL]))) - cg.add(var.set_battery_level_sensor(await sensor.new_sensor(config[c.CONF_BATTERY_LEVEL]))) - cg.add(var.set_door_contact_binary_sensor(await binary_sensor.new_binary_sensor(config[CONF_DOOR_CONTACT]))) - cg.add(var.set_door_contact_sensor_text_sensor(await text_sensor.new_text_sensor(config[CONF_DOOR_CONTACT_SENSOR]))) - cg.add(var.set_trigger_text_sensor(await text_sensor.new_text_sensor(config[CONF_TRIGGER]))) - cg.add(var.set_night_mode_active_binary_sensor(await binary_sensor.new_binary_sensor(config[CONF_NIGHT_MODE_ACTIVE]))) - - if CONF_BEACON_RSSI in config: - cg.add(var.set_beacon_rssi_sensor( await sensor.new_sensor(config[CONF_BEACON_RSSI]))) - - if CONF_BEACON_LATENCY in config: - cg.add(var.set_beacon_latency_sensor(await sensor.new_sensor(config[CONF_BEACON_LATENCY]))) - - if CONF_HEARTBEAT_LATENCY in config: - cg.add(var.set_heartbeat_latency_sensor(await sensor.new_sensor(config[CONF_HEARTBEAT_LATENCY]))) - - if CONF_BEACON_BLE_ADDRESS in config: - cg.add(var.set_beacon_ble_address_text_sensor(await text_sensor.new_text_sensor(config[CONF_BEACON_BLE_ADDRESS]))) - - if CONF_LOCK_CURRENT_DATETIME in config: - sens = await text_sensor.new_text_sensor(config[CONF_LOCK_CURRENT_DATETIME]) - cg.add(var.set_lock_current_datetime_text_sensor(sens)) - - if CONF_CONFIG_UPDATE_COUNT in config: - cg.add(var.set_config_update_count_sensor(await sensor.new_sensor(config[CONF_CONFIG_UPDATE_COUNT]))) - - if CONF_LAST_ACTION in config: - cg.add(var.set_last_action_text_sensor(await text_sensor.new_text_sensor(config[CONF_LAST_ACTION]))) - - if CONF_LAST_ACTION_TRIGGER in config: - cg.add(var.set_last_action_trigger_text_sensor(await text_sensor.new_text_sensor(config[CONF_LAST_ACTION_TRIGGER]))) - - if CONF_LAST_ACTION_COMPLETION_STATUS in config: - cg.add(var.set_last_action_completion_status_text_sensor(await text_sensor.new_text_sensor(config[CONF_LAST_ACTION_COMPLETION_STATUS]))) - - if config.get(CONF_REQUEST_BATTERY_REPORTS): - cg.add(var.set_request_battery_reports(True)) - cg.add(var.set_battery_voltage_sensor(await sensor.new_sensor(config[c.CONF_BATTERY_VOLTAGE]))) - cg.add(var.set_battery_resistance_sensor(await sensor.new_sensor(config[CONF_BATTERY_RESISTANCE]))) - cg.add(var.set_last_action_lowest_voltage_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_LOWEST_VOLTAGE]))) - cg.add(var.set_last_action_start_voltage_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_START_VOLTAGE]))) - cg.add(var.set_last_action_lock_distance_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_LOCK_DISTANCE]))) - cg.add(var.set_last_action_start_temperature_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_START_TEMPERATURE]))) - cg.add(var.set_last_action_battery_drain_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_BATTERY_DRAIN]))) - cg.add(var.set_last_action_max_turn_current_sensor(await sensor.new_sensor(config[CONF_LAST_ACTION_MAX_TURN_CURRENT]))) - - if CONF_RESTART_AFTER_BEACON_LATENCY in config: - cg.add(var.set_restart_after_beacon_latency(config[CONF_RESTART_AFTER_BEACON_LATENCY])) - - if c.CONF_PIN in config: - cg.add(var.set_pin(config[c.CONF_PIN])) - - if CONF_TIME_SOURCE in config: - cg.add(var.set_time_source(await cg.get_variable(config[CONF_TIME_SOURCE]))) diff --git a/components/nuki_lock/nuki_lock.cpp b/components/nuki_lock/nuki_lock.cpp deleted file mode 100644 index f1ed1ff..0000000 --- a/components/nuki_lock/nuki_lock.cpp +++ /dev/null @@ -1,543 +0,0 @@ -#include "nuki_lock.h" - -#include "esphome/core/application.h" -#include "esphome/core/log.h" - -namespace { - -using namespace esphome; - -const char *TAG = "nuki_lock"; - -class Adapt { - public: - static esphome::lock::LockState lock_state_to_esphome( - NukiLock::LockState state) { - switch (state) { - case NukiLock::LockState::Locked: - return esphome::lock::LOCK_STATE_LOCKED; - case NukiLock::LockState::Unlocked: - return esphome::lock::LOCK_STATE_UNLOCKED; - case NukiLock::LockState::MotorBlocked: - return esphome::lock::LOCK_STATE_JAMMED; - case NukiLock::LockState::Locking: - return esphome::lock::LOCK_STATE_LOCKING; - case NukiLock::LockState::Unlocking: - return esphome::lock::LOCK_STATE_UNLOCKING; - default: - return esphome::lock::LOCK_STATE_NONE; - } - } - - static std::string lock_action_to_string(NukiLock::LockAction action) { - char result[256]; - NukiLock::lockactionToString(action, result); - return result; - } - - static bool door_sensor_state_to_is_door_open(Nuki::DoorSensorState state) { - switch (state) { - case Nuki::DoorSensorState::DoorClosed: - return false; - default: - return true; - } - } - - static std::string door_sensor_state_to_string(Nuki::DoorSensorState state) { - char result[256]; - NukiLock::doorSensorStateToString(state, result); - return result; - } - - static std::string key_turner_datetime_iso( - const NukiLock::KeyTurnerState &state) { - uint8_t tzOffsetHours = abs(state.timeZoneOffset / 60); - uint8_t tzOffsetMinutes = abs(state.timeZoneOffset % 60); - - char ts[256]; - sprintf(ts, "%d-%.2d-%.2dT%.2d:%.2d:%.2d%c%.2d:%.2d", state.currentTimeYear, - state.currentTimeMonth, state.currentTimeDay, state.currentTimeHour, - state.currentTimeMinute, state.currentTimeSecond, - state.timeZoneOffset >= 0 ? '+' : '-', tzOffsetHours, - tzOffsetMinutes); - return ts; - } - - static std::string trigger_to_string(NukiLock::Trigger trigger) { - char result[256]; - NukiLock::triggerToString(trigger, result); - return result; - } - - static std::string completion_status_to_string( - NukiLock::CompletionStatus status) { - char result[256]; - NukiLock::completionStatusToString(status, result); - return result; - } - - static std::string cmd_result_to_string(Nuki::CmdResult result) { - char resultStr[256]; - NukiLock::cmdResultToString(result, resultStr); - return resultStr; - } - - static std::string error_to_string(NukiLock::ErrorCode error) { - switch (error) { - case NukiLock::ErrorCode::ERROR_BAD_CRC: - return "ERROR_BAD_CRC"; - case NukiLock::ErrorCode::ERROR_BAD_LENGTH: - return "ERROR_BAD_LENGTH"; - case NukiLock::ErrorCode::ERROR_UNKNOWN: - return "ERROR_UNKNOWN"; - case NukiLock::ErrorCode::P_ERROR_NOT_PAIRING: - return "P_ERROR_NOT_PAIRING"; - case NukiLock::ErrorCode::P_ERROR_BAD_AUTHENTICATOR: - return "P_ERROR_BAD_AUTHENTICATOR"; - case NukiLock::ErrorCode::P_ERROR_BAD_PARAMETER: - return "P_ERROR_BAD_PARAMETER"; - case NukiLock::ErrorCode::P_ERROR_MAX_USER: - return "P_ERROR_MAX_USER"; - case NukiLock::ErrorCode::K_ERROR_NOT_AUTHORIZED: - return "K_ERROR_NOT_AUTHORIZED"; - case NukiLock::ErrorCode::K_ERROR_BAD_PIN: - return "K_ERROR_BAD_PIN"; - case NukiLock::ErrorCode::K_ERROR_BAD_NONCE: - return "K_ERROR_BAD_NONCE"; - case NukiLock::ErrorCode::K_ERROR_BAD_PARAMETER: - return "K_ERROR_BAD_PARAMETER"; - case NukiLock::ErrorCode::K_ERROR_INVALID_AUTH_ID: - return "K_ERROR_INVALID_AUTH_ID"; - case NukiLock::ErrorCode::K_ERROR_DISABLED: - return "K_ERROR_DISABLED"; - case NukiLock::ErrorCode::K_ERROR_REMOTE_NOT_ALLOWED: - return "K_ERROR_REMOTE_NOT_ALLOWED"; - case NukiLock::ErrorCode::K_ERROR_TIME_NOT_ALLOWED: - return "K_ERROR_TIME_NOT_ALLOWED"; - case NukiLock::ErrorCode::K_ERROR_TOO_MANY_PIN_ATTEMPTS: - return "K_ERROR_TOO_MANY_PIN_ATTEMPTS"; - case NukiLock::ErrorCode::K_ERROR_TOO_MANY_ENTRIES: - return "K_ERROR_TOO_MANY_ENTRIES"; - case NukiLock::ErrorCode::K_ERROR_CODE_ALREADY_EXISTS: - return "K_ERROR_CODE_ALREADY_EXISTS"; - case NukiLock::ErrorCode::K_ERROR_CODE_INVALID: - return "K_ERROR_CODE_INVALID"; - case NukiLock::ErrorCode::K_ERROR_CODE_INVALID_TIMEOUT_1: - return "K_ERROR_CODE_INVALID_TIMEOUT_1"; - case NukiLock::ErrorCode::K_ERROR_CODE_INVALID_TIMEOUT_2: - return "K_ERROR_CODE_INVALID_TIMEOUT_2"; - case NukiLock::ErrorCode::K_ERROR_CODE_INVALID_TIMEOUT_3: - return "K_ERROR_CODE_INVALID_TIMEOUT_3"; - case NukiLock::ErrorCode::K_ERROR_AUTO_UNLOCK_TOO_RECENT: - return "K_ERROR_AUTO_UNLOCK_TOO_RECENT"; - case NukiLock::ErrorCode::K_ERROR_POSITION_UNKNOWN: - return "K_ERROR_POSITION_UNKNOWN"; - case NukiLock::ErrorCode::K_ERROR_MOTOR_BLOCKED: - return "K_ERROR_MOTOR_BLOCKED"; - case NukiLock::ErrorCode::K_ERROR_CLUTCH_FAILURE: - return "K_ERROR_CLUTCH_FAILURE"; - case NukiLock::ErrorCode::K_ERROR_MOTOR_TIMEOUT: - return "K_ERROR_MOTOR_TIMEOUT"; - case NukiLock::ErrorCode::K_ERROR_BUSY: - return "K_ERROR_BUSY"; - case NukiLock::ErrorCode::K_ERROR_CANCELED: - return "K_ERROR_CANCELED"; - case NukiLock::ErrorCode::K_ERROR_NOT_CALIBRATED: - return "K_ERROR_NOT_CALIBRATED"; - case NukiLock::ErrorCode::K_ERROR_MOTOR_POSITION_LIMIT: - return "K_ERROR_MOTOR_POSITION_LIMIT"; - case NukiLock::ErrorCode::K_ERROR_MOTOR_LOW_VOLTAGE: - return "K_ERROR_MOTOR_LOW_VOLTAGE"; - case NukiLock::ErrorCode::K_ERROR_MOTOR_POWER_FAILURE: - return "K_ERROR_MOTOR_POWER_FAILURE"; - case NukiLock::ErrorCode::K_ERROR_CLUTCH_POWER_FAILURE: - return "K_ERROR_CLUTCH_POWER_FAILURE"; - case NukiLock::ErrorCode::K_ERROR_VOLTAGE_TOO_LOW: - return "K_ERROR_VOLTAGE_TOO_LOW"; - case NukiLock::ErrorCode::K_ERROR_FIRMWARE_UPDATE_NEEDED: - return "K_ERROR_FIRMWARE_UPDATE_NEEDED"; - default: - return std::string("Unknown #") + - std::to_string(static_cast(error)); - } - } -}; -} // namespace - -namespace esphome { -namespace nuki_lock { - -bool NukiLockComponent::update_key_turner_state_() { - NukiLock::KeyTurnerState retrievedKeyTurnerState; - Nuki::CmdResult result = - nuki_lock_->requestKeyTurnerState(&retrievedKeyTurnerState); - - if (result != Nuki::CmdResult::Success) { - ESP_LOGE(TAG, "request for key turner state failed: %s", - Adapt::cmd_result_to_string(result).c_str()); - - publish_state(lock::LOCK_STATE_NONE); - error_text_sensor_->publish_state( - Adapt::error_to_string(nuki_lock_->getLastError())); - - // TODO(https://github.com/esphome/feature-requests/issues/1568): publish - // unavailable for all related sensors. - - schedule_update(); - - return false; - } - - publish_state( - Adapt::lock_state_to_esphome(retrievedKeyTurnerState.lockState)); - - door_contact_binary_sensor_->publish_state( - Adapt::door_sensor_state_to_is_door_open( - retrievedKeyTurnerState.doorSensorState)); - door_contact_sensor_text_sensor_->publish_state( - Adapt::door_sensor_state_to_string( - retrievedKeyTurnerState.doorSensorState)); - battery_level_sensor_->publish_state(nuki_lock_->getBatteryPerc()); - battery_critical_binary_sensor_->publish_state( - nuki_lock_->isBatteryCritical()); - trigger_text_sensor_->publish_state( - Adapt::trigger_to_string(retrievedKeyTurnerState.trigger)); - night_mode_active_binary_sensor_->publish_state( - retrievedKeyTurnerState.nightModeActive > 0); - - if (lock_current_datetime_text_sensor_ != nullptr) { - lock_current_datetime_text_sensor_->publish_state( - Adapt::key_turner_datetime_iso(retrievedKeyTurnerState)); - } - if (config_update_count_sensor_ != nullptr) { - config_update_count_sensor_->publish_state( - retrievedKeyTurnerState.configUpdateCount); - } - if (last_action_text_sensor_ != nullptr) { - last_action_text_sensor_->publish_state( - Adapt::lock_action_to_string(retrievedKeyTurnerState.lastLockAction)); - } - if (last_action_trigger_text_sensor_ != nullptr) { - last_action_trigger_text_sensor_->publish_state(Adapt::trigger_to_string( - retrievedKeyTurnerState.lastLockActionTrigger)); - } - if (last_action_completion_status_text_sensor_ != nullptr) { - last_action_completion_status_text_sensor_->publish_state( - Adapt::completion_status_to_string( - retrievedKeyTurnerState.lastLockActionCompletionStatus)); - } - - return true; -} - -bool NukiLockComponent::update_lock_time_() { - if (time_source_ == nullptr) { - ESP_LOGE(TAG, "updating lock time failed: time source not set"); - return false; - } - - Nuki::CmdResult result = nuki_lock_->verifySecurityPin(); - if (result != Nuki::CmdResult::Success) { - ESP_LOGE(TAG, "verifying security pin for lock time update failed: %s", - Adapt::cmd_result_to_string(result).c_str()); - error_text_sensor_->publish_state( - Adapt::error_to_string(nuki_lock_->getLastError())); - return false; - } - - ESPTime now = time_source_->utcnow(); - if (!now.is_valid()) { - ESP_LOGE(TAG, "updating lock time failed: time source is invalid"); - return false; - } - - Nuki::TimeValue tv = { - .year = now.year, - .month = now.month, - .day = now.day_of_month, - .hour = now.hour, - .minute = now.minute, - .second = now.second, - }; - - ESP_LOGI(TAG, "Setting lock time: %.4d-%.2d-%.2d %.2d:%.2d:%.2d", tv.year, - tv.month, tv.day, tv.hour, tv.minute, tv.second); - result = nuki_lock_->updateTime(tv); - if (result != Nuki::CmdResult::Success) { - ESP_LOGE(TAG, "updating lock time failed: %s", - Adapt::cmd_result_to_string(result).c_str()); - error_text_sensor_->publish_state( - Adapt::error_to_string(nuki_lock_->getLastError())); - return false; - } - return true; -} - -bool NukiLockComponent::update_battery_report_() { - NukiLock::BatteryReport batteryReport; - Nuki::CmdResult result = - this->nuki_lock_->requestBatteryReport(&batteryReport); - - if (result != Nuki::CmdResult::Success) { - ESP_LOGE(TAG, "request for battery report failed: %s", - Adapt::cmd_result_to_string(result).c_str()); - // TODO(https://github.com/esphome/feature-requests/issues/1568): publish - // unavailable for all related sensors. - error_text_sensor_->publish_state( - Adapt::error_to_string(nuki_lock_->getLastError())); - - return false; - } - - battery_voltage_sensor_->publish_state(batteryReport.batteryVoltage / - 1000.0f); - battery_resistance_sensor_->publish_state(batteryReport.batteryResistance / - 1000.0f); - last_action_lowest_voltage_sensor_->publish_state( - batteryReport.lowestVoltage / 1000.0f); - last_action_start_voltage_sensor_->publish_state(batteryReport.startVoltage / - 1000.0f); - last_action_lock_distance_sensor_->publish_state(batteryReport.lockDistance); - last_action_start_temperature_sensor_->publish_state( - batteryReport.startTemperature); - // Milliwattseconds (mWs) to Wh. - last_action_battery_drain_sensor_->publish_state(batteryReport.batteryDrain / - 1000.0f / 3600.0f); - last_action_max_turn_current_sensor_->publish_state( - batteryReport.maxTurnCurrent / 1000.0f); - - return true; -} - -void NukiLockComponent::notify(Nuki::EventType event) { - ESP_LOGI(TAG, "received Nuki event - updating state"); - // Have to execute later as this runs in BLE scanner context and we can't do - // any BLE in this context. - schedule_update(); -} - -void NukiLockComponent::schedule_update() { - if (!update_scheduled_) { - update_scheduled_ = true; - defer([this]() { - update(); - update_scheduled_ = false; - }); - } -} - -void NukiLockComponent::setup() { - traits.set_supports_open(true); - traits.set_supported_states(std::set{ - lock::LOCK_STATE_NONE, lock::LOCK_STATE_LOCKED, lock::LOCK_STATE_UNLOCKED, - lock::LOCK_STATE_JAMMED, lock::LOCK_STATE_LOCKING, - lock::LOCK_STATE_UNLOCKING}); - publish_state(lock::LOCK_STATE_NONE); - - uint8_t mac[6]; - get_mac_address_raw(mac); - our_device_id_ = mac[0] + (mac[1] << 8) + (mac[2] << 16) + (mac[3] << 24); - // name will be used as part of the Preferences key to save credentials. - // There's a limit of 15 characters on key length, keep it predictable. - our_device_name_ = "nuki" + std::to_string(get_object_id_hash()); - - nuki_lock_ = new NukiLock::NukiLock(our_device_name_, our_device_id_); - scanner_.initialize(); - nuki_lock_->registerBleScanner(&scanner_); - nuki_lock_->initialize(); - nuki_lock_->setEventHandler(this); - - if (pin_set_) { - nuki_lock_->saveSecurityPincode(pin_); - } - - bool paired = nuki_lock_->isPairedWithLock(); - paired_binary_sensor_->publish_initial_state(paired); - error_text_sensor_->publish_state("No error"); - - set_interval("ble_loop", 320 /* ms*/, [this]() { ble_loop_(); }); - schedule_update(); -} - -void NukiLockComponent::unpair() { - ESP_LOGI(TAG, "unpairing Nuki lock"); - nuki_lock_->unPairNuki(); - // Force BLE update on the next loop. - last_passive_update_millis_ = 0; - // And a regular fetch. - schedule_update(); -} - -void NukiLockComponent::ble_loop_() { - scanner_.update(); - - unsigned long ts = millis(); - bool should_publish_update = last_passive_update_millis_ == 0 || - last_passive_update_millis_ + 60000 < ts; - - bool paired = nuki_lock_->isPairedWithLock(); - if (should_publish_update) { - last_passive_update_millis_ = ts; - paired_binary_sensor_->publish_state(paired); - } - - if (!paired) { - if (nuki_lock_->pairNuki() == Nuki::PairingResult::Success) { - ESP_LOGI(TAG, "Nuki lock successfully paired!"); - // Force BLE update on the next loop. - last_passive_update_millis_ = 0; - // And a regular fetch. - schedule_update(); - } else if (should_publish_update) { - ESP_LOGW(TAG, - "Nuki lock is not yet paired. Make sure Bluetooth pairing " - "is enabled in lock settings, then press and hold the button " - "on the lock for a few seconds until LED glows constantly"); - } - - return; - } - - nuki_lock_->updateConnectionState(); - // Update timestamp as we might have gotten a refresh packet on BLE. - ts = millis(); - unsigned long beaconLatency = ts - nuki_lock_->getLastReceivedBeaconTs(), - heartbeatLatency = ts - nuki_lock_->getLastHeartbeat(); - if (should_publish_update) { - if (beacon_rssi_sensor_ != nullptr) { - int rssi = nuki_lock_->getRssi(); - if (rssi != 0) { - beacon_rssi_sensor_->publish_state(rssi); - } - } - if (beacon_latency_sensor_ != nullptr) { - beacon_latency_sensor_->publish_state(beaconLatency); - } - if (heartbeat_latency_sensor_ != nullptr) { - heartbeat_latency_sensor_->publish_state(heartbeatLatency); - } - if (beacon_ble_address_text_sensor_ != nullptr) { - beacon_ble_address_text_sensor_->publish_state( - nuki_lock_->getBleAddress().toString()); - } - } - - if (restart_after_beacon_latency_ != 0 && - beaconLatency > restart_after_beacon_latency_) { - ESP_LOGE(TAG, - "Beacon latency %d higher than configured maximum %d. Restarting " - "the device"); - App.safe_reboot(); - } -} - -void NukiLockComponent::update() { - bool paired = nuki_lock_->isPairedWithLock(); - if (paired) { - if (time_source_ != nullptr) { - // Update time first, then request the state so we get updated time. - update_lock_time_(); - } - update_key_turner_state_(); - if (request_battery_reports_) { - update_battery_report_(); - } - } -} - -void NukiLockComponent::send_action_(NukiLock::LockAction action) { - if (!this->nuki_lock_->isPairedWithLock()) { - ESP_LOGE(TAG, "lock or unlock action %d called before a lock is paired", - action); - return; - } - Nuki::CmdResult result = this->nuki_lock_->lockAction(action); - if (result != Nuki::CmdResult::Success) { - ESP_LOGE(TAG, "setting state %d failed: %s", action, - Adapt::cmd_result_to_string(result).c_str()); - publish_state(lock::LOCK_STATE_NONE); - error_text_sensor_->publish_state( - Adapt::error_to_string(nuki_lock_->getLastError())); - schedule_update(); - } -} - -void NukiLockComponent::control(const lock::LockCall &call) { - auto action = *call.get_state(); - switch (action) { - case lock::LOCK_STATE_LOCKED: - publish_state(lock::LOCK_STATE_LOCKING); - send_action_(NukiLock::LockAction::Lock); - break; - - case lock::LOCK_STATE_UNLOCKED: - publish_state(lock::LOCK_STATE_UNLOCKING); - send_action_(NukiLock::LockAction::Unlock); - break; - - default: - ESP_LOGE(TAG, "unsupported lock state requested: %d", action); - return; - } - - // Final lock state will be published once Nuki informs us of an update. -} - -void NukiLockComponent::open_latch() { - publish_state(lock::LOCK_STATE_UNLOCKING); - send_action_(NukiLock::LockAction::Unlatch); -} - -void NukiLockComponent::dump_config() { - char device_id[256]; - sprintf(device_id, "%s (0x%.8x)", our_device_name_.c_str(), our_device_id_); - LOG_LOCK("", device_id, this); - - // Required. - LOG_BINARY_SENSOR(" ", "", paired_binary_sensor_); - LOG_TEXT_SENSOR(" ", "", error_text_sensor_); - LOG_BINARY_SENSOR(" ", "", battery_critical_binary_sensor_); - LOG_SENSOR(" ", "", battery_level_sensor_); - LOG_BINARY_SENSOR(" ", "", door_contact_binary_sensor_); - LOG_TEXT_SENSOR(" ", "", door_contact_sensor_text_sensor_); - LOG_TEXT_SENSOR(" ", "", trigger_text_sensor_); - LOG_BINARY_SENSOR(" ", "", night_mode_active_binary_sensor_); - - // Optional. - LOG_SENSOR(" ", "", beacon_rssi_sensor_); - LOG_SENSOR(" ", "", beacon_latency_sensor_); - LOG_SENSOR(" ", "", heartbeat_latency_sensor_); - LOG_TEXT_SENSOR(" ", "", beacon_ble_address_text_sensor_); - LOG_TEXT_SENSOR(" ", "", lock_current_datetime_text_sensor_); - LOG_SENSOR(" ", "", config_update_count_sensor_); - LOG_TEXT_SENSOR(" ", "", last_action_text_sensor_); - LOG_TEXT_SENSOR(" ", "", last_action_trigger_text_sensor_); - LOG_TEXT_SENSOR(" ", "", last_action_completion_status_text_sensor_); - - if (request_battery_reports_) { - // Optional sensors - battery report. - LOG_SENSOR(" ", "", battery_voltage_sensor_); - LOG_SENSOR(" ", "", battery_resistance_sensor_); - LOG_SENSOR(" ", "", last_action_lowest_voltage_sensor_); - LOG_SENSOR(" ", "", last_action_start_voltage_sensor_); - LOG_SENSOR(" ", "", last_action_lock_distance_sensor_); - LOG_SENSOR(" ", "", last_action_start_temperature_sensor_); - LOG_SENSOR(" ", "", last_action_battery_drain_sensor_); - LOG_SENSOR(" ", "", last_action_max_turn_current_sensor_); - } - - ESP_LOGCONFIG(TAG, " Restart after beacon latency: %dms", - restart_after_beacon_latency_); - if (time_source_ != nullptr) { - ESP_LOGCONFIG(TAG, " Time source: set"); - } - if (pin_set_) { - ESP_LOGCONFIG( - TAG, " Pin: " ESPHOME_LOG_SECRET_BEGIN "%d" ESPHOME_LOG_SECRET_END, - pin_); - } -} - -} // namespace nuki_lock -} // namespace esphome diff --git a/components/nuki_lock/nuki_lock.h b/components/nuki_lock/nuki_lock.h deleted file mode 100644 index 174538f..0000000 --- a/components/nuki_lock/nuki_lock.h +++ /dev/null @@ -1,145 +0,0 @@ -#pragma once - -#include "BleScanner.h" -#include "NukiConstants.h" -#include "NukiLock.h" -#include "esphome/components/binary_sensor/binary_sensor.h" -#include "esphome/components/button/button.h" -#include "esphome/components/lock/lock.h" -#include "esphome/components/sensor/sensor.h" -#include "esphome/components/text_sensor/text_sensor.h" -#include "esphome/components/time/real_time_clock.h" -#include "esphome/core/component.h" -#include "esphome/core/time.h" - -namespace esphome { -namespace nuki_lock { - -class NukiLockComponent : public lock::Lock, - public PollingComponent, - public Nuki::SmartlockEventHandler { - public: - explicit NukiLockComponent() - : Lock(), - last_passive_update_millis_(0), - restart_after_beacon_latency_(0), - update_scheduled_(false), - request_battery_reports_(false), - pin_set_(false) {}; - - // Component. - void setup() override; - float get_setup_priority() const override { - return setup_priority::HARDWARE - 1.0f; - } - void dump_config() override; - - // PollingComponent. - void update() override; - - // Nuki::SmartlockEventHandler. - void notify(Nuki::EventType event); - - // Passive updates (predefined update frequency). - SUB_BINARY_SENSOR(paired) - SUB_SENSOR(beacon_rssi) - SUB_SENSOR(beacon_latency) - SUB_SENSOR(heartbeat_latency) - SUB_TEXT_SENSOR(beacon_ble_address) - - // Active updates (configured update_interval frequency). - // Key turner state. - SUB_BINARY_SENSOR(battery_critical) - SUB_SENSOR(battery_level) - SUB_BINARY_SENSOR(door_contact) - SUB_TEXT_SENSOR(door_contact_sensor) - SUB_TEXT_SENSOR(lock_current_datetime) - SUB_TEXT_SENSOR(error) - SUB_TEXT_SENSOR(trigger) - SUB_SENSOR(config_update_count) - SUB_TEXT_SENSOR(last_action) - SUB_TEXT_SENSOR(last_action_trigger) - SUB_TEXT_SENSOR(last_action_completion_status) - SUB_BINARY_SENSOR(night_mode_active) - // Battery report. - SUB_SENSOR(battery_voltage) - SUB_SENSOR(battery_resistance) - SUB_SENSOR(last_action_lowest_voltage) - SUB_SENSOR(last_action_start_voltage) - SUB_SENSOR(last_action_lock_distance) - SUB_SENSOR(last_action_start_temperature) - SUB_SENSOR(last_action_battery_drain) - SUB_SENSOR(last_action_max_turn_current) - - // Actions. - SUB_BUTTON(lock_n_go) - SUB_BUTTON(unpair) - SUB_BUTTON(request_state) - - void set_request_battery_reports(bool value) { - request_battery_reports_ = value; - } - - void set_restart_after_beacon_latency(unsigned long value) { - restart_after_beacon_latency_ = value; - } - - void set_pin(unsigned long value) { - pin_ = value; - pin_set_ = true; - } - - void set_time_source(time::RealTimeClock *value) { time_source_ = value; } - - // RequestStateButton. - void schedule_update(); - - // UnpairButton. - void unpair(); - - protected: - // lock::Lock. - void control(const lock::LockCall &call) override; - void open_latch() override; - - private: - bool update_key_turner_state_(); - bool update_battery_report_(); - bool update_lock_time_(); - void ble_loop_(); - void send_action_(NukiLock::LockAction action); - - NukiLock::NukiLock *nuki_lock_; - BleScanner::Scanner scanner_; - time::RealTimeClock *time_source_{nullptr}; - uint16_t pin_; - bool pin_set_; - - unsigned long last_passive_update_millis_; - unsigned long restart_after_beacon_latency_; - bool update_scheduled_; - bool request_battery_reports_; - - uint32_t our_device_id_; - std::string our_device_name_; -}; - -class RequestStateButton : public button::Button, - public Parented { - public: - RequestStateButton() = default; - - protected: - void press_action() override { get_parent()->schedule_update(); } -}; - -class UnpairButton : public button::Button, public Parented { - public: - UnpairButton() = default; - - protected: - void press_action() override { get_parent()->unpair(); } -}; - -} // namespace nuki_lock -} // namespace esphome diff --git a/components/somfy/somfy.cpp b/components/somfy/somfy.cpp index 7932213..daa8921 100644 --- a/components/somfy/somfy.cpp +++ b/components/somfy/somfy.cpp @@ -166,7 +166,7 @@ void SomfyRTSCover::setup() { /*qos=*/1 /* (at least once) */); } else { this->rolling_code_ = 0; - this->mark_failed("Missing rolling_code"); + this->mark_failed(LOG_STR("Missing rolling_code")); ESP_LOGE(TAG, "No rolling code in flash, and MQTT client unavailable"); } } diff --git a/components/syslog/syslog.cpp b/components/syslog/syslog.cpp index 90f65dd..8355f20 100644 --- a/components/syslog/syslog.cpp +++ b/components/syslog/syslog.cpp @@ -63,21 +63,22 @@ Syslog::Syslog() { this->errors_encountered_ = 0; } +void Syslog::on_log(uint8_t level, const char *tag, const char *raw_message, size_t raw_message_len) { + if (level > this->min_log_level_) return; + + std::string message = std::string(raw_message, raw_message_len); + if (this->strip_color_codes_) { + std::string clean_message = remove_ansi_colors(message); + this->log(level, tag, clean_message); + } else { + this->log(level, tag, message); + } +} + void Syslog::setup() { #ifdef USE_LOGGER if (logger::global_logger != nullptr && this->forward_logger_) { - logger::global_logger->add_on_log_callback( - [this](int level, const char *tag, const char *raw_message, size_t raw_message_len) { - if (level > this->min_log_level_) return; - - std::string message = std::string(raw_message, raw_message_len); - if (this->strip_color_codes_) { - std::string clean_message = remove_ansi_colors(message); - this->log(level, tag, clean_message); - } else { - this->log(level, tag, message); - } - }); + logger::global_logger->add_log_listener(this); } #endif diff --git a/components/syslog/syslog.h b/components/syslog/syslog.h index 1b9a744..85672a6 100644 --- a/components/syslog/syslog.h +++ b/components/syslog/syslog.h @@ -16,6 +16,7 @@ #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "esphome/core/log.h" +#include "esphome/components/logger/logger.h" #if defined(USE_SOCKET_IMPL_BSD_SOCKETS) || \ defined(USE_SOCKET_IMPL_LWIP_SOCKETS) @@ -28,7 +29,7 @@ namespace esphome { namespace syslog { -class Syslog : public Component { +class Syslog : public Component, public logger::LogListener { public: explicit Syslog(); @@ -49,6 +50,7 @@ class Syslog : public Component { void set_forward_logger(bool forward) { this->forward_logger_ = forward; } void set_strip_color_codes(bool strip) { this->strip_color_codes_ = strip; } + void on_log(uint8_t, const char *, const char *, size_t) override; void log(int level, const std::string &tag, const std::string &msg); protected: diff --git a/flake.lock b/flake.lock index 10a7414..5fd6f52 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1765472234, - "narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=", + "lastModified": 1767379071, + "narHash": "sha256-EgE0pxsrW9jp9YFMkHL9JMXxcqi/OoumPJYwf+Okucw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b", + "rev": "fb7944c166a3b630f177938e478f0378e64ce108", "type": "github" }, "original": { diff --git a/templates/syslog.yaml b/templates/syslog.yaml index 832f8c5..510a056 100644 --- a/templates/syslog.yaml +++ b/templates/syslog.yaml @@ -2,6 +2,7 @@ external_components: # Path is relative to the main YAML file, not this device_base template! - source: components +# https://github.com/esphome/esphome/issues/12591 syslog: ip_address: !secret syslog_server