diff --git a/gateway/include/Protocol.h b/gateway/include/Protocol.h index 9d966c9..056adc8 100644 --- a/gateway/include/Protocol.h +++ b/gateway/include/Protocol.h @@ -2,15 +2,24 @@ #include #include +using namespace std; + class Protocol { protected: - unsigned int protocol; + unsigned int no; public: + static unordered_map mapProtocols; + 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) { unsigned int protocol = rcSwitch["protocol"]; @@ -20,8 +29,9 @@ public: virtual void toJson(unsigned long value, JsonDocument& jsonDoc) { JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch"); - rcSwitch["protocol"] = protocol; + rcSwitch["protocol"] = no; rcSwitch["value"] = value; } - -}; \ No newline at end of file +}; +unordered_map Protocol::mapProtocols; +Protocol fallbackProtocol{ 0 }; diff --git a/gateway/include/Protocol_1.h b/gateway/include/Protocol_1.h index 6d9dd85..112104d 100644 --- a/gateway/include/Protocol_1.h +++ b/gateway/include/Protocol_1.h @@ -5,8 +5,7 @@ class Protocol_1 : public Protocol { public: - Protocol_1() : Protocol(1) { - } + Protocol_1() : Protocol(1) {} void fromJson(JsonObjectConst& rcSwitch, RCSwitch& rcDevice) override { unsigned int protocol = rcSwitch["protocol"]; @@ -18,7 +17,7 @@ public: void toJson(unsigned long value, JsonDocument& jsonDoc) override { JsonObject rcSwitch = jsonDoc.createNestedObject("rcSwitch"); - rcSwitch["protocol"] = protocol; + rcSwitch["protocol"] = no; RcDecoder decoder; decoder.decode(value); rcSwitch["state"] = decoder.state; @@ -32,4 +31,4 @@ public: sprintf(uId, "%s_%d", group, channel); return std::string{ uId }; } -}; +} protocol1; diff --git a/gateway/include/Protocol_2.h b/gateway/include/Protocol_2.h index 589154e..9e780f2 100644 --- a/gateway/include/Protocol_2.h +++ b/gateway/include/Protocol_2.h @@ -5,8 +5,7 @@ class Protocol_2 : public Protocol { public: - Protocol_2() : Protocol(2) { - } + Protocol_2() : Protocol(2) {} void toJson(unsigned long value, JsonDocument& jsonDoc) override { switch (value) { @@ -33,4 +32,4 @@ public: } } -}; \ No newline at end of file +} protocol2; \ No newline at end of file diff --git a/gateway/include/Protocol_Doorbell.h b/gateway/include/Protocol_Doorbell.h new file mode 100644 index 0000000..59285cf --- /dev/null +++ b/gateway/include/Protocol_Doorbell.h @@ -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; diff --git a/gateway/include/devices.h b/gateway/include/devices.h index b59c9cb..4353af7 100644 --- a/gateway/include/devices.h +++ b/gateway/include/devices.h @@ -6,44 +6,50 @@ using namespace Ha; -DeviceConfig* gatewayDevice = (new DeviceConfig{MAIN_DEVICE_ID})->withName("RC Gateway")->withManufacturer("Adafruit")->withModel("Huzzah Esp8266"); +typedef unordered_multimap mapswitches; + +mapswitches onSwitches; +mapswitches offSwitches; +unordered_map p1Switches; + +auto gatewayDevice = &DeviceConfig::create(MAIN_DEVICE_ID).withName("RC Gateway").withManufacturer("Adafruit").withModel("Huzzah Esp8266"); namespace OilTank { Sensor* buildRoomSensor(const char* id) { - auto device = DeviceConfig::create(id) - ->withName("Oil tank room") - ->withManufacturer("Atmel") - ->withModel("AtTiny85") - ->withArea("Basement") - ->withParent(gatewayDevice); + DeviceConfig* device = &DeviceConfig::create(id) + .withName("Oil tank room") + .withManufacturer("Atmel") + .withModel("AtTiny85") + .withArea("Basement") + .withParent(gatewayDevice); return Builder::instance(id) .asDevice(device) .withValueTemplate("{{ value_json.sensor.temperature }}") - .withDiagnostic(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 VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"}) + .asDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"}) .build(); } Sensor* buildTankSensor(const char* id) { - auto device = DeviceConfig::create(id) - ->withName("Oil tank") - ->withManufacturer("Arduino") - ->withModel("Pro Mini") - ->withArea("Basement") - ->withParent(gatewayDevice); + DeviceConfig* device = &DeviceConfig::create(id) + .withName("Oil tank") + .withManufacturer("Arduino") + .withModel("Pro Mini") + .withArea("Basement") + .withParent(gatewayDevice); return Builder::instance(new Sensor{ "Depth", id }) .asDevice(device) .withDeviceClass("distance") .withUnitMseasure("cm") .withValueTemplate("{{ value_json.sensor.value }}") - .withSecondary( + .asSecondary( Builder::instance(new Sensor{ "Level", id }) .withUnitMseasure("%") .withValueTemplate("{{ 100 - ((value_json.sensor.value-7)|float*100/110)|round(2) }}") .build() ) - .withDiagnostic(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 VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"}) + .asDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"}) .build(); } } @@ -60,7 +66,7 @@ struct PollinSwitch : Switch { strcpy(uId, s.c_str()); return uId; }()), 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"; p1Switches.insert({ string(id), this }); } @@ -80,7 +86,7 @@ struct EasyHomeSwitch : Switch { : Switch(name, id) { memcpy(&this->on[4], on, 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"; for (int i = 0; i < 8; i++) { onSwitches.insert({ this->on[i], this }); @@ -101,6 +107,19 @@ Command* commands[] = { if (strcmp("PRESS", msg) == 0) ESP.restart(); } }).asDevice(gatewayDevice).build(), + Builder