m5stack co2 sensor
This commit is contained in:
parent
513cab32b7
commit
55ec47e3af
|
@ -0,0 +1,59 @@
|
|||
.
|
||||
|
||||
light:
|
||||
- platform: monochromatic
|
||||
name: "Livingroom Ceiling light"
|
||||
id: light_0
|
||||
output: light_0_out
|
||||
|
||||
# Example output entry
|
||||
output:
|
||||
- platform: esp8266_pwm
|
||||
id: light_0_out
|
||||
pin: D4
|
||||
inverted: true
|
||||
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
pin: D2
|
||||
id: light_0_touch
|
||||
on_click:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
light.is_off: light_0
|
||||
then:
|
||||
light.turn_on:
|
||||
id: light_0
|
||||
brightness: 1.0
|
||||
else:
|
||||
light.turn_off: light_0
|
||||
on_press:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
light.is_off: light_0
|
||||
then:
|
||||
- delay: 0.5s
|
||||
- while:
|
||||
condition:
|
||||
binary_sensor.is_on: light_0_touch
|
||||
then:
|
||||
- light.dim_relative:
|
||||
id: light_0
|
||||
relative_brightness: 5%
|
||||
transition_length: 0.1s
|
||||
- delay: 0.1s
|
||||
else:
|
||||
- delay: 0.5s
|
||||
- while:
|
||||
condition:
|
||||
and:
|
||||
- binary_sensor.is_on: light_0_touch
|
||||
- light.is_on: light_0
|
||||
then:
|
||||
- light.dim_relative:
|
||||
id: light_0
|
||||
relative_brightness: -5%
|
||||
transition_length: 0.1s
|
||||
- delay: 0.1s
|
|
@ -0,0 +1,243 @@
|
|||
---
|
||||
esphome:
|
||||
name: m5atom1
|
||||
friendly_name: M5Atom1
|
||||
name_add_mac_suffix: true
|
||||
project:
|
||||
name: m5stack.atom-echo-voice-assistant
|
||||
version: "1.0"
|
||||
min_version: 2023.11.1
|
||||
|
||||
esp32:
|
||||
board: m5stack-atom
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
logger:
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
password: !secret ota_password
|
||||
|
||||
dashboard_import:
|
||||
package_import_url: github://esphome/firmware/voice-assistant/m5stack-atom-echo.yaml@main
|
||||
|
||||
wifi:
|
||||
on_connect:
|
||||
- delay: 5s # Gives time for improv results to be transmitted
|
||||
- ble.disable:
|
||||
on_disconnect:
|
||||
- ble.enable:
|
||||
ssid: WLAN
|
||||
password: !secret wifi_password
|
||||
|
||||
improv_serial:
|
||||
|
||||
esp32_improv:
|
||||
authorizer: none
|
||||
|
||||
button:
|
||||
- platform: factory_reset
|
||||
id: factory_reset_btn
|
||||
name: Factory reset
|
||||
|
||||
i2s_audio:
|
||||
i2s_lrclk_pin: GPIO33
|
||||
i2s_bclk_pin: GPIO19
|
||||
|
||||
microphone:
|
||||
- platform: i2s_audio
|
||||
id: echo_microphone
|
||||
i2s_din_pin: GPIO23
|
||||
adc_type: external
|
||||
pdm: true
|
||||
|
||||
speaker:
|
||||
- platform: i2s_audio
|
||||
id: echo_speaker
|
||||
i2s_dout_pin: GPIO22
|
||||
dac_type: external
|
||||
mode: mono
|
||||
|
||||
voice_assistant:
|
||||
id: va
|
||||
microphone: echo_microphone
|
||||
speaker: echo_speaker
|
||||
noise_suppression_level: 2
|
||||
auto_gain: 31dBFS
|
||||
volume_multiplier: 2.0
|
||||
vad_threshold: 3
|
||||
on_listening:
|
||||
- light.turn_on:
|
||||
id: led
|
||||
blue: 100%
|
||||
red: 0%
|
||||
green: 0%
|
||||
effect: "Slow Pulse"
|
||||
on_stt_vad_end:
|
||||
- light.turn_on:
|
||||
id: led
|
||||
blue: 100%
|
||||
red: 0%
|
||||
green: 0%
|
||||
effect: "Fast Pulse"
|
||||
on_tts_start:
|
||||
- light.turn_on:
|
||||
id: led
|
||||
blue: 100%
|
||||
red: 0%
|
||||
green: 0%
|
||||
brightness: 100%
|
||||
effect: none
|
||||
on_end:
|
||||
- delay: 100ms
|
||||
- wait_until:
|
||||
not:
|
||||
speaker.is_playing:
|
||||
- script.execute: reset_led
|
||||
on_error:
|
||||
- light.turn_on:
|
||||
id: led
|
||||
red: 100%
|
||||
green: 0%
|
||||
blue: 0%
|
||||
brightness: 100%
|
||||
effect: none
|
||||
- delay: 1s
|
||||
- script.execute: reset_led
|
||||
on_client_connected:
|
||||
- if:
|
||||
condition:
|
||||
switch.is_on: use_wake_word
|
||||
then:
|
||||
- voice_assistant.start_continuous:
|
||||
- script.execute: reset_led
|
||||
on_client_disconnected:
|
||||
- if:
|
||||
condition:
|
||||
switch.is_on: use_wake_word
|
||||
then:
|
||||
- voice_assistant.stop:
|
||||
- light.turn_off: led
|
||||
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: GPIO39
|
||||
inverted: true
|
||||
name: Button
|
||||
disabled_by_default: true
|
||||
entity_category: diagnostic
|
||||
id: echo_button
|
||||
on_multi_click:
|
||||
- timing:
|
||||
- ON for at least 250ms
|
||||
- OFF for at least 50ms
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
switch.is_off: use_wake_word
|
||||
then:
|
||||
- if:
|
||||
condition: voice_assistant.is_running
|
||||
then:
|
||||
- voice_assistant.stop:
|
||||
- script.execute: reset_led
|
||||
else:
|
||||
- voice_assistant.start:
|
||||
else:
|
||||
- voice_assistant.stop
|
||||
- delay: 1s
|
||||
- script.execute: reset_led
|
||||
- script.wait: reset_led
|
||||
- voice_assistant.start_continuous:
|
||||
- timing:
|
||||
- ON for at least 10s
|
||||
then:
|
||||
- button.press: factory_reset_btn
|
||||
|
||||
light:
|
||||
- platform: esp32_rmt_led_strip
|
||||
id: led
|
||||
name: None
|
||||
disabled_by_default: true
|
||||
entity_category: config
|
||||
pin: GPIO27
|
||||
default_transition_length: 0s
|
||||
chipset: SK6812
|
||||
num_leds: 1
|
||||
rgb_order: grb
|
||||
rmt_channel: 0
|
||||
effects:
|
||||
- pulse:
|
||||
name: "Slow Pulse"
|
||||
transition_length: 250ms
|
||||
update_interval: 250ms
|
||||
min_brightness: 50%
|
||||
max_brightness: 100%
|
||||
- pulse:
|
||||
name: "Fast Pulse"
|
||||
transition_length: 100ms
|
||||
update_interval: 100ms
|
||||
min_brightness: 50%
|
||||
max_brightness: 100%
|
||||
|
||||
script:
|
||||
- id: reset_led
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
- switch.is_on: use_wake_word
|
||||
- switch.is_on: use_listen_light
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: led
|
||||
red: 100%
|
||||
green: 89%
|
||||
blue: 71%
|
||||
brightness: 60%
|
||||
effect: none
|
||||
else:
|
||||
- light.turn_off: led
|
||||
|
||||
switch:
|
||||
- platform: template
|
||||
name: Use wake word
|
||||
id: use_wake_word
|
||||
optimistic: true
|
||||
restore_mode: RESTORE_DEFAULT_ON
|
||||
entity_category: config
|
||||
on_turn_on:
|
||||
- lambda: id(va).set_use_wake_word(true);
|
||||
- if:
|
||||
condition:
|
||||
not:
|
||||
- voice_assistant.is_running
|
||||
then:
|
||||
- voice_assistant.start_continuous
|
||||
- script.execute: reset_led
|
||||
on_turn_off:
|
||||
- voice_assistant.stop
|
||||
- lambda: id(va).set_use_wake_word(false);
|
||||
- script.execute: reset_led
|
||||
- platform: template
|
||||
name: Use Listen Light
|
||||
id: use_listen_light
|
||||
optimistic: true
|
||||
restore_mode: RESTORE_DEFAULT_ON
|
||||
entity_category: config
|
||||
on_turn_on:
|
||||
- script.execute: reset_led
|
||||
on_turn_off:
|
||||
- script.execute: reset_led
|
||||
|
||||
external_components:
|
||||
- source: github://pr#5230
|
||||
components:
|
||||
- esp_adf
|
||||
refresh: 0s
|
||||
|
||||
esp_adf:
|
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
|
@ -0,0 +1,185 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="320mm"
|
||||
height="240mm"
|
||||
viewBox="0 0 320 240"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
sodipodi:docname="m5stack_display.svg"
|
||||
inkscape:export-filename="/home/martin/code/esphome/m5stack_display.png"
|
||||
inkscape:export-xdpi="25.4"
|
||||
inkscape:export-ydpi="25.4"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1474186"
|
||||
inkscape:cx="722.05556"
|
||||
inkscape:cy="440.11836"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2063"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer2" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<rect
|
||||
x="-263.52751"
|
||||
y="328.9208"
|
||||
width="56.257952"
|
||||
height="42.873549"
|
||||
id="rect29523" />
|
||||
<rect
|
||||
x="81.093522"
|
||||
y="296.73663"
|
||||
width="416.73771"
|
||||
height="44.334986"
|
||||
id="rect4969" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Background"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.96470606;stroke:none;stroke-width:2.23467;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect848"
|
||||
width="320"
|
||||
height="240"
|
||||
x="0"
|
||||
y="0"
|
||||
ry="2.5911958e-13" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Elements">
|
||||
<rect
|
||||
style="fill:#0076ff;fill-opacity:0.96470606;stroke:none;stroke-width:1.32314;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122"
|
||||
width="320"
|
||||
height="30"
|
||||
x="0"
|
||||
y="0"
|
||||
ry="9.4221316e-14" />
|
||||
<rect
|
||||
style="fill:#0076ff;fill-opacity:0.964706;stroke:none;stroke-width:1.3777;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3"
|
||||
width="130"
|
||||
height="30"
|
||||
x="15"
|
||||
y="63.852001"
|
||||
ry="9.8846529e-14" />
|
||||
<rect
|
||||
style="fill:#0076ff;fill-opacity:0.964706;stroke:none;stroke-width:1.3777;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3-6"
|
||||
width="130"
|
||||
height="30"
|
||||
x="15"
|
||||
y="122.02885"
|
||||
ry="9.8846529e-14" />
|
||||
<rect
|
||||
style="fill:#0076ff;fill-opacity:0.964706;stroke:none;stroke-width:1.26316;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3-7"
|
||||
width="130"
|
||||
height="30"
|
||||
x="15"
|
||||
y="180.2054"
|
||||
ry="9.9489962e-14" />
|
||||
<rect
|
||||
style="fill:#009600;fill-opacity:0.96470606;stroke:none;stroke-width:1.3777;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3-8"
|
||||
width="130"
|
||||
height="30"
|
||||
x="168.81218"
|
||||
y="63.851997"
|
||||
ry="9.8846529e-14" />
|
||||
<rect
|
||||
style="fill:#009600;fill-opacity:0.96470606;stroke:none;stroke-width:1.3777;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3-6-8"
|
||||
width="130"
|
||||
height="30"
|
||||
x="168.81218"
|
||||
y="122.02884"
|
||||
ry="9.8846529e-14" />
|
||||
<rect
|
||||
style="fill:#009600;fill-opacity:0.96470606;stroke:none;stroke-width:1.26316;stroke-linecap:round;stroke-opacity:0.968627"
|
||||
id="rect1122-3-7-6"
|
||||
width="130"
|
||||
height="30"
|
||||
x="168.81218"
|
||||
y="180.2054"
|
||||
ry="9.9489962e-14" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="scale(0.26458333)"
|
||||
id="text4967"
|
||||
style="font-size:24px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect4969);fill:#ffd5d5" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16.9333px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="20.979563"
|
||||
y="84.87159"
|
||||
id="text14105"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14103"
|
||||
style="font-size:16.9333px;fill:#e8e8e8;fill-opacity:1;stroke-width:0.264583"
|
||||
x="20.979563"
|
||||
y="84.87159">CO </tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16.9333px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="21.558338"
|
||||
y="142.9158"
|
||||
id="text14105-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14103-29"
|
||||
style="font-size:16.9333px;fill:#e8e8e8;fill-opacity:1;stroke-width:0.264583"
|
||||
x="21.558338"
|
||||
y="142.9158">Temperatur</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16.9333px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="20.574421"
|
||||
y="200.93526"
|
||||
id="text14105-0-0"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14103-29-9"
|
||||
style="font-size:16.9333px;fill:#e8e8e8;fill-opacity:1;stroke-width:0.264583"
|
||||
x="20.574421"
|
||||
y="200.93526">Luftfeuchtigkeit</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.1111px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="46.06287"
|
||||
y="88.702797"
|
||||
id="text14105-5"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14103-2"
|
||||
style="font-size:14.1111px;fill:#e8e8e8;fill-opacity:1;stroke-width:0.264583"
|
||||
x="46.06287"
|
||||
y="88.702797">2</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="scale(0.26458333)"
|
||||
id="text29521"
|
||||
style="font-family:Roboto;font-size:24px;line-height:1.25;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Roboto;white-space:pre;shape-inside:url(#rect29523)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Text" />
|
||||
</svg>
|
After Width: | Height: | Size: 6.3 KiB |
|
@ -46,12 +46,12 @@ ip5306:
|
|||
# Buttons
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
id: M5_BtnA
|
||||
id: m5stackfire_button_left
|
||||
pin:
|
||||
number: 39
|
||||
inverted: true
|
||||
- platform: gpio
|
||||
id: M5_BtnB
|
||||
id: m5stackfire_button_middle
|
||||
pin:
|
||||
number: 38
|
||||
inverted: true
|
||||
|
@ -59,11 +59,14 @@ binary_sensor:
|
|||
then:
|
||||
- switch.toggle: backlight
|
||||
- platform: gpio
|
||||
id: M5_BtnC
|
||||
id: m5stackfire_button_right
|
||||
pin:
|
||||
number: 37
|
||||
inverted: true
|
||||
|
||||
- platform: gpio
|
||||
pin: 36
|
||||
name: m5stackfire-motion
|
||||
device_class: motion
|
||||
# GPIO pin of the display backlight
|
||||
switch:
|
||||
- platform: gpio
|
||||
|
@ -88,6 +91,19 @@ light:
|
|||
restore_mode: ALWAYS_OFF
|
||||
id: side_light
|
||||
default_transition_length: 0s
|
||||
- platform: partition
|
||||
name: "${friendly_name} Side Light Right"
|
||||
segments:
|
||||
- id: side_light
|
||||
from: 0
|
||||
to: 4
|
||||
- platform: partition
|
||||
name: "${friendly_name} Side Light Left"
|
||||
segments:
|
||||
- id: side_light
|
||||
from: 5
|
||||
to: 9
|
||||
|
||||
|
||||
i2c:
|
||||
sda: 21
|
||||
|
@ -103,7 +119,13 @@ spi:
|
|||
font:
|
||||
- file: "gfonts://Roboto"
|
||||
id: roboto
|
||||
size: 24
|
||||
size: 18
|
||||
|
||||
image:
|
||||
- file: m5stack_display.png
|
||||
id: img_background
|
||||
type: RGB24
|
||||
|
||||
|
||||
display:
|
||||
- platform: ili9xxx
|
||||
|
@ -113,9 +135,10 @@ display:
|
|||
reset_pin: 33
|
||||
id: my_display
|
||||
lambda: |-
|
||||
it.printf(80, 0, id(roboto), Color(255, 255, 255), TextAlign::TOP_CENTER, "CO2 Value %.1f", id(co2value).state );
|
||||
it.printf(80, 30, id(roboto), Color(255, 255, 255), TextAlign::TOP_CENTER, "CO2 Temp %.1f", id(co2temp).state );
|
||||
|
||||
it.image(0, 0, id(img_background));
|
||||
it.printf(240, 67, id(roboto), Color(255, 255, 255), TextAlign::TOP_CENTER, "%.0f ppm", id(co2value).state );
|
||||
it.printf(240, 125, id(roboto), Color(255, 255, 255), TextAlign::TOP_CENTER, "%.1f °C", id(co2temp).state );
|
||||
it.printf(240, 184, id(roboto), Color(255, 255, 255), TextAlign::TOP_CENTER, "%.1f %%", id(m5stackfire_dht22_humidity).state );
|
||||
|
||||
#display:
|
||||
# - platform: ili9xxx
|
||||
|
@ -176,4 +199,15 @@ sensor:
|
|||
update_interval: 5s
|
||||
automatic_baseline_calibration: false
|
||||
uart_id: uart_co2
|
||||
id: my_mhz19
|
||||
id: my_mhz19
|
||||
- platform: dht
|
||||
pin: 26
|
||||
temperature:
|
||||
id: m5stackfire_dht22_temperature
|
||||
name: "DHT22 Temperature"
|
||||
humidity:
|
||||
id: m5stackfire_dht22_humidity
|
||||
name: "DHT22 humidity"
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
from esphome.components import select
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
|
||||
|
||||
from esphome.const import CONF_ID, CONF_ADDRESS
|
||||
from esphome.components.modbus_controller import (
|
||||
add_modbus_base_properties,
|
||||
modbus_controller_ns,
|
||||
modbus_calc_properties,
|
||||
validate_modbus_register,
|
||||
ModbusItemBaseSchema,
|
||||
SensorItem,
|
||||
MODBUS_REGISTER_TYPE,
|
||||
)
|
||||
|
||||
from ..const import (
|
||||
CONF_BITMASK,
|
||||
CONF_FORCE_NEW_RANGE,
|
||||
CONF_MODBUS_CONTROLLER_ID,
|
||||
CONF_REGISTER_TYPE,
|
||||
CONF_SKIP_UPDATES,
|
||||
CONF_USE_WRITE_MULTIPLE,
|
||||
CONF_WRITE_LAMBDA,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["modbus_controller"]
|
||||
CODEOWNERS = ["@mabau"]
|
||||
|
||||
|
||||
NeopoolFiltrationMode = modbus_controller_ns.class_(
|
||||
"NeopoolFiltrationMode", cg.Component, select.Select, SensorItem
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
select.select_schema(NeopoolFiltrationMode)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
#.extend(ModbusItemBaseSchema)
|
||||
#.extend(
|
||||
# {
|
||||
# cv.Required(CONF)
|
||||
# cv.Optional(CONF_REGISTER_TYPE): cv.enum(MODBUS_REGISTER_TYPE),
|
||||
# cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
|
||||
# cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda,
|
||||
# }
|
||||
#),
|
||||
#validate_modbus_register,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
byte_offset, _ = modbus_calc_properties(config)
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
config[CONF_REGISTER_TYPE],
|
||||
config[CONF_ADDRESS],
|
||||
byte_offset,
|
||||
config[CONF_BITMASK],
|
||||
config[CONF_SKIP_UPDATES],
|
||||
config[CONF_FORCE_NEW_RANGE],
|
||||
)
|
||||
await cg.register_component(var, config)
|
||||
await switch.register_switch(var, config)
|
||||
|
||||
paren = await cg.get_variable(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
cg.add(var.set_parent(paren))
|
||||
cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE]))
|
||||
cg.add(paren.add_sensor_item(var))
|
||||
if CONF_WRITE_LAMBDA in config:
|
||||
template_ = await cg.process_lambda(
|
||||
config[CONF_WRITE_LAMBDA],
|
||||
[
|
||||
(ModbusSwitch.operator("ptr"), "item"),
|
||||
(cg.bool_, "x"),
|
||||
(cg.std_vector.template(cg.uint8).operator("ref"), "payload"),
|
||||
],
|
||||
return_type=cg.optional.template(bool),
|
||||
)
|
||||
cg.add(var.set_write_template(template_))
|
||||
await add_modbus_base_properties(var, config, ModbusSwitch, bool, bool)
|
|
@ -0,0 +1,89 @@
|
|||
#include "filtration_mode.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
|
||||
namespace esphome {
|
||||
namespace neopool {
|
||||
|
||||
void FiltrationSelect::dump_config() { LOG_SELECT(TAG, "Modbus Neopool Filtration Select", this); }
|
||||
|
||||
void FiltrationSelect::parse_and_publish(const std::vector<uint8_t> &data)
|
||||
{
|
||||
int64_t value = payload_to_number(data, this->sensor_value_type, this->offset, this->bitmask);
|
||||
|
||||
ESP_LOGD(TAG, "New select value %lld from payload", value);
|
||||
|
||||
optional<std::string> new_state;
|
||||
|
||||
if (this->transform_func_.has_value()) {
|
||||
auto val = (*this->transform_func_)(this, value, data);
|
||||
if (val.has_value()) {
|
||||
new_state = *val;
|
||||
ESP_LOGV(TAG, "lambda returned option %s", new_state->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_state.has_value()) {
|
||||
auto map_it = std::find(this->mapping_.cbegin(), this->mapping_.cend(), value);
|
||||
|
||||
if (map_it != this->mapping_.cend()) {
|
||||
size_t idx = std::distance(this->mapping_.cbegin(), map_it);
|
||||
new_state = this->traits.get_options()[idx];
|
||||
ESP_LOGV(TAG, "Found option %s for value %lld", new_state->c_str(), value);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "No option found for mapping %lld", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_state.has_value()) {
|
||||
this->publish_state(new_state.value());
|
||||
}
|
||||
}
|
||||
|
||||
void FiltrationSelect::control(const std::string &value) {
|
||||
auto options = this->traits.get_options();
|
||||
auto opt_it = std::find(options.cbegin(), options.cend(), value);
|
||||
size_t idx = std::distance(options.cbegin(), opt_it);
|
||||
optional<int64_t> mapval = this->mapping_[idx];
|
||||
ESP_LOGD(TAG, "Found value %lld for option '%s'", *mapval, value.c_str());
|
||||
|
||||
std::vector<uint16_t> data;
|
||||
|
||||
if (this->write_transform_func_.has_value()) {
|
||||
auto val = (*this->write_transform_func_)(this, value, *mapval, data);
|
||||
if (val.has_value()) {
|
||||
mapval = *val;
|
||||
ESP_LOGV(TAG, "write_lambda returned mapping value %lld", *mapval);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Communication handled by write_lambda - exiting control");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.empty()) {
|
||||
number_to_payload(data, *mapval, this->sensor_value_type);
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Using payload from write lambda");
|
||||
}
|
||||
|
||||
if (data.empty()) {
|
||||
ESP_LOGW(TAG, "No payload was created for updating select");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t write_address = this->start_address + this->offset / 2;
|
||||
ModbusCommandItem write_cmd;
|
||||
if ((this->register_count == 1) && (!this->use_write_multiple_)) {
|
||||
write_cmd = ModbusCommandItem::create_write_single_command(parent_, write_address, data[0]);
|
||||
} else {
|
||||
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, write_address, this->register_count, data);
|
||||
}
|
||||
|
||||
parent_->queue_command(write_cmd);
|
||||
|
||||
if (this->optimistic_)
|
||||
this->publish_state(value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/modbus_controller/modbus_controller.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace neopool {
|
||||
/**
|
||||
* @brief Controls the filtration mode of the Neopool device connected via modbus
|
||||
*
|
||||
* Possible states:
|
||||
* - automatic
|
||||
* - off
|
||||
* - slow
|
||||
* - medium
|
||||
* - fast
|
||||
*
|
||||
* To read the state:
|
||||
* reads relay register 0x010E, with bitmasks
|
||||
* - 0x0100 slow
|
||||
* - 0x0200 medium
|
||||
* - 0x0400 high
|
||||
* - 0x0010 filtering
|
||||
* auto / non-auto: 0x0411:
|
||||
* - MBV_PAR_FILT_MANUAL = 0, // This mode allows to turn the filtration (and all other systems that depend on it) on and off manually.
|
||||
* MBV_PAR_FILT_AUTO = 1, // This mode allows filtering to be turned on and off according to the settings of the TIMER1, TIMER2 and TIMER3 timers.
|
||||
*
|
||||
* To set the manual state:
|
||||
* set filtration speed to addr 0x050F (MBF_PAR_FILTRATION_CONF), register needs to be read first to be correctly modified
|
||||
* set MBF_EXEC to 1
|
||||
* set filtration mode to manual (=0) via MBF_PAR_FILT_MODE (0x0411)
|
||||
* set manual mode filtration to on 0x0413 to 0, 1, 2, ?
|
||||
*
|
||||
*/
|
||||
class FiltrationMode : public Component, public select::Select {
|
||||
public:
|
||||
void set_parent(ModbusController *const parent) { this->parent_ = parent; }
|
||||
|
||||
void dump_config() override;
|
||||
void control(const std::string &value) override;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
ModbusController *parent_;
|
||||
};
|
||||
|
||||
} // namespace modbus_controller
|
||||
} // namespace esphome
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
|||
|
||||
esphome:
|
||||
name: test-dmx
|
||||
|
||||
esp32:
|
||||
board: wt32-eth01
|
||||
framework:
|
||||
type: arduino
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
|
||||
wifi:
|
||||
ssid: WLAN
|
||||
password: !secret wifi_password
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: "https://github.com/andyboeh/esphome-dmx512"
|
||||
ref: master
|
||||
|
||||
|
||||
uart:
|
||||
- id: "uart_dmx1"
|
||||
rx_pin: 2
|
||||
tx_pin: 4 # the pin where the transmission happens connected to tx (not reversed)
|
||||
stop_bits: 2
|
||||
baud_rate: 250000
|
||||
|
||||
dmx512:
|
||||
- id: dmx1
|
||||
uart_id: uart_dmx1
|
||||
tx_pin: 4
|
||||
uart_num: 1
|
||||
periodic_update: true
|
||||
force_full_frames: true
|
||||
#update_interval: 100
|
||||
#custom_break_len: 176
|
||||
|
||||
output:
|
||||
- platform: dmx512
|
||||
channel: 1
|
||||
universe: dmx1
|
||||
id: test_licht_r
|
||||
- platform: dmx512
|
||||
channel: 2
|
||||
universe: dmx1
|
||||
id: test_licht_g
|
||||
- platform: dmx512
|
||||
channel: 3
|
||||
universe: dmx1
|
||||
id: test_licht_b
|
||||
|
||||
light:
|
||||
- platform: rgb
|
||||
name: test_licht
|
||||
red: test_licht_r
|
||||
green: test_licht_g
|
||||
blue: test_licht_b
|
||||
restore_mode: RESTORE_DEFAULT_OFF
|
Loading…
Reference in New Issue