Added ads131m08, etc. external component
This commit is contained in:
parent
da6e5961e9
commit
d0f97b46a6
6
.gitignore
vendored
6
.gitignore
vendored
@ -2,10 +2,4 @@
|
|||||||
# This is an example and may include too much for your use-case.
|
# This is an example and may include too much for your use-case.
|
||||||
# You can modify this file to suit your needs.
|
# You can modify this file to suit your needs.
|
||||||
/.esphome/
|
/.esphome/
|
||||||
.esphome/external_components
|
|
||||||
/secrets.yaml
|
/secrets.yaml
|
||||||
/.esphome.bak/
|
|
||||||
/fonts/
|
|
||||||
**/__pycache__/
|
|
||||||
components/ads131m08/__pycache__/sensor.cpython-312.pyc
|
|
||||||
components/ads131m08/__pycache__/__init__.cpython-312.pyc
|
|
||||||
|
|||||||
@ -1,29 +1,80 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
from esphome.components import spi
|
from esphome.components import spi
|
||||||
from esphome.const import (
|
from esphome.const import CONF_ID #, CONF_MODE
|
||||||
CONF_ID
|
|
||||||
)
|
# Import ThreadModel enum
|
||||||
|
#from esphome.core import ThreadModel
|
||||||
CONF_DRDY_PIN = "drdy_pin"
|
|
||||||
CONF_REFERENCE_VOLTAGE = "reference_voltage"
|
MULTI_CONF = True
|
||||||
|
|
||||||
DEPENDENCIES = ["spi"]
|
CONF_DRDY_PIN = "drdy_pin"
|
||||||
ads131m08_ns = cg.esphome_ns.namespace("ads131m08")
|
CONF_SYNC_RESET_PIN = "sync_reset_pin"
|
||||||
ADS131M08Hub = ads131m08_ns.class_("ADS131M08Hub", cg.Component, spi.SPIDevice)
|
CONF_REFERENCE_VOLTAGE = "reference_voltage"
|
||||||
|
CONF_CLOCK_FREQUENCY = "clock_frequency"
|
||||||
CONFIG_SCHEMA = cv.Schema({
|
CONF_ADS131M08_ID = "_ads131m08_id"
|
||||||
cv.GenerateID(): cv.declare_id(ADS131M08Hub),
|
CONF_OSR = "oversampling_ratio"
|
||||||
cv.Required(CONF_DRDY_PIN): pins.internal_gpio_input_pin_schema,
|
|
||||||
cv.Optional(CONF_REFERENCE_VOLTAGE, default=1.2): cv.float_range(min=1.1, max=1.3),
|
DEPENDENCIES = ["spi"]
|
||||||
}).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema(cs_pin_required=True))
|
|
||||||
|
ads131m08_ns = cg.esphome_ns.namespace("ads131m08")
|
||||||
async def to_code(config):
|
ADS131M08Hub = ads131m08_ns.class_("ADS131M08Hub", cg.Component, spi.SPIDevice)
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
|
||||||
await cg.register_component(var, config)
|
OSR = ads131m08_ns.enum("ADS131M08_OVERSAMPLING_RATIO")
|
||||||
await spi.register_spi_device(var, config)
|
ALLOWED_OSRS = {
|
||||||
drdy = await cg.gpio_pin_expression(config[CONF_DRDY_PIN])
|
128: OSR.OSR_128,
|
||||||
reference_voltage = config[CONF_REFERENCE_VOLTAGE]
|
256: OSR.OSR_256,
|
||||||
cg.add(var.set_reference_voltage(reference_voltage))
|
512: OSR.OSR_512,
|
||||||
cg.add(var.set_drdy_pin(drdy))
|
1024: OSR.OSR_1024,
|
||||||
|
2048: OSR.OSR_2048,
|
||||||
|
4096: OSR.OSR_4096,
|
||||||
|
8192: OSR.OSR_8192,
|
||||||
|
16256: OSR.OSR_16256,
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLOWED_CLOCK_FREQUENCIES = {
|
||||||
|
2048000: 2048000,
|
||||||
|
4096000: 4096000,
|
||||||
|
8192000: 8192000,
|
||||||
|
"2048kHz": 2048000,
|
||||||
|
"4096kHz": 4096000,
|
||||||
|
"8192kHz": 8192000,
|
||||||
|
"2.048MHz": 2048000,
|
||||||
|
"4.096MHz": 4096000,
|
||||||
|
"8.192MHz": 8192000,
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(ADS131M08Hub),
|
||||||
|
cv.Required(CONF_DRDY_PIN): pins.internal_gpio_input_pin_schema,
|
||||||
|
cv.Optional(CONF_SYNC_RESET_PIN): pins.internal_gpio_input_pin_schema,
|
||||||
|
cv.Optional(CONF_CLOCK_FREQUENCY, default="8192kHz"): cv.All(cv.frequency, cv.one_of(*ALLOWED_CLOCK_FREQUENCIES.keys())),
|
||||||
|
cv.Optional(CONF_OSR, default=1024): cv.enum(ALLOWED_OSRS, int=True),
|
||||||
|
cv.Optional(CONF_REFERENCE_VOLTAGE, default=1.2): cv.float_range(min=1.1, max=1.3),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(spi.spi_device_schema(cs_pin_required=True, default_data_rate="10MHz"))
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
drdy = await cg.gpio_pin_expression(config[CONF_DRDY_PIN])
|
||||||
|
if CONF_SYNC_RESET_PIN in config:
|
||||||
|
sync_reset = await cg.gpio_pin_expression(config[CONF_SYNC_RESET_PIN])
|
||||||
|
cg.add(var.set_sync_reset_pin(sync_reset))
|
||||||
|
clock_frequency = ALLOWED_CLOCK_FREQUENCIES[config[CONF_CLOCK_FREQUENCY]]
|
||||||
|
cg.add(var.set_clock_frequency(clock_frequency))
|
||||||
|
osr = config[CONF_OSR]
|
||||||
|
cg.add(var.set_osr(osr))
|
||||||
|
reference_voltage = config[CONF_REFERENCE_VOLTAGE]
|
||||||
|
cg.add(var.set_reference_voltage(reference_voltage))
|
||||||
|
cg.add(var.set_drdy_pin(drdy))
|
||||||
|
#cg.add(var.set_thread_model(ThreadModel.MULTI_ATOMICS))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,503 +1,229 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
// using external voltage reference
|
// using external voltage reference
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/automation.h"
|
||||||
#include "esphome/components/spi/spi.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/core/optional.h"
|
||||||
|
#include "ads131m08_defs.h"
|
||||||
namespace esphome {
|
#include "frame.h"
|
||||||
namespace ads131m08 {
|
#include <string>
|
||||||
|
#include <charconv>
|
||||||
typedef union {
|
#include <format>
|
||||||
|
|
||||||
int32_t i;
|
//#include "esphome/core/component.h"
|
||||||
float f;
|
//#include <esphome/core/hal.h>
|
||||||
uint16_t u[2];
|
#include "esphome/components/spi/spi.h"
|
||||||
uint8_t b[4];
|
#include "esphome/components/sensor/sensor.h"
|
||||||
} flex32_t;
|
//
|
||||||
|
//#include <vector>
|
||||||
|
//#include <esphome/core/gpio.h>
|
||||||
/* Adc Structure. Ch can be read as int32 or float*/
|
//#include <freertos/FreeRTOS.h>
|
||||||
struct AdcOutput
|
//#include <freertos/semphr.h>
|
||||||
{
|
//#include <atomic>
|
||||||
uint16_t status;
|
|
||||||
flex32_t ch[8];
|
namespace esphome {
|
||||||
};
|
namespace ads131m08 {
|
||||||
|
|
||||||
enum ADS131M08_DRDY_STATE
|
static const int MAX_CHANNELS = 11; // for debugging
|
||||||
{
|
static const int ADC_CHANNELS = 8;
|
||||||
DS_LOGIC_HIGH = 0, // DEFAULT
|
static const int SAMPLE_TIME_SENSOR = 8; // for debugging
|
||||||
DS_HI_Z = 1
|
static const int MAX_SAMPLES_SENSOR = 9; // for debugging
|
||||||
};
|
static const int CRC_ERRORS_SENSOR = 10; // for debugging
|
||||||
|
|
||||||
enum ADS131M08_POWERMODE
|
typedef union {
|
||||||
{
|
|
||||||
PM_VERY_LOW_POWER = 0,
|
int32_t i;
|
||||||
PM_LOW_POWER = 1,
|
float f;
|
||||||
PM_HIGH_RESOLUTION = 2 // DEFAULT
|
uint16_t u[2];
|
||||||
};
|
uint8_t b[4];
|
||||||
|
} flex32_t;
|
||||||
enum ADS131M08_PGA_GAIN
|
|
||||||
{
|
|
||||||
PGA_1 = 0,
|
/* Adc Structure. Ch can be read as int32 or float*/
|
||||||
PGA_2 = 1,
|
struct AdcOutput
|
||||||
PGA_4 = 2,
|
{
|
||||||
PGA_8 = 3,
|
uint16_t status;
|
||||||
PGA_16 = 4,
|
flex32_t ch[ADC_CHANNELS];
|
||||||
PGA_32 = 5,
|
};
|
||||||
PGA_64 = 6,
|
|
||||||
PGA_128 = 7,
|
//#define SET_IRAM IRAM_ATTR
|
||||||
PGA_INVALID
|
#define SET_IRAM
|
||||||
};
|
|
||||||
|
typedef std::vector<uint8_t> spiframe;
|
||||||
enum ADS131M08_INPUT_CHANNEL_MUX
|
typedef uint_str<uint16_t>::Ty_string uint16_str; // we want to use the stack to pass small arrays
|
||||||
{
|
|
||||||
ICM_AIN0P_AIN0N = 0, // DEFAULT
|
class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_8MHZ>
|
||||||
ICM_INPUT_SHORTED = 1,
|
{
|
||||||
ICM_POSITIVE_DC_TEST_SIGNAL = 2,
|
friend class ads131m08_select;
|
||||||
ICM_NEGATIVE_DC_TEST_SIGNAL = 3,
|
public:
|
||||||
};
|
enum crc_pos: uint8_t {
|
||||||
|
crc_after_frame,
|
||||||
enum ADS131M08_OVERSAMPLING_RATIO
|
crc_after_firstword,
|
||||||
{
|
};
|
||||||
OSR_128 = 0,
|
// register config values used
|
||||||
OSR_256 = 1,
|
static constexpr uint16_t reg_clock_cfg = MASK_CLOCK_EXTREF_EN | OSR_1024 | PM_HIGH_RESOLUTION;
|
||||||
OSR_512 = 2,
|
static constexpr uint16_t reg_clock_allch_on = MASK_CLOCK_ALLCH | reg_clock_cfg;
|
||||||
OSR_1024 = 3, // default
|
static constexpr uint16_t reg_clock_allch_off = ~MASK_CLOCK_ALLCH & reg_clock_cfg;
|
||||||
OSR_2048 = 4,
|
static constexpr uint16_t reg_mode_cfg16 = WLENGTH_16_BITS | DRDY_FMT_PULSE | TIMEOUT_ENABLED;
|
||||||
OSR_4096 = 5,
|
static constexpr uint16_t reg_mode_cfg24 = WLENGTH_24_BITS | DRDY_FMT_PULSE | TIMEOUT_ENABLED;
|
||||||
OSR_8192 = 6,
|
static constexpr uint16_t reg_mode_cfg32 = WLENGTH_32_BITS_MSB_SIGN_EXTEND | DRDY_FMT_PULSE | TIMEOUT_ENABLED;
|
||||||
OSR_16384 = 7
|
// masks for the above
|
||||||
};
|
static constexpr uint16_t reg_clock_cfg_mask = MASK_CLOCK_EXTREF_EN | MASK_CLOCK_OSR | MASK_CLOCK_PWR;
|
||||||
|
static constexpr uint16_t reg_clock_allch_mask = MASK_CLOCK_ALLCH_OFF | reg_clock_cfg_mask;
|
||||||
enum ADS131M08_WAIT_TIME
|
static constexpr uint16_t reg_mode_cfg_mask = MASK_MODE_WLENGTH | MASK_MODE_DRDY_FMT | MASK_MODE_TIMEOUT;
|
||||||
{
|
// Semaphore handles
|
||||||
WT_128 = 856,
|
SemaphoreHandle_t data_ready_semhandle = NULL;
|
||||||
WT_256 = 1112,
|
//SemaphoreHandle_t spi_mutex = NULL;
|
||||||
WT_512 = 1624,
|
// from datasheet pg. 93:
|
||||||
WT_1024 = 2648,
|
const int numFrameWords = 10; // Number of words in a full ADS131M08 SPI frame
|
||||||
WT_2048 = 4696,
|
spiframe base_frame;
|
||||||
WT_4096 = 8792,
|
bool firstRead = true; // Flag to tell us if we are reading ADC data for the first time
|
||||||
WT_8192 = 16984,
|
signed long adcData; // Location where DMA will store ADC data in memory, length defined elsewhere
|
||||||
WT_16384 = 33368
|
ADS131M08Hub();
|
||||||
};
|
void txf_init();
|
||||||
|
bool adc_initialize(uint8_t word_length);
|
||||||
// MODE Register
|
bool adc_set_word_length(uint8_t word_length);
|
||||||
enum ADS131M08_RESET : uint16_t
|
// end of from datasheet
|
||||||
{
|
void set_channel_gain(uint8_t channel, ADS131M08_PGA_GAIN gain);
|
||||||
MODE_NO_RESET = 0x0000, // DEFAULT
|
//virtual void spi_setup() override;
|
||||||
MODE_RESET_HAPPENED = 0x0400
|
void setup() override;
|
||||||
};
|
void loop() override;
|
||||||
|
void set_drdy_pin(InternalGPIOPin *pin) { drdy_pin_ = pin; }
|
||||||
enum ADS131M08_CRC_TYPE : uint16_t
|
void set_sync_reset_pin(InternalGPIOPin *pin) { sync_reset_pin_ = pin; }
|
||||||
{
|
void set_clock_frequency(float clock_frequency) { this->clock_frequency_ = clock_frequency; }
|
||||||
CRC_CCITT_16BIT = 0x0000, // DEFAULT
|
void register_sensor_ac(int channel, sensor::Sensor *s) { sensors_ac[channel] = s; }
|
||||||
CRC_ANSI_16BIT = 0x0800
|
void register_sensor_dc(int channel, sensor::Sensor *s) { sensors_dc[channel] = s; }
|
||||||
};
|
void set_reference_voltage(float reference_voltage) { this->reference_voltage_ = reference_voltage; }
|
||||||
|
void set_osr(uint16_t osr) { this->osr_ = osr; }
|
||||||
enum ADS131M08_WORD_LENGTH : uint16_t
|
void dump_config() override;
|
||||||
{
|
|
||||||
WLENGTH_16_BITS = 0x0000,
|
// from tpcorrea
|
||||||
WLENGTH_24_BITS = 0x0100, // DEFAULT
|
ADS131M08_PGA_GAIN pgaGain[ADC_CHANNELS] = {PGA_1}; // Store the current PGA gain settings for each channel
|
||||||
WLENGTH_32_BITS_LSB_ZERO_PADDING = 0x0200,
|
int8_t is_data_ready_soft(uint8_t channel);
|
||||||
WLENGTH_32_BITS_MSB_SIGN_EXTEND = 0x0300
|
bool is_data_ready();
|
||||||
};
|
bool is_reset_status();
|
||||||
|
bool is_lock_spi();
|
||||||
enum ADS131M08_TIMEOUT : uint16_t
|
bool set_drdy_format(uint8_t drdy_format);
|
||||||
{
|
bool set_drdy_idle_state(uint8_t drdy_state);
|
||||||
TIMEOUT_DISABLED = 0x0000,
|
bool set_power_mode(uint8_t power_mode);
|
||||||
TIMEOUT_ENABLED = 0x0010 // DEFAULT
|
bool set_channel_enable(uint8_t channel, bool enable);
|
||||||
};
|
bool set_channel_pga(uint8_t channel, ADS131M08_PGA_GAIN pga);
|
||||||
|
ADS131M08_PGA_GAIN get_channel_pga(uint8_t channel);
|
||||||
enum ADS131M08_DRDY_SELECTION : uint16_t
|
void set_global_chop(uint16_t global_chop);
|
||||||
{
|
void set_global_chop_delay(uint16_t delay);
|
||||||
DRDY_SEL_MOST_LAGGING = 0x0000, // DEFAULT
|
bool set_channel_input_selection(uint8_t channel, ADS131M08_INPUT_CHANNEL_MUX input);
|
||||||
DRDY_SEL_LOGICAL_OR = 0x0004,
|
bool set_channel_offset_calibration(uint8_t channel, int32_t offset);
|
||||||
DRDY_SEL_MOST_LEADING_CHAN = 0x0008,
|
bool set_channel_gain_calibration(uint8_t channel, uint32_t gain);
|
||||||
DRDY_SEL_MOST_LEADING_CHAN = 0x000C
|
bool set_channel_phase_calibration(uint8_t channel, int16_t phase_offset);
|
||||||
};
|
bool set_dcblock_filter_disable(uint8_t channel, bool disable);
|
||||||
enum ADS131M08_DRDY_FORMAT : uint16_t
|
void set_measure_rms(uint8_t channel, bool enable);
|
||||||
{
|
float get_sampled_value(uint8_t channel) { return sampled_values_[channel]; }
|
||||||
DRDY_FMT_LEVEL = 0x0000, // Logic low (default)
|
bool set_reg_osr();
|
||||||
DRDY_FMT_PULSE = 0x0001 // Low pulse with a fixed duration
|
void set_full_scale(uint8_t channel, float scale);
|
||||||
};
|
float get_full_scale(uint8_t channel);
|
||||||
// end of MODE Register
|
uint16_t get_id();
|
||||||
|
uint16_t get_mode_reg();
|
||||||
// GAIN1 Register
|
uint16_t get_clock_reg();
|
||||||
enum ADS131M08_GAIN1_CHANNEL_PGA : uint16_t {
|
uint16_t get_cfg_reg();
|
||||||
PGAGAIN0_1 = 0x0000, // default
|
AdcOutput read_adc_raw();
|
||||||
PGAGAIN0_2 = 0x0001,
|
AdcOutput read_adc_float();
|
||||||
PGAGAIN0_4 = 0x0002,
|
|
||||||
PGAGAIN0_8 = 0x0003,
|
protected:
|
||||||
PGAGAIN0_16 = 0x0004,
|
static void IRAM_ATTR isr_handler(ADS131M08Hub *arg);
|
||||||
PGAGAIN0_32 = 0x0005,
|
//volatile bool data_ready_{false};
|
||||||
PGAGAIN0_64 = 0x0006,
|
//static void isr(ADS131M08Hub *arg);
|
||||||
PGAGAIN0_128 = 0x0007,
|
float reference_voltage_;
|
||||||
PGAGAIN1_1 = 0x0000, // default
|
float clock_frequency_;
|
||||||
PGAGAIN1_2 = 0x0010,
|
InternalGPIOPin *drdy_pin_;
|
||||||
PGAGAIN1_4 = 0x0020,
|
InternalGPIOPin *sync_reset_pin_= {nullptr};
|
||||||
PGAGAIN1_8 = 0x0030,
|
sensor::Sensor *sensors_ac[MAX_CHANNELS] = {nullptr};
|
||||||
PGAGAIN1_16 = 0x0040,
|
sensor::Sensor *sensors_dc[MAX_CHANNELS] = {nullptr};
|
||||||
PGAGAIN1_32 = 0x0050,
|
float sampled_values_[ADC_CHANNELS];
|
||||||
PGAGAIN1_64 = 0x0060,
|
bool rms_enabled_[ADC_CHANNELS];
|
||||||
PGAGAIN1_128 = 0x0070,
|
bool rms_calc_req_{false};
|
||||||
PGAGAIN2_1 = 0x0000, // default
|
uint16_t osr_{3};
|
||||||
PGAGAIN2_2 = 0x0100,
|
uint8_t update_adc_word_length();
|
||||||
PGAGAIN2_4 = 0x0200,
|
void SET_IRAM read_single();
|
||||||
PGAGAIN2_8 = 0x0300,
|
std::pair<uint32_t, uint32_t> SET_IRAM read_multi();
|
||||||
PGAGAIN2_16 = 0x0400,
|
bool adc_lock(bool enable);
|
||||||
PGAGAIN2_32 = 0x0500,
|
bool adc_register_write(uint16_t address, uint16_t data);
|
||||||
PGAGAIN2_64 = 0x0600,
|
bool adc_register_write(uint16_t address, const uint16_str& data);
|
||||||
PGAGAIN2_128 = 0x0700,
|
uint16_str adc_register_read(uint8_t address, uint8_t nregs);
|
||||||
PGAGAIN3_1 = 0x0000, // default
|
bool adc_register_write_masked(uint8_t address, uint16_t value, uint16_t mask, int line);
|
||||||
PGAGAIN3_2 = 0x1000,
|
bool adc_register_write_masked(uint8_t start_address, const uint16_str& values, const uint16_str& masks, int line);
|
||||||
PGAGAIN3_4 = 0x2000,
|
uint16_t readRegister(uint8_t address);
|
||||||
PGAGAIN3_8 = 0x3000,
|
bool adc_reset_retry();
|
||||||
PGAGAIN3_16 = 0x4000,
|
bool adc_soft_reset();
|
||||||
PGAGAIN3_32 = 0x5000, // Set PGA gain to 32 for channel
|
void adc_hard_reset();
|
||||||
PGAGAIN3_64 = 0x6000,
|
void adc_sync();
|
||||||
PGAGAIN3_128 = 0x7000
|
void write_byte(uint8_t byte);
|
||||||
};
|
bool write(uint32_t data, uint8_t adcWordLength);
|
||||||
// end of GAIN1 Register
|
uint8_t read_byte();
|
||||||
|
void write_array(const spiframe& data);
|
||||||
// GAIN2 Register
|
void SET_IRAM read_array(spiframe& buffer);
|
||||||
enum ADS131M08_GAIN2_CHANNEL_PGA : uint16_t {
|
void transfer_array(const spiframe& data_out, spiframe& data_in);
|
||||||
PGAGAIN4_1 = 0x0000, // default
|
uint16_t SET_IRAM get_crc(const spiframe& frame);
|
||||||
PGAGAIN4_2 = 0x0001,
|
bool SET_IRAM check_crc(const spiframe& frame_with_crc);
|
||||||
PGAGAIN4_4 = 0x0002,
|
size_t SET_IRAM add_crc(spiframe& frame, crc_pos crcpos);
|
||||||
PGAGAIN4_8 = 0x0003,
|
uint16_t SET_IRAM read_frame_crc(const spiframe& frame);
|
||||||
PGAGAIN4_16 = 0x0004,
|
uint16_t SET_IRAM crc(uint16_t crc_register, uint8_t data);
|
||||||
PGAGAIN4_32 = 0x0005,
|
bool SET_IRAM set_frame_word(spiframe& frame, int w_index, uint16_t data); // write 16 bit data to first two bytes of word
|
||||||
PGAGAIN4_64 = 0x0006,
|
bool SET_IRAM set_frame_word(spiframe& frame, int w_index, uint32_t data);
|
||||||
PGAGAIN4_128 = 0x0007,
|
uint32_t SET_IRAM get_unsigned_frame_word(const spiframe& frame, int w_index, bool force_16bits = false);
|
||||||
PGAGAIN5_1 = 0x0000, // default
|
int32_t SET_IRAM get_sign_ext_frame_word(const spiframe& frame, int w_index);
|
||||||
PGAGAIN5_2 = 0x0010,
|
std::atomic<int> adc_init_{0};
|
||||||
PGAGAIN5_4 = 0x0020,
|
std::atomic<int> cs_ctr_{0}; // Counter to track nested CS enable/disable calls for proper handling of multiple transfers in a row
|
||||||
PGAGAIN5_8 = 0x0030,
|
std::atomic<uint16_t> isr_ctr_{0};
|
||||||
PGAGAIN5_16 = 0x0040,
|
void enable(const char *txt);
|
||||||
PGAGAIN5_32 = 0x0050,
|
void disable(const char *txt);
|
||||||
PGAGAIN5_64 = 0x0060,
|
struct chipselect {
|
||||||
PGAGAIN5_128 = 0x0070,
|
ADS131M08Hub* parent_{nullptr};
|
||||||
PGAGAIN6_1 = 0x0000, // default
|
const char *txt_;
|
||||||
PGAGAIN6_2 = 0x0100,
|
chipselect(ADS131M08Hub *parent, const char *txt = nullptr) {
|
||||||
PGAGAIN6_4 = 0x0200,
|
parent_ = parent;
|
||||||
PGAGAIN6_8 = 0x0300,
|
if(parent_ != nullptr)
|
||||||
PGAGAIN6_16 = 0x0400,
|
txt_ = txt;
|
||||||
PGAGAIN6_32 = 0x0500,
|
parent_->enable(txt_);
|
||||||
PGAGAIN6_64 = 0x0600,
|
}
|
||||||
PGAGAIN6_128 = 0x0700,
|
~chipselect() {
|
||||||
PGAGAIN7_1 = 0x0000, // default
|
if(parent_ != nullptr) {
|
||||||
PGAGAIN7_2 = 0x1000,
|
parent_->disable(txt_);
|
||||||
PGAGAIN7_4 = 0x2000,
|
parent_ = nullptr;
|
||||||
PGAGAIN7_8 = 0x3000,
|
}
|
||||||
PGAGAIN7_16 = 0x4000,
|
}
|
||||||
PGAGAIN7_32 = 0x5000,
|
};
|
||||||
PGAGAIN7_64 = 0x6000,
|
private:
|
||||||
PGAGAIN7_128 = 0x7000
|
|
||||||
};
|
uint8_t adc_word_length_{24};
|
||||||
// end of GAIN2 Register
|
float conversion_factor_{1.2/8388608.0};
|
||||||
|
const uint32_t sample_time_ = 40000; // 250 ms
|
||||||
|
float sps_{0.0f};
|
||||||
// Commands
|
uint32_t num_samples_[ADC_CHANNELS];
|
||||||
enum ADS131M08_COMMANDS : uint16_t {
|
int64_t sample_sum_[ADC_CHANNELS];
|
||||||
CMD_NULL = 0x0000, // No operation; used to read STATUS register
|
float sample_squared_sum_[ADC_CHANNELS];
|
||||||
CMD_RESET = 0x0011, // RESET the device
|
// for debug only
|
||||||
CMD_STANDBY = 0x0022, // Place the device into standby mode
|
std::string frame_to_string(const spiframe& frame);
|
||||||
CMD_WAKEUP = 0x0033, // Wake up device from standby mode to conversion mode
|
std::string conversion_frame_to_string(const spiframe& frame);
|
||||||
CMD_LOCK = 0x0555, // Lock the interface such that only the NULL, UNLOCK, and RREG commands are valid
|
std::string command_to_string(uint16_t cmdadr);
|
||||||
CMD_UNLOCK = 0x0655, // Unlock the interface after the interface is locked
|
void print_command_response_to_string(uint16_t cmdadr_sent, const spiframe& frame);
|
||||||
CMD_RREG = 0xA000, // Read register command base; number of registers to read added to lower byte; register address to upper byte
|
std::string rwreg_command_frame_to_string(const spiframe& frame);
|
||||||
CMD_WREG = 0x6000, // Write register command base; number of registers to write added to lower byte; register address to upper byte
|
std::string status_to_string(uint16_t response);
|
||||||
};
|
std::string reg_data_to_string(int address, uint16_t data, bool nameonly = false);
|
||||||
|
std::string reg_addr_to_string(int address);
|
||||||
// Responses
|
std::string reg_config_to_string(int address, uint16_t data, bool nameonly = false);
|
||||||
enum ADS131M08_RESPONSES : uint16_t {
|
//temp
|
||||||
RSP_RESET_OK = 0xFF28,
|
int first_read_data {0};
|
||||||
RSP_RESET_NOK = 0x0011
|
};
|
||||||
};
|
|
||||||
|
#ifndef CHIP_SELECT
|
||||||
enum ADS131M08_REG {
|
# if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||||
REG_ID = 0x00,
|
# define CHIP_SELECT volatile chipselect cs(this, __FUNCTION__);
|
||||||
REG_STATUS = 0x01,
|
# else
|
||||||
REG_MODE = 0x02,
|
# define CHIP_SELECT volatile chipselect cs(this);
|
||||||
REG_CLOCK = 0x03,
|
# endif
|
||||||
REG_GAIN1 = 0x04,
|
# define CHIP_SELECTx volatile chipselect cs(this);
|
||||||
REG_GAIN2 = 0x05,
|
#endif
|
||||||
REG_CFG = 0x06,
|
|
||||||
REG_THRSHLD_MSB = 0x07,
|
} // namespace ads131m08
|
||||||
REG_THRSHLD_LSB = 0x08,
|
} // namespace esphome
|
||||||
REG_CH0_CFG = 0x09,
|
|
||||||
REG_CH0_OCAL_MSB = 0x0A,
|
|
||||||
REG_CH0_OCAL_LSB = 0x0B,
|
|
||||||
REG_CH0_GCAL_MSB = 0x0C,
|
|
||||||
REG_CH0_GCAL_LSB = 0x0D,
|
|
||||||
REG_CH1_CFG = 0x0E,
|
|
||||||
REG_CH1_OCAL_MSB = 0x0F,
|
|
||||||
REG_CH1_OCAL_LSB = 0x10,
|
|
||||||
REG_CH1_GCAL_MSB = 0x11,
|
|
||||||
REG_CH1_GCAL_LSB = 0x12,
|
|
||||||
REG_CH2_CFG = 0x13,
|
|
||||||
REG_CH2_OCAL_MSB= 0x14,
|
|
||||||
REG_CH2_OCAL_LSB= 0x15,
|
|
||||||
REG_CH2_GCAL_MSB= 0x16,
|
|
||||||
REG_CH2_GCAL_LSB= 0x17,
|
|
||||||
REG_CH3_CFG = 0x18,
|
|
||||||
REG_CH3_OCAL_MSB= 0x19,
|
|
||||||
REG_CH3_OCAL_LSB= 0x1A,
|
|
||||||
REG_CH3_GCAL_MSB= 0x1B,
|
|
||||||
REG_CH3_GCAL_LSB= 0x1C,
|
|
||||||
REG_CH4_CFG = 0x1D,
|
|
||||||
REG_CH4_OCAL_MSB= 0x1E,
|
|
||||||
REG_CH4_OCAL_LSB= 0x1F,
|
|
||||||
REG_CH4_GCAL_MSB= 0x20,
|
|
||||||
REG_CH4_GCAL_LSB= 0x21,
|
|
||||||
REG_CH5_CFG = 0x22,
|
|
||||||
REG_CH5_OCAL_MSB= 0x23,
|
|
||||||
REG_CH5_OCAL_LSB= 0x24,
|
|
||||||
REG_CH5_GCAL_MSB= 0x25,
|
|
||||||
REG_CH5_GCAL_LSB= 0x26,
|
|
||||||
REG_CH6_CFG = 0x27,
|
|
||||||
REG_CH6_OCAL_MSB= 0x28,
|
|
||||||
REG_CH6_OCAL_LSB= 0x29,
|
|
||||||
REG_CH6_GCAL_MSB= 0x2A,
|
|
||||||
REG_CH6_GCAL_LSB= 0x2B,
|
|
||||||
REG_CH7_CFG = 0x2C,
|
|
||||||
REG_CH7_OCAL_MSB= 0x2D,
|
|
||||||
REG_CH7_OCAL_LSB= 0x2E,
|
|
||||||
REG_CH7_GCAL_MSB= 0x2F,
|
|
||||||
REG_CH7_GCAL_LSB= 0x30,
|
|
||||||
REGMAP_CRC = 0x3E,
|
|
||||||
};
|
|
||||||
// Mask READ_REG
|
|
||||||
static constexpr uint16_t MASK_CMD_READ_REG_ADDRESS = 0x1F80;
|
|
||||||
static constexpr uint16_t MASK_CMD_READ_REG_BYTES = 0x007F;
|
|
||||||
|
|
||||||
// Mask Register STATUS
|
|
||||||
static constexpr uint16_t MASK_STATUS_LOCK = 0x8000;
|
|
||||||
static constexpr uint16_t MASK_STATUS_RESYNC = 0x4000;
|
|
||||||
static constexpr uint16_t MASK_STATUS_REGMAP = 0x2000;
|
|
||||||
static constexpr uint16_t MASK_STATUS_CRC_ERR = 0x1000;
|
|
||||||
static constexpr uint16_t MASK_STATUS_CRC_TYPE = 0x0800;
|
|
||||||
static constexpr uint16_t MASK_STATUS_RESET = 0x0400;
|
|
||||||
static constexpr uint16_t MASK_STATUS_WLENGTH = 0x0300;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY7 = 0x0080;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY6 = 0x0040;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY5 = 0x0020;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY4 = 0x0010;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY3 = 0x0008;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY2 = 0x0004;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY1 = 0x0002;
|
|
||||||
static constexpr uint16_t MASK_STATUS_DRDY0 = 0x0001;
|
|
||||||
|
|
||||||
// Mask Register MODE
|
|
||||||
static constexpr uint16_t MASK_MODE_REG_CRC_EN = 0x2000;
|
|
||||||
static constexpr uint16_t MASK_MODE_RX_CRC_EN = 0x1000;
|
|
||||||
static constexpr uint16_t MASK_MODE_CRC_TYPE = 0x0800;
|
|
||||||
static constexpr uint16_t MASK_MODE_RESET = 0x0400;
|
|
||||||
static constexpr uint16_t MASK_MODE_WLENGTH = 0x0300;
|
|
||||||
static constexpr uint16_t MASK_MODE_TIMEOUT = 0x0010;
|
|
||||||
static constexpr uint16_t MASK_MODE_DRDY_SEL = 0x000C;
|
|
||||||
static constexpr uint16_t MASK_MODE_DRDY_HiZ = 0x0002;
|
|
||||||
static constexpr uint16_t MASK_MODE_DRDY_FMT = 0x0001;
|
|
||||||
|
|
||||||
// Mask Register CLOCK
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH7_EN = 0x8000;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH6_EN = 0x4000;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH5_EN = 0x2000;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH4_EN = 0x1000;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH3_EN = 0x0800;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH2_EN = 0x0400;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH1_EN = 0x0200;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_CH0_EN = 0x0100;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_OSR = 0x001C;
|
|
||||||
static constexpr uint16_t MASK_CLOCK_PWR = 0x0003;
|
|
||||||
static constexpr uint32_t MASK_CLOCK_ALL_CH_DISABLE = 0x0000;
|
|
||||||
static constexpr uint32_t MASK_CLOCK_ALL_CH_ENABLE = 0xFF00;
|
|
||||||
// Mask Register GAIN
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN7 = 0x7000;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN6 = 0x0700;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN5 = 0x0070;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN4 = 0x0007;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN3 = 0x7000;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN2 = 0x0700;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN1 = 0x0070;
|
|
||||||
static constexpr uint16_t MASK_GAIN_PGAGAIN0 = 0x0007;
|
|
||||||
|
|
||||||
// Mask Register CFG
|
|
||||||
static constexpr uint16_t MASK_CFG_GC_DLY = 0x1E00;
|
|
||||||
static constexpr uint16_t MASK_CFG_GC_EN = 0x0100;
|
|
||||||
static constexpr uint16_t MASK_CFG_CD_ALLCH = 0x0080;
|
|
||||||
static constexpr uint16_t MASK_CFG_CD_NUM = 0x0070;
|
|
||||||
static constexpr uint16_t MASK_CFG_CD_LEN = 0x000E;
|
|
||||||
static constexpr uint16_t MASK_CFG_CD_EN = 0x0001;
|
|
||||||
|
|
||||||
// Mask Register THRSHLD_MSB - dummy, for completeness
|
|
||||||
static constexpr uint16_t MASK_THRSHLD_MSB_CD_TH_MSB = 0xFFFF;
|
|
||||||
|
|
||||||
// Mask Register THRSHLD_LSB
|
|
||||||
static constexpr uint16_t MASK_THRSHLD_LSB_CD_TH_LSB = 0xFF00;
|
|
||||||
static constexpr uint16_t MASK_THRSHLD_LSB_DCBLOCK = 0x000F;
|
|
||||||
|
|
||||||
// Mask Register CHX_CFG
|
|
||||||
static constexpr uint16_t MASK_CHX_CFG_PHASE = 0xFFC0;
|
|
||||||
static constexpr uint16_t MASK_CHX_CFG_DCBLKX_DIS = 0x0004;
|
|
||||||
static constexpr uint16_t MASK_CHX_CFG_MUX = 0x0003;
|
|
||||||
|
|
||||||
// Mask Register CHX_OCAL_MSB - dummy, for completeness
|
|
||||||
static constexpr uint16_t MASK_CHX_OCAL_MSB = 0xFFFF;
|
|
||||||
|
|
||||||
// Mask Register CHX_OCAL_LSB
|
|
||||||
static constexpr uint16_t MASK_CHX_OCAL_LSB = 0xFF00;
|
|
||||||
|
|
||||||
// Mask Register CHX_GCAL_MSB - dummy, for completeness
|
|
||||||
static constexpr uint16_t MASK_CHX_GCAL_MSB = 0xFFFF;
|
|
||||||
|
|
||||||
// Mask Register CHX_GCAL_LSB
|
|
||||||
static constexpr uint16_t MASK_CHX_GCAL_LSB = 0xFF00;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Conversion modes
|
|
||||||
static constexpr uint16_t CONVERSION_MODE_CONT = 0;
|
|
||||||
static constexpr uint16_t CONVERSION_MODE_SINGLE = 1;
|
|
||||||
|
|
||||||
// Data Format
|
|
||||||
static constexpr uint16_t DATA_FORMAT_TWO_COMPLEMENT = 0;
|
|
||||||
static constexpr uint16_t DATA_FORMAT_BINARY = 1;
|
|
||||||
|
|
||||||
// Measure Mode
|
|
||||||
static constexpr uint8_t MEASURE_UNIPOLAR = 1;
|
|
||||||
static constexpr uint8_t MEASURE_BIPOLAR = 0;
|
|
||||||
|
|
||||||
// Clock Type
|
|
||||||
static constexpr uint8_t CLOCK_EXTERNAL = 1;
|
|
||||||
static constexpr uint8_t CLOCK_INTERNAL = 0;
|
|
||||||
|
|
||||||
// PGA Gain
|
|
||||||
// static constexpr uint16_t PGA_GAIN_1 = 0;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_2 = 1;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_4 = 2;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_8 = 3;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_16 = 4;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_32 = 5;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_64 = 6;
|
|
||||||
// static constexpr uint16_t PGA_GAIN_128 = 7;
|
|
||||||
|
|
||||||
// Input Filter
|
|
||||||
static constexpr uint16_t FILTER_SYNC = 0;
|
|
||||||
static constexpr uint16_t FILTER_FIR = 2;
|
|
||||||
static constexpr uint16_t FILTER_FIR_IIR = 3;
|
|
||||||
|
|
||||||
// Data Mode
|
|
||||||
static constexpr uint8_t DATA_MODE_24BITS = 0;
|
|
||||||
static constexpr uint8_t DATA_MODE_32BITS = 1;
|
|
||||||
|
|
||||||
// Data Rate
|
|
||||||
static constexpr uint8_t DATA_RATE_0 = 0;
|
|
||||||
static constexpr uint8_t DATA_RATE_1 = 1;
|
|
||||||
static constexpr uint8_t DATA_RATE_2 = 2;
|
|
||||||
static constexpr uint8_t DATA_RATE_3 = 3;
|
|
||||||
static constexpr uint8_t DATA_RATE_4 = 4;
|
|
||||||
static constexpr uint8_t DATA_RATE_5 = 5;
|
|
||||||
static constexpr uint8_t DATA_RATE_6 = 6;
|
|
||||||
static constexpr uint8_t DATA_RATE_7 = 7;
|
|
||||||
static constexpr uint8_t DATA_RATE_8 = 8;
|
|
||||||
static constexpr uint8_t DATA_RATE_9 = 9;
|
|
||||||
static constexpr uint8_t DATA_RATE_10 = 10;
|
|
||||||
static constexpr uint8_t DATA_RATE_11 = 11;
|
|
||||||
static constexpr uint8_t DATA_RATE_12 = 12;
|
|
||||||
static constexpr uint8_t DATA_RATE_13 = 13;
|
|
||||||
static constexpr uint8_t DATA_RATE_14 = 14;
|
|
||||||
static constexpr uint8_t DATA_RATE_15 = 15;
|
|
||||||
// Sync Mpdes
|
|
||||||
static constexpr uint16_t SYNC_CONTINUOUS = 1;
|
|
||||||
static constexpr uint16_t SYNC_PULSE = 0;
|
|
||||||
|
|
||||||
// DIO Config Mode
|
|
||||||
static constexpr uint8_t DIO_OUTPUT = 1;
|
|
||||||
static constexpr uint8_t DIO_INPUT = 0;
|
|
||||||
|
|
||||||
static constexpr uint8_t SPI_MASTER_DUMMY = 0xFF;
|
|
||||||
static constexpr uint16_t SPI_MASTER_DUMMY16 = 0xFFFF;
|
|
||||||
static constexpr uint32_t SPI_MASTER_DUMMY32 = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
|
|
||||||
// end of from datasheet
|
|
||||||
|
|
||||||
class ADS131M08Sensor : public sensor::Sensor, public Component
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_8MHZ>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// from datasheet pg. 93:
|
|
||||||
const int numFrameWords = 10; // Number of words in a full ADS131M08 SPI frame
|
|
||||||
unsigned long spiDummyWord[10 /*numFrameWords*/] = {
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000
|
|
||||||
}; // Dummy word frame to write ADC during ADC data reads
|
|
||||||
bool firstRead = true; // Flag to tell us if we are reading ADC data for the first time
|
|
||||||
signed long adcData; // Location where DMA will store ADC data in memory, length defined elsewhere
|
|
||||||
void txf_init();
|
|
||||||
bool adcRegisterWrite(unsigned short addrMask, unsigned short data, unsigned char adcWordLength);
|
|
||||||
void initialize_ads131m08_datasheet();
|
|
||||||
// end of from datasheet
|
|
||||||
|
|
||||||
bool setChannelPGA(uint8_t channel, uint8_t pga);
|
|
||||||
void setup() override;
|
|
||||||
void loop() override;
|
|
||||||
void set_drdy_pin(InternalGPIOPin *pin) { drdy_pin_ = pin; }
|
|
||||||
void register_sensor(int channel, ADS131M08Sensor *s) { sensors_[channel] = s; }
|
|
||||||
void set_reference_voltage(float reference_voltage) { this->reference_voltage_ = reference_voltage; }
|
|
||||||
void dump_config() override;
|
|
||||||
|
|
||||||
// from tpcorrea
|
|
||||||
void begin(uint8_t clk_pin, uint8_t miso_pin, uint8_t mosi_pin, uint8_t cs_pin, uint8_t drdy_pin, uint8_t reset_pin);
|
|
||||||
int8_t isDataReadySoft(uint8_t channel);
|
|
||||||
bool isDataReady(void);
|
|
||||||
bool isResetStatus(void);
|
|
||||||
bool isLockSPI(void);
|
|
||||||
bool setDrdyFormat(uint8_t drdyFormat);
|
|
||||||
bool setDrdyStateWhenUnavailable(uint8_t drdyState);
|
|
||||||
bool setPowerMode(uint8_t powerMode);
|
|
||||||
bool setChannelEnable(uint8_t channel, uint16_t enable);
|
|
||||||
bool setChannelPGA(uint8_t channel, ADS131M08_PGA_GAIN pga);
|
|
||||||
ADS131M08_PGA_GAIN getChannelPGA(uint8_t channel);
|
|
||||||
void setGlobalChop(uint16_t global_chop);
|
|
||||||
void setGlobalChopDelay(uint16_t delay);
|
|
||||||
bool setInputChannelSelection(uint8_t channel, uint8_t input);
|
|
||||||
bool setChannelOffsetCalibration(uint8_t channel, int32_t offset);
|
|
||||||
bool setChannelGainCalibration(uint8_t channel, uint32_t gain);
|
|
||||||
bool setOsr(uint16_t osr);
|
|
||||||
void setFullScale(uint8_t channel, float scale);
|
|
||||||
float getFullScale(uint8_t channel);
|
|
||||||
void reset();
|
|
||||||
uint16_t getId();
|
|
||||||
uint16_t getModeReg();
|
|
||||||
uint16_t getClockReg();
|
|
||||||
uint16_t getCfgReg();
|
|
||||||
AdcOutput readAdcRaw(void);
|
|
||||||
AdcOutput readAdcFloat(void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
float reference_voltage_;
|
|
||||||
InternalGPIOPin *drdy_pin_;
|
|
||||||
ADS131M08Sensor *sensors_[8] = {nullptr};
|
|
||||||
volatile bool data_ready_{false};
|
|
||||||
static void isr(ADS131M08Hub *arg);
|
|
||||||
void read_data_();
|
|
||||||
void write_register(uint8_t reg, uint16_t value);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ads131m08
|
|
||||||
} // namespace esphome
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ void DS3231Component::dump_config() {
|
|||||||
if (this->is_failed()) {
|
if (this->is_failed()) {
|
||||||
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
||||||
}
|
}
|
||||||
ESP_LOGCONFIG(TAG, " Timezone: '%s'", this->timezone_.c_str());
|
// ESP_LOGCONFIG(TAG, " Timezone: '%s'", this->timezone_.c_str());
|
||||||
if (!this->read_bytes(0, this->ds3231_.raw, sizeof(this->ds3231_.raw))) {
|
if (!this->read_bytes(0, this->ds3231_.raw, sizeof(this->ds3231_.raw))) {
|
||||||
ESP_LOGE(TAG, "Can't read I2C data.");
|
ESP_LOGE(TAG, "Can't read I2C data.");
|
||||||
}
|
}
|
||||||
@ -50,7 +50,8 @@ void DS3231Component::read_time() {
|
|||||||
.year = uint16_t(ds3231_.reg.year + 10u * ds3231_.reg.year_10 + 2000),
|
.year = uint16_t(ds3231_.reg.year + 10u * ds3231_.reg.year_10 + 2000),
|
||||||
.is_dst = false, // not used
|
.is_dst = false, // not used
|
||||||
.timestamp = 0 // overwritten by recalc_timestamp_utc(false)
|
.timestamp = 0 // overwritten by recalc_timestamp_utc(false)
|
||||||
};
|
|
||||||
|
};
|
||||||
rtc_time.recalc_timestamp_utc(false);
|
rtc_time.recalc_timestamp_utc(false);
|
||||||
if (!rtc_time.is_valid()) {
|
if (!rtc_time.is_valid()) {
|
||||||
ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock.");
|
ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock.");
|
||||||
@ -79,7 +80,7 @@ void DS3231Component::write_time() {
|
|||||||
ds3231_.reg.second = now.second % 10;
|
ds3231_.reg.second = now.second % 10;
|
||||||
ds3231_.reg.second_10 = now.second / 10;
|
ds3231_.reg.second_10 = now.second / 10;
|
||||||
ds3231_.reg.ch = false;
|
ds3231_.reg.ch = false;
|
||||||
|
// ESPHOME emits warning about synchronous mode; must check datasheet to see if this is a problem for us. Datasheet pg. 6 says "The DS3231 is designed to operate in a synchronous mode, where the timekeeping registers are updated at the end of each second. This ensures that the timekeeping registers always contain valid data and eliminates the need for software to handle potential timing issues when reading or writing the registers."
|
||||||
this->write_rtc_();
|
this->write_rtc_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,30 +77,30 @@ void TLC59208FOutput::setup() {
|
|||||||
auto errcode = this->bus_->write_readv(TLC59208F_SWRST_ADDR >> 1, TLC59208F_SWRST_SEQ, sizeof TLC59208F_SWRST_SEQ, nullptr, 0);
|
auto errcode = this->bus_->write_readv(TLC59208F_SWRST_ADDR >> 1, TLC59208F_SWRST_SEQ, sizeof TLC59208F_SWRST_SEQ, nullptr, 0);
|
||||||
if (errcode != i2c::ERROR_OK) {
|
if (errcode != i2c::ERROR_OK) {
|
||||||
ESP_LOGE(TAG, "RESET failed");
|
ESP_LOGE(TAG, "RESET failed");
|
||||||
this->mark_failed("RESET failed");
|
this->mark_failed(LOG_STR("RESET failed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Auto increment registers, and respond to all-call address
|
// Auto increment registers, and respond to all-call address
|
||||||
if (!this->write_byte(TLC59208F_REG_MODE1, TLC59208F_MODE1_AI2 | TLC59208F_MODE1_ALLCALL)) {
|
if (!this->write_byte(TLC59208F_REG_MODE1, TLC59208F_MODE1_AI2 | TLC59208F_MODE1_ALLCALL)) {
|
||||||
ESP_LOGE(TAG, "MODE1 failed");
|
ESP_LOGE(TAG, "MODE1 failed");
|
||||||
this->mark_failed("MODE1 failed");
|
this->mark_failed(LOG_STR("MODE1 failed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this->write_byte(TLC59208F_REG_MODE2, this->mode_)) {
|
if (!this->write_byte(TLC59208F_REG_MODE2, this->mode_)) {
|
||||||
ESP_LOGE(TAG, "MODE2 failed");
|
ESP_LOGE(TAG, "MODE2 failed");
|
||||||
this->mark_failed("MODE2 failed");
|
this->mark_failed(LOG_STR("MODE2 failed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Set all 3 outputs to be individually controlled
|
// Set all 3 outputs to be individually controlled
|
||||||
// TODO: think of a way to support group dimming
|
// TODO: think of a way to support group dimming
|
||||||
if (!this->write_byte(TLC59208F_REG_LEDOUT0, (LDR_PWM << 6) | (LDR_PWM << 4) | (LDR_PWM << 2) | (LDR_PWM << 0))) {
|
if (!this->write_byte(TLC59208F_REG_LEDOUT0, (LDR_PWM << 6) | (LDR_PWM << 4) | (LDR_PWM << 2) | (LDR_PWM << 0))) {
|
||||||
ESP_LOGE(TAG, "LEDOUT0 failed");
|
ESP_LOGE(TAG, "LEDOUT0 failed");
|
||||||
this->mark_failed("LEDOUT0 failed");
|
this->mark_failed(LOG_STR("LEDOUT0 failed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this->write_byte(TLC59208F_REG_LEDOUT1, (LDR_PWM << 6) | (LDR_PWM << 4) | (LDR_PWM << 2) | (LDR_PWM << 0))) {
|
if (!this->write_byte(TLC59208F_REG_LEDOUT1, (LDR_PWM << 6) | (LDR_PWM << 4) | (LDR_PWM << 2) | (LDR_PWM << 0))) {
|
||||||
ESP_LOGE(TAG, "LEDOUT1 failed");
|
ESP_LOGE(TAG, "LEDOUT1 failed");
|
||||||
this->mark_failed("LEDOUT1 failed");
|
this->mark_failed(LOG_STR("LEDOUT1 failed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delayMicroseconds(500);
|
delayMicroseconds(500);
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define __SOLAR_CB_FRAME
|
#define __SOLAR_CB_FRAME
|
||||||
#include "esphome.h"
|
#include "esphome.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <queue>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
using namespace esphome;
|
using namespace esphome;
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,8 @@ namespace solar
|
|||||||
#define SEARCHWILD 0x0100000 // do wildcard comparison (only searchkey should contain wildcards)
|
#define SEARCHWILD 0x0100000 // do wildcard comparison (only searchkey should contain wildcards)
|
||||||
#define num_compare(a, b) ((a) > (b)) ? +1 : ((a) < (b)) ? -1 : 0
|
#define num_compare(a, b) ((a) > (b)) ? +1 : ((a) < (b)) ? -1 : 0
|
||||||
#define bool_compare(a, b) ((!(a) && !(b)) || ((a) && (b))) ? 0 : (a) ? +1 : -1
|
#define bool_compare(a, b) ((!(a) && !(b)) || ((a) && (b))) ? 0 : (a) ? +1 : -1
|
||||||
#define max(a, b) ((a) > (b)) ? (a) : (b)
|
#define mmax(a, b) ((a) > (b)) ? (a) : (b)
|
||||||
#define min(a, b) ((a) < (b)) ? (a) : (b)
|
#define mmin(a, b) ((a) < (b)) ? (a) : (b)
|
||||||
|
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef std::vector<uint8_t> byte_vector;
|
typedef std::vector<uint8_t> byte_vector;
|
||||||
|
|||||||
2103
sthome-ut10.yaml
2103
sthome-ut10.yaml
File diff suppressed because it is too large
Load Diff
742
sthome-ut2.yaml
742
sthome-ut2.yaml
@ -1,6 +1,8 @@
|
|||||||
packages:
|
packages:
|
||||||
- !include common/wifi.yaml
|
- !include common/wifi.yaml
|
||||||
- !include common/felicityinverter.yaml
|
- !include common/felicityinverter.yaml
|
||||||
|
- !include common/canbus.yaml
|
||||||
|
- !include common/modbus.yaml
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
name: sthome-ut2
|
name: sthome-ut2
|
||||||
@ -9,13 +11,38 @@ substitutions:
|
|||||||
esphome:
|
esphome:
|
||||||
name: "${name}"
|
name: "${name}"
|
||||||
friendly_name: "${friendly_name}"
|
friendly_name: "${friendly_name}"
|
||||||
|
includes:
|
||||||
|
- source # copies folder with files to relevant to be included in esphome compile
|
||||||
|
- <source/solar/cb_frame.h> # angle brackets ensure file is included above globals in main.cpp. Make sure to use include GUARDS in the file to prevent double inclusion
|
||||||
|
- <source/solar/cbf_store.h>
|
||||||
|
- <source/solar/cbf_pylon.h>
|
||||||
|
- <source/solar/cbf_store_pylon.h>
|
||||||
|
- <source/solar/cbf_sthome.h>
|
||||||
|
- <source/solar/cbf_store_sthome.h>
|
||||||
|
- <source/solar/cbf_cache.h>
|
||||||
|
|
||||||
external_components:
|
#external_components:
|
||||||
- source: github://pr#8103
|
# - source: github://pr#8103
|
||||||
components: [uart]
|
# components: [uart]
|
||||||
- source: github://pr#8032
|
# - source: github://pr#8032
|
||||||
components: [modbus, modbus_controller, growatt_solar]
|
# components: [modbus, modbus_controller, growatt_solar]
|
||||||
refresh: 1h
|
# refresh: 1h
|
||||||
|
globals:
|
||||||
|
- id: can_msgctr
|
||||||
|
type: int
|
||||||
|
restore_value: no
|
||||||
|
- id: can2_msgctr
|
||||||
|
type: int
|
||||||
|
restore_value: no
|
||||||
|
- id: last_battery_message_time
|
||||||
|
type: time_t
|
||||||
|
restore_value: no
|
||||||
|
- id: g_cb_cache # the cache is used to only accept a frame after it has been received a specified number of times within a specified period. this hopefully will iron out spurious corrupted frames
|
||||||
|
type: solar::cbf_cache
|
||||||
|
restore_value: no
|
||||||
|
- id: g_cb_request_queue
|
||||||
|
type: std::queue< std::set<uint32_t> >
|
||||||
|
restore_value: no
|
||||||
|
|
||||||
esp32:
|
esp32:
|
||||||
board: esp32dev
|
board: esp32dev
|
||||||
@ -27,9 +54,10 @@ logger:
|
|||||||
level: VERY_VERBOSE
|
level: VERY_VERBOSE
|
||||||
initial_level: INFO
|
initial_level: INFO
|
||||||
logs:
|
logs:
|
||||||
uart: VERY_VERBOSE
|
canbus: INFO
|
||||||
modbus: DEBUG
|
uart_debug: VERY_VERBOSE
|
||||||
modbus_controller: DEBUG
|
modbus: VERBOSE
|
||||||
|
modbus_controller: VERBOSE
|
||||||
|
|
||||||
# Enable Home Assistant API
|
# Enable Home Assistant API
|
||||||
api:
|
api:
|
||||||
@ -51,18 +79,30 @@ wifi:
|
|||||||
|
|
||||||
captive_portal:
|
captive_portal:
|
||||||
|
|
||||||
|
spi:
|
||||||
|
- id: spi_bus0
|
||||||
|
clk_pin: GPIO18
|
||||||
|
mosi_pin: GPIO23
|
||||||
|
miso_pin: GPIO19
|
||||||
|
interface: any
|
||||||
|
|
||||||
uart:
|
uart:
|
||||||
- id: inv_uart1
|
- id: sth_uart
|
||||||
rx_pin: GPIO16
|
rx_pin:
|
||||||
tx_pin: GPIO17
|
number: GPIO17
|
||||||
baud_rate: 2400
|
inverted: false
|
||||||
|
mode:
|
||||||
|
input: true
|
||||||
|
pullup: true
|
||||||
|
tx_pin: GPIO16
|
||||||
|
baud_rate: 9600
|
||||||
stop_bits: 1
|
stop_bits: 1
|
||||||
parity: NONE
|
parity: NONE
|
||||||
debug:
|
debug:
|
||||||
direction: BOTH
|
direction: BOTH
|
||||||
dummy_receiver: false
|
dummy_receiver: false
|
||||||
after:
|
after:
|
||||||
delimiter: "\r"
|
delimiter: "\n"
|
||||||
sequence:
|
sequence:
|
||||||
- lambda: UARTDebug::log_hex(direction, bytes, ',');
|
- lambda: UARTDebug::log_hex(direction, bytes, ',');
|
||||||
|
|
||||||
@ -80,328 +120,404 @@ switch:
|
|||||||
name: "${name} Restart"
|
name: "${name} Restart"
|
||||||
id: "restart_switch"
|
id: "restart_switch"
|
||||||
|
|
||||||
|
interval:
|
||||||
|
- interval: 10s
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
id(canbus_send_heartbeat).execute();
|
||||||
|
# - interval: 2.36s
|
||||||
|
# then:
|
||||||
|
# - uart.write:
|
||||||
|
# data: "sthome2 heartbeat\r\n"
|
||||||
|
# - sth_uart.write: !lambda
|
||||||
|
# return std::vector<uint8_t>({0x0D, 0x0A, 0x43, 0x50, 0x53, 0x00, 0x0D, 0x0A, 0x43, 0x50, 0x53, 0x00});
|
||||||
|
|
||||||
|
canbus:
|
||||||
|
- platform: mcp2515
|
||||||
|
cs_pin: GPIO32 # CBCS
|
||||||
|
spi_id: spi_bus0
|
||||||
|
id: canbus_sthome
|
||||||
|
mode: NORMAL
|
||||||
|
can_id: ${CB_CANBUS_ID03}
|
||||||
|
bit_rate: 500KBPS
|
||||||
|
on_frame:
|
||||||
|
- can_id: 0
|
||||||
|
can_id_mask: 0
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
id(can_msgctr)++;
|
||||||
|
using namespace solar;
|
||||||
|
auto time_obj = id(time_source).now();
|
||||||
|
//ESP_LOGI("CB REC", "%s", id(time_source).now().strftime("%a %d %b %Y - %I:%M:%S %p"));
|
||||||
|
if(time_obj.is_valid()) {
|
||||||
|
if (can_id >= 0x380 && can_id < 0x3C0) {
|
||||||
|
auto cbitem = cbf_store_sthome(id(can_msgctr), can_id, x, remote_transmission_request, time_obj.timestamp);
|
||||||
|
bool publish = id(g_cb_cache).additem(cbitem);
|
||||||
|
if(publish) {
|
||||||
|
ESP_LOGI(cbitem.tag().c_str(), "%s", cbitem.to_string().c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto cbitem = cbf_store_sthome(id(can_msgctr), can_id, x, remote_transmission_request, time_obj.timestamp);
|
||||||
|
ESP_LOGI(cbitem.tag().c_str(), "%s", cbitem.to_string().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
modbus:
|
modbus:
|
||||||
- id: modbus1
|
- id: modbus_server
|
||||||
uart_id: inv_uart1
|
uart_id: sth_uart
|
||||||
flow_control_pin: GPIO4
|
send_wait_time: 1200ms #250ms
|
||||||
send_wait_time: 1000ms #250ms
|
|
||||||
disable_crc: false
|
disable_crc: false
|
||||||
role: server
|
role: server
|
||||||
|
|
||||||
modbus_controller:
|
modbus_controller:
|
||||||
- id: modbus_device1
|
- id: modbus_alarm_server
|
||||||
modbus_id: modbus1
|
modbus_id: modbus_server
|
||||||
address: 0x1
|
address: 0x01
|
||||||
allow_duplicate_commands: False
|
|
||||||
command_throttle: 0ms
|
|
||||||
update_interval: 4s #30s
|
|
||||||
offline_skip_updates: 2
|
|
||||||
max_cmd_retries: 04
|
|
||||||
setup_priority: -10
|
|
||||||
server_registers:
|
server_registers:
|
||||||
- address: ${Felicity_Inv_WorkingMode} # 0x1101
|
- address: 0x0001
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0001;
|
|
||||||
- address: ${Felicity_Inv_BatteryChargingStage} # 0x1102
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0002;
|
|
||||||
- address: ${Felicity_Inv_FaultCode} # 0x1103
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0003;
|
|
||||||
- address: ${Felicity_Inv_PowerFlowMsg} # 0x1104
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0004;
|
|
||||||
- address: 0x1106
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: ${Felicity_Inv_BatteryVoltage} # 0x1108
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0005;
|
|
||||||
- address: ${Felicity_Inv_BatteryCurrent} # 0x1109
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0006;
|
|
||||||
- address: ${Felicity_Inv_BatteryPower} # 0x110A
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0007;
|
|
||||||
- address: 0x110C
|
|
||||||
value_type: U_QWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: 0x1110
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: ${Felicity_Inv_ACOutputVoltage} # 0x1111
|
|
||||||
value_type: U_QWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0008;
|
|
||||||
- address: 0x1115
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: ${Felicity_Inv_ACInputVoltage} # 0x1117
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0009;
|
|
||||||
- address: ${Felicity_Inv_ACInputFrequency} # 0x1119
|
|
||||||
value_type: U_QWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x000A;
|
|
||||||
- address: 0x111D
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: ${Felicity_Inv_ACOutputActivePower} # 0x111E
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x000B;
|
|
||||||
- address: ${Felicity_Inv_ACOutputApparentPower} # 0x111F
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x000C;
|
|
||||||
- address: ${Felicity_Inv_LoadPercentage} # 0x1120
|
|
||||||
value_type: U_QWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x000D;
|
|
||||||
- address: 0x1124
|
|
||||||
value_type: U_DWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
- address: ${Felicity_Inv_PVInputVoltage} # 0x1126
|
|
||||||
value_type: U_QWORD_R
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x000E;
|
|
||||||
- address: ${Felicity_Inv_PVInputPower} # 0x112A
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0x0010;
|
|
||||||
- address: 0x112C
|
|
||||||
value_type: U_WORD
|
|
||||||
read_lambda: |-
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- address: 0xF800
|
|
||||||
value_type: S_DWORD_R
|
value_type: S_DWORD_R
|
||||||
read_lambda: |-
|
read_lambda: |-
|
||||||
return 0x400D;
|
uint16_t alarm_status = id(person_detected_switch).state ? 1 : 0;
|
||||||
- address: 0xF802
|
alarm_status |= id(alarm_zone4_relay).state ? 2 : 0;
|
||||||
value_type: S_DWORD_R
|
alarm_status |= id(lights_backyard_relay).state ? 4 : 0;
|
||||||
read_lambda: |-
|
alarm_status |= id(lights_frontyard_relay).state ? 8 : 0;
|
||||||
return 0x500E;
|
alarm_status |= id(floodlight_test).state ? 16 : 0;
|
||||||
- address: 0xF804
|
alarm_status |= id(night_time).state ? 32 : 0;
|
||||||
value_type: S_DWORD_R
|
alarm_status |= id(zone1_triggered).state ? 64 : 0;
|
||||||
read_lambda: |-
|
alarm_status |= id(zone2_triggered).state ? 128 : 0;
|
||||||
return 0x4142;
|
alarm_status |= id(zone3_triggered).state ? 256 : 0;
|
||||||
- address: 0xF806
|
alarm_status |= id(zone4_triggered).state ? 512 : 0;
|
||||||
value_type: S_DWORD_R
|
alarm_status |= id(zone5_triggered).state ? 1024 : 0;
|
||||||
read_lambda: |-
|
alarm_status |= id(zone6_triggered).state ? 2048 : 0;
|
||||||
return 0x4344;
|
return alarm_status;
|
||||||
- address: 0xF808
|
binary_sensor:
|
||||||
value_type: S_DWORD_R
|
- platform: template
|
||||||
read_lambda: |-
|
id: person_detected_switch
|
||||||
return 0x4546;
|
name: "Person Detected Switch"
|
||||||
- address: 0xF80A
|
lambda: |-
|
||||||
value_type: S_DWORD_R
|
return true;
|
||||||
read_lambda: |-
|
- platform: template
|
||||||
return 0x4748;
|
id: alarm_zone4_relay
|
||||||
- address: 0xF80C
|
name: "Alarm Zone 4 Relay"
|
||||||
value_type: S_DWORD_R
|
lambda: |-
|
||||||
read_lambda: |-
|
return true;
|
||||||
return 0x494A;
|
- platform: template
|
||||||
- address: 0xF80E
|
id: lights_backyard_relay
|
||||||
value_type: S_DWORD_R
|
name: "Lights Backyard Relay"
|
||||||
read_lambda: |-
|
lambda: |-
|
||||||
return 0x4B4C;
|
return true;
|
||||||
- address: 0xF810
|
- platform: template
|
||||||
value_type: S_DWORD_R
|
id: lights_frontyard_relay
|
||||||
read_lambda: |-
|
name: "Lights Frontyard Relay"
|
||||||
return 0;
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: floodlight_test
|
||||||
|
name: "Floodlight Test"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: night_time
|
||||||
|
name: "Night Time"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone1_triggered
|
||||||
|
name: "Zone 1 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone2_triggered
|
||||||
|
name: "Zone 2 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone3_triggered
|
||||||
|
name: "Zone 3 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone4_triggered
|
||||||
|
name: "Zone 4 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone5_triggered
|
||||||
|
name: "Zone 5 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
- platform: template
|
||||||
|
id: zone6_triggered
|
||||||
|
name: "Zone 6 Triggered"
|
||||||
|
lambda: |-
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
#modbus:
|
#modbus:
|
||||||
# - id: modbus1
|
# - id: modbus_client
|
||||||
# uart_id: inv_uart1
|
# uart_id: sth_uart
|
||||||
# flow_control_pin: GPIO4
|
# send_wait_time: 1200ms #250ms
|
||||||
# send_wait_time: 1000ms #250ms
|
|
||||||
# disable_crc: false
|
# disable_crc: false
|
||||||
# role: client
|
# role: client
|
||||||
#
|
#
|
||||||
#modbus_controller:
|
#modbus_controller:
|
||||||
# - id: modbus_device1
|
# - id: modbus_alarm_client
|
||||||
# modbus_id: modbus1
|
# modbus_id: modbus_client
|
||||||
# address: 0x01
|
# address: 0x01
|
||||||
# allow_duplicate_commands: False
|
# allow_duplicate_commands: False
|
||||||
# command_throttle: 0ms
|
# command_throttle: 700ms #2022ms
|
||||||
# update_interval: 4s #30s
|
# update_interval: 10s #305s
|
||||||
# offline_skip_updates: 2
|
# offline_skip_updates: 2
|
||||||
# max_cmd_retries: 0
|
# max_cmd_retries: 1
|
||||||
# setup_priority: -10
|
# setup_priority: -10
|
||||||
#
|
#
|
||||||
|
#binary_sensor:
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: person_detected
|
||||||
|
# name: "Person Detected"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x1
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: alarm_zone4_relay
|
||||||
|
# name: "Alarm Zone 4 Relay"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x2
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: lights_backyard_relay
|
||||||
|
# name: "Lights Backyard Relay"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x4
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: lights_frontyard_relay
|
||||||
|
# name: "Lights Frontyard Relay"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x8
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: floodlight_test
|
||||||
|
# name: "Floodlight Test"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x10
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: night_time
|
||||||
|
# name: "Night Time"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x20
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone1_triggered
|
||||||
|
# name: "Zone 1 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x40
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone2_triggered
|
||||||
|
# name: "Zone 2 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x80
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone3_triggered
|
||||||
|
# name: "Zone 3 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x100
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone4_triggered
|
||||||
|
# name: "Zone 4 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x200
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone5_triggered
|
||||||
|
# name: "Zone 5 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x400
|
||||||
|
#- platform: modbus_controller
|
||||||
|
# modbus_controller_id: modbus_alarm_client
|
||||||
|
# id: zone6_triggered
|
||||||
|
# name: "Zone 6 Triggered"
|
||||||
|
# register_type: read
|
||||||
|
# address: 0x0001
|
||||||
|
# bitmask: 0x800
|
||||||
|
#
|
||||||
#sensor:
|
#sensor:
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Type"
|
# id: z1z4_current
|
||||||
# register_type: holding
|
# name: "Z1Z4 Current"
|
||||||
# address: ${Felicity_Inv_Type} # 0xF800
|
# address: 0x0002
|
||||||
# value_type: U_DWORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
#- platform: modbus_controller
|
# register_count: 4
|
||||||
# modbus_controller_id: modbus_device1
|
# unit_of_measurement: "mA"
|
||||||
# name: "Inverter1 Sub Type"
|
# lambda: |-
|
||||||
# register_type: holding
|
# return x / 1024.0;
|
||||||
# address: ${Felicity_Inv_SubType} # 0xF801
|
|
||||||
# value_type: U_DWORD
|
|
||||||
# register_count: 3
|
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 CPU1 F/W Version"
|
# id: z2z5_current
|
||||||
# register_type: holding
|
# name: "Z2Z5 Current"
|
||||||
# address: ${Felicity_Inv_CPU1_FW_Version} # 0xF80B
|
# address: 0x0006
|
||||||
# value_type: U_DWORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "mA"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 CPU2 F/W Version"
|
# id: z3z6_current
|
||||||
# register_type: holding
|
# name: "Z3Z6 Current"
|
||||||
# address: ${Felicity_Inv_CPU2_FW_Version} # 0xF80C
|
# address: 0x000A
|
||||||
# value_type: U_DWORD
|
# register_type: holding
|
||||||
# register_count: 3
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "mA"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Working Mode"
|
# id: z1z4_bus_voltage
|
||||||
# register_type: holding
|
# name: "Z1Z4 Bus Voltage"
|
||||||
# address: ${Felicity_Inv_WorkingMode} # 0x1101
|
# address: 0x000E
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "V"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Charge Mode"
|
# id: z2z5_bus_voltage
|
||||||
# register_type: holding
|
# name: "Z2Z5 Bus Voltage"
|
||||||
# address: ${Felicity_Inv_BatteryChargingStage} # 0x1102
|
# address: 0x0012
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "V"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Fault Code"
|
# id: z3z6_bus_voltage
|
||||||
# register_type: holding
|
# name: "Z3Z6 Bus Voltage"
|
||||||
# address: ${Felicity_Inv_FaultCode} # 0x1103
|
# address: 0x0016
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "V"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Power Flow"
|
# id: z1z4_power
|
||||||
# register_type: holding
|
# name: "Z1Z4 Power"
|
||||||
# address: ${Felicity_Inv_PowerFlowMsg} # 0x1104
|
# address: 0x001A
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 4
|
# value_type: S_WORD
|
||||||
|
# register_count: 4
|
||||||
|
# unit_of_measurement: "W"
|
||||||
|
# lambda: |-
|
||||||
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 Battery Voltage"
|
# id: z2z5_power
|
||||||
# register_type: holding
|
# name: "Z2Z5 Power"
|
||||||
# address: ${Felicity_Inv_BatteryVoltage} # 0x1108
|
# address: 0x001E
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
#
|
# register_count: 4
|
||||||
#- platform: modbus_controller
|
# unit_of_measurement: "W"
|
||||||
# modbus_controller_id: modbus_device1
|
# lambda: |-
|
||||||
# name: "Inverter1 Battery Current"
|
# return x / 1024.0;
|
||||||
# register_type: holding
|
#
|
||||||
# address: ${Felicity_Inv_BatteryCurrent} # 0x1109
|
# - platform: modbus_controller
|
||||||
# value_type: U_WORD
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# register_count: 1
|
# id: z3z6_power
|
||||||
#
|
# name: "Z3Z6 Power"
|
||||||
#- platform: modbus_controller
|
# address: 0x0022
|
||||||
# modbus_controller_id: modbus_device1
|
# register_type: holding
|
||||||
# name: "Inverter1 BatteryPower"
|
# value_type: S_WORD
|
||||||
# register_type: holding
|
# register_count: 4
|
||||||
# address: ${Felicity_Inv_BatteryPower} # 0x110A
|
# unit_of_measurement: "W"
|
||||||
# value_type: U_WORD
|
# lambda: |-
|
||||||
# register_count: 7
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 AC Output Voltage"
|
# id: z1z4_shunt_voltage
|
||||||
# register_type: holding
|
# name: "Z1Z4 Shunt Voltage"
|
||||||
# address: ${Felicity_Inv_ACOutputVoltage} # 0x1111
|
# address: 0x0026
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 6
|
# value_type: S_WORD
|
||||||
#
|
# register_count: 4
|
||||||
#- platform: modbus_controller
|
# unit_of_measurement: "V"
|
||||||
# modbus_controller_id: modbus_device1
|
# lambda: |-
|
||||||
# name: "Inverter1 AC Input Voltage"
|
# return x / 1024.0;
|
||||||
# register_type: holding
|
#
|
||||||
# address: ${Felicity_Inv_ACInputVoltage} # 0x1117
|
# - platform: modbus_controller
|
||||||
# value_type: U_WORD
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# register_count: 2
|
# id: z2z5_shunt_voltage
|
||||||
#
|
# name: "Z2Z5 Shunt Voltage"
|
||||||
#- platform: modbus_controller
|
# address: 0x002A
|
||||||
# modbus_controller_id: modbus_device1
|
# register_type: holding
|
||||||
# name: "Inverter1 AC Input Frequency"
|
# value_type: S_WORD
|
||||||
# register_type: holding
|
# register_count: 4
|
||||||
# address: ${Felicity_Inv_ACInputFrequency} # 0x1119
|
# unit_of_measurement: "V"
|
||||||
# value_type: U_WORD
|
# lambda: |-
|
||||||
# register_count: 5
|
# return x / 1024.0;
|
||||||
#
|
#
|
||||||
#- platform: modbus_controller
|
# - platform: modbus_controller
|
||||||
# modbus_controller_id: modbus_device1
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# name: "Inverter1 AC Output Active Power"
|
# id: z3z6_shunt_voltage
|
||||||
# register_type: holding
|
# name: "Z3Z6 Shunt Voltage"
|
||||||
# address: ${Felicity_Inv_ACOutputActivePower} # 0x111E
|
# address: 0x002E
|
||||||
# value_type: U_WORD
|
# register_type: holding
|
||||||
# register_count: 1
|
# value_type: S_WORD
|
||||||
#
|
# register_count: 4
|
||||||
#- platform: modbus_controller
|
# unit_of_measurement: "V"
|
||||||
# modbus_controller_id: modbus_device1
|
# lambda: |-
|
||||||
# name: "Inverter1 AC Output Apparent Power"
|
# return x / 1024.0;
|
||||||
# register_type: holding
|
#
|
||||||
# address: ${Felicity_Inv_ACOutputApparentPower} # 0x111F
|
# - platform: modbus_controller
|
||||||
# value_type: U_WORD
|
# modbus_controller_id: modbus_alarm_client
|
||||||
# register_count: 1
|
# id: alarm_signal
|
||||||
#
|
# name: "Alarm Signal"
|
||||||
#- platform: modbus_controller
|
# address: 0x0032
|
||||||
# modbus_controller_id: modbus_device1
|
# register_type: holding
|
||||||
# name: "Inverter1 Load Percentage"
|
# value_type: S_WORD
|
||||||
# register_type: holding
|
# register_count: 4
|
||||||
# address: ${Felicity_Inv_LoadPercentage} # 0x1120
|
# unit_of_measurement: "V"
|
||||||
# value_type: U_WORD
|
# lambda: |-
|
||||||
# register_count: 6
|
# return x / 1024.0;
|
||||||
#
|
|
||||||
#- platform: modbus_controller
|
script:
|
||||||
# modbus_controller_id: modbus_device1
|
- id: canbus_send_heartbeat
|
||||||
# name: "Inverter1 PV Input Voltage"
|
then:
|
||||||
# register_type: holding
|
lambda: |-
|
||||||
# address: ${Felicity_Inv_PVInputVoltage} # 0x1126
|
using namespace solar;
|
||||||
# value_type: U_WORD
|
std::vector<uint8_t> x(cbf_sthome::heartbeat.begin(), cbf_sthome::heartbeat.end());
|
||||||
# register_count: 4
|
id(g_cb_cache).send_frame(id(canbus_sthome), cbf_sthome::CB_CANBUS_ID02, x);
|
||||||
#
|
|
||||||
#- platform: modbus_controller
|
|
||||||
# modbus_controller_id: modbus_device1
|
|
||||||
# name: "Inverter1 PV Input Power"
|
|
||||||
# register_type: holding
|
|
||||||
# address: ${Felicity_Inv_PVInputPower} # 0x112A
|
|
||||||
# value_type: U_WORD
|
|
||||||
# register_count: 1
|
|
||||||
#
|
|
||||||
#text_sensor:
|
|
||||||
#- platform: modbus_controller
|
|
||||||
# modbus_controller_id: modbus_device1
|
|
||||||
# name: "Inverter1 SerialNo"
|
|
||||||
# register_type: holding
|
|
||||||
# address: ${Felicity_Inv_SerialNo} # 0xF804
|
|
||||||
# response_size: 14
|
|
||||||
# register_count: 7
|
|
||||||
# raw_encode: HEXBYTES
|
|
||||||
#
|
|
||||||
960
sthome-ut3.yaml
960
sthome-ut3.yaml
File diff suppressed because it is too large
Load Diff
140
sthome-ut9.yaml
140
sthome-ut9.yaml
@ -47,6 +47,30 @@ wifi:
|
|||||||
|
|
||||||
captive_portal:
|
captive_portal:
|
||||||
|
|
||||||
|
uart:
|
||||||
|
- id: sth_uart
|
||||||
|
rx_pin: GPIO15
|
||||||
|
tx_pin: GPIO16
|
||||||
|
baud_rate: 2400
|
||||||
|
stop_bits: 1
|
||||||
|
parity: NONE
|
||||||
|
debug:
|
||||||
|
direction: BOTH
|
||||||
|
dummy_receiver: true
|
||||||
|
after:
|
||||||
|
delimiter: "\r"
|
||||||
|
sequence:
|
||||||
|
- lambda: UARTDebug::log_hex(direction, bytes, ',');
|
||||||
|
|
||||||
|
interval:
|
||||||
|
# - interval: 10s
|
||||||
|
# then:
|
||||||
|
# - lambda: |-
|
||||||
|
# id(canbus_send_heartbeat).execute();
|
||||||
|
- interval: 3.14s
|
||||||
|
then:
|
||||||
|
- uart.write:
|
||||||
|
data: "sthome9 heartbeat\r\n"
|
||||||
|
|
||||||
sun:
|
sun:
|
||||||
id: sun_sensor
|
id: sun_sensor
|
||||||
@ -69,126 +93,12 @@ text_sensor:
|
|||||||
id: uptime_human
|
id: uptime_human
|
||||||
icon: mdi:clock-start
|
icon: mdi:clock-start
|
||||||
|
|
||||||
|
|
||||||
#define OUTPUT_R1 16
|
|
||||||
#define OUTPUT_R2 17
|
|
||||||
#define OUTPUT_R3 18
|
|
||||||
#define OUTPUT_R4 19
|
|
||||||
switch:
|
switch:
|
||||||
- platform: restart
|
- platform: restart
|
||||||
name: "${name} Restart"
|
name: "${name} Restart"
|
||||||
id: "restart_switch"
|
id: "restart_switch"
|
||||||
|
|
||||||
- platform: gpio
|
sensor:
|
||||||
pin:
|
|
||||||
number: GPIO16
|
|
||||||
inverted: true
|
|
||||||
id: relay1
|
|
||||||
name: "Floodlights Backyard"
|
|
||||||
icon: "mdi:light-flood-down"
|
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
|
||||||
# the backyard floodlight auto turns off in 4min 14 sec. So we need to switch relay off just before or at this time
|
|
||||||
# TODO: remove or extend auto turn off to >= 10min
|
|
||||||
on_turn_on:
|
|
||||||
- delay: 250s
|
|
||||||
- switch.turn_off: relay1
|
|
||||||
|
|
||||||
- platform: gpio
|
|
||||||
pin:
|
|
||||||
number: GPIO17
|
|
||||||
inverted: true
|
|
||||||
id: relay2
|
|
||||||
name: "Relay 2"
|
|
||||||
icon: "mdi:run-fast"
|
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
|
||||||
on_turn_on:
|
|
||||||
- delay: 1000ms
|
|
||||||
- switch.turn_off: relay2
|
|
||||||
|
|
||||||
- platform: gpio
|
|
||||||
pin:
|
|
||||||
number: GPIO18
|
|
||||||
inverted: true
|
|
||||||
id: relay3
|
|
||||||
name: "Relay 3"
|
|
||||||
icon: "mdi:run-fast"
|
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
|
||||||
on_turn_on:
|
|
||||||
- delay: 1000ms
|
|
||||||
- switch.turn_off: relay3
|
|
||||||
|
|
||||||
- platform: gpio
|
|
||||||
pin:
|
|
||||||
number: GPIO19
|
|
||||||
inverted: true
|
|
||||||
id: relay4
|
|
||||||
name: "Alarm Zone 4"
|
|
||||||
icon: "mdi:alarm-light-outline"
|
|
||||||
restore_mode: RESTORE_DEFAULT_OFF
|
|
||||||
on_turn_on:
|
|
||||||
- if:
|
|
||||||
condition:
|
|
||||||
- lambda: |-
|
|
||||||
double sun_elevation = id(sun_sensor).elevation();
|
|
||||||
return (sun_elevation <= -6); // -6° = civil twilight, -12° = nautical twilight, -18° = astronomical twilight
|
|
||||||
#- sun.is_below_horizon:
|
|
||||||
then:
|
|
||||||
- switch.turn_on: relay1
|
|
||||||
- if:
|
|
||||||
condition:
|
|
||||||
- binary_sensor.is_on: floodlight_test
|
|
||||||
then:
|
|
||||||
- switch.turn_on: relay1
|
|
||||||
- delay: 30s
|
|
||||||
- switch.turn_off: relay4
|
|
||||||
|
|
||||||
|
|
||||||
# define DIGITAL_D1 04
|
|
||||||
binary_sensor:
|
|
||||||
- platform: gpio
|
|
||||||
# device_class: light
|
|
||||||
id: floodlight_test
|
|
||||||
pin:
|
|
||||||
number: GPIO04
|
|
||||||
mode:
|
|
||||||
input: true
|
|
||||||
pullup: true
|
|
||||||
filters:
|
|
||||||
- delayed_off: 100ms
|
|
||||||
name: "Floodlights Test Mode"
|
|
||||||
icon: "mdi:lightbulb-on-outline"
|
|
||||||
|
|
||||||
#define ANALOG_A1 33
|
|
||||||
#define ANALOG_A2 32
|
|
||||||
#define ANALOG_A3 35
|
|
||||||
#define ANALOG_A4 34
|
|
||||||
#define ANALOG_A5 39
|
|
||||||
#define ANALOG_A6 36
|
|
||||||
sensor:
|
|
||||||
# - platform: adc
|
|
||||||
# pin: 35
|
|
||||||
# name: "Alarm Signal"
|
|
||||||
# id: alarm_signal
|
|
||||||
# update_interval: 2000ms
|
|
||||||
# attenuation: 12db
|
|
||||||
# sampling_mode: avg
|
|
||||||
# filters:
|
|
||||||
# - lambda:
|
|
||||||
# if (x >= 3.11) {
|
|
||||||
# return x * 1.60256;
|
|
||||||
# } else if (x <= 0.25) {
|
|
||||||
# return 0;
|
|
||||||
# } else {
|
|
||||||
# return x * 1.51;
|
|
||||||
# }
|
|
||||||
# on_value:
|
|
||||||
# then:
|
|
||||||
# # switch on floodlights
|
|
||||||
# lambda: |-
|
|
||||||
# if (id(alarm_signal).state > 1.5) {
|
|
||||||
# id(relay1).turn_on();
|
|
||||||
# }
|
|
||||||
|
|
||||||
# human readable uptime sensor output to the text sensor above
|
# human readable uptime sensor output to the text sensor above
|
||||||
- platform: uptime
|
- platform: uptime
|
||||||
name: Uptime in Days
|
name: Uptime in Days
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user