Compare commits
	
		
			5 Commits
		
	
	
		
			8198d8f62e
			...
			3ef68a9539
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3ef68a9539 | |||
| 31861e7785 | |||
| b8581dcf31 | |||
| 2809b1a167 | |||
| d3f0520123 | 
| @@ -0,0 +1,42 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome import pins | ||||||
|  | from esphome.components import uart | ||||||
|  | from esphome.const import ( | ||||||
|  |   CONF_ID | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CODEOWNERS = ["@nbsgames"] | ||||||
|  | DEPENDENCIES=["uart"] | ||||||
|  |  | ||||||
|  | hoermann_door_ns = cg.esphome_ns.namespace('hoermann_door') | ||||||
|  | HoermannDoor = hoermann_door_ns.class_('HoermannMainComponent', cg.Component) | ||||||
|  |  | ||||||
|  | CONF_UART_ENTRY = "uart_connection" | ||||||
|  | CONF_TX_PIN = "tx_pin" | ||||||
|  |  | ||||||
|  | def validate_config(config): | ||||||
|  |   return config | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.All( | ||||||
|  |   cv.COMPONENT_SCHEMA.extend({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(HoermannDoor), | ||||||
|  |     cv.Required(CONF_UART_ENTRY): cv.use_id(uart.UARTComponent), | ||||||
|  |     cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_schema, | ||||||
|  |   }), | ||||||
|  |   validate_config | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |   var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |   await cg.register_component(var, config) | ||||||
|  |   #yield mqtt.register_mqtt_component(var, config) | ||||||
|  |    | ||||||
|  |   #btnReset = yield cg.gpio_pin_expression(config[CONF_SENSOR_PIN]) | ||||||
|  |   #cg.add(var.set_input_pin(btnReset)) | ||||||
|  |    | ||||||
|  |   code = await cg.get_variable(config[CONF_UART_ENTRY]) | ||||||
|  |   cg.add(var.set_seriel_connection(code)) | ||||||
|  |    | ||||||
|  |   code2 = await cg.gpio_pin_expression(config[CONF_TX_PIN]) | ||||||
|  |   cg.add(var.set_tx_on_pin(code2)) # Needs be configured before sensor | ||||||
| @@ -3,18 +3,23 @@ import esphome.config_validation as cv | |||||||
| from esphome import automation | from esphome import automation | ||||||
| from esphome.components import cover | from esphome.components import cover | ||||||
| from esphome.const import CONF_ID | from esphome.const import CONF_ID | ||||||
|  | from . import HoermannDoor | ||||||
|  |  | ||||||
| hoermann_cover_ns = cg.esphome_ns.namespace('hoermann_door') | hoermann_cover_ns = cg.esphome_ns.namespace('hoermann_door') | ||||||
| HoermannDoor = hoermann_cover_ns.class_('HoermanDoor', cover.Cover, cg.Component) | HoermannCover = hoermann_cover_ns.class_('HoermannDoor', cover.Cover, cg.Component) | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({ | CONF_HOERMANN_CONTROLLER = "hoermann_controller" | ||||||
|     cv.GenerateID(): cv.declare_id(HoermannDoor) |  | ||||||
| }).extend(cv.COMPONENT_SCHEMA) |  | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cover.cover_schema(HoermannCover).extend({ | ||||||
|  |     cv.Required(CONF_HOERMANN_CONTROLLER): cv.use_id(HoermannDoor) | ||||||
|  | }) | ||||||
|  |  | ||||||
| def to_code(config): | async def to_code(config): | ||||||
|     var = cg.new_Pvariable(config[CONF_ID]) |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|     yield cg.register_component(var, config) |     await cg.register_component(var, config) | ||||||
|     yield cover.register_cover(var, config) |     await cover.register_cover(var, config) | ||||||
|  |      | ||||||
|  |     controller = await cg.get_variable(config[CONF_HOERMANN_CONTROLLER]) | ||||||
|  |     cg.add(var.set_emulator_component(controller)) | ||||||
|  |  | ||||||
| cg.add_library("plerup/EspSoftwareSerial", "8.2.0") | cg.add_library("plerup/EspSoftwareSerial", "8.2.0") | ||||||
| @@ -1,11 +1,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "door_singleton.h" |  | ||||||
|  |  | ||||||
| #ifdef USE_COVER | #ifdef USE_COVER | ||||||
|  |  | ||||||
|  | class HoermannDoorx; | ||||||
|  |  | ||||||
| #include "esphome.h" | #include "esphome.h" | ||||||
| #include "Arduino.h" | #include "hoermann.h" | ||||||
| #include "hciemulator.h" | #include "hciemulator.h" | ||||||
| //#include "cover.h" | //#include "cover.h" | ||||||
|  |  | ||||||
| @@ -13,14 +13,13 @@ | |||||||
| #define TX_ON 25 | #define TX_ON 25 | ||||||
| //#define configMAX_PRIORITIES 25 | //#define configMAX_PRIORITIES 25 | ||||||
|  |  | ||||||
| #define TAG "hoermann_door" |  | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace hoermann_door { | namespace hoermann_door { | ||||||
|  |  | ||||||
| void modBusPolling(void *parameter); | class HoermannDoor : public Component, public cover::Cover | ||||||
| class HoermanDoor : public Component, public cover::Cover |  | ||||||
| { | { | ||||||
|  | private: | ||||||
|  |     HoermannMainComponent* mainComponent; | ||||||
| public: | public: | ||||||
|  |  | ||||||
|   cover::CoverTraits get_traits() override { |   cover::CoverTraits get_traits() override { | ||||||
| @@ -48,11 +47,11 @@ public: | |||||||
|        |        | ||||||
|  |  | ||||||
|       if(pos == 1.0){ |       if(pos == 1.0){ | ||||||
|         HoermannSingleton::getInstance()->getEmulator()->openDoor(); |         mainComponent->getEmulator()->openDoor(); | ||||||
|         manual = false; |         manual = false; | ||||||
|       } |       } | ||||||
|       else if(pos == 0.0){ |       else if(pos == 0.0){ | ||||||
|         HoermannSingleton::getInstance()->getEmulator()->closeDoor(); |         mainComponent->getEmulator()->closeDoor(); | ||||||
|         manual = false; |         manual = false; | ||||||
|       } |       } | ||||||
|       else{ |       else{ | ||||||
| @@ -61,39 +60,22 @@ public: | |||||||
|  |  | ||||||
|     } |     } | ||||||
|     if (call.get_stop()) { |     if (call.get_stop()) { | ||||||
|       HoermannSingleton::getInstance()->getEmulator()->stopDoor(); |       mainComponent->getEmulator()->stopDoor(); | ||||||
|     } |     } | ||||||
|     //if(call.get_close()) { |     //if(call.get_close()) { | ||||||
|       //emulator.closeDoor(); |       //emulator.closeDoor(); | ||||||
|     //} |     //} | ||||||
|   } |   } | ||||||
|  |  | ||||||
|      |  | ||||||
|     /* |  | ||||||
| void modBusPolling(void *parameter) |  | ||||||
| { |  | ||||||
|   while (true) |  | ||||||
|   { |  | ||||||
|     if (lastCall > 0) |  | ||||||
|     { |  | ||||||
|       maxPeriod = _max(micros() - lastCall, maxPeriod); |  | ||||||
|     } |  | ||||||
|     lastCall = micros(); |  | ||||||
|     emulator.poll(); |  | ||||||
|     vTaskDelay(1); |  | ||||||
|   } |  | ||||||
|   vTaskDelete(NULL); |  | ||||||
| } |  | ||||||
|     */ |  | ||||||
|  |  | ||||||
|     void setup() override |     void setup() override | ||||||
|     { |     { | ||||||
|       HoermannSingleton::getInstance()->initializeEmulator(); |       //HoermannSingleton::getInstance()->initializeEmulator(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void set_emulator_component(HoermannMainComponent* component){ | ||||||
|  |       this->mainComponent = component; | ||||||
|  |     } | ||||||
|      |      | ||||||
|  |  | ||||||
|  |  | ||||||
|     void open(){ |     void open(){ | ||||||
|       //emulator.openDoor(); |       //emulator.openDoor(); | ||||||
|     } |     } | ||||||
| @@ -109,7 +91,7 @@ void modBusPolling(void *parameter) | |||||||
|     u_int8_t pos = 255; |     u_int8_t pos = 255; | ||||||
|     void loop() override |     void loop() override | ||||||
|     { |     { | ||||||
|       u_int8_t position = HoermannSingleton::getInstance()->getEmulator()->getState().doorCurrentPosition; |       u_int8_t position = mainComponent->getEmulator()->getState().doorCurrentPosition; | ||||||
|       if(pos != position){ |       if(pos != position){ | ||||||
|         this->position = (float) position / 200.0; |         this->position = (float) position / 200.0; | ||||||
|         this->publish_state(); |         this->publish_state(); | ||||||
|   | |||||||
| @@ -1,79 +0,0 @@ | |||||||
| #pragma once  |  | ||||||
|  |  | ||||||
| #include "esphome.h" |  | ||||||
| #include "Arduino.h" |  | ||||||
| #include "hciemulator.h" |  | ||||||
| //#include "cover.h" |  | ||||||
|  |  | ||||||
| #define RS485 Serial2 |  | ||||||
| #define TX_ON 25 |  | ||||||
| //#define configMAX_PRIORITIES 25 |  | ||||||
|  |  | ||||||
| #define TAG "hoermann_door" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void modBusPolling(void *parameter); |  | ||||||
|  |  | ||||||
| class HoermannSingleton { |  | ||||||
|   public: |  | ||||||
|     HoermannSingleton() { |  | ||||||
|       emulator; |  | ||||||
|     } |  | ||||||
|     static HoermannSingleton* instance_; |  | ||||||
|     HCIEmulator emulator; |  | ||||||
|     TaskHandle_t modBusTask; |  | ||||||
|     bool hasBeenInitialized = false; |  | ||||||
|  |  | ||||||
|   public: |  | ||||||
|     static HoermannSingleton* getInstance(){ |  | ||||||
|       if(instance_ == nullptr){ |  | ||||||
|         instance_ = new HoermannSingleton(); |  | ||||||
|       } |  | ||||||
|       return instance_; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void initializeEmulator(){ |  | ||||||
|       if(hasBeenInitialized) return; |  | ||||||
|       hasBeenInitialized = true; |  | ||||||
|       RS485.begin(57600, SERIAL_8E1, 16, 17); |  | ||||||
|       pinMode(TX_ON, OUTPUT); |  | ||||||
|       digitalWrite(TX_ON, LOW); |  | ||||||
|          |  | ||||||
|       xTaskCreatePinnedToCore( |  | ||||||
|         modBusPolling, // Function to implement the task |  | ||||||
|         "ModBusTask",   // Name of the task |  | ||||||
|         10000,          // Stack size in words |  | ||||||
|         NULL,           // Task input parameter |  | ||||||
|         // 1,           // Priority of the task |  | ||||||
|         configMAX_PRIORITIES - 1, |  | ||||||
|         &modBusTask,    // Task handle. |  | ||||||
|         1               // Core where the task should run |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|     HCIEmulator *getEmulator(){ |  | ||||||
|       return &emulator; |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| HoermannSingleton* HoermannSingleton::instance_ = nullptr; |  | ||||||
|  |  | ||||||
| //DoorManager *DoorManager::getInstance() |  | ||||||
|  |  | ||||||
|  |  | ||||||
| volatile unsigned long lastCall = 0; |  | ||||||
| volatile unsigned long maxPeriod = 0; |  | ||||||
| void modBusPolling(void *parameter) |  | ||||||
| { |  | ||||||
|   auto emulator = HoermannSingleton::getInstance()->getEmulator(); |  | ||||||
|   while (true) |  | ||||||
|   { |  | ||||||
|     if (lastCall > 0) |  | ||||||
|     { |  | ||||||
|       maxPeriod = _max(micros() - lastCall, maxPeriod); |  | ||||||
|     } |  | ||||||
|     lastCall = micros(); |  | ||||||
|     emulator->poll(); |  | ||||||
|     vTaskDelay(1); |  | ||||||
|   } |  | ||||||
|   vTaskDelete(NULL); |  | ||||||
| } |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "hciemulator.h" | #include "hciemulator.h" | ||||||
| #include "Arduino.h" |  | ||||||
| #define CHECKCHANGEDSET(Target, Value, Flag) \ | #define CHECKCHANGEDSET(Target, Value, Flag) \ | ||||||
|     if ((Target) != (Value))                 \ |     if ((Target) != (Value))                 \ | ||||||
|     {                                        \ |     {                                        \ | ||||||
| @@ -22,18 +22,23 @@ void LogCore(int Level, const char *msg, const unsigned char *data = NULL, size_ | |||||||
|     } |     } | ||||||
|     if (data != NULL && datalen > 0) |     if (data != NULL && datalen > 0) | ||||||
|     { |     { | ||||||
|         String newmsg(msg); |         //std::string newmsg(msg); | ||||||
|  |         char* newmsg = (char*)malloc(strlen(msg) + datalen * 3 + 1); | ||||||
|  |         strncpy(newmsg, msg, strlen(msg) + 1); | ||||||
|  |         newmsg[strlen(msg)] = '\0'; | ||||||
|         char str[4]; |         char str[4]; | ||||||
|         for (size_t i = 0; i < datalen; i++) |         for (size_t i = 0; i < datalen; i++) | ||||||
|         { |         { | ||||||
|             snprintf(str, sizeof(str), "%02x ", data[i]); |             snprintf(str, sizeof(str), "%02x ", data[i]); | ||||||
|             newmsg += str; |             str[3] = '\0'; | ||||||
|  |             strncat(newmsg, str, sizeof(str)); | ||||||
|         } |         } | ||||||
|         Serial.println(newmsg); |         ESP_LOGD(TAG, newmsg); | ||||||
|  |         free(newmsg); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         Serial.println(msg); |         ESP_LOGD(TAG, msg); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #else | #else | ||||||
| @@ -50,6 +55,12 @@ void HCIEmulator::setLogLevel(int level) | |||||||
|     hciloglevel = level; |     hciloglevel = level; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //#ifdef USE_ESP_IDF | ||||||
|  |     uint16_t HCIEmulator::word(uint8_t high, uint8_t low){ | ||||||
|  |         return (uint16_t) ((high << 8) | low); | ||||||
|  |     } | ||||||
|  | //#endif | ||||||
|  |  | ||||||
| // modbus crc calculation borrowed from: | // modbus crc calculation borrowed from: | ||||||
| // https://github.com/yaacov/ArduinoModbusSlave | // https://github.com/yaacov/ArduinoModbusSlave | ||||||
| #define MODBUS_CRC_LENGTH 2 | #define MODBUS_CRC_LENGTH 2 | ||||||
| @@ -98,14 +109,15 @@ uint16_t calculateCRC(uint8_t *buffer, int length) | |||||||
|     return crc; |     return crc; | ||||||
| } | } | ||||||
|  |  | ||||||
| HCIEmulator::HCIEmulator() | HCIEmulator::HCIEmulator(esphome::InternalGPIOPin* pin, esphome::uart::UARTComponent* uart) | ||||||
| { | { | ||||||
|     m_state.valid = false; |     m_state.valid = false; | ||||||
|     m_statemachine = WAITING; |     m_statemachine = WAITING; | ||||||
|     m_rxlen = m_txlen = 0; |     m_rxlen = m_txlen = 0; | ||||||
|     m_recvTime = m_lastStateTime = 0; |     m_recvTime = m_lastStateTime = 0; | ||||||
|     m_skipFrame = false; |     m_skipFrame = false; | ||||||
|     m_port = &Serial2; |     m_port = uart; | ||||||
|  |     m_pin = pin; | ||||||
|     m_statusCallback = NULL; |     m_statusCallback = NULL; | ||||||
|     setLogLevel(DEFAULTLOGLEVEL); |     setLogLevel(DEFAULTLOGLEVEL); | ||||||
| }; | }; | ||||||
| @@ -122,7 +134,13 @@ void HCIEmulator::poll() | |||||||
|     if (m_port->available() > 0) |     if (m_port->available() > 0) | ||||||
|     { |     { | ||||||
|         // Serial.println("got data"); |         // Serial.println("got data"); | ||||||
|         m_rxlen += m_port->readBytes((char *)(m_rxbuffer + m_rxlen), _min((int)(255 - m_rxlen), m_port->available())); |         int bytesToRead = std::min((int)(255 - m_rxlen), m_port->available()); | ||||||
|  |         if(m_port->read_array((uint8_t *)(m_rxbuffer + m_rxlen), bytesToRead)) { | ||||||
|  |             m_rxlen += bytesToRead; | ||||||
|  |         } else { | ||||||
|  |             Log(LL_ERROR, "Error reading from UART"); | ||||||
|  |             //m_port->flush(); | ||||||
|  |         } | ||||||
|         if (m_rxlen > 254) |         if (m_rxlen > 254) | ||||||
|         { |         { | ||||||
|             Log(LL_ERROR, "RX Bufferoverflow, skip next Frame"); |             Log(LL_ERROR, "RX Bufferoverflow, skip next Frame"); | ||||||
| @@ -130,16 +148,16 @@ void HCIEmulator::poll() | |||||||
|             m_rxlen = 0; |             m_rxlen = 0; | ||||||
|             m_skipFrame = true; |             m_skipFrame = true; | ||||||
|         } |         } | ||||||
|         m_recvTime = micros(); |         m_recvTime = esphome::micros(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Serial.printf("Data % x\n", m_txbuffer); |     // Serial.printf("Data % x\n", m_txbuffer); | ||||||
|     //  check frame, process frame |     //  check frame, process frame | ||||||
|     if (m_rxlen > 0 && (micros() - m_recvTime > T3_5)) |     if (m_rxlen > 0 && (esphome::micros() - m_recvTime > T3_5)) | ||||||
|     { |     { | ||||||
|         // Serial.printf("Act on it % x\n", m_txbuffer); |         // Serial.printf("Act on it % x\n", m_txbuffer); | ||||||
|         //  check last action timeout -> reset > then 2sec |         //  check last action timeout -> reset > then 2sec | ||||||
|         if (m_statemachine != WAITING && m_lastStateTime + 2000 < millis()) |         if (m_statemachine != WAITING && m_lastStateTime + 2000 < esphome::millis()) | ||||||
|         { |         { | ||||||
|             m_statemachine = WAITING; |             m_statemachine = WAITING; | ||||||
|         } |         } | ||||||
| @@ -158,22 +176,23 @@ void HCIEmulator::poll() | |||||||
|                 m_txbuffer[(m_txlen - MODBUS_CRC_LENGTH) + 1] = crc >> 8; |                 m_txbuffer[(m_txlen - MODBUS_CRC_LENGTH) + 1] = crc >> 8; | ||||||
|  |  | ||||||
|                 // send data |                 // send data | ||||||
|                 m_lastSendTime = micros() - m_recvTime; |                 m_lastSendTime = esphome::micros() - m_recvTime; | ||||||
|  |  | ||||||
|                 // Log(LL_DEBUG, ("ST:"+String(m_lastSendTime)).c_str()); |                 // Log(LL_DEBUG, ("ST:"+String(m_lastSendTime)).c_str()); | ||||||
|  |  | ||||||
|                 digitalWrite(TX_ON, HIGH); |                 m_pin->digital_write(true); | ||||||
|  |  | ||||||
|                 // Log3(LL_DEBUG, "write data: "); |                 // Log3(LL_DEBUG, "write data: "); | ||||||
|                 m_port->write(m_txbuffer, m_txlen); |                 m_port->write_array(m_txbuffer, m_txlen); | ||||||
|                 Log3(LL_DEBUG, "Response: ", m_txbuffer, m_txlen); |                 Log3(LL_DEBUG, "Response: ", m_txbuffer, m_txlen); | ||||||
|                 delayMicroseconds(m_txlen * 9 * 22); // 8 bits + par * Bittime 18 micros on 57600 bauds |                 esphome::delayMicroseconds(m_txlen * 9 * 22); // 8 bits + par * Bittime 18 micros on 57600 bauds | ||||||
|                 digitalWrite(TX_ON, LOW); |                 m_pin->digital_write(false); | ||||||
|                 m_txlen = 0; |                 m_txlen = 0; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             Serial.println("skipped frame"); |             ESP_LOGD(TAG, "skipped frame"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         m_skipFrame = false; |         m_skipFrame = false; | ||||||
| @@ -274,10 +293,10 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x02; |                 m_txbuffer[7] = 0x02; | ||||||
|                 m_txbuffer[8] = 0x10; |                 m_txbuffer[8] = 0x10; | ||||||
|                 m_statemachine = STARTOPENDOOR_RELEASE; |                 m_statemachine = STARTOPENDOOR_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|             case STARTOPENDOOR_RELEASE: |             case STARTOPENDOOR_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x01; |                     m_txbuffer[7] = 0x01; | ||||||
|                     m_txbuffer[8] = 0x10; |                     m_txbuffer[8] = 0x10; | ||||||
| @@ -290,10 +309,10 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x02; |                 m_txbuffer[7] = 0x02; | ||||||
|                 m_txbuffer[8] = 0x20; |                 m_txbuffer[8] = 0x20; | ||||||
|                 m_statemachine = STARTCLOSEDOOR_RELEASE; |                 m_statemachine = STARTCLOSEDOOR_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|             case STARTCLOSEDOOR_RELEASE: |             case STARTCLOSEDOOR_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x01; |                     m_txbuffer[7] = 0x01; | ||||||
|                     m_txbuffer[8] = 0x20; |                     m_txbuffer[8] = 0x20; | ||||||
| @@ -306,10 +325,10 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x02; |                 m_txbuffer[7] = 0x02; | ||||||
|                 m_txbuffer[8] = 0x40; |                 m_txbuffer[8] = 0x40; | ||||||
|                 m_statemachine = STARTSTOPDOOR_RELEASE; |                 m_statemachine = STARTSTOPDOOR_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|             case STARTSTOPDOOR_RELEASE: |             case STARTSTOPDOOR_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x01; |                     m_txbuffer[7] = 0x01; | ||||||
|                     m_txbuffer[8] = 0x40; |                     m_txbuffer[8] = 0x40; | ||||||
| @@ -322,10 +341,10 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x02; |                 m_txbuffer[7] = 0x02; | ||||||
|                 m_txbuffer[9] = 0x40; |                 m_txbuffer[9] = 0x40; | ||||||
|                 m_statemachine = STARTVENTPOSITION_RELEASE; |                 m_statemachine = STARTVENTPOSITION_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|             case STARTVENTPOSITION_RELEASE: |             case STARTVENTPOSITION_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x01; |                     m_txbuffer[7] = 0x01; | ||||||
|                     m_txbuffer[9] = 0x40; |                     m_txbuffer[9] = 0x40; | ||||||
| @@ -338,11 +357,11 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x02; |                 m_txbuffer[7] = 0x02; | ||||||
|                 m_txbuffer[9] = 0x04; |                 m_txbuffer[9] = 0x04; | ||||||
|                 m_statemachine = STARTOPENDOORHALF_RELEASE; |                 m_statemachine = STARTOPENDOORHALF_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             case STARTOPENDOORHALF_RELEASE: |             case STARTOPENDOORHALF_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x01; |                     m_txbuffer[7] = 0x01; | ||||||
|                     m_txbuffer[9] = 0x04; |                     m_txbuffer[9] = 0x04; | ||||||
| @@ -355,10 +374,10 @@ void HCIEmulator::processDeviceStatusFrame() | |||||||
|                 m_txbuffer[7] = 0x10; |                 m_txbuffer[7] = 0x10; | ||||||
|                 m_txbuffer[9] = 0x02; |                 m_txbuffer[9] = 0x02; | ||||||
|                 m_statemachine = STARTTOGGLELAMP_RELEASE; |                 m_statemachine = STARTTOGGLELAMP_RELEASE; | ||||||
|                 m_lastStateTime = millis(); |                 m_lastStateTime = esphome::millis(); | ||||||
|                 break; |                 break; | ||||||
|             case STARTTOGGLELAMP_RELEASE: |             case STARTTOGGLELAMP_RELEASE: | ||||||
|                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < millis()) |                 if (m_lastStateTime + SIMULATEKEYPRESSDELAYMS < esphome::millis()) | ||||||
|                 { |                 { | ||||||
|                     m_txbuffer[7] = 0x08; |                     m_txbuffer[7] = 0x08; | ||||||
|                     m_txbuffer[9] = 0x02; |                     m_txbuffer[9] = 0x02; | ||||||
| @@ -432,7 +451,7 @@ void HCIEmulator::openDoor() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTOPENDOOR; |     m_statemachine = STARTOPENDOOR; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -442,7 +461,7 @@ void HCIEmulator::openDoorHalf() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTOPENDOORHALF; |     m_statemachine = STARTOPENDOORHALF; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -452,7 +471,7 @@ void HCIEmulator::closeDoor() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTCLOSEDOOR; |     m_statemachine = STARTCLOSEDOOR; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -462,7 +481,7 @@ void HCIEmulator::stopDoor() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTSTOPDOOR; |     m_statemachine = STARTSTOPDOOR; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -472,7 +491,7 @@ void HCIEmulator::toggleLamp() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTTOGGLELAMP; |     m_statemachine = STARTTOGGLELAMP; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -482,7 +501,7 @@ void HCIEmulator::ventilationPosition() | |||||||
|     { |     { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     m_lastStateTime = millis(); |     m_lastStateTime = esphome::millis(); | ||||||
|     m_statemachine = STARTVENTPOSITION; |     m_statemachine = STARTVENTPOSITION; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,9 +1,13 @@ | |||||||
| #ifndef __hciemulator_h | #ifndef __hciemulator_h | ||||||
| #define __hciemulator_h | #define __hciemulator_h | ||||||
|  |  | ||||||
| #include <Arduino.h> | #ifdef USE_ESP_IDF | ||||||
| #include <Stream.h> |     //#include <cstdint> | ||||||
| #include <SoftwareSerial.h> |     //#include <functional> | ||||||
|  |     //#include <algorithm> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "esphome/components/uart/uart.h" | ||||||
|  |  | ||||||
| #define LL_OFF 0 | #define LL_OFF 0 | ||||||
| #define LL_ERROR 1 | #define LL_ERROR 1 | ||||||
| @@ -26,7 +30,9 @@ | |||||||
| // intercharacter must be 1.5T or 1.5 times longer than a normal character and thus | // intercharacter must be 1.5T or 1.5 times longer than a normal character and thus | ||||||
| // 1.5T = 1.04167ms * 1.5 = 1.5625ms. A frame delay is 3.5T. | // 1.5T = 1.04167ms * 1.5 = 1.5625ms. A frame delay is 3.5T. | ||||||
| #define T1_5 750 | #define T1_5 750 | ||||||
| #define T3_5 4800 // 1750 | #define T3_5 4800 //  | ||||||
|  |  | ||||||
|  | static const char *const TAG = "HCIEmulator"; | ||||||
|  |  | ||||||
| enum DoorState : uint8_t | enum DoorState : uint8_t | ||||||
| { | { | ||||||
| @@ -75,7 +81,7 @@ class HCIEmulator | |||||||
| public: | public: | ||||||
|     typedef std::function<void(const SHCIState &)> callback_function_t; |     typedef std::function<void(const SHCIState &)> callback_function_t; | ||||||
|  |  | ||||||
|     HCIEmulator(); |     HCIEmulator(esphome::InternalGPIOPin* pin, esphome::uart::UARTComponent* uart); | ||||||
|  |  | ||||||
|     void poll(); |     void poll(); | ||||||
|  |  | ||||||
| @@ -88,7 +94,7 @@ public: | |||||||
|  |  | ||||||
|     const SHCIState &getState() |     const SHCIState &getState() | ||||||
|     { |     { | ||||||
|         if (micros() - m_recvTime > 2000000) |         if (esphome::micros() - m_recvTime > 2000000) | ||||||
|         { |         { | ||||||
|             // 2 sec without statusmessage |             // 2 sec without statusmessage | ||||||
|             m_state.valid = false; |             m_state.valid = false; | ||||||
| @@ -98,7 +104,7 @@ public: | |||||||
|  |  | ||||||
|     unsigned long getMessageAge() |     unsigned long getMessageAge() | ||||||
|     { |     { | ||||||
|         return micros() - m_recvTime; |         return esphome::micros() - m_recvTime; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int getLogLevel(); |     int getLogLevel(); | ||||||
| @@ -111,10 +117,16 @@ protected: | |||||||
|     void processDeviceStatusFrame(); |     void processDeviceStatusFrame(); | ||||||
|     void processDeviceBusScanFrame(); |     void processDeviceBusScanFrame(); | ||||||
|     void processBroadcastStatusFrame(); |     void processBroadcastStatusFrame(); | ||||||
|  |     //#ifdef USE_ESP_IDF | ||||||
|  |         uint16_t word(uint8_t high, uint8_t low); | ||||||
|  |     //#endif | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     callback_function_t m_statusCallback; |     callback_function_t m_statusCallback; | ||||||
|     Stream *m_port; |  | ||||||
|  |     esphome::InternalGPIOPin* m_pin; | ||||||
|  |     esphome::uart::UARTComponent* m_port; | ||||||
|  |  | ||||||
|     SHCIState m_state; |     SHCIState m_state; | ||||||
|     StateMachine m_statemachine; |     StateMachine m_statemachine; | ||||||
|  |  | ||||||
| @@ -125,10 +137,10 @@ private: | |||||||
|     size_t m_rxlen; |     size_t m_rxlen; | ||||||
|     size_t m_txlen; |     size_t m_txlen; | ||||||
|  |  | ||||||
|     unsigned char m_rxbuffer[255] = { |     uint8_t m_rxbuffer[255] = { | ||||||
|         0, |         0, | ||||||
|     }; |     }; | ||||||
|     unsigned char m_txbuffer[255] = { |     uint8_t m_txbuffer[255] = { | ||||||
|         0, |         0, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										89
									
								
								external_components/hoermann_door/hoermann.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								external_components/hoermann_door/hoermann.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <algorithm> | ||||||
|  |  | ||||||
|  | class HoermannMainComponent; | ||||||
|  | #include "hciemulator.h" | ||||||
|  | #include "esphome/components/uart/uart.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace hoermann_door { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "Hoermann"; | ||||||
|  |  | ||||||
|  | void dispatcherFn(void *arg); | ||||||
|  |  | ||||||
|  | class HoermannMainComponent: public Component{ | ||||||
|  |   protected: | ||||||
|  |     HCIEmulator* emulator; | ||||||
|  |     TaskHandle_t modBusTask; | ||||||
|  |  | ||||||
|  |     uart::UARTComponent* _uart; | ||||||
|  |     InternalGPIOPin* _tx_on; | ||||||
|  |  | ||||||
|  |     volatile bool set_continue_ = true; | ||||||
|  |     volatile unsigned long lastCall = 0; | ||||||
|  |     volatile unsigned long maxPeriod = 0; | ||||||
|  |  | ||||||
|  |   public: | ||||||
|  |  | ||||||
|  |     void set_seriel_connection(uart::UARTComponent* uart){ | ||||||
|  |       this->_uart = uart; | ||||||
|  |     } | ||||||
|  |     void set_tx_on_pin(InternalGPIOPin* pin){ | ||||||
|  |       this->_tx_on = pin; | ||||||
|  |     } | ||||||
|  |     HCIEmulator* getEmulator(){ | ||||||
|  |       return emulator; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     void setup() override { | ||||||
|  |        | ||||||
|  |       this->_tx_on->setup(); | ||||||
|  |       this->emulator = new HCIEmulator(this->_tx_on, this->_uart); | ||||||
|  |  | ||||||
|  |       this->_tx_on->digital_write(false); | ||||||
|  |       this->set_continue_ = true; | ||||||
|  |       xTaskCreatePinnedToCore( | ||||||
|  |         dispatcherFn, // Function to implement the task | ||||||
|  |         "ModBusTask",   // Name of the task | ||||||
|  |         10000,          // Stack size in words | ||||||
|  |         this,           // Task input parameter | ||||||
|  |         // 1,           // Priority of the task | ||||||
|  |         configMAX_PRIORITIES - 1, | ||||||
|  |         &modBusTask,    // Task handle. | ||||||
|  |         1               // Core where the task should run | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     void modBusPolling(void *parameter) | ||||||
|  |     { | ||||||
|  |       while (set_continue_) | ||||||
|  |       { | ||||||
|  |         if (lastCall > 0) | ||||||
|  |         { | ||||||
|  |           maxPeriod = std::max((micros() - lastCall), (unsigned long)maxPeriod); | ||||||
|  |         } | ||||||
|  |         lastCall = micros(); | ||||||
|  |         emulator->poll(); | ||||||
|  |         vTaskDelay(1); | ||||||
|  |       } | ||||||
|  |       vTaskDelete(NULL); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void dump_config() override { | ||||||
|  |       ESP_LOGCONFIG(TAG, "hoermann_door_component:"); | ||||||
|  |       ESP_LOGCONFIG(TAG, "  UART: %d", this->_uart->get_baud_rate()); | ||||||
|  |       //LOG_PIN(TAG, this->_tx_on); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void dispatcherFn(void *arg) | ||||||
|  | { | ||||||
|  |   HoermannMainComponent *x = (HoermannMainComponent *)arg; | ||||||
|  |   x->modBusPolling(arg); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
|  | } | ||||||
| @@ -2,10 +2,11 @@ | |||||||
|  |  | ||||||
| #ifdef USE_LIGHT | #ifdef USE_LIGHT | ||||||
|  |  | ||||||
|  | class NbsLightManager; | ||||||
|  |  | ||||||
| #include "esphome.h" | #include "esphome.h" | ||||||
| #include "Arduino.h" |  | ||||||
| #include "hciemulator.h" | #include "hciemulator.h" | ||||||
| #include "door_singleton.h" | #include "hoermann.h" | ||||||
| //#include "cover.h" | //#include "cover.h" | ||||||
|  |  | ||||||
| #define RS485 Serial2 | #define RS485 Serial2 | ||||||
| @@ -20,13 +21,14 @@ namespace hoermann_door { | |||||||
| // Custom binary output, for exposing binary states | // Custom binary output, for exposing binary states | ||||||
| class NbsLightManager: public binary::BinaryLightOutput, public light::LightState { | class NbsLightManager: public binary::BinaryLightOutput, public light::LightState { | ||||||
|   protected: |   protected: | ||||||
|     HoermannSingleton *single; |  | ||||||
|   public: |   public: | ||||||
|     void setup() override { |     void setup() override { | ||||||
|       //single = HoermannSingleton::getInstance(); |       //single = HoermannSingleton::getInstance(); | ||||||
|       //single->initializeGetInstance |       //single->initializeGetInstance | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|     bool lastState = false; |     bool lastState = false; | ||||||
|     bool firstState = false; |     bool firstState = false; | ||||||
|     void loop() override { |     void loop() override { | ||||||
| @@ -45,15 +47,15 @@ class NbsLightManager: public binary::BinaryLightOutput, public light::LightStat | |||||||
| class NbsLightOutput: public output::BinaryOutput, public Component{ | class NbsLightOutput: public output::BinaryOutput, public Component{ | ||||||
|  |  | ||||||
|   light::LightState *callback; |   light::LightState *callback; | ||||||
|   HoermannSingleton *single; |  | ||||||
|   bool lastState = false; |   bool lastState = false; | ||||||
|   bool firstState = true; |   bool firstState = true; | ||||||
|  |   HoermannMainComponent *mainComponent; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|  |  | ||||||
|     virtual void write_state(bool state){ |     virtual void write_state(bool state){ | ||||||
|       if(lastState != state){ |       if(lastState != state){ | ||||||
|         single->getEmulator()->toggleLamp(); |         mainComponent->getEmulator()->toggleLamp(); | ||||||
|         //lastState = state; |         //lastState = state; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -62,21 +64,24 @@ class NbsLightOutput: public output::BinaryOutput, public Component{ | |||||||
|       if(callback == nullptr) ESP_LOGW("Hoermann_door(Light)", "Got Nullable callback"); |       if(callback == nullptr) ESP_LOGW("Hoermann_door(Light)", "Got Nullable callback"); | ||||||
|       this->callback = callback; |       this->callback = callback; | ||||||
|     } |     } | ||||||
|  |     void set_emulator_component(HoermannMainComponent* component){ | ||||||
|  |       this->mainComponent = component; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void loop() override { |     void loop() override { | ||||||
|       if(!single->getEmulator()->getState().valid) false; |       if(!mainComponent->getEmulator()->getState().valid) false; | ||||||
|       if(firstState || single->getEmulator()->getState().lampOn != lastState){ |       if(firstState || mainComponent->getEmulator()->getState().lampOn != lastState){ | ||||||
|       //ESP_LOGD("Test", "I have no idea"); |       //ESP_LOGD("Test", "I have no idea"); | ||||||
|         lastState = single->getEmulator()->getState().lampOn; |         lastState = mainComponent->getEmulator()->getState().lampOn; | ||||||
|         if(lastState == true){ |         if(lastState == true){ | ||||||
|           ESP_LOGD("Hoermann_door(Light)", "Light State ON"); |           ESP_LOGD(TAG, "Hoermann_door(Light)", "Light State ON"); | ||||||
|  |  | ||||||
|           auto call = callback->make_call(); |           auto call = callback->make_call(); | ||||||
|           call.set_state(true); |           call.set_state(true); | ||||||
|           call.perform(); |           call.perform(); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           ESP_LOGD("Hoermann_door(Light)", "Light State OFF"); |           ESP_LOGD(TAG, "Hoermann_door(Light)", "Light State OFF"); | ||||||
|           auto call = callback->make_call(); |           auto call = callback->make_call(); | ||||||
|           call.set_state(false); |           call.set_state(false); | ||||||
|           call.perform(); |           call.perform(); | ||||||
| @@ -87,8 +92,7 @@ class NbsLightOutput: public output::BinaryOutput, public Component{ | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void setup() override { |     void setup() override { | ||||||
|       single = HoermannSingleton::getInstance(); |  | ||||||
|       single->initializeEmulator(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void turn_on() override { |     void turn_on() override { | ||||||
|   | |||||||
| @@ -2,23 +2,29 @@ import esphome.codegen as cg | |||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.components import output, light | from esphome.components import output, light | ||||||
| from esphome.const import CONF_ID | from esphome.const import CONF_ID | ||||||
|  | from . import HoermannDoor | ||||||
|  |  | ||||||
| hoermann_cover_ns = cg.esphome_ns.namespace('hoermann_door') | hoermann_cover_ns = cg.esphome_ns.namespace('hoermann_door') | ||||||
| HoermannCoverLight = hoermann_cover_ns.class_('NbsLightOutput', output.BinaryOutput, cg.Component) | HoermannCoverLight = hoermann_cover_ns.class_('NbsLightOutput', output.BinaryOutput, cg.Component) | ||||||
| CONF_STATE_CALLBACK = "state_callback" | CONF_STATE_CALLBACK = "state_callback" | ||||||
|  | CONF_HOERMANN_CONTROLLER = "hoermann_controller" | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend({ | CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend({ | ||||||
|     cv.GenerateID(CONF_ID): cv.declare_id(HoermannCoverLight), |     cv.GenerateID(CONF_ID): cv.declare_id(HoermannCoverLight), | ||||||
|     cv.Required(CONF_STATE_CALLBACK): cv.use_id(light.LightState) |     cv.Required(CONF_STATE_CALLBACK): cv.use_id(light.LightState), | ||||||
|  |     cv.Required(CONF_HOERMANN_CONTROLLER): cv.use_id(HoermannDoor) | ||||||
| }).extend(cv.COMPONENT_SCHEMA) | }).extend(cv.COMPONENT_SCHEMA) | ||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | async def to_code(config): | ||||||
|     var = cg.new_Pvariable(config[CONF_ID]) |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|     yield cg.register_component(var, config) |     await cg.register_component(var, config) | ||||||
|     yield output.register_output(var, config) |     await output.register_output(var, config) | ||||||
|      |      | ||||||
|     callback = yield cg.get_variable(config[CONF_STATE_CALLBACK]) |     callback = await cg.get_variable(config[CONF_STATE_CALLBACK]) | ||||||
|     cg.add(var.set_state_callback(callback)) |     cg.add(var.set_state_callback(callback)) | ||||||
|  |      | ||||||
|  |     controller = await cg.get_variable(config[CONF_HOERMANN_CONTROLLER]) | ||||||
|  |     cg.add(var.set_emulator_component(controller)) | ||||||
|  |  | ||||||
| cg.add_library("plerup/EspSoftwareSerial", "8.2.0") | # cg.add_library("plerup/EspSoftwareSerial", "8.2.0") | ||||||
							
								
								
									
										29
									
								
								garage1.yaml
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								garage1.yaml
									
									
									
									
									
								
							| @@ -3,8 +3,11 @@ substitutions: | |||||||
|  |  | ||||||
| esphome: | esphome: | ||||||
|   name: garage${garageSide} |   name: garage${garageSide} | ||||||
|   platform: ESP32 |  | ||||||
|   board: esp32dev | esp32: | ||||||
|  |   board: wemos_d1_mini32 | ||||||
|  |   framework: | ||||||
|  |     type: esp-idf | ||||||
|  |  | ||||||
| ota: | ota: | ||||||
|   - platform: esphome |   - platform: esphome | ||||||
| @@ -29,8 +32,24 @@ external_components: | |||||||
|     components: [ hoermann_door ] |     components: [ hoermann_door ] | ||||||
|  |  | ||||||
| cover: | cover: | ||||||
|   - platform: hoermann_door |  - platform: hoermann_door | ||||||
|     name: door_${garageSide} |    name: door_${garageSide} | ||||||
|  |    hoermann_controller: door_controll_internal | ||||||
|  |  | ||||||
|  | uart: | ||||||
|  |   rx_pin: 16 | ||||||
|  |   tx_pin: 17 | ||||||
|  |   baud_rate: 57600 | ||||||
|  |   id: hm_connection | ||||||
|  |   data_bits: 8 # Standard | ||||||
|  |   parity: EVEN # NON Standard, None would be standard | ||||||
|  |   stop_bits: 1 # Standard | ||||||
|  |  | ||||||
|  |  | ||||||
|  | hoermann_door: | ||||||
|  |   id: door_controll_internal | ||||||
|  |   uart_connection: hm_connection | ||||||
|  |   tx_pin: 25 | ||||||
|  |  | ||||||
| light: | light: | ||||||
|   - platform: binary |   - platform: binary | ||||||
| @@ -42,5 +61,7 @@ output: | |||||||
|   - id: light_out |   - id: light_out | ||||||
|     platform: hoermann_door |     platform: hoermann_door | ||||||
|     state_callback: lamp_id_${garageSide} |     state_callback: lamp_id_${garageSide} | ||||||
|  |     hoermann_controller: door_controll_internal | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    | ||||||
		Reference in New Issue
	
	Block a user