Hello,
Im looking to use a Wemos D1 Mini as a light switch controller - I have wired all my lights to a central point in the house where i have multiple Sonoff 4 Chan’s to turn the light on / off.
I have also wired a ethernet cable to each light switch and Im connecting the other end to the ground and one of the digital pins on the D1 Mini.
The idea being that when a light switch is toggled, the D1 Mini will send an MQTT message saying what switch was toggled and Home assistant will turn on / off the required light (as programmed).
Below is my code however it doesn’t seem to be working too well - it will send commands for the D1 input but that seems to be all.
#include <ESP8266WiFi.h>
#include <MQTTClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
/* ---------- DO NOT EDIT ANYTHING ABOVE THIS LINE ---------- */
//Only edit the settings in this section
/* WIFI Settings */
// Name of wifi network
const char* ssid = "Wifi Network";
// Password to wifi network
const char* password = "Wifi Password";
/* Web Updater Settings */
// Host Name of Device
const char* hostName = "Wemos-Loft-Switch_Control";
// Path to access firmware update page (Not Neccessary to change)
const char* update_path = "/firmware";
// Username to access the web update page
const char* update_username = "admin";
// Password to access the web update page
const char* update_password = "Admin Password";
/* MQTT Settings */
// Topic which sends commands
char* mqttTopic = "Loft/Switch_Control";
//MQTT Server IP Address
const char* server = "MQTT Host";
/* ---------- DO NOT EDIT ANYTHING BELOW THIS LINE ---------- */
int ledPin = 2; //D4
static byte lastSwitchState[8] = {1, 1, 1, 1, 1, 1, 1, 1}; //1 = Switch Unpressed, 0 = Switch Pressed
static byte SwitchArray[8] = {5, 4, 0, 16, 14, 12, 13, 15}; //D1, D2, D3, D0, D5, D6, D7, D8
static byte SwitchNumber[8] = {1, 2, 3, 4, 5, 6, 7, 8}; //Sequential Numbers
byte numberOfSwitches = 8;
byte lastSwitchPressed = 0;
long lastActivityTime = 0;
#define DEBOUNCE_DELAY 100
//webserver
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
//MQTT
WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;
//Connect to WiFI and MQTT
void connect();
//Setup pins, wifi, webserver and MQTT
void setup()
{
Serial.begin(115200);
delay(100);
//Set up Switches
Serial.println("Setting input pull-ups");
for( byte i = 0; i < numberOfSwitches; i++){
pinMode(SwitchArray[i], INPUT_PULLUP);
Serial.println("");
Serial.print(SwitchArray[i]);
}
WiFi.mode(WIFI_STA);
WiFi.hostname(hostName);
WiFi.begin(ssid, password);
client.begin(server, net);
connect();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP Address: ");
Serial.println(WiFi.localIP());
MDNS.begin(hostName);
httpUpdater.setup(&httpServer, update_path, update_username, update_password);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
pinMode(ledPin, OUTPUT); // Set the LED Pin as an output
}
//Connect to wifi and MQTT
void connect()
{
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
while (!client.connect(hostName))
{
delay(1000);
}
}
void loop()
{
// MQTT Loop
client.loop();
// Make sure device is connected
if(!client.connected())
{
connect();
}
httpServer.handleClient();
byte i;
for(i = 0; i <numberOfSwitches; i++) {
processSwitchDigital(SwitchArray[i]);
}
}
void processSwitchDigital(byte SwitchId)
{
int sensorReading = digitalRead(SwitchArray[SwitchId]);
//Serial.println( "Switch pressed" );
if(lastSwitchState[SwitchId] != sensorReading) // The Switch was previously un-pressed
{
if((millis() - lastActivityTime) > DEBOUNCE_DELAY) // Proceed if we haven't seen a recent event on this Switch
{
lastActivityTime = millis();
lastSwitchPressed = SwitchId;
Serial.print("Switch ID: ");
Serial.println(SwitchId);
Serial.print("Switch Number: ");
Serial.println(SwitchNumber[SwitchId]);
client.publish(mqttTopic, String(SwitchNumber[SwitchId]).c_str());
digitalWrite(ledPin,LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
}
if(sensorReading == 0) // Input pulled low to GND. Switch pressed.
{
lastSwitchState[SwitchId] = 0;
}
else
{
lastSwitchState[SwitchId] = 1;
}
}
}
I have also looked into using Tasmota however there is only 4 Switch components that are available and i couldnt get the topic to change based on what switch had been toggled.
Any help would be appreciated!
Cheers all!