ESP32 to emulate a cover on Home Assistant avoiding a Shelly Plus Uni

Hi there. I’m working on making smart my japanese curtains. On the Shelly Forum a very heplful guy (thgoebel there) provided me with a solution involving a Shelly Plus Uni. I would like to use ESP32 board because I have some spare units home. Could it be possible to replicate the circuit of the image with a ESP32 instead of the Shelly Uni?

Maybe.
You need to provide lot mor info to get there.
Esp can’t be powered at 24V and it doesn’t have dry contact outputs…

This is the schema of the motor. I would like to use 2 physical burttons in addition to the Home Assistant Control:

The motor is always powered.

ESP32 (you already have)
Power supply, either from the 24v or line to power your ESP32 and relays.
Two relays
Two buttons
Case/mounting/wiring
Software
Configuration

Simplez.

You may even find a working example in the ESPHome sample configs you can follow.

You should also consider if your time is free and how much a Shelly Plus Uni will cost with a Black Friday discount instead.

Shelly Plus Uni can be added as every other Shelly to Home Assistant? Would it be possible to show the shelly as a cover entity?

Thank you. I have never used a Shelly Uni.

Be aware that the max current of Uni outputs is marginal.
If those wires are not just for signal, have a look at Shelly 2PM, it can be powered at 24VDC.

The 3 cables from the motor doesn’t anything but be connected. The motor powers them.

If they are just signal wires, Uni is ok.
If PSU negative is interconnected to Com, also 2PM is an option.

I’m trying this option. My question is where should I connect the physical switch button?

Your image doesn’t present circuit with 24VDC actuator…

This is what I have right now and its working. I want to add two physical buttons so they also control the cover and echen used the final state is syncrojised to the HA state.

That kind of circuit depends completely on ESP. So in this case it would be logical to connect the button to esp as well. Button between esp GND and GPIO, configured as gpio binary sensor with input pullup.
But what your button should do? Swap the direction or start/stop?

Do you want one button like a garage door, so pressing it when open will close it, and pressing it again when closed will open it? All the way? Quick press again during travel to interrupt progress?
Alternative is one button for open and one for close, same as original functionality? Is it press and hold till it reaches desirable opening, or just quick press to initiate full travel in that direction? Is fully open and fully closed the only curtain options you want, or do you want partially open as well? These are configuration aspects - you still need to connect the switches to the ESP32 GPIO ports and configure in HomeAssistant.

Some added things to consider:
What determines when your curtain has reached the limits of open/closed to tell the motor to stop? A timing delay? Current sensing? Do you need a sensor such as a magnetic reed switch as well? One for fully open and another for fully closed? There goes another two GPIO ports.

It’s two mounted wall buttons. One for open, one for close.

Two buttons.
I push the open button the curtain opens. I push open again, it stops. Same with the close button. The curtains has their own electronic limits to to know the end. I have it configured as a time based cover on ESPHome. Without the buttons until I find the solution.

I tried the binary sensor option but the sensor entity does not evean appear on Home Assistant.

If you have config like this, it should be available on HA

binary_sensor:
  - platform: gpio
    id: button1
    name: "Button 1"
    pin:
      number: GPIO16 #your actual pin
      mode: INPUT_PULLUP
      inverted: true
    filters:
      - delayed_on: 20ms
      - delayed_off: 20ms

That is OK. Now the problem is the actions to ber performed when, for example, the open button is pushed. I want:

If I press the open button and the cover is opening, then stop the cover, else open the cover.

But I am having trobule with the operation: if the cover is stopped and I push the open button, it does nothing.


switch:
  - platform: gpio
    id: apertura_panel
    pin: GPIO15
    internal: true
    name: "Interruptor apertura panel"
  - platform: gpio
    id: cierre_panel
    pin: GPIO4
    internal: true
    name: "Interruptor cierre panel"
cover:
  - platform: time_based
    id: panel_japones
    name: "Panel japonés"
    open_action:
      - switch.turn_off: cierre_panel
      - switch.turn_on: apertura_panel
    open_duration: 19s

    close_action:
      - switch.turn_off: apertura_panel
      - switch.turn_on: cierre_panel
    close_duration: 19s

    stop_action:
        - switch.turn_on: apertura_panel
        - switch.turn_on: cierre_panel
        - delay: 100ms
        - switch.turn_off: apertura_panel
        - switch.turn_off: cierre_panel


binary_sensor:
  - platform: gpio
    id: boton_apertura_panel
    internal: true
    device_class: power
    pin:
      number: GPIO19
      inverted: true
      mode:
        input: true
        pullup: true

    on_press:
    - lambda: !lambda |-
          if (id(panel_japones).get_last_operation() == CoverOperation::COVER_OPERATION_OPENING) {
            // Cover is currently opening
              auto call1 = id(panel_japones).make_call();
              call1.set_command_stop();
              call1.perform();
          } 
          else {
              auto call2 = id(panel_japones).make_call();
              call2.set_command_open();
              call2.perform();
          }

I’m not sure if I follow you, but if you want to stop the cover when it’s opening, you should use

if (id(panel_japones).current_operation == CoverOperation::COVER_OPERATION_OPENING) {

that options gices me the error:

/config/esphome/panel-japones.yaml: In lambda function:
/config/esphome/panel-japones.yaml:88:43: error: expression cannot be used as a function
88 | if (id(panel_japones).current_operation() == CoverOperation::COVER_OPERATION_OPENING) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/config/esphome/panel-japones.yaml:94:48: error: expression cannot be used as a function
94 | else if (id(panel_japones).current_operation() == CoverOperation::COVER_OPERATION_IDLE) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
*** [.pioenvs/panel-japones/src/main.cpp.o] Error 1
========================= [FAILED] Took 10.57 seconds =========================