refactor: split logic for incoming and outgoing json #3
@ -1,5 +1,6 @@
|
||||
#if DHT_SENSOR
|
||||
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <DHT.h>
|
||||
|
||||
#define DHT11_PIN 12
|
||||
@ -9,27 +10,30 @@ DHT dht = DHT(DHT11_PIN, DHT11);
|
||||
unsigned long currentTime = 0;
|
||||
|
||||
namespace Dht {
|
||||
void setup() {
|
||||
void setup() {
|
||||
dht.begin();
|
||||
}
|
||||
}
|
||||
|
||||
void read(JsonDocument& jsonDoc) {
|
||||
void read() {
|
||||
currentTime = millis();
|
||||
static unsigned long lastReadTime = 0;
|
||||
if (currentTime > lastReadTime) {
|
||||
lastReadTime = currentTime + READ_INTERVAL(5);
|
||||
StaticJsonDocument<200> jsonDoc;
|
||||
JsonObject dht11 = jsonDoc.createNestedObject("dht11");
|
||||
dht11["temperature"] = dht.readTemperature();
|
||||
dht11["humidity"] = dht.readHumidity();
|
||||
serializeJson(jsonDoc, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
namespace Dht {
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void read(JsonDocument& jsonDoc) {
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void read() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
26
gateway/include/Protocol.h
Normal file
26
gateway/include/Protocol.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <ArduinoJson.h>
|
||||
#include <RCSwitch.h>
|
||||
|
||||
class Protocol {
|
||||
protected:
|
||||
unsigned int protocol;
|
||||
|
||||
public:
|
||||
Protocol(unsigned int protocol) {
|
||||
this->protocol = protocol;
|
||||
}
|
||||
|
||||
virtual void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) {
|
||||
unsigned int protocol = rcSwitch["protocol"];
|
||||
rcDevice.setProtocol(protocol);
|
||||
rcDevice.send(rcSwitch["value"]);
|
||||
}
|
||||
|
||||
virtual void toJson(unsigned long value, JsonDocument& jsonDoc) {
|
||||
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
||||
rcSwitch["protocol"] = protocol;
|
||||
rcSwitch["value"] = value;
|
||||
}
|
||||
|
||||
};
|
||||
68
gateway/include/Protocol_1.h
Normal file
68
gateway/include/Protocol_1.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include "Protocol.h"
|
||||
|
||||
#define RC_STATE(value) value & 0x1
|
||||
#define RC_DEVICE(value) (value >> 1) & 0x1F
|
||||
#define RC_GROUP(value) (value >> 6) & 0x1F
|
||||
|
||||
class Protocol_1 : public Protocol {
|
||||
|
||||
public:
|
||||
Protocol_1() : Protocol(1) {
|
||||
}
|
||||
|
||||
void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) override {
|
||||
unsigned int protocol = rcSwitch["protocol"];
|
||||
rcDevice.setProtocol(protocol);
|
||||
char* group = rcSwitch["group"];
|
||||
int channel = rcSwitch["channel"];
|
||||
rcSwitch["state"] ? rcDevice.switchOn(group, channel) : rcDevice.switchOff(group, channel);
|
||||
}
|
||||
|
||||
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
||||
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
||||
rcSwitch["protocol"] = protocol;
|
||||
Decoder decoder;
|
||||
decoder.decode(value);
|
||||
rcSwitch["state"] = decoder.state;
|
||||
rcSwitch["group"] = String(decoder.group, BIN);
|
||||
rcSwitch["channel"] = decoder.device;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Decoder {
|
||||
bool state;
|
||||
char group;
|
||||
byte device;
|
||||
|
||||
void decode(unsigned long value) {
|
||||
value = value >> 2;
|
||||
unsigned long res = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
res |= ((value & 1) ^ 1) << i;
|
||||
value = value >> 2;
|
||||
}
|
||||
|
||||
state = RC_STATE(res);
|
||||
group = RC_GROUP(res);
|
||||
switch (RC_DEVICE(res)) {
|
||||
case 0b10000:
|
||||
device = 1;
|
||||
break;
|
||||
case 0b01000:
|
||||
device = 2;
|
||||
break;
|
||||
case 0b00100:
|
||||
device = 3;
|
||||
break;
|
||||
case 0b00010:
|
||||
device = 4;
|
||||
break;
|
||||
case 0b00001:
|
||||
device = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
} protocol_1;
|
||||
|
||||
67
gateway/include/Protocol_2.h
Normal file
67
gateway/include/Protocol_2.h
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include "Protocol.h"
|
||||
#include "Tiny.h"
|
||||
|
||||
class Protocol_2 : public Protocol {
|
||||
|
||||
public:
|
||||
Protocol_2() : Protocol(2) {
|
||||
}
|
||||
|
||||
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
||||
switch (value) {
|
||||
case 637541753L:
|
||||
case 771759481L: {
|
||||
JsonObject motion = jsonDoc.createNestedObject("motion");
|
||||
motion["kitchen"] = value == 637541753L ? "on" : "off";
|
||||
break;
|
||||
}
|
||||
case 1879048230L:
|
||||
case 1879048198L: {
|
||||
JsonObject motion = jsonDoc.createNestedObject("motion");
|
||||
motion["basement"] = value == 1879048230L ? "on" : "off";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
StaticJsonDocument<200> jsonSensor;
|
||||
if (buildSensorJson(value, jsonSensor)) {
|
||||
jsonDoc.add(jsonSensor);
|
||||
} else {
|
||||
Protocol::toJson(value, jsonDoc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool buildSensorJson(unsigned long value, JsonDocument& jsonDoc) {
|
||||
JsonObject sensor = jsonDoc.createNestedObject("sensor");
|
||||
sensor["id"] = ID(value);
|
||||
|
||||
float voltage = (float)GET_VCC(value) / 1000;
|
||||
if (voltage != 0) {
|
||||
JsonObject diagnostic = sensor.createNestedObject("diagnostic");
|
||||
diagnostic["voltage"] = voltage;
|
||||
}
|
||||
|
||||
switch (GET_TYPE(value)) {
|
||||
case SensorType::GENERIC:
|
||||
sensor["value"] = GET_VALUE(value);
|
||||
break;
|
||||
case SensorType::TEMPERATURE:
|
||||
sensor["temperature"] = (float)GET_TEMP(value) / 10;
|
||||
break;
|
||||
case SensorType::HUMIDITY:
|
||||
sensor["humidity"] = (float)GET_HUMIDITY(value) / 10;
|
||||
break;
|
||||
case SensorType::CONTACT:
|
||||
sensor["state"] = GET_STATE(value) ? "on" : "off";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} protocol_2;
|
||||
@ -1,40 +0,0 @@
|
||||
#define RC_STATE(value) value & 0x1
|
||||
#define RC_DEVICE(value) (value >> 1) & 0x1F
|
||||
#define RC_GROUP(value) (value >> 6) & 0x1F
|
||||
|
||||
namespace RcDecoder {
|
||||
|
||||
struct RcSwitch {
|
||||
bool state;
|
||||
char group;
|
||||
byte device;
|
||||
};
|
||||
|
||||
void decode(unsigned long value, RcSwitch& decoded) {
|
||||
value = value >> 2;
|
||||
unsigned long res = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
res |= ((value & 1) ^ 1) << i;
|
||||
value = value >> 2;
|
||||
}
|
||||
decoded.state = RC_STATE(res);
|
||||
decoded.group = RC_GROUP(res);
|
||||
switch (RC_DEVICE(res)) {
|
||||
case 0b10000:
|
||||
decoded.device = 1;
|
||||
break;
|
||||
case 0b01000:
|
||||
decoded.device = 2;
|
||||
break;
|
||||
case 0b00100:
|
||||
decoded.device = 3;
|
||||
break;
|
||||
case 0b00010:
|
||||
decoded.device = 4;
|
||||
break;
|
||||
case 0b00001:
|
||||
decoded.device = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
#include <Arduino.h>
|
||||
#include <RCSwitch.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include "Tiny.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include "Dht.h"
|
||||
#include "RcDecoder.h"
|
||||
#include "Protocol_1.h"
|
||||
#include "Protocol_2.h"
|
||||
|
||||
#define RESET_PIN 10
|
||||
#define SEND_PIN 11
|
||||
@ -13,9 +11,6 @@
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void readRcSwitch(JsonDocument& jsonDoc);
|
||||
void readCommand();
|
||||
|
||||
void setup() {
|
||||
digitalWrite(RESET_PIN, HIGH);
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
@ -32,77 +27,27 @@ void setup() {
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
readCommand();
|
||||
StaticJsonDocument<200> jsonDoc;
|
||||
readRcSwitch(jsonDoc);
|
||||
Dht::read(jsonDoc);
|
||||
if (!jsonDoc.isNull()) {
|
||||
serializeJson(jsonDoc, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
bool buildSensorJson(JsonDocument& jsonDoc, unsigned long value) {
|
||||
JsonObject sensor = jsonDoc.createNestedObject("sensor");
|
||||
sensor["id"] = ID(value);
|
||||
|
||||
float voltage = (float)GET_VCC(value) / 1000;
|
||||
if (voltage != 0) {
|
||||
JsonObject diagnostic = sensor.createNestedObject("diagnostic");
|
||||
diagnostic["voltage"] = voltage;
|
||||
}
|
||||
|
||||
switch (GET_TYPE(value)) {
|
||||
case SensorType::GENERIC:
|
||||
sensor["value"] = GET_VALUE(value);
|
||||
break;
|
||||
case SensorType::TEMPERATURE:
|
||||
sensor["temperature"] = (float)GET_TEMP(value) / 10;
|
||||
break;
|
||||
case SensorType::HUMIDITY:
|
||||
sensor["humidity"] = (float)GET_HUMIDITY(value) / 10;
|
||||
break;
|
||||
case SensorType::CONTACT:
|
||||
sensor["state"] = GET_STATE(value) ? "on" : "off";
|
||||
break;
|
||||
Protocol findProtocol(unsigned int protocol) {
|
||||
switch (mySwitch.getReceivedProtocol()) {
|
||||
case 1:
|
||||
return protocol_1;
|
||||
case 2:
|
||||
return protocol_2;
|
||||
default:
|
||||
return false;
|
||||
return Protocol(protocol);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void readRcSwitch(JsonDocument& jsonDoc) {
|
||||
void readRcSwitch() {
|
||||
if (mySwitch.available()) {
|
||||
unsigned long value = mySwitch.getReceivedValue();
|
||||
mySwitch.resetAvailable();
|
||||
|
||||
if (mySwitch.getReceivedProtocol() == 2) {
|
||||
if (value == 637541753L || value == 771759481L) {
|
||||
JsonObject motion = jsonDoc.createNestedObject("motion");
|
||||
motion["kitchen"] = value == 637541753L ? "on" : "off";
|
||||
return;
|
||||
}
|
||||
if (value == 1879048230L || value == 1879048198L) {
|
||||
JsonObject motion = jsonDoc.createNestedObject("motion");
|
||||
motion["basement"] = value == 1879048230L ? "on" : "off";
|
||||
return;
|
||||
}
|
||||
if (buildSensorJson(jsonDoc, value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
||||
rcSwitch["protocol"] = mySwitch.getReceivedProtocol();
|
||||
if (mySwitch.getReceivedProtocol() == 1) {
|
||||
RcDecoder::RcSwitch decoded;
|
||||
RcDecoder::decode(value, decoded);
|
||||
rcSwitch["state"] = decoded.state;
|
||||
rcSwitch["group"] = String(decoded.group, BIN);
|
||||
rcSwitch["channel"] = decoded.device;
|
||||
} else {
|
||||
rcSwitch["value"] = value;
|
||||
StaticJsonDocument<200> jsonDoc;
|
||||
findProtocol(mySwitch.getReceivedProtocol()).toJson(value, jsonDoc);
|
||||
if (!jsonDoc.isNull()) {
|
||||
serializeJson(jsonDoc, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,23 +58,6 @@ void blink() {
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
|
||||
void runRcSwitchCommand(JsonVariant jsonDoc) {
|
||||
JsonObject rcSwitch = jsonDoc["rcSwitch"];
|
||||
unsigned int protocol = rcSwitch["protocol"];
|
||||
if (protocol == 1) {
|
||||
mySwitch.setProtocol(protocol);
|
||||
char* group = rcSwitch["group"];
|
||||
int channel = rcSwitch["channel"];
|
||||
rcSwitch["state"] ? mySwitch.switchOn(group, channel) : mySwitch.switchOff(group, channel);
|
||||
} else {
|
||||
mySwitch.setProtocol(protocol);
|
||||
mySwitch.send(rcSwitch["value"]);
|
||||
}
|
||||
serializeJson(jsonDoc, Serial);
|
||||
Serial.println();
|
||||
// blink();
|
||||
}
|
||||
|
||||
void runJsonCommands(const char* cmd) {
|
||||
String origCmd = String(cmd);
|
||||
StaticJsonDocument<512> jsonArray;
|
||||
@ -138,7 +66,10 @@ void runJsonCommands(const char* cmd) {
|
||||
JsonArray array = jsonArray.as<JsonArray>();
|
||||
for (JsonVariant jsonDoc : array) {
|
||||
if (jsonDoc.containsKey("rcSwitch")) {
|
||||
runRcSwitchCommand(jsonDoc);
|
||||
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
|
||||
findProtocol(rcSwitch["protocol"]).fromJson(rcSwitch, mySwitch);
|
||||
serializeJson(jsonDoc, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -164,3 +95,9 @@ void readCommand() {
|
||||
runJsonCommands(cmd.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
readCommand();
|
||||
readRcSwitch();
|
||||
Dht::read();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user