Intigrate rfsockets subsystem support
This enables the nodemcu to listen for multiple topics. First comes the subsystem which is then followed by parameters for that specific subsystem. For 433MHz sockets this subsystem is called "rfsockets". It operates on "rfsockets/<socket_name>/(status|switch)" wher it accepts and reports with either "ON" or "OFF" as payloads. The subsystem therefore complies with the Home Assistant mqtt component.
This commit is contained in:
parent
1ac1ce1be1
commit
0356892526
123
multi-esp.ino
123
multi-esp.ino
|
@ -11,7 +11,7 @@ RCSwitch mySwitch = RCSwitch();
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* channel;
|
char* channel;
|
||||||
char* id;
|
char* id;
|
||||||
String name;
|
char name[255];
|
||||||
bool powered;
|
bool powered;
|
||||||
uint8_t type; // 0=DIP, 1=Learned
|
uint8_t type; // 0=DIP, 1=Learned
|
||||||
int on_code;
|
int on_code;
|
||||||
|
@ -42,11 +42,11 @@ const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MQTT: topics
|
//// MQTT: topics
|
||||||
const char* MQTT_LIGHT_STATE_TOPIC = "balcony/hanging_lamp/status";
|
//const char* MQTT_LIGHT_STATE_TOPIC = "balcony/hanging_lamp/status";
|
||||||
const char* MQTT_LIGHT_COMMAND_TOPIC = "balcony/hanging_lamp/switch";
|
//const char* MQTT_LIGHT_COMMAND_TOPIC = "balcony/hanging_lamp/switch";
|
||||||
|
|
||||||
const char* MQTT_RFSOCKET_STATE_BASE = "rfsockets/";
|
const char* MQTT_RFSOCKET_SUBSYSTEM = "rfsockets/";
|
||||||
const char* MQTT_RFSOCKET_STATE_TOPIC = "/status";
|
const char* MQTT_RFSOCKET_STATE_TOPIC = "/status";
|
||||||
const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch";
|
const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch";
|
||||||
|
|
||||||
|
@ -54,25 +54,27 @@ const char* MQTT_RFSOCKET_COMMAND_TOPIC = "/switch";
|
||||||
const char* LIGHT_ON = "ON";
|
const char* LIGHT_ON = "ON";
|
||||||
const char* LIGHT_OFF = "OFF";
|
const char* LIGHT_OFF = "OFF";
|
||||||
|
|
||||||
//const PROGMEM uint8_t LED_PIN = 5;
|
|
||||||
boolean m_light_state = false; // light is turned off by default
|
|
||||||
|
|
||||||
WiFiClient wifiClient;
|
WiFiClient wifiClient;
|
||||||
PubSubClient client(wifiClient);
|
PubSubClient client(wifiClient);
|
||||||
|
|
||||||
// function called to publish the state of the light (on/off)
|
// function called to publish the state of the light (on/off)
|
||||||
void publishLightState() {
|
void publishLightState(int socketIdx) {
|
||||||
if (m_light_state) {
|
char *socket_name = sockets[socketIdx].name;
|
||||||
client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
|
char topic[strlen(MQTT_RFSOCKET_SUBSYSTEM) + strlen(MQTT_RFSOCKET_STATE_TOPIC) + strlen(socket_name)];
|
||||||
|
strcpy(topic, MQTT_RFSOCKET_SUBSYSTEM);
|
||||||
|
strcat(topic, socket_name);
|
||||||
|
strcat(topic, MQTT_RFSOCKET_STATE_TOPIC);
|
||||||
|
|
||||||
|
if (sockets[socketIdx].powered) {
|
||||||
|
client.publish(topic, LIGHT_ON, true);
|
||||||
} else {
|
} else {
|
||||||
client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
|
client.publish(topic, LIGHT_OFF, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// function called to turn on/off the light
|
// function called to turn on/off the light
|
||||||
void setLightState() {
|
void setLightState(byte socketIdx) {
|
||||||
byte socketIdx = 7;
|
if (sockets[socketIdx].powered) {
|
||||||
if (m_light_state) {
|
|
||||||
setSocket(socketIdx, true);
|
setSocket(socketIdx, true);
|
||||||
Serial.println("INFO: Turn light on...");
|
Serial.println("INFO: Turn light on...");
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,22 +92,54 @@ void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle message topic
|
// handle message topic
|
||||||
if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) {
|
Serial.print("Got a message on topic: ");
|
||||||
// test if the payload is equal to "ON" or "OFF"
|
Serial.println(p_topic);
|
||||||
if (payload.equals(String(LIGHT_ON))) {
|
|
||||||
if (m_light_state != true) {
|
char *topic_ptr;
|
||||||
m_light_state = true;
|
const char* delimiter = "/";
|
||||||
setLightState();
|
topic_ptr = strtok(p_topic, delimiter);
|
||||||
publishLightState();
|
if (topic_ptr != NULL) {
|
||||||
}
|
char *subsystem = topic_ptr;
|
||||||
} else if (payload.equals(String(LIGHT_OFF))) {
|
Serial.print("Found subsystem: ");
|
||||||
if (m_light_state != false) {
|
Serial.println(subsystem);
|
||||||
m_light_state = false;
|
topic_ptr = strtok(NULL, delimiter);
|
||||||
setLightState();
|
if (topic_ptr != NULL) {
|
||||||
publishLightState();
|
char *name = topic_ptr;
|
||||||
}
|
Serial.print("Found socket name: ");
|
||||||
}
|
Serial.println(name);
|
||||||
}
|
int socketIdx = findSocketIndex(name);
|
||||||
|
Serial.print("Found socket index ");
|
||||||
|
Serial.println(socketIdx);
|
||||||
|
// We only listen on the command channel so no further splitting needed
|
||||||
|
if (payload.equals(String(LIGHT_ON))) {
|
||||||
|
if (sockets[socketIdx].powered != true) {
|
||||||
|
sockets[socketIdx].powered = true;
|
||||||
|
setLightState(socketIdx);
|
||||||
|
publishLightState(socketIdx);
|
||||||
|
}
|
||||||
|
} else if (payload.equals(String(LIGHT_OFF))) {
|
||||||
|
if (sockets[socketIdx].powered != false) {
|
||||||
|
sockets[socketIdx].powered = false;
|
||||||
|
setLightState(socketIdx);
|
||||||
|
publishLightState(socketIdx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print("Unknown payload received: ");
|
||||||
|
Serial.println(payload);
|
||||||
|
Serial.println("Ignoring it…\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print("Got topic without delimiter (");
|
||||||
|
Serial.print(delimiter);
|
||||||
|
Serial.print("), topic was:");
|
||||||
|
Serial.println(p_topic);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print("Got topic without delimiter (");
|
||||||
|
Serial.print(delimiter);
|
||||||
|
Serial.print("), topic was:");
|
||||||
|
Serial.println(p_topic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reconnect() {
|
void reconnect() {
|
||||||
|
@ -115,10 +149,21 @@ void reconnect() {
|
||||||
// Attempt to connect
|
// Attempt to connect
|
||||||
if (client.connect(MQTT_CLIENT_ID)) {
|
if (client.connect(MQTT_CLIENT_ID)) {
|
||||||
Serial.println("INFO: connected");
|
Serial.println("INFO: connected");
|
||||||
// Once connected, publish an announcement...
|
for (int i = 0; i < numofsockets; i++) {
|
||||||
publishLightState();
|
publishLightState(i);
|
||||||
// ... and resubscribe
|
}
|
||||||
client.subscribe(MQTT_LIGHT_COMMAND_TOPIC);
|
for (int i = 0; i < numofsockets; i++) {
|
||||||
|
char *socket_name = sockets[i].name;
|
||||||
|
char topic[strlen(MQTT_RFSOCKET_SUBSYSTEM) + strlen(MQTT_RFSOCKET_COMMAND_TOPIC) + strlen(socket_name)];
|
||||||
|
strcpy(topic, MQTT_RFSOCKET_SUBSYSTEM);
|
||||||
|
strcat(topic, socket_name);
|
||||||
|
strcat(topic, MQTT_RFSOCKET_COMMAND_TOPIC);
|
||||||
|
|
||||||
|
Serial.print("INFO: subscribing to topic \"");
|
||||||
|
Serial.print(topic);
|
||||||
|
Serial.println("\"");
|
||||||
|
client.subscribe(topic);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.print("ERROR: failed, rc=");
|
Serial.print("ERROR: failed, rc=");
|
||||||
Serial.print(client.state());
|
Serial.print(client.state());
|
||||||
|
@ -171,10 +216,13 @@ bool setSocket(int socketIdx, bool newStatus) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findSocketIndex(String name) {
|
int findSocketIndex(char *name) {
|
||||||
for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) {
|
for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) {
|
||||||
PowerSocket canidateSocket = sockets[socketIdx];
|
PowerSocket canidateSocket = sockets[socketIdx];
|
||||||
if (canidateSocket.name == name) {
|
if (strcmp(canidateSocket.name, name) == 0) {
|
||||||
|
Serial.print(canidateSocket.name);
|
||||||
|
Serial.print(" equals ");
|
||||||
|
Serial.println(name);
|
||||||
return socketIdx;
|
return socketIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +243,6 @@ void setup() {
|
||||||
Serial.println("Enable transmission while waiting on wifi");
|
Serial.println("Enable transmission while waiting on wifi");
|
||||||
mySwitch.enableTransmit(2);
|
mySwitch.enableTransmit(2);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
setLightState();
|
|
||||||
Serial.print("Transmission enabled, waiting for wifi now.");
|
Serial.print("Transmission enabled, waiting for wifi now.");
|
||||||
|
|
||||||
// Wait for connection
|
// Wait for connection
|
||||||
|
|
Loading…
Reference in a new issue