Hi guys,
this is more an Arduino version, but I am sure you can help me.
I need a phisical button that switch on the led if pressed, and switch off when not.
With Home Assistant I have a switch button
Everything is working fine (I am not a programmer so I probably copy too much code for simply task).
The problem is that if board go offline nothing is working, I NEED the phisical button that works even offline.
Any suggestion? Below my code.
Thank you for your time and help.
#include <MQTTClient.h>
#include <SPI.h>
#include <WiFi101.h>
#include <Bridge.h>
#include <PubSubClient.h>
#define MQTT_VERSION MQTT_VERSION_3_1_1
const char ssid[] = "ssid";
const char pass[] = "psw";
// constants won't change. They're used here to set pin numbers:
const int buttonPin1 = 2; // the number of the pushbutton pin
const int ledPin1 = 6; // the number of the LED pin
// variables will change:
int buttonState1 = 0; // variable for reading the pushbutton status
int mainPreviousMillis = 0;
// MQTT: ID, server IP, port, username and password
const PROGMEM char* MQTT_CLIENT_ID = "office_light1";
const PROGMEM char* MQTT_SERVER_IP = "MY IP";
const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
const PROGMEM char* MQTT_USER = "";
const PROGMEM char* MQTT_PASSWORD = "";
// MQTT: topics
const char* MQTT_LIGHT_STATE_TOPIC = "office/light1/status";
const char* MQTT_LIGHT_COMMAND_TOPIC = "office/light1/switch";
// payloads by default (on/off)
const char* LIGHT_ON = "ON";
const char* LIGHT_OFF = "OFF";
const PROGMEM uint8_t LED_PIN = 6;
boolean m_light_state = false; // light is turned off by default
WiFiClient wifiClient;
PubSubClient client(wifiClient);
//Class flasher
class Flasher
{
// Class Member Variables
// These are initialized at startup
int ledPin; // the number of the LED pin
long OnTime; // milliseconds of on-time
long OffTime; // milliseconds of off-time
int buttonPin;
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
// These maintain the current state
int ledState; // ledState used to set the LED
int bState;
int reading;
unsigned long previousMillis; // will store last time LED was updated
unsigned long onPreviousMillis;
unsigned long offPreviousMillis;
// Constructor - creates a Flasher
// and initializes the member variables and state
public:
Flasher(int pin, int butPin, long on, long off)
{
ledPin = pin;
pinMode(ledPin, OUTPUT);
buttonPin = butPin;
pinMode(buttonPin, INPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
bState = LOW;
previousMillis = 0;
onPreviousMillis = 0;
offPreviousMillis = 0;
}
//Class flasher
void Update()
{
// check to see if it's time to change the state of the LED
unsigned long currentMillis = millis();
reading = buttonState();
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState()) {
reading = buttonState();
// only toggle the LED if the new button state is HIGH
if (buttonState() == HIGH) {
ledState = !ledState;
}
}
}
if(ledState == HIGH)
{
if (currentMillis - previousMillis >= OnTime){
previousMillis = currentMillis; // Remember the time
switchOff();
}else if(buttonState() == HIGH){
switchOff();
}
}
else if ((ledState == LOW) && (buttonState() == HIGH))/*currentMillis - previousMillis >= OffTime*/
{
switchOn();
}
lastButtonState = reading;
}
//Class flasher
void switchOn(){
unsigned long currentMillis = millis();
ledState = HIGH;
digitalWrite(ledPin, ledState);
//client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
//delay(100);
}
//Class flasher
void switchOff(){
ledState = LOW;
digitalWrite(ledPin, ledState);
//client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
}
//Class flasher
int buttonState(){
int bState = digitalRead(buttonPin);
return bState;
}
};
// function called to publish the state of the light (on/off)
void publishLightState() {
if (m_light_state) {
client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
} else {
client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
}
}
// function called to turn on/off the light
void setLightState() {
if (m_light_state) {
digitalWrite(LED_PIN, HIGH);
Serial.println("INFO: Turn light on...");
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("INFO: Turn light off...");
}
}
// function called when a MQTT message arrived
void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
// concat the payload into a string
String payload;
for (uint8_t i = 0; i < p_length; i++) {
payload.concat((char)p_payload[i]);
}
// handle message topic
if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) {
// test if the payload is equal to "ON" or "OFF"
if (payload.equals(String(LIGHT_ON))) {
if (m_light_state != true) {
m_light_state = true;
setLightState();
publishLightState();
}
} else if (payload.equals(String(LIGHT_OFF))) {
if (m_light_state != false) {
m_light_state = false;
setLightState();
publishLightState();
}
}
}
}
void reconnect() {
// Loop until we're reconnected
//while (!client.connected()) {
if (!client.connected()) {
WiFi.begin(ssid, pass);
Serial.print("INFO: Attempting MQTT connection...");
// Attempt to connect
if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
Serial.println("INFO: connected");
// Once connected, publish an announcement...
publishLightState();
// ... and resubscribe
client.subscribe(MQTT_LIGHT_COMMAND_TOPIC);
} else {
Serial.print("ERROR: failed, rc=");
Serial.print(client.state());
Serial.println("DEBUG: try again in 5 seconds");
// Wait 5 seconds before retrying
//delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
// init the led
pinMode(LED_PIN, OUTPUT);
// analogWriteRange(255);
setLightState();
// init the WiFi connection
Serial.println();
Serial.println();
Serial.print("INFO: Connecting to ");
//WiFi.mode(WIFI_STA);
//Serial.println(WIFI_SSID);
// WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
/* while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}*/
Serial.println("");
Serial.println("INFO: WiFi connected");
Serial.print("INFO: IP address: ");
Serial.println(WiFi.localIP());
// init the MQTT connection
client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
client.setCallback(callback);
// initialize the LED pin as an output:
pinMode(ledPin1, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin1, INPUT);
}
void connect() {
Serial.print("checking wifi...");
/*while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
//delay(1000);
}*/
}
//Class flasher
Flasher led1(6, 2, 1000, 100);
void loop() {
//class flasher
led1.Update();
unsigned long mainCurrentMillis = millis();
//try to connect every 5 secs
if ((!client.connected())&&(mainCurrentMillis - mainPreviousMillis >= 5000)) {
reconnect();
mainPreviousMillis = mainCurrentMillis;
}
client.loop();
}