visualapproach / WiFi-remote-for-Bestway-Lay-Z-SPA

Hack - ESP8266 as WiFi remote control for Bestway Lay-Z spa Helsinki
GNU General Public License v3.0
304 stars 74 forks source link

WS2812 Pool LEDs controlled by key "UNIT" and "TIMER" #213

Closed dietmar-1 closed 1 year ago

dietmar-1 commented 2 years ago

With this software extension in main.cpp from line 155 ("own code here" section) , a WS2812 LED strip can be controlled via the "UNIT" and "TIMER" buttons. I disabled the buttons in the BWC_8266_globals.h file. The keys are processed in the main.cpp and sent a POST request to the LED controller WLED (by Christian Schwinne Aircoookie) via an HTTP Request API. No MQTT server ist needed.

A 5m long WS2812 LED strip is used as strip. This means that 150 or 300 individually addressable LEDs can be controlled as lighting the pool. There are countless hardware as ws2812 controller which work with ESP8266. Here is an example of a controller available from AliExpress.

wled_controller

This code is for experimenting and adapting to your own needs. Since I'm not 100% fit in cpp programming, I'm happy to be improved if necessary.

WLED on GitHub WLED Wiki

This combination of pump control (WiFi-remote-for-Bestway-Lay-Z-SPA by visualapproach) and light control (WLED by Aircoookie) is the best for comfortable operation of the LAY-Z-SPA pools.

Thanks to visualapproach, aircoookie and all contributors for this awesome software.

One of the great possibilities: I integrated an analogue clock as a special effect, so I can detect the time via the leds in the pool. Brilliant !

The (new 22.03.2022) code:

main.cpp line 155 add:

  // You can add own code here, but don't stall!
  // If CPU is choking you can try to run @ 160 MHz, but that's cheating!

  // Function buttons for WLED controller to switch WS2812 LED Strip in LAY-Z-SPA
  // Button UNIT and TIMER deactivated (BWC_8266_globals.h)
  // 
  String extbutton = bwc.getButtonName();

  if (!extbutton.equals(prevButtonName))
    {
      if (extbutton == "UNIT")
      {
        bwc.print("led");
        handleWLED("&T=2"); // Toggle WLED on/off
        if (acresponse == "err")
        {
          bwc.print(acresponse);
        } else if (acresponse == "0")
        {
          bwc.print("off");
        } else {
          bwc.print(" on");
        }
      }
      if (extbutton == "TIMER")
      {
        bwc.print("pr ");
        handleWLED("&P1=1&P2=4&PL=~"); // Toggle WLED presets 1-4
        if (psresponse == "err") {
          bwc.print(psresponse);
        } else {
          bwc.print("pr" + psresponse);
        }
      }

      prevButtonName = extbutton;
    }
}

void handleWLED(String queryString)
{
  // Connect to WLED HTTP Request API
  // queryString -> see: https://kno.wled.ge/interfaces/http-api/
  // 
  int    HTTP_PORT   = 80;
  String HTTP_METHOD = "GET";
  char   HOST_NAME[] = "192.168.0.214"; // WLED IP-Adress
  String PATH_NAME   = "/win";

  // connect to WLED server on port 80:
  if(aWifiClient.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to WLED server - HTTP Request API Command: " + queryString);
    // make a HTTP request:
    aWifiClient.println(HTTP_METHOD + " " + PATH_NAME + queryString + " HTTP/1.1"); // send HTTP header
    aWifiClient.println("Host: " + String(HOST_NAME));
    aWifiClient.println("Connection: close");
    aWifiClient.println();
    delay(10);

    // wait for data to be available
    unsigned long timeout = millis();
    while (aWifiClient.available() == 0) {
      if (millis() - timeout > 5000) {
       Serial.println("client timeout !");
       aWifiClient.stop();
       delay(60000);
      return;
      }
    }

    // Read all the lines of the XML reply from WLED and put them to String out
    String out = "";
    while (aWifiClient.available()) {
      char ch = static_cast<char>(aWifiClient.read());
      out += ch;
    }
    // Read <ac> tag
    int startac = out.indexOf("<ac>")+4;
    int endac = out.indexOf("</ac>");
    acresponse = out.substring(startac, endac);
    Serial.println("<ac> response (Master Brightness): " + acresponse);

    // Read <ps> tag
    int startps = out.indexOf("<ps>")+4;
    int endps = out.indexOf("</ps>");
    psresponse = out.substring(startps, endps);
    Serial.println("<ps> response (Current Preset): " + psresponse);

    aWifiClient.stop();
    Serial.println("Disconnected from WLED server!");

  } else {// if not connected:
    Serial.println("Connection to WLED failed!");
    acresponse = "err";
    psresponse = "err";
  }
}

main.h line 59 add:
String prevButtonName = "";

main.h line 65 add:
/** used for WLED control */
String psresponse; 
String acresponse;

main.h line 75 add:
void handleWLED(String queryString);

