Merge branch 'doorbell' into huzzah
This commit is contained in:
commit
4096bfc83a
@ -2,15 +2,24 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <RCSwitch.h>
|
#include <RCSwitch.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class Protocol {
|
class Protocol {
|
||||||
protected:
|
protected:
|
||||||
unsigned int protocol;
|
unsigned int no;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static unordered_map<unsigned int, Protocol*> mapProtocols;
|
||||||
|
|
||||||
Protocol(unsigned int protocol) {
|
Protocol(unsigned int protocol) {
|
||||||
this->protocol = protocol;
|
no = protocol;
|
||||||
|
mapProtocols.insert({ no, this });
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol& setProtocol(unsigned int p) {
|
||||||
|
no = p;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
virtual ~Protocol() {}
|
|
||||||
|
|
||||||
virtual void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) {
|
virtual void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) {
|
||||||
unsigned int protocol = rcSwitch["protocol"];
|
unsigned int protocol = rcSwitch["protocol"];
|
||||||
@ -20,8 +29,9 @@ public:
|
|||||||
|
|
||||||
virtual void toJson(unsigned long value, JsonDocument& jsonDoc) {
|
virtual void toJson(unsigned long value, JsonDocument& jsonDoc) {
|
||||||
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
||||||
rcSwitch["protocol"] = protocol;
|
rcSwitch["protocol"] = no;
|
||||||
rcSwitch["value"] = value;
|
rcSwitch["value"] = value;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
};
|
unordered_map<unsigned int, Protocol*> Protocol::mapProtocols;
|
||||||
|
Protocol fallbackProtocol{ 0 };
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
class Protocol_1 : public Protocol {
|
class Protocol_1 : public Protocol {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Protocol_1() : Protocol(1) {
|
Protocol_1() : Protocol(1) {}
|
||||||
}
|
|
||||||
|
|
||||||
void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) override {
|
void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) override {
|
||||||
unsigned int protocol = rcSwitch["protocol"];
|
unsigned int protocol = rcSwitch["protocol"];
|
||||||
@ -18,7 +17,7 @@ public:
|
|||||||
|
|
||||||
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
||||||
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch");
|
||||||
rcSwitch["protocol"] = protocol;
|
rcSwitch["protocol"] = no;
|
||||||
RcDecoder decoder;
|
RcDecoder decoder;
|
||||||
decoder.decode(value);
|
decoder.decode(value);
|
||||||
rcSwitch["state"] = decoder.state;
|
rcSwitch["state"] = decoder.state;
|
||||||
@ -32,4 +31,4 @@ public:
|
|||||||
sprintf(uId, "%s_%d", group, channel);
|
sprintf(uId, "%s_%d", group, channel);
|
||||||
return std::string{ uId };
|
return std::string{ uId };
|
||||||
}
|
}
|
||||||
};
|
} protocol1;
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
class Protocol_2 : public Protocol {
|
class Protocol_2 : public Protocol {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Protocol_2() : Protocol(2) {
|
Protocol_2() : Protocol(2) {}
|
||||||
}
|
|
||||||
|
|
||||||
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
@ -33,4 +32,4 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
} protocol2;
|
||||||
64
gateway/include/Protocol_Doorbell.h
Normal file
64
gateway/include/Protocol_Doorbell.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Protocol.h"
|
||||||
|
|
||||||
|
#define BIT_LENGTH 40
|
||||||
|
#define BIT_LENGTH_3 BIT_LENGTH*3
|
||||||
|
#define TX_DELAY 620
|
||||||
|
|
||||||
|
class Protocol_Doorbell : public Protocol {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Protocol_Doorbell() : Protocol(16) {}
|
||||||
|
|
||||||
|
void ring() {
|
||||||
|
preamble();
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
delayMicroseconds(TX_DELAY);
|
||||||
|
code("00000000110100101000100");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) override {
|
||||||
|
}
|
||||||
|
|
||||||
|
void toJson(unsigned long value, JsonDocument& jsonDoc) override {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void transmitBit(uint8_t value) {
|
||||||
|
digitalWrite(SEND_PIN, value);
|
||||||
|
delayMicroseconds(BIT_LENGTH);
|
||||||
|
digitalWrite(SEND_PIN, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitHigh() {
|
||||||
|
digitalWrite(SEND_PIN, HIGH);
|
||||||
|
delayMicroseconds(BIT_LENGTH_3);
|
||||||
|
digitalWrite(SEND_PIN, LOW);
|
||||||
|
delayMicroseconds(BIT_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transmitLow() {
|
||||||
|
digitalWrite(SEND_PIN, HIGH);
|
||||||
|
delayMicroseconds(BIT_LENGTH);
|
||||||
|
digitalWrite(SEND_PIN, LOW);
|
||||||
|
delayMicroseconds(BIT_LENGTH_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void preamble() {
|
||||||
|
noInterrupts();
|
||||||
|
for (int i = 0; i < 370; i++) {
|
||||||
|
transmitBit(HIGH);
|
||||||
|
transmitBit(LOW);
|
||||||
|
}
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void code(const char* value) {
|
||||||
|
noInterrupts();
|
||||||
|
for (const char* p = value; *p; p++) {
|
||||||
|
*p == '1' ? transmitHigh() : transmitLow();
|
||||||
|
}
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
} doorbell;
|
||||||
@ -6,44 +6,50 @@
|
|||||||
|
|
||||||
using namespace Ha;
|
using namespace Ha;
|
||||||
|
|
||||||
DeviceConfig* gatewayDevice = (new DeviceConfig{MAIN_DEVICE_ID})->withName("RC Gateway")->withManufacturer("Adafruit")->withModel("Huzzah Esp8266");
|
typedef unordered_multimap<unsigned long, Ha::Switch*> mapswitches;
|
||||||
|
|
||||||
|
mapswitches onSwitches;
|
||||||
|
mapswitches offSwitches;
|
||||||
|
unordered_map<string, Ha::Switch*> p1Switches;
|
||||||
|
|
||||||
|
auto gatewayDevice = &DeviceConfig::create(MAIN_DEVICE_ID).withName("RC Gateway").withManufacturer("Adafruit").withModel("Huzzah Esp8266");
|
||||||
|
|
||||||
namespace OilTank {
|
namespace OilTank {
|
||||||
Sensor* buildRoomSensor(const char* id) {
|
Sensor* buildRoomSensor(const char* id) {
|
||||||
auto device = DeviceConfig::create(id)
|
DeviceConfig* device = &DeviceConfig::create(id)
|
||||||
->withName("Oil tank room")
|
.withName("Oil tank room")
|
||||||
->withManufacturer("Atmel")
|
.withManufacturer("Atmel")
|
||||||
->withModel("AtTiny85")
|
.withModel("AtTiny85")
|
||||||
->withArea("Basement")
|
.withArea("Basement")
|
||||||
->withParent(gatewayDevice);
|
.withParent(gatewayDevice);
|
||||||
return Builder<TemperatureSensor>::instance(id)
|
return Builder<TemperatureSensor>::instance(id)
|
||||||
.asDevice(device)
|
.asDevice(device)
|
||||||
.withValueTemplate("{{ value_json.sensor.temperature }}")
|
.withValueTemplate("{{ value_json.sensor.temperature }}")
|
||||||
.withDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
.asDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
||||||
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"})
|
.asDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
Sensor* buildTankSensor(const char* id) {
|
Sensor* buildTankSensor(const char* id) {
|
||||||
auto device = DeviceConfig::create(id)
|
DeviceConfig* device = &DeviceConfig::create(id)
|
||||||
->withName("Oil tank")
|
.withName("Oil tank")
|
||||||
->withManufacturer("Arduino")
|
.withManufacturer("Arduino")
|
||||||
->withModel("Pro Mini")
|
.withModel("Pro Mini")
|
||||||
->withArea("Basement")
|
.withArea("Basement")
|
||||||
->withParent(gatewayDevice);
|
.withParent(gatewayDevice);
|
||||||
return Builder<Sensor>::instance(new Sensor{ "Depth", id })
|
return Builder<Sensor>::instance(new Sensor{ "Depth", id })
|
||||||
.asDevice(device)
|
.asDevice(device)
|
||||||
.withDeviceClass("distance")
|
.withDeviceClass("distance")
|
||||||
.withUnitMseasure("cm")
|
.withUnitMseasure("cm")
|
||||||
.withValueTemplate("{{ value_json.sensor.value }}")
|
.withValueTemplate("{{ value_json.sensor.value }}")
|
||||||
.withSecondary(
|
.asSecondary(
|
||||||
Builder<Sensor>::instance(new Sensor{ "Level", id })
|
Builder<Sensor>::instance(new Sensor{ "Level", id })
|
||||||
.withUnitMseasure("%")
|
.withUnitMseasure("%")
|
||||||
.withValueTemplate("{{ 100 - ((value_json.sensor.value-7)|float*100/110)|round(2) }}")
|
.withValueTemplate("{{ 100 - ((value_json.sensor.value-7)|float*100/110)|round(2) }}")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.withDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
.asDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
||||||
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"})
|
.asDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +66,7 @@ struct PollinSwitch : Switch {
|
|||||||
strcpy(uId, s.c_str());
|
strcpy(uId, s.c_str());
|
||||||
return uId;
|
return uId;
|
||||||
}()), group(group), channel(channel) {
|
}()), group(group), channel(channel) {
|
||||||
mainDevice = (new DeviceConfig{id})->withName(name)->withManufacturer("Pollin")->withArea(area)->withParent(gatewayDevice);
|
mainDevice = &DeviceConfig::create(id).withName(name).withManufacturer("Pollin").withArea(area).withParent(gatewayDevice);
|
||||||
deviceClass = "outlet";
|
deviceClass = "outlet";
|
||||||
p1Switches.insert({ string(id), this });
|
p1Switches.insert({ string(id), this });
|
||||||
}
|
}
|
||||||
@ -80,7 +86,7 @@ struct EasyHomeSwitch : Switch {
|
|||||||
: Switch(name, id) {
|
: Switch(name, id) {
|
||||||
memcpy(&this->on[4], on, 4 * sizeof(unsigned long));
|
memcpy(&this->on[4], on, 4 * sizeof(unsigned long));
|
||||||
memcpy(&this->off[4], off, 4 * sizeof(unsigned long));
|
memcpy(&this->off[4], off, 4 * sizeof(unsigned long));
|
||||||
mainDevice = (new DeviceConfig{id})->withName(name)->withManufacturer("Intertek")->withModel("Easy Home")->withArea(area)->withParent(gatewayDevice);
|
mainDevice = &DeviceConfig::create(id).withName(name).withManufacturer("Intertek").withModel("Easy Home").withArea(area).withParent(gatewayDevice);
|
||||||
deviceClass = "outlet";
|
deviceClass = "outlet";
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
onSwitches.insert({ this->on[i], this });
|
onSwitches.insert({ this->on[i], this });
|
||||||
@ -101,6 +107,19 @@ Command* commands[] = {
|
|||||||
if (strcmp("PRESS", msg) == 0) ESP.restart();
|
if (strcmp("PRESS", msg) == 0) ESP.restart();
|
||||||
}
|
}
|
||||||
}).asDevice(gatewayDevice).build(),
|
}).asDevice(gatewayDevice).build(),
|
||||||
|
Builder<Button>::instance(new Button{"Front door", "doorbell_front",
|
||||||
|
[](const char* msg) {
|
||||||
|
if (strcmp("PRESS", msg) == 0) doorbell.ring();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.asDevice(
|
||||||
|
&DeviceConfig::create("doorbell")
|
||||||
|
.withName("Doorbell")
|
||||||
|
.withManufacturer("Thomson")
|
||||||
|
.withModel("Kinetic Halo")
|
||||||
|
.withParent(gatewayDevice)
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
(new EasyHomeSwitch{"FritzBox", "easy_home_a", (unsigned long[4]) { 4483136, 4626800, 4661552, 4819632 }, (unsigned long[4]) { 4326544, 4537104, 4767520, 4972704 }, "Basement"})->withStateTopic(),
|
(new EasyHomeSwitch{"FritzBox", "easy_home_a", (unsigned long[4]) { 4483136, 4626800, 4661552, 4819632 }, (unsigned long[4]) { 4326544, 4537104, 4767520, 4972704 }, "Basement"})->withStateTopic(),
|
||||||
(new EasyHomeSwitch{"Outside", "easy_home_b", (unsigned long[4]) { 4483140, 4626804, 4661556, 4819636 }, (unsigned long[4]) { 4326548, 4537108, 4767524, 4972708 }, "Basement"})->withStateTopic(),
|
(new EasyHomeSwitch{"Outside", "easy_home_b", (unsigned long[4]) { 4483140, 4626804, 4661556, 4819636 }, (unsigned long[4]) { 4326548, 4537108, 4767524, 4972708 }, "Basement"})->withStateTopic(),
|
||||||
(new PollinSwitch{"Meeting sensor", "00001", 1, "Dining room"})->withStateTopic(),
|
(new PollinSwitch{"Meeting sensor", "00001", 1, "Dining room"})->withStateTopic(),
|
||||||
|
|||||||
@ -16,12 +16,10 @@ namespace Ha {
|
|||||||
const char* model = nullptr;
|
const char* model = nullptr;
|
||||||
const char* manufacturer = nullptr;
|
const char* manufacturer = nullptr;
|
||||||
const char* area = nullptr;
|
const char* area = nullptr;
|
||||||
DeviceConfig* parent = nullptr;
|
const DeviceConfig* parent = nullptr;
|
||||||
|
|
||||||
DeviceConfig(const char* id) : id(id) {}
|
static DeviceConfig& create(const char* id) {
|
||||||
|
return *(new DeviceConfig{ id });
|
||||||
static DeviceConfig* create(const char* id) {
|
|
||||||
return new DeviceConfig{ id };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildConfig(JsonDocument& jsonDoc) {
|
void buildConfig(JsonDocument& jsonDoc) {
|
||||||
@ -35,30 +33,33 @@ namespace Ha {
|
|||||||
identifiers.add(id);
|
identifiers.add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceConfig* withName(const char* value) {
|
DeviceConfig& withName(const char* value) {
|
||||||
name = value;
|
name = value;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceConfig* withModel(const char* value) {
|
DeviceConfig& withModel(const char* value) {
|
||||||
model = value;
|
model = value;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceConfig* withManufacturer(const char* value) {
|
DeviceConfig& withManufacturer(const char* value) {
|
||||||
manufacturer = value;
|
manufacturer = value;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceConfig* withArea(const char* value) {
|
DeviceConfig& withArea(const char* value) {
|
||||||
area = value;
|
area = value;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceConfig* withParent(DeviceConfig* deviceConfig) {
|
DeviceConfig& withParent(const DeviceConfig* deviceConfig) {
|
||||||
parent = deviceConfig;
|
parent = deviceConfig;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DeviceConfig(const char* id) : id(id) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Component {
|
struct Component {
|
||||||
@ -108,7 +109,6 @@ namespace Ha {
|
|||||||
publisher(configTopic, "");
|
publisher(configTopic, "");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
List<Component> Component::components;
|
|
||||||
|
|
||||||
struct AbstractBuilder {
|
struct AbstractBuilder {
|
||||||
static List<AbstractBuilder> builders;
|
static List<AbstractBuilder> builders;
|
||||||
@ -122,7 +122,6 @@ namespace Ha {
|
|||||||
builders.empty();
|
builders.empty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
List<AbstractBuilder> AbstractBuilder::builders;
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct Builder : AbstractBuilder {
|
struct Builder : AbstractBuilder {
|
||||||
@ -161,15 +160,14 @@ namespace Ha {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder& withSecondary(Component* c) {
|
Builder& asSecondary(Component* c) {
|
||||||
c->mainDevice = new DeviceConfig{ cmp->id };
|
c->mainDevice = &DeviceConfig::create(cmp->id);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder& withDiagnostic(Component* c) {
|
Builder& asDiagnostic(Component* c) {
|
||||||
c->entityCategory = "diagnostic";
|
c->entityCategory = "diagnostic";
|
||||||
c->mainDevice = new DeviceConfig{ cmp->id };
|
return asSecondary(c);
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder& asDevice(DeviceConfig* deviceConfig) {
|
Builder& asDevice(DeviceConfig* deviceConfig) {
|
||||||
@ -198,7 +196,6 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
unordered_map<string, Command*> Command::mapCommands;
|
|
||||||
|
|
||||||
struct Button : Command {
|
struct Button : Command {
|
||||||
|
|
||||||
@ -227,7 +224,7 @@ namespace Ha {
|
|||||||
if (stateTopic[0]) jsonDoc["state_topic"] = stateTopic;
|
if (stateTopic[0]) jsonDoc["state_topic"] = stateTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void publishState(bool state) {
|
void updateState(bool state) {
|
||||||
publisher(stateTopic, state ? "ON" : "OFF");
|
publisher(stateTopic, state ? "ON" : "OFF");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -235,13 +232,11 @@ namespace Ha {
|
|||||||
struct Sensor : Component, StateConfig<Sensor> {
|
struct Sensor : Component, StateConfig<Sensor> {
|
||||||
const char* unitMeasure = nullptr;
|
const char* unitMeasure = nullptr;
|
||||||
const char* valueTemplate = nullptr;
|
const char* valueTemplate = nullptr;
|
||||||
|
static unordered_map<string, Sensor*> mapSensors;
|
||||||
Sensor() : Component(name, id, "sensor") {
|
|
||||||
withStateTopic();
|
|
||||||
}
|
|
||||||
|
|
||||||
Sensor(const char* name, const char* id) : Component(name, id, "sensor") {
|
Sensor(const char* name, const char* id) : Component(name, id, "sensor") {
|
||||||
withStateTopic();
|
withStateTopic();
|
||||||
|
mapSensors.insert({ id, this });
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildUniqueId(char* uniqueId) override {
|
void buildUniqueId(char* uniqueId) override {
|
||||||
@ -267,6 +262,10 @@ namespace Ha {
|
|||||||
jsonDoc["state_topic"] = stateTopic;
|
jsonDoc["state_topic"] = stateTopic;
|
||||||
jsonDoc["suggested_display_precision"] = 2;
|
jsonDoc["suggested_display_precision"] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateState(const char* message) {
|
||||||
|
publisher(stateTopic, message);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TemperatureSensor : Sensor {
|
struct TemperatureSensor : Sensor {
|
||||||
@ -307,4 +306,9 @@ namespace Ha {
|
|||||||
// valueTemplate = "{{ value_json.sensor.pressure }}";
|
// valueTemplate = "{{ value_json.sensor.pressure }}";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
List<Component> Component::components;
|
||||||
|
List<AbstractBuilder> AbstractBuilder::builders;
|
||||||
|
unordered_map<string, Command*> Command::mapCommands;
|
||||||
|
unordered_map<string, Sensor*> Sensor::mapSensors;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,9 @@
|
|||||||
#include <TaskScheduler.h>
|
#include <TaskScheduler.h>
|
||||||
|
|
||||||
#define SEND_PIN 14
|
|
||||||
#define RECEIVE_PIN 12
|
|
||||||
#define RED_LED LED_BUILTIN
|
|
||||||
#define BLUE_LED 2
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Scheduler ts;
|
Scheduler ts;
|
||||||
|
|
||||||
namespace Ha {
|
|
||||||
struct Switch;
|
|
||||||
}
|
|
||||||
typedef unordered_multimap<unsigned long, Ha::Switch*> mapswitches;
|
|
||||||
mapswitches onSwitches;
|
|
||||||
mapswitches offSwitches;
|
|
||||||
unordered_map<string, Ha::Switch*> p1Switches;
|
|
||||||
|
|
||||||
void turnLed(uint8_t led, bool on = true) {
|
void turnLed(uint8_t led, bool on = true) {
|
||||||
on ? digitalWrite(led, LOW) : digitalWrite(led, HIGH);
|
on ? digitalWrite(led, LOW) : digitalWrite(led, HIGH);
|
||||||
}
|
}
|
||||||
@ -57,7 +44,7 @@ namespace Board {
|
|||||||
case 1: {
|
case 1: {
|
||||||
string id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]);
|
string id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]);
|
||||||
Ha::Switch* el = p1Switches[id];
|
Ha::Switch* el = p1Switches[id];
|
||||||
if (el) el->publishState((bool)rcSwitch["state"]);
|
if (el) el->updateState((bool)rcSwitch["state"]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
@ -66,11 +53,11 @@ namespace Board {
|
|||||||
unsigned long value = rcSwitch["value"];
|
unsigned long value = rcSwitch["value"];
|
||||||
auto range = onSwitches.equal_range(value);
|
auto range = onSwitches.equal_range(value);
|
||||||
for_each(range.first, range.second, [](mapswitches::value_type& x){
|
for_each(range.first, range.second, [](mapswitches::value_type& x){
|
||||||
x.second->publishState(true);
|
x.second->updateState(true);
|
||||||
});
|
});
|
||||||
range = offSwitches.equal_range(value);
|
range = offSwitches.equal_range(value);
|
||||||
for_each(range.first, range.second, [](mapswitches::value_type& x){
|
for_each(range.first, range.second, [](mapswitches::value_type& x){
|
||||||
x.second->publishState(false);
|
x.second->updateState(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,10 +66,8 @@ namespace Board {
|
|||||||
void parseSensors(JsonDocument& jsonDoc, char* message) {
|
void parseSensors(JsonDocument& jsonDoc, char* message) {
|
||||||
JsonObjectConst json = jsonDoc["sensor"];
|
JsonObjectConst json = jsonDoc["sensor"];
|
||||||
string id = to_string((unsigned int)json["id"]);
|
string id = to_string((unsigned int)json["id"]);
|
||||||
char stateTopic[TOPIC_SIZE];
|
auto sensor = Sensor::mapSensors[id];
|
||||||
sprintf(stateTopic, "homeassistant/sensor/%s/%s/state", MAIN_DEVICE_ID, id.c_str());
|
if (sensor) sensor->updateState(message);
|
||||||
Mqtt::publish(stateTopic, message);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void publishResponse(JsonDocument& jsonDoc) {
|
void publishResponse(JsonDocument& jsonDoc) {
|
||||||
|
|||||||
12
gateway/include/pins.h
Normal file
12
gateway/include/pins.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
#define SEND_PIN 14
|
||||||
|
#define RECEIVE_PIN 12
|
||||||
|
#define RED_LED LED_BUILTIN
|
||||||
|
#define BLUE_LED 2
|
||||||
|
#else
|
||||||
|
#define RESET_PIN 10
|
||||||
|
#define SEND_PIN 11
|
||||||
|
#define RECEIVE_PIN 2
|
||||||
|
#endif
|
||||||
@ -1,9 +1,5 @@
|
|||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
|
||||||
#define RESET_PIN 10
|
|
||||||
#define SEND_PIN 11
|
|
||||||
#define RECEIVE_PIN 2
|
|
||||||
|
|
||||||
namespace Board {
|
namespace Board {
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <RCSwitch.h>
|
#include <RCSwitch.h>
|
||||||
#include <SerialReader.h>
|
#include <SerialReader.h>
|
||||||
|
#include "pins.h"
|
||||||
#include "Dht.h"
|
#include "Dht.h"
|
||||||
#include "Protocol_1.h"
|
#include "Protocol_1.h"
|
||||||
#include "Protocol_2.h"
|
#include "Protocol_2.h"
|
||||||
|
#include "Protocol_Doorbell.h"
|
||||||
|
|
||||||
RCSwitch mySwitch;
|
RCSwitch mySwitch;
|
||||||
SerialReader<200> serialReader;
|
SerialReader<200> serialReader;
|
||||||
@ -29,15 +31,9 @@ void setup() {
|
|||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol* findProtocol(unsigned int protocol) {
|
Protocol& findProtocol(unsigned int protocol) {
|
||||||
switch (protocol) {
|
auto p = Protocol::mapProtocols[protocol];
|
||||||
case 1:
|
return p ? *p : fallbackProtocol.setProtocol(protocol);
|
||||||
return new Protocol_1();
|
|
||||||
case 2:
|
|
||||||
return new Protocol_2();
|
|
||||||
default:
|
|
||||||
return new Protocol(protocol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void readRcSwitch() {
|
void readRcSwitch() {
|
||||||
@ -52,9 +48,8 @@ void readRcSwitch() {
|
|||||||
mySwitch.resetAvailable();
|
mySwitch.resetAvailable();
|
||||||
|
|
||||||
StaticJsonDocument<128> jsonDoc;
|
StaticJsonDocument<128> jsonDoc;
|
||||||
Protocol* p = findProtocol(mySwitch.getReceivedProtocol());
|
Protocol& p = findProtocol(mySwitch.getReceivedProtocol());
|
||||||
p->toJson(value, jsonDoc);
|
p.toJson(value, jsonDoc);
|
||||||
delete p;
|
|
||||||
if (!jsonDoc.isNull()) {
|
if (!jsonDoc.isNull()) {
|
||||||
serializeJson(jsonDoc, Serial);
|
serializeJson(jsonDoc, Serial);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@ -75,14 +70,13 @@ void handleJsonError(DeserializationError err, const char* cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void runJsonCommand(char* cmd) {
|
void runJsonCommand(char* cmd) {
|
||||||
StaticJsonDocument<50> jsonDoc;
|
StaticJsonDocument<128> jsonDoc;
|
||||||
DeserializationError err = deserializeJson(jsonDoc, cmd);
|
DeserializationError err = deserializeJson(jsonDoc, cmd);
|
||||||
if (err == DeserializationError::Ok) {
|
if (err == DeserializationError::Ok) {
|
||||||
if (jsonDoc.containsKey("rcSwitch")) {
|
if (jsonDoc.containsKey("rcSwitch")) {
|
||||||
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
|
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
|
||||||
Protocol* p = findProtocol(rcSwitch["protocol"]);
|
Protocol& p = findProtocol(rcSwitch["protocol"]);
|
||||||
p->fromJson(rcSwitch, mySwitch);
|
p.fromJson(rcSwitch, mySwitch);
|
||||||
delete p;
|
|
||||||
serializeJson(jsonDoc, Serial);
|
serializeJson(jsonDoc, Serial);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Board::publishResponse(jsonDoc);
|
Board::publishResponse(jsonDoc);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user