-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add info for multiplexing to sml.rst #5341
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -212,6 +212,47 @@ sensor: | |||||||||
| state_class: measurement | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ## Reading multiple meters | ||||||||||
|
|
||||||||||
| If you are reading data from more meters than your controller has UARTs available (e.g. more than two for an ESP32), you can use multiplexing to switch between reading data from different meters. | ||||||||||
|
|
||||||||||
| In order to do this, after each SML update, the used UART can be set to listen to a different pin. | ||||||||||
| An example on how to do this is this: | ||||||||||
|
|
||||||||||
| ```yaml | ||||||||||
| uart: | ||||||||||
| - baud_rate: 9600 | ||||||||||
| data_bits: 8 | ||||||||||
| rx_pin: | ||||||||||
| number: GPIO17 # Set to the first of the GPIO pins in multiplex_pins | ||||||||||
| id: uart_multiplex_rx_pin | ||||||||||
| stop_bits: 1 | ||||||||||
| rx_buffer_size: 512 | ||||||||||
| id: uart_multiplexed | ||||||||||
| sml: | ||||||||||
| - id: sml_multiplexed | ||||||||||
| uart_id: uart_multiplexed | ||||||||||
| on_data: | ||||||||||
| - lambda: |- | ||||||||||
| std::vector<gpio_num_t> multiplex_pins = {::GPIO_NUM_17,::GPIO_NUM_19}; | ||||||||||
| static size_t current_index = 0; | ||||||||||
| current_index = (current_index + 1) % multiplex_pins.size(); | ||||||||||
| gpio_num_t new_rx_pin = multiplex_pins[current_index]; | ||||||||||
| id(uart_multiplex_rx_pin).set_pin(new_rx_pin); | ||||||||||
|
||||||||||
| id(uart_multiplex_rx_pin).set_pin(new_rx_pin); | |
| id(uart_multiplex_rx_pin).set_pin(new_rx_pin); | |
| // Reload the UART settings after changing the RX pin. | |
| // The 'true' parameter forces the reload, which is necessary for multiplexing to work properly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix YAML indentation (invalid as written) and guard pin switch on valid frames.
- The list items under uart:, sml:, and sensor: must be indented.
- Only rotate RX after a valid SML frame to reduce missed reads.
- Use realistic server_id examples (consistent length/format with earlier docs).
- Consider adding a short note that the gpio_num_t example is ESP32/ESP-IDF–specific.
```yaml
-uart:
-- baud_rate: 9600
- data_bits: 8
- rx_pin:
- number: GPIO17 # Set to the first of the GPIO pins in multiplex_pins
- id: uart_multiplex_rx_pin
- stop_bits: 1
- rx_buffer_size: 512
- id: uart_multiplexed
+uart:
+ - baud_rate: 9600
+ data_bits: 8
+ rx_pin:
+ number: GPIO17 # Set to the first of the GPIO pins in multiplex_pins
+ id: uart_multiplex_rx_pin
+ stop_bits: 1
+ rx_buffer_size: 512
+ id: uart_multiplexed
sml:
-- id: sml_multiplexed
- uart_id: uart_multiplexed
- on_data:
- - lambda: |-
- std::vector<gpio_num_t> multiplex_pins = {::GPIO_NUM_17,::GPIO_NUM_19};
- static size_t current_index = 0;
- current_index = (current_index + 1) % multiplex_pins.size();
- gpio_num_t new_rx_pin = multiplex_pins[current_index];
- id(uart_multiplex_rx_pin).set_pin(new_rx_pin);
- id(uart_multiplexed).load_settings(true);
+ - id: sml_multiplexed
+ uart_id: uart_multiplexed
+ on_data:
+ - lambda: |-
+ // NOTE: ESP32-only example using ESP-IDF types (gpio_num_t).
+ std::vector<gpio_num_t> multiplex_pins = {::GPIO_NUM_17, ::GPIO_NUM_19};
+ if (valid) {
+ static size_t current_index = 0;
+ current_index = (current_index + 1) % multiplex_pins.size();
+ gpio_num_t new_rx_pin = multiplex_pins[current_index];
+ id(uart_multiplex_rx_pin).set_pin(new_rx_pin);
+ id(uart_multiplexed).load_settings(true);
+ }
sensor:
-- platform: sml
- name: "Solar Roof"
- sml_id: sml_multiplexed
- server_id: "12345ab" # IMPORTANT! Set the correct server id
- obis_code: "1-0:2.8.0"
-- platform: sml
- name: "Solar Carport"
- sml_id: sml_multiplexed
- server_id: "67890cd" # IMPORTANT! Set the correct server id
- obis_code: "1-0:2.8.0"
+ - platform: sml
+ name: "Solar Roof"
+ sml_id: sml_multiplexed
+ server_id: "0123456789abcdef" # Set your meter's server_id
+ obis_code: "1-0:2.8.0"
+ - platform: sml
+ name: "Solar Carport"
+ sml_id: sml_multiplexed
+ server_id: "fedcba9876543210" # Set your meter's server_id
+ obis_code: "1-0:2.8.0"🤖 Prompt for AI Agents
In content/components/sml.md around lines 222–254, fix the invalid YAML and
unsafe pin rotation: indent the list items under uart:, sml:, and sensor: so
each block is a proper list element (e.g., "- baud_rate..." under uart:), change
the on_data lambda to only rotate the RX pin after a validated SML frame (wrap
the current_index increment, set_pin and load_settings calls in an if(valid)
guard or equivalent), replace the example server_id values with realistic-length
hex strings consistent with the docs, and add a brief inline note that
gpio_num_t/::GPIO_NUM_* usage is ESP32/ESP-IDF specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lambda code uses ESP-IDF specific
gpio_num_tandGPIO_NUM_*constants without explaining this is ESP-specific. Consider adding a note that this example is for ESP32/ESP8266 platforms or provide a more platform-agnostic example.