The LEDs can also be controlled via the web interface. The following code was added to index.html for this purpose. For this, WLED is controlled via a Post Script for JSON API of WLED.

web_interface

Code:

index.html
<section>
<h2>Pool-LED Presets</h2>
 <table>
  <tr>
   <td class="center"> 
    <button class="button" onclick="setledpreset(1)">1</button>&nbsp;<button class="button" onclick="setledpreset(2)">2</button>&nbsp;<button class="button" onclick="setledpreset(3)">3</button>&nbsp;<button class="button" onclick="setledpreset(4)">4</button>&nbsp;<button class="button" onclick="setledoff()">Off</button>
   </td>
  </tr>
 </table>
</section>

End of index.html :

<!-- Post Script for JSON API of WLED to control presets and on/off -->
<script>
    // change to your ip !!!
    const url='http://192.168.0.214/json/state';

    function setledpreset(val){
        const Http = new XMLHttpRequest();
        Http.open("POST", url);
        var msgobj = {"ps": val}
        Http.send(JSON.stringify(msgobj));
        console.log(msgobj);
    }
    function setledoff(){
        const Http = new XMLHttpRequest();
        Http.open("POST", url);
        var msgobj = {"on":false}
        Http.send(JSON.stringify(msgobj));
        console.log(msgobj);
    }

</script>

I hope this gives some creative ideas and solutions.

visualapproach commented 2 years ago

Hey @dietmar-1 that's super cool! Feels good that someone uses the prepared features in the code to make such creative stuff! Cheers mate and great idea. Thanks for sharing

chunkysteveo commented 2 years ago

Amazing!

torei commented 2 years ago

Hi @dietmar-1, great project! Do have some pictures about your installation? cable and stuff I want the same for mine! :-)

dietmar-1 commented 2 years ago

Hi @torei , thank you very much. My code snippet merged the two awesome GitHub projects. The SPA controller and the LED controller have their own IP address on the router but they require static IP addresses.

system2

Any ESP8266 based pixel controller can be used as LED controller hardware.

Example 1

wled_controller Pixeldriver Hardware from Aliexpress This hardware has the advantage that an IR receiver is on board. The LEDs can operated remotely with an IR remote control.

1646167740112

Example 2

mottramlab Pixeldriver Hardware from David Mottram This hardware has the advantage that it can be operated with 5v and 12v leds and this controller has 2 data outputs for over 2000 LEDs.

Example 3

zq2o3x7k5wp71

Athom Light Strip Controller
Pre installed WLED, simple controller with enclosure for reliaby driving 3 pin 5V LEDs uses 2M ESP8266. Indeed without IR receiver.

Software for the LEDs

The software for the LED controlers is WLED by Aircoookie You can find the Software on GitHub here . An excellent tutorial and getting started Page can you find here.

I hope I was able to explain the hardware a bit and wish you a lot of fun with these outstanding software projects. Amazing what came out of this small, cheap ESP through these two software projects.

torei commented 2 years ago

nice, thank you @dietmar-1 how about the lightstrip? how did you install the cable and stuff in the water?

chunkysteveo commented 2 years ago

Most likely the tub is like the Paris and similar, so it's translucent, and you can install a light strip under the hot tub which is attached using loops in the hot tub webbing. The Hot tub sits on top of the lights and they shine through the walls, base, and into the water. They need to be IP67, along with the controller, as they can get wet from the water and rain ingress. Looks like the strip is covered in that IP67 version silicone cover that you can buy on AliExpress etc.

torei commented 2 years ago

ah, i see. thanks for that. got a miami :-(

chunkysteveo commented 2 years ago

Ahh yeah, those are "white/blue" inside and guessing not translucent very much, if at all?

You "could" put fully IP67 strips into water, but I wouldn't be keen on it!

image This is probably the best idea how the range of Lay Z Spa LEDs work, you can see the black controller bottom left and how the lights are placed "under" the tub in a ring.

torei commented 2 years ago

yeah, that was the question. how to put those into the water... but i dont want china electronics in my tub :D

dietmar-1 commented 2 years ago

The leds are out of the water under the pool, in translucent silicon tube. The led strip is mounted under the plastic. It shines perfect into the water. The bestway original strip works the same way.

aufbau

This youtube video here shows exactly how the LED strip is installed (look to 1:40)

Laudings commented 2 years ago

@dietmar-1 how did you get the web interface in German? This would be really great! Thanks!

visualapproach commented 2 years ago

@dietmar-1 how did you get the web interface in German? This would be really great! Thanks!

I guess he just edited the .html files in the data/ directory.

dietmar-1 commented 2 years ago

@Laudings: yes :+1: visualapproach is absolutely right: just edit the html and style files, compile and enjoy :relaxed:. If you only need to change files in the data directory, you can also use the file upload feature, you do not need to compile new.

Laudings commented 2 years ago

@visualapproach @dietmar-1 thank you! I allready found it. Good to know!

github-actions[bot] commented 1 year ago

Stale issue message