Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce flow control pin (Closes: #18) #19

Merged
merged 4 commits into from
Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ repos:
rev: v1.3.5
hooks:
- id: clang-format
- id: clang-tidy
39 changes: 30 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ ESPHome component to monitor a Solax X1 mini via RS485.
## Supported devices

* SolaX X1 Mini
- SolaX X1 Mini X1-0.6-S-D
- SolaX X1 Mini X1-0.6-S-D(L)
* SolaX X1 Mini G2
- SolaX X1 Mini X1-1.5-S-D(L) (master version 1.08, manager version 1.07) (reported by [@beocycris](https://github.com/syssi/esphome-modbus-solax-x1/issues/18#issuecomment-1073188868))
- SolaX X1 Mini X1-2.0-S-D(L) (master version 1.08, manager version 1.07) (reported by [@zcloud-at](https://github.com/syssi/esphome-modbus-solax-x1/issues/15))

## Requirements
Expand All @@ -26,15 +27,34 @@ ESPHome component to monitor a Solax X1 mini via RS485.

## Schematics

#### RS485-TTL module without flow control pin

```
RS485 UART
┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ │ │ GND│<--------->│GND │
│ Solax │<-----B- ---->│ RS485 RXD│<--------->│RX ESP32/ │
│ X1 Mini │<---- A+ ---->│ to TTL TXD│<--------->│TX ESP8266 │
│ │<--- GND ---->│ module VCC│<--------->│3.3V VCC│<--
│ │ │ │ │ GND│<--
└─────────┘ └─────────────┘ └─────────────────┘

```
RS485 UART
┌─────────┐ ┌──────────┐ ┌─────────┐
│ │ │ │<----- RX ----->│ │
│ Solax │<-----B- ---->│ RS485 │<----- TX ----->│ ESP32/ │
│ X1 Mini │<---- A+ ---->│ to TTL │<----- GND ---->│ ESP8266 │
│ │<--- GND ---->│ module │<-- 3.3 VCC --->│ │<-- VCC
│ │ │ │ │ │<-- GND
└─────────┘ └──────────┘ └─────────┘

#### RS485-TTL module with flow control pin

```
RS485 UART
┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ │ │ DI│<--------->│TX │
│ Solax │<-----B- ---->│ RS485 DE│<--\ │ ESP32/ │
│ X1 Mini │<---- A+ ---->│ to TTL RE│<---+----->│GPIO0 ESP8266 │
│ │<--- GND ---->│ module RO│<--------->│RX │
│ │ │ │ │ │
│ │ │ VCC│<--------->│3.3V VCC│<--
│ │ │ GND│<--------->│GND GND│<--
└─────────┘ └─────────────┘ └─────────────────┘

```

Please make sure to power the RS485 module with 3.3V because it affects the TTL (transistor-transistor logic) voltage between RS485 module and ESP.
Expand Down Expand Up @@ -126,6 +146,7 @@ solax_x1:
serial_number: "3132333435363737363534333231"
address: 0x0A
update_interval: 1s
# flow_control_pin: GPIO0

text_sensor:
- platform: solax_x1
Expand Down
29 changes: 19 additions & 10 deletions components/modbus_solax/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart
from esphome.const import CONF_ADDRESS, CONF_ID
from esphome.core import coroutine
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_FLOW_CONTROL_PIN, CONF_ID
from esphome.cpp_helpers import gpio_pin_expression
from esphome import pins

CODEOWNERS = ["@syssi"]
DEPENDENCIES = ["uart"]
Expand All @@ -15,7 +16,12 @@
CONF_MODBUS_SOLAX_ID = "modbus_solax_id"
CONF_SERIAL_NUMBER = "serial_number"
CONFIG_SCHEMA = (
cv.Schema({cv.GenerateID(): cv.declare_id(ModbusSolax)})
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ModbusSolax),
cv.Optional(CONF_FLOW_CONTROL_PIN): pins.gpio_output_pin_schema,
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(uart.UART_DEVICE_SCHEMA)
)
Expand Down Expand Up @@ -46,12 +52,16 @@ def as_hex_array(value):
return cg.RawExpression(f"(uint8_t*)(const uint8_t[16]){{{','.join(cpp_array)}}}")


def to_code(config):
async def to_code(config):
cg.add_global(modbus_solax_ns.using)
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
await cg.register_component(var, config)

await uart.register_uart_device(var, config)

yield uart.register_uart_device(var, config)
if CONF_FLOW_CONTROL_PIN in config:
pin = await gpio_pin_expression(config[CONF_FLOW_CONTROL_PIN])
cg.add(var.set_flow_control_pin(pin))


def modbus_solax_device_schema():
Expand All @@ -63,9 +73,8 @@ def modbus_solax_device_schema():
return cv.Schema(schema)


@coroutine
def register_modbus_solax_device(var, config):
parent = yield cg.get_variable(config[CONF_MODBUS_SOLAX_ID])
async def register_modbus_solax_device(var, config):
parent = await cg.get_variable(config[CONF_MODBUS_SOLAX_ID])
cg.add(var.set_parent(parent))
cg.add(var.set_address(config[CONF_ADDRESS]))
cg.add(var.set_serial_number(as_hex_array(config[CONF_SERIAL_NUMBER])))
Expand Down
17 changes: 16 additions & 1 deletion components/modbus_solax/modbus_solax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ namespace modbus_solax {

static const char *const TAG = "modbus_solax";

void ModbusSolax::setup() {
if (this->flow_control_pin_ != nullptr) {
this->flow_control_pin_->setup();
}
}

void ModbusSolax::loop() {
const uint32_t now = millis();
if (now - this->last_modbus_solax_byte_ > 50) {
Expand Down Expand Up @@ -138,7 +144,10 @@ bool ModbusSolax::parse_modbus_solax_byte_(uint8_t byte) {
return false;
}

void ModbusSolax::dump_config() { ESP_LOGCONFIG(TAG, "ModbusSolax:"); }
void ModbusSolax::dump_config() {
ESP_LOGCONFIG(TAG, "ModbusSolax:");
LOG_PIN(" Flow Control Pin: ", this->flow_control_pin_);
}
float ModbusSolax::get_setup_priority() const {
// After UART bus
return setup_priority::BUS - 1.0f;
Expand Down Expand Up @@ -217,8 +226,14 @@ void ModbusSolax::send(SolaxMessageT *tx_message) {

ESP_LOGVV(TAG, "TX -> %s", format_hex_pretty((const uint8_t *) tx_message, msg_len).c_str());

if (this->flow_control_pin_ != nullptr)
this->flow_control_pin_->digital_write(true);

this->write_array((const uint8_t *) tx_message, msg_len);
this->flush();

if (this->flow_control_pin_ != nullptr)
this->flow_control_pin_->digital_write(false);
}

} // namespace modbus_solax
Expand Down
3 changes: 3 additions & 0 deletions components/modbus_solax/modbus_solax.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ class ModbusSolax : public uart::UARTDevice, public Component {
public:
ModbusSolax() = default;

void setup() override;
void loop() override;

void dump_config() override;

void register_device(ModbusSolaxDevice *device) { this->devices_.push_back(device); }
void set_flow_control_pin(GPIOPin *flow_control_pin) { this->flow_control_pin_ = flow_control_pin; }

float get_setup_priority() const override;

Expand All @@ -38,6 +40,7 @@ class ModbusSolax : public uart::UARTDevice, public Component {

protected:
bool parse_modbus_solax_byte_(uint8_t byte);
GPIOPin *flow_control_pin_{nullptr};

std::vector<uint8_t> rx_buffer_;
uint32_t last_modbus_solax_byte_{0};
Expand Down
2 changes: 1 addition & 1 deletion components/solax_x1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import modbus_solax
import esphome.config_validation as cv
from esphome.const import CONF_ID

AUTO_LOAD = ["modbus_solax", "sensor", "text_sensor"]
Expand Down
2 changes: 1 addition & 1 deletion components/solax_x1/sensor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_MODE,
CONF_TEMPERATURE,
Expand Down
2 changes: 1 addition & 1 deletion components/solax_x1/text_sensor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import text_sensor
import esphome.config_validation as cv
from esphome.const import CONF_ICON, CONF_ID

from . import CONF_SOLAX_X1_ID, SolaxX1
Expand Down
7 changes: 7 additions & 0 deletions esp32-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,18 @@ mqtt:
id: mqtt_client

uart:
id: uart0
baud_rate: 9600
tx_pin: GPIO1
rx_pin: GPIO3

modbus_solax:
- id: modbus0
uart_id: uart0
# flow_control_pin: GPIO0

solax_x1:
modbus_solax_id: modbus0
serial_number: "3132333435363737363534333231"
address: 0x0A
update_interval: 1s
Expand Down