mirror of
https://github.com/randybb/esphome-configs.git
synced 2026-01-02 19:47:29 +01:00
have fun
This commit is contained in:
30
components/m5stack_4relay/__init__.py
Normal file
30
components/m5stack_4relay/__init__.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
AUTO_LOAD = ["switch"]
|
||||
CODEOWNERS = ["@brotherdust"]
|
||||
|
||||
m5stack_4relay_ns = cg.esphome_ns.namespace("m5stack_4relay")
|
||||
M5STACK4RELAYOutput = m5stack_4relay_ns.class_(
|
||||
"M5STACK4RELAYSwitchComponent", cg.Component, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(M5STACK4RELAYOutput),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x26))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
49
components/m5stack_4relay/m5stack_4relay.cpp
Normal file
49
components/m5stack_4relay/m5stack_4relay.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "m5stack_4relay.h"
|
||||
#include <bitset>
|
||||
#include "esphome/core/log.h"
|
||||
namespace esphome {
|
||||
namespace m5stack_4relay {
|
||||
static const char *const TAG = "m5stack_4relay.switch";
|
||||
|
||||
void M5STACK4RELAYSwitchComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up M5STACK4RELAY (0x%02X)...", this->address_);
|
||||
component_status = 0;
|
||||
get_status(&component_status);
|
||||
ESP_LOGD(TAG, "Setup Status 0x%02X", component_status);
|
||||
}
|
||||
|
||||
M5STACK4RELAYChannel *M5STACK4RELAYSwitchComponent::create_channel(uint8_t channel) {
|
||||
return new M5STACK4RELAYChannel(this, channel);
|
||||
}
|
||||
|
||||
void M5STACK4RELAYSwitchComponent::get_status(uint8_t *state) { this->read_byte(RELAY_CONTROL_REG); }
|
||||
|
||||
bool M5STACK4RELAYSwitchComponent::set_channel_value_(uint8_t channel, bool state) {
|
||||
get_status(&component_status);
|
||||
|
||||
ESP_LOGD(TAG, "Current status 0x%02X", component_status);
|
||||
ESP_LOGD(TAG, "Desired channel: %1u", channel);
|
||||
ESP_LOGD(TAG, "Desired state: %1u", state);
|
||||
|
||||
channel = 3 - channel;
|
||||
if (state) {
|
||||
component_status |= (1u << channel);
|
||||
} else {
|
||||
component_status &= ~(1u << channel);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "New status 0x%02X", component_status);
|
||||
|
||||
return this->write_byte(this->address_, RELAY_CONTROL_REG, component_status);
|
||||
}
|
||||
|
||||
void M5STACK4RELAYChannel::write_state(bool state) {
|
||||
if (!this->set_channel_value_(this->channel_, state)) {
|
||||
publish_state(false);
|
||||
} else {
|
||||
publish_state(state);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace m5stack_4relay
|
||||
} // namespace esphome
|
||||
49
components/m5stack_4relay/m5stack_4relay.h
Normal file
49
components/m5stack_4relay/m5stack_4relay.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace m5stack_4relay {
|
||||
|
||||
class M5STACK4RELAYSwitchComponent;
|
||||
class M5STACK4RELAYChannel : public switch_::Switch {
|
||||
public:
|
||||
M5STACK4RELAYChannel(M5STACK4RELAYSwitchComponent *parent, uint8_t channel) : parent_(parent), channel_(channel) {}
|
||||
|
||||
protected:
|
||||
void write_state(bool state) override;
|
||||
|
||||
M5STACK4RELAYSwitchComponent *parent_;
|
||||
uint8_t channel_;
|
||||
};
|
||||
|
||||
class M5STACK4RELAYSwitchComponent : public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
const uint8_t MODE_CONTROL_REG = 0x10;
|
||||
const uint8_t RELAY_CONTROL_REG = 0x11;
|
||||
uint8_t component_status;
|
||||
M5STACK4RELAYSwitchComponent() {}
|
||||
M5STACK4RELAYChannel *create_channel(uint8_t channel);
|
||||
|
||||
void setup() override;
|
||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
|
||||
protected:
|
||||
friend M5STACK4RELAYChannel;
|
||||
|
||||
void get_status(uint8_t *state);
|
||||
|
||||
bool set_channel_value_(uint8_t channel, bool state);
|
||||
|
||||
bool read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion) {
|
||||
return this->raw_receive(this->address_, data, len);
|
||||
}
|
||||
|
||||
float value_;
|
||||
};
|
||||
|
||||
} // namespace m5stack_4relay
|
||||
} // namespace esphome
|
||||
25
components/m5stack_4relay/switch.py
Normal file
25
components/m5stack_4relay/switch.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import switch
|
||||
from esphome.const import CONF_ID, CONF_CHANNEL
|
||||
from . import M5STACK4RELAYOutput, m5stack_4relay_ns
|
||||
|
||||
DEPENDENCIES = ["m5stack_4relay"]
|
||||
|
||||
M5STACK4RELAYChannel = m5stack_4relay_ns.class_("M5STACK4RELAYChannel", switch.Switch)
|
||||
CONF_M5STACK_4RELAY_ID = "m5stack_4relay_id"
|
||||
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(M5STACK4RELAYChannel),
|
||||
cv.GenerateID(CONF_M5STACK_4RELAY_ID): cv.use_id(M5STACK4RELAYOutput),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=3),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
paren = await cg.get_variable(config[CONF_M5STACK_4RELAY_ID])
|
||||
rhs = paren.create_channel(config[CONF_CHANNEL])
|
||||
var = cg.Pvariable(config[CONF_ID], rhs)
|
||||
await switch.register_switch(var, config)
|
||||
Reference in New Issue
Block a user