你好,
我用家里助理一个操场19463331伟德国际至少两年了,因为它是优秀的文档和实现成千上万的设备,我决定用它生产在我们新装修的家。www.19463331.com
目前我想集成一些“haus-bus.de“开关(6 fach Multitaster代表)到我的设置和变得疯狂。这不是造成的设备或家庭助理,我目前感觉主演的一堵墙和无法发现这扇门!19463331伟德国际

我要描述我的设置的相关部分(和承诺对我的整个设置创建一个详细的博文的时候竞选文档如果有人感兴趣):www.19463331.com

  • 我上面提到的交换机使用RS485接口
  • 我有个ESP8266 MAX485板(NodeMCU)运行
  • 出于测试目的,我有一个RS485 u盘连接到一个全面的电脑
  • 这三个设备(ESP、开关、u盘)物理连接和使用正确的序列(和控制字符)设置,我通常可以传输和接收数据使用Arudino IDE如它们之间。

我努力当我想使用ESPhome跟开关,也许任何人都可以帮我在这一点上。

据我understod定制UART文本传感器,它是等待CR / LF行结束解释正确的数据,对吧?

交换机发送十六进制值在0 xfd数据集的开始,以0 xfe结束字符。取决于行动之间的东西(例如按钮一按,导致2点亮等)或传感器读数(亮度、湿度或温度)的开关。

一个例子:

切换通知有关当前相对湿度在% (30)
fd 31 33 39 35 2 e 52 48 44 31 2 e 2 e 53 54 41 54 55 53 2 e 33 30铁
.1395.RHD.1.STATUS.30

我现在不知道如何

  • 阅读来自MAX485 UART接口和输入
  • 找到相关的值(0 xfd和以0 xfe)
    在ESPHome。

通过USB-to-RS485-Stick与手动输入字符串发送电脑的终端与CR / LF结束,一切工作正常。

我想我也可以把东西尽快回家助理我可以检测这些东西在论坛有很多例子。19463331伟德国际伟德国际官方app下载苹果版

请嘲笑我,叫我白痴或者只是摇头不信我的无能…但我无法运作,找不到任何我能够适应在google最近几天。

感谢这个不错的软件,请道歉痛我造成这个问题!

关于communction protocoll我会看着iobroker集成(https://github.com/hausbus/ioBroker.hausbusde/blob/85801718d2171ec8ae503433371fe3e4bfb54066/main.js)的命令,您可以发送到开关还可以使用模板Loxone发生器(http://www.haus-bus.de/loxone/templates.php)。

发送的命令应该使用:https://esphome.io/components/uart.html uart-write-action甚至更好的UART开关:https://esphome.io/components/switch/uart.html

传感器的值你可以试试自定义UART文本传感器,但我可能会编写一个定制的UART /传感器组件https://esphome.io/custom/uart.htmlhttps://esphome.io/components/text_sensor/uart.html

酷,谢谢你的提示,我知道Github回购,但没有特定的文件。一般来说,命令不是问题,我可以通过电脑控制开关已经(你提到的模板生成器使用),头痛伴随着ESPhome实现眨眼:

是的,我明白了,谢谢你的提示。但在发送命令从ESP开关之前,我想读数据。

我发现这些页面,什么我不明白:我怎么从UART读取数据?在传感器的UART文本,他们使用read ()(必须是Serial.read ()根据数据和arduino文档)publish_state(缓冲)将缓冲(文本存储)终端输出。在自定义UART设备文档更通用。www.19463331.com我不是最好的编程和c#看起来有点奇怪,尤其是当它涉及到的数据类型。与Serial.read ()Serial.ReadBytes ()我应该能够得到输入,但我怎么处理输入?只是改变线的结局\ nr \0 xfd以0 xfe在文本中传感器的头文件不会工作…我需要的是屁股上踢了一脚绊跌的解决方案无辜的:

好的,现在我第一次试图收集信息从开关Arduino IDE中的一个小程序。目前它是使用以下quick-n-dirty代码(改编自那个人在这里):

#定义DE D6 / / RS485方向控制#定义再保险D5 / / RS485方向控制2 # define RS485Transmit高# define RS485Receive低空隙setup () {pinMode(德、输出);pinMode(再保险、输出);系列。(57600年开始,SERIAL_8O1);延迟(100);}无效循环(){char RS485Eingabe [36];RS485Eingabe [1] = 0;而(RS485Eingabe [1] ! = 0 x03){/ /如果收到的消息有错误/ / MODBUS接待风速计的回答digitalWrite (DE RS485Receive);/ /初始化接收digitalWrite(再保险、RS485Receive);/ /初始化接收串行。readBytes(RS485Eingabe, 99); Serial.print("Antwort: "); for( byte i=0; i<36; i++ ) { if( RS485Eingabe[i] < 253 ) { Serial.print(RS485Eingabe[i]); } else if( RS485Eingabe[i] == 254 ) { break; } } Serial.println(); delay(500); } // end of while } // end of loop

下一步:我不得不在一个头文件转换为在ESPHome使用这些代码。但不是今晚,我的脑子烧坏了:sweat_smile:

我希望它是好的,我用这个线程写下我的发现…也许将来会帮助别人类似的问题。
经过短暂的夜晚,我又开始运行的东西。我仍然有点在ESPHome失去了关于lambda函数,我开始重新定义代码Arduino IDE和希望能够适应ESPHome之后。
这是我目前的代码删除所有不必要的东西(ESP8266):

#定义DE D6 / / RS485方向控制(低当接待)# define再保险D5 / / RS485方向控制2(低当接待)# define RS485Transmit高# define RS485Receive低空隙setup () {pinMode(德、输出);pinMode(再保险、输出);系列。(57600年开始,SERIAL_8O1);延迟(100);}无效循环(){char RS485Eingabe [36] = {};/ /下降的char数组专用的长度(长度tbd) digitalWrite (DE RS485Receive);/ /初始化接收MAX485 digitalWrite(再保险、RS485Receive);/ /初始化接收MAX485系列。以readBytesUntil (0 xfe RS485Eingabe, 99); // read from UART until you find character 0xFE, if you don't find 0xFE, stop after 99 bytes if( RS485Eingabe[0] == 0xFD ) { // only do something when the recieved stuff begins with 0xFD Serial.print("Antwort: "); // tbd for( byte i=1; i<36; i++ ) { // start with second character (first is always 0xFD), iterate over all characters in array Serial.print(RS485Eingabe[i]); // gimme that shit on screen } // end of for Serial.println(); // daddy needs a new line } // end of if } // end of loop

我的发现:系列。ReadBytesUntil(性格、缓冲区长度)是一个非常有用的功能,可以检测到一个自定义结束字符(这是什么以0 xfe在我的例子中)来读取UART直到这个角色。一个好处相比Serial.ReadByte ()是,我不要错过任何RS485消息,如:当按下两个按钮开关在同一时间或当一个传感器发送其当前值,同时按下一个按钮。
所以目前我阅读从UART系列。readBytesUntil (0 xfd, RS485Eingabe, 99);在哪里长度参数是目前只是一个愚蠢的错误处理方式在未来,必须进行相应的调整。
在这个阶段中,代码工作很好,我可以从开关检测每条消息打印到终端的纯文本。
下一步:港口ESPHome:sweat_smile:
随意评论我的文章的每一位我没有编程技能眨眼:

好的,我更进一步,能够将我的代码迁移到一个ESP32转换成ESPHome头文件使用。我创建的头文件haus-bus-test.h:

# include“esphome。h”# include <字符串> / / # include”传感器。使用名称空间std h”;类HausbusRead:公共PollingComponent UARTDevice{公众:HausbusRead (UARTComponent *父母):PollingComponent (1000), UARTDevice(父){}传感器* LichtschalterTest =新的传感器();无效的设置()覆盖{/ /这里无关}无效更新()覆盖{char RS485Eingabe [36] = {};以readBytesUntil (0 xfe RS485Eingabe, 99);如果(RS485Eingabe [0] = = 0 xfd) {LichtschalterTest - > publish_state (RS485Eingabe [2]);/ /用于测试仅仅发布第二字符}}};

ESPHome YAML:

esphome:包括:- haus-bus-test。h名称:hausbus平台:ESP32板:esp-wrover-kit wifi:名称:“白痴”密码:“verySecure”manual_ip: static_ip: ip网关:gw子网:子网#启用后备热点(俘虏门户),以防wifi连接失败美联社:名称:“hausbus后备热点”密码:“veryUnsecure”captive_portal: #启用日志记录器:水平:详细baud_rate: 0 #使家庭助理API API:密码:“api-pw”ota:密码:“ota-pw”uart: tx_pin: TX rx_pin: RX baud_rate: 57600平价:奇怪的id: HausbusUART输出:-平台:gpio销:18 id: gpio_18 -平台:gpio销:19 id: gpio_19间隔:-19463331伟德国际间隔:3秒然后:输出。turn_on: gpio_18 -输出。turn_on: gpio_19 - uart。写:“ESP仍然存在”——输出。turn_off: gpio_18 -输出。turn_off: gpio_19传感器:平台:自定义λ:| -汽车my_hausbus = new HausbusRead (id (HausbusUART));App.register_component (my_hausbus);返回{my_hausbus - > LichtschalterTest};传感器:名字:“Hausbus Multitaster ESP32”

通过集成页面手动添加ESPHome集成之后,设备创建和实体是开关上的一个按钮被按下后发现。源自英国始于1946
在当前阶段,到目前为止,我只有两个问题:有一个错误和警告多次在ESP日志:

[22:09:00][E] [uart_esp32:147]:阅读从字节0 UART超时![22:09:00][V][应用程序:081]:一个组件在一个循环中花了很长时间()循环(1.00秒)。[22:09:00][V][应用程序:082]:组件应该最多20-30ms的块循环()。[22:09:01][E] [uart_esp32:147]:阅读从字节0 UART超时![22:09:01][V][应用程序:081]:一个组件在一个循环中花了很长时间()循环(1.01秒)。[22:09:01][V][应用程序:082]:组件应该最多20-30ms的块循环()。[22:09:02][E] [uart_esp32:147]:阅读从字节0 UART超时![22:09:02][V][应用程序:081]:一个组件在一个循环中花了很长时间()循环(1.00秒)。[22:09:02][V][应用程序:082]:组件应该最多20-30ms的块循环()……

在阅读线程,我认为这与旧ESP8266我使用这里并切换到一个ESP32董事会,但这个问题似乎是硬件不可知论者。
又迟到了,我明天会到…

这是一个阻塞的函数,不应该在这样的环境下使用。

你必须检查如果有可用的字节,读取所有可用的字节数和处理它们。如果您收到的数据并不完整,记住的实际状态,并继续下一个循环周期。

也许这将帮助:https://github.com/esphome/esphome/blob/5e239d3d882aa2b6d2d8556b7c08ea54f238c91a/esphome/components/teleinfo/teleinfo.cpp

我也有过类似usecase与我站在桌子上在这里,你可以找到我的头文件:
LoctekMotion_IoT / desk_height_sensor。在主要·h iMicknl / LoctekMotion_IoT (github.com)

请注意,这段代码可以清洁,但我走过这六角十六进制笑脸:

我只是来这里帮助你。(昨天没有时间回答,有一个电子邮件通知,你回答我的帖子)。

但是:我真的很惊讶你已经走了多远。不错的工作。但是我不相信你没有progrmaming技能。

关于你的循环问题:@EnRav是正确的。循环()方法并不是“允许”块,恢复很快。没有真正的多任务处理像你知道它在你的电脑。ESPHome将所谓的“循环”的每个组件一个接一个,然后等待几个女士(让ESP做事像WLAN)和循环再次呼吁所有组件。如果你的组件块循环一切被阻塞。

(同样适用于Arduino的循环()方法。但它在ESPHome甚至更糟,因为它有很多组件交互)。

非常感谢你,我真的很感激你的帮助,当你向我正确的方向!我有同样的问题最后几天(没有时间玩ESP)。

再次感谢,我很惊讶,但是没有选择:开关安装和电缆外径,所以这个必须工作,激励我前进。

你尊重我的谷歌,也许一些逆向工程技能,我自己没有类型的代码行:sweat_smile:

现在,我得到了这一点。我将试着帮助设计一个更好的解决方案@EnRav@imick,谢谢你们!:partying_face:

也许你可以帮我和你的ESP技能在另一个主题:在第一个概念我喜欢外包等“情报”ESP处理组件的标识(这是厨房的开关说话)和更新实体(助理19463331伟德国际开关厨房:临时21°C,按钮1按下和释放),这确实是静态的,厨房的ID开关不会改变,直到它坏了,更换,要么将厨房开关不会突然改变居室开关没有灾难影响到我家的物理学。与你的输入,你认为这可能会为一个小ESP32多吗?我一共有26 rs485总线设备连接到它可能会有点拥挤的公车上我认为。据我了解,有一些相关的开销ESPHome东西和可用的代码执行时间仅限于几毫秒,对吧?
目前我正在考虑一个简单的RS485-to-MQTT或RS485-to-Hass-API网关,所有的逻辑是强大的家庭助理硬件上完成的。19463331伟德国际

好吧,是时候喂孩子,狗,我的妻子,鸟儿,海豚…只是文档我目前的进展——一如既往:随意评论,告诉我为什么我的代码看起来怪异或奇怪www.19463331.com:slight_smile:

我采用了LoctekMotion-Code@imick(再次:非常感谢:partying_face:!),有点超过最后一次搜索,导致一个工作原型。
ESPHome现在的头文件:

# include“esphome。h”# include <字符串> / / # include”传感器。使用名称空间std h”;类HausbusRead:公共PollingComponent UARTDevice{公众:HausbusRead (UARTComponent *父母):PollingComponent (1000), UARTDevice(父){}TextSensor * LichtschalterTest = new TextSensor ();char RS485Eingabe [36] = {};int msg_len = 0;std:: string Ausgabe = " ";无效的设置()覆盖{/ /这里无关}无效更新()覆盖{虽然(可用()> 0){字节incomingByte =阅读();/ /得到最后一个字节从UART开关(incomingByte) / /最后还是第一个字节?{0 xfd: / /每条消息从0 xfd开始,这意味着在这里开始一个新消息msg_len = 0;RS485Eingabe [msg_len] = incomingByte; // add the last byte to the array break; case 0xFE: // every message ends with 0xFE, this means the message ends here for (int i = 1; i <=msg_len; i++) // create a string from the array for the HAss Sensor { Ausgabe = Ausgabe + RS485Eingabe[i]; } LichtschalterTest->publish_state(Ausgabe); // push the string to the sensor Ausgabe = ""; // Reset the string break; default: msg_len = msg_len + 1; // in case it is not the beginning oder the end of the message RS485Eingabe[msg_len] = incomingByte; // add the last byte to the array if (msg_len == 36) { msg_len = 0; // stupidest way of error handling so far } break; } } } };

我终于发现TextSensor是什么:nerd_face:,所以在我hausbus传感器部分。yml略为:

text_sensor:平台:定制λ:| -汽车my_hausbus = new HausbusRead (id (HausbusUART));App.register_component (my_hausbus);返回{my_hausbus - > LichtschalterTest};text_sensors:名字:“Hausbus Multitaster ESP32”

跑步,我取得了里程碑似的进展:消息从hausbus-devices finalyy哈斯,ESPHome日志中可以看到:

[17:37:17][D] [text_sensor: 015]:“Hausbus Multitaster ESP32”:发送状态“1395. brs.23.status.5”

现在我必须决定如果我想过程本文HAss传感器或如果我想更新不同实体从一个更高级的lambda函数/头文件。

1像

一般来说,应该没有问题ESP32如果这些设备设备不太忙了。ESP32本身是相当快的。但是我没有经历与RS485。

恭喜获得工作。我认为这是好的。而软件开发是我的工作与所有要求的测试,代码检查、文档等等我很喜欢在这样的sma工作。www.19463331.com基于l ESP项目水准的主要指标是“如果其作品和我的理解是足够好”。

但有一个小错误(也许更多):在默认情况下添加msg_len(你可以写成msg_len + +;),然后写入数组中的位置。问题:你会写即使是36但你数组只是从0到35。所以你需要移动如果= = 36写入数组或改变之前检查35。

你知道你使用ESP_LOGD输出调试消息?

像这样:

ESP_LOGE (“Hausbus”、“消息超过36个字符”);/ / E错误ESP_LOGD (“Hausbus”,得到了新的消息:% s, Ausgabe.c_str ());/ / D调试

我会做这种类型的处理ESPHome节点和发送更多的现实世界中表现哈。就像一个开关或温度读数等等。

顺便说一句:现在你是ESPHome运行眨眼:)你可以快速锁定MySensors。它类似于ESPHome(没有yaml),但更多的关注RS485和HA的集成。但是:我从来没有使用RS485。

一个简短的更新与一些非常小的进展到目前为止(主要是为我的文档www.19463331.com:sweat_smile:)。

谢谢你再一次@danielw,这是一个很好的提示,我认为一个典型的初学者的错误眨眼:

谢谢你的提示,我将来一定会使用这个代码!

我还没有决定在哪里管理的处理不同的设备(又名:ESP只有RS485-to-HA-API-Gateway还是会做更多)。利弊目前:我更擅长HAss yaml结构然后c++代码,但这样做在ESP似乎是一个更优雅的解决方案。我想确定这后,我有点进一步向ESP发送命令。
昨晚我迁移后的代码从一个通用的ESP32董事会WT32-ETH01,带有一个集成以太网端口但没有一个usb端口。我很多闪光的东西通过UART别针和一个外部USB-to-Serial适配器,现在运行了一些调整。由于Ethernet-Chip,只有少数GPIOs左和制造商的文档有点不清楚目的的别针,所以它是一种尝试和错误但最终我找到了工作。www.19463331.com
供您参考(当然和我)是当前引出线概述这适合我(我怎么粘贴ASCII艺术? ?)


我决定不使用两个UART接口并使用串行连接销IO33/32。文档,他们用485 _en标记和CFG但我没有发现信息意味着什么,也许ESP32能够RS485默认吗?当我使用MAX485董事会,我只是需要一些针串行通信,不关心标签。UART接口的问题,这个委员会总是喊一些终端输出UART,即使你配置日志记录器baud_rate: 0。还有一些其他的好奇心与这个板,如只有较低的EN销(销4左侧)适合我而通过连续闪烁,上层(销1左)不起作用。和闪烁,只有可能是通过RX0 / TX0别针。

使用此设置,我现在yaml是:

esphome:包括:- hausbus-efficient。h名称:hausbuswrite平台:ESP32板:esp-wrover-kit wifi:名称:"密码:“manual_ip: static_ip:网关:子网:#启用后备热点(俘虏门户),以防wifi连接失败美联社:名称:“回退热点”密码:“captive_portal: #启用日志记录器:水平:详细baud_rate: 0 #使家庭助理API API:密码:“在线旅行社:密码:“uart: tx_pin: GPIO32 rx_pin: GPIO33 baud_rate: 57600平价:奇怪的id: HausbusUART输出:-平台:gpio销:GPIO12 id: DE -平台:gpio销:GPIO14 id:再保险间隔:19463331伟德国际-间隔:3秒然后:输出。turn_on: DE -输出。turn_on: RE - uart。写:“ESP是带da”text_sensor: -平台:自定义λ:| -汽车my_hausbus = new HausbusRead (id (HausbusUART));App.register_component (my_hausbus);返回{my_hausbus - > LichtschalterTest};text_sensors:名字:“Hausbus Multitaster ESP32”

和我开德和别针在c++代码,所以头文件更改为:

# include“esphome。h”# include <字符串> / / # include”传感器。使用名称空间std h”;类HausbusRead:公共PollingComponent UARTDevice{公众:HausbusRead (UARTComponent *父母):PollingComponent (1000), UARTDevice(父){}TextSensor * LichtschalterTest = new TextSensor ();char RS485Eingabe [36] = {};int msg_len = 0;std:: string Ausgabe = " ";无效的设置()覆盖{pinMode(12、输出);pinMode(14、输出);/ /这里无关}无效更新()覆盖{虽然(可用()> 0){digitalWrite(12、低);digitalWrite(14、低);字节incomingByte =阅读(); // get last byte from UART switch (incomingByte) // is it the last or the first Byte? { case 0xFD: // every message starts with 0xFD, this means here starts a new message msg_len = 0; RS485Eingabe[msg_len] = incomingByte; // add the last byte to the array break; case 0xFE: // every message ends with 0xFE, this means the message ends here for (int i = 1; i <=msg_len; i++) // create a string from the array for the HAss Sensor { Ausgabe = Ausgabe + RS485Eingabe[i]; } LichtschalterTest->publish_state(Ausgabe); // push the string to the sensor Ausgabe = ""; // Reset the string break; default: msg_len = msg_len + 1; // in case it is not the beginning oder the end of the message RS485Eingabe[msg_len] = incomingByte; // add the last byte to the array if (msg_len == 35) { msg_len = 0; // stupidest way of error handling so far } break; } } } };

目前我面临一个问题,董事会可以防止董事会的权力循环工作。当我拔掉MAX485董事会的权力针(3 v3和接地),我可以开始董事会和接续马克斯董事会将比准确无误地工作。我认为这是一个电源的问题将得到解决,当我可以安装板在最后的地方。此外,我下令一些MAX3485董事会,他们将需要3 3 v输入而MAX485正式需要5 v,不匹配的TTL ESP的水平。这就是为什么我使用MAX485 3 v3迄今为止。
下一步将是获得可靠连接的以太网接口运行(我使用电灯开关的连接,他们必须工作在每个按键响应而不必等待Wifi)和管理/闪光董事会局域网。

好吧,这很容易!董事会成功运行了以太网和改变了MAX485 MAX3485板板。我有点好奇,MAX3485董事会没有德/ RE的引出线,但随着一些更好的眼镜我发现,他们已经成型,以便发送和接收通道并行总是打开。这可能有助于检测碰撞在公共汽车上,我希望我以后会记住!
编辑:重启问题不再出现在使用MAX3485董事会。:white_check_mark:

我改变了标题更加匹配我基本上解决了初始任务ESPHome UART的十六进制数据。现在,更多的是对消息的处理从这些haus-bus设备,不再是一个十六进制数据的问题。

我很幸运与MAX3485 WT32-ETH01,目前正在稳定供生产使用。

现在我决定如何处理所有的总线上的消息。我有一些用于c++代码,并将尝试这种方式。首先,我将专注于haus-bus Multitaster,稍后我将实现I / O模块。
我现在的想法是创建一个每个Multitaster ESPHome传感器为每个传感器的头文件。这将导致大量的传感器为一个ESP32板(3传感器/ * 22 = 66传感器和设备)。或有容易的解决方案吗?
我宁愿定义传感器在HA template-sensors并简单地通过ESPHome更新它们,但是我可以更新一个传感器在HA lambda函数从没有在头文件中定义这个传感器ESPHome ?
如果是,我怎么定义value_templatetemplate-sensor,它使用ESPHome传感器回来了吗?

与c++代码漫长的一天后,我最终与非工作的解决方案。我调整的主要代码,替代德国变量和相应的英语的分离到他们的子字符串的消息。
我试图通过传感器数据与一个if语句,但挣扎。这是我目前的进展和一些描述如果有人能指出我错过了(@danielw吗?无辜的:)。

# include“esphome。h”# include <字符串> / / # include”传感器。使用名称空间std h”;类HausbusRead:公共PollingComponent UARTDevice{公众:HausbusRead (UARTComponent *父母):PollingComponent (1000), UARTDevice(父){}TextSensor * LastHausBusMessage = new TextSensor () * LastHausBusID = new TextSensor () * LastHausBusSensorType = new TextSensor () * LastHausBusSensorID = new TextSensor () * LastHausBusSensorState = new TextSensor () * LastHausBusSensorValue = new TextSensor ();传感器* Hausbus_taster_1395_brightness =新的传感器();传感器* Hausbus_taster_1395_temperature =新的传感器();传感器* Hausbus_taster_1395_humidity =新的传感器();char RS485Message [36] = {};std:: string Message = " ", device_id = " ", sensor_type = " ", sensor_id = " ", sensor_state = " ", sensor_value = " ", outputsensor = " ";int msg_len = 0;int point_counter = 0; void setup() override { //pinMode(12, Message); // no longer necessary with RS3485 (only needed for DE/RE) //pinMode(14, Message); // no longer necessary with RS3485 (only needed for DE/RE) }//end of setup void update() override { while (available() > 0) { //digitalWrite(12, LOW); // no longer necessary with RS3485 (only needed for DE/RE) //digitalWrite(14, LOW); // no longer necessary with RS3485 (only needed for DE/RE) byte incomingByte = read(); // get last byte from UART switch (incomingByte) // is it the last or the first Byte? { case 0xFD: // every message starts with 0xFD, this means here starts a new message msg_len = 0; point_counter = 0; RS485Message[msg_len] = incomingByte; // add the incoming byte to the array break; case 0xFE: // every message ends with 0xFE, this means the message ends here for (int i = 1; i <=msg_len; i++) // create a string from the array for the HAss Sensor { Message = Message + RS485Message[i]; }//end of for outputsensor = "Hausbus_taster_" + device_id + "_"; if (sensor_type == "BRS") { outputsensor = outputsensor + "brightness"; } else if (sensor_type == "TMP") { outputsensor = outputsensor + "temperature"; } else if (sensor_type == "RHD") { outputsensor = outputsensor + "humidity"; } outputsensor->publish_state(sensor_value); LastHausBusMessage->publish_state(Message); // push the strings to the sensors (currently for debugging purposes only) LastHausBusID->publish_state(device_id); LastHausBusSensorType->publish_state(sensor_type); LastHausBusSensorID->publish_state(sensor_id); LastHausBusSensorState->publish_state(sensor_state); LastHausBusSensorValue->publish_state(sensor_value); Message = ""; // Reset the strings device_id = ""; sensor_type = ""; sensor_id = ""; sensor_state = ""; sensor_value = ""; outputsensor = ""; break; case '.': // Count the . chars to separate the substrings of the message point_counter++; // no break, we want to go to default after increasing the . counter default: // in case it is not the beginning oder the end of the message msg_len = msg_len + 1; RS485Message[msg_len] = incomingByte; // add the last byte to the array if (msg_len == 35) { msg_len = 0; // stupidest way of error handling so far Message = ""; }//end of if if(RS485Message[msg_len] != '.') // jump over the . chars, they are useless { switch (point_counter) { case 0: // 1st substring is the DeviceID device_id = device_id + RS485Message[msg_len]; break; case 1: // 2nd substring is the sensor type sensor_type = sensor_type + RS485Message[msg_len]; break; case 2: // 3rd substring is the sensor id sensor_id = sensor_id + RS485Message[msg_len]; break; case 3: // 4th substring is the sensor state sensor_state = sensor_state + RS485Message[msg_len]; break; case 4: // 5th substring is the sensor value sensor_value = sensor_value + RS485Message[msg_len]; break; }//end of switch }//end of if break; }//end of switch }//end of while }//end of update };//end of class

正如之前提到的,我想我必须定义所有Multitaster的所有传感器TextSensors传感器在c++代码(目前只有一个设备有三个传感器是在上面的代码中定义)。我意识到,每个开关都是一个传感器,所以每个Multitaster 9传感器定义,有22个设备,我最终在近220个变量,多数工作都是复制粘贴和excel魔法,它不是太难。一般比例是非常糟糕的,尽管它是静态的,因此接受的。

但是我有点失去了一部分,我想发布电流传感器的值

outputsensor = " Hausbus_taster_ " + device_id +“_”;如果(sensor_type = =“集团”){outputsensor = outputsensor +“亮度”;}else if (sensor_type = = TMP) {outputsensor = outputsensor +“温度”;}else if (sensor_type = = RHD) {outputsensor = outputsensor +“湿度”;}outputsensor - > publish_state (sensor_value);

在我看来这是一个非常优雅的解决方案,使用变量,只发布之前我从UART读什么——例如温度的值19日,5传感器的Hausbus_taster_1395_temperature
来完成,我想“创建”正确的传感器名称(即正确的变量名称发布)在运行时和——在那之后发布。我没有运气谷歌一下,如何将一个字符串值转换为被解释为一个变量的名字,也许我在寻找错误的搜索词,这叫一个程序员的语言怎么样?

另外上面的处理代码,我不确定如何处理yaml中代码的输出。目前我使用类似

传感器:平台:定制λ:| -汽车my_hausbus = new Hausbusread (id (HausbusUART));App.register_component (my_hausbus);返回{my_hausbus - > Hausbus_taster_1395_brightness, my_hausbus - > Hausbus_taster_1395_temperature, my_hausbus - > Hausbus_taster_1395_humidity};传感器:名字:“Hausbus_taster_1395_brightness”——名字:“Hausbus_taster_1395_temperature”——名字:“Hausbus_taster_1395_humidity”

得到的值在HA相应的传感器。但这尺度比在变量定义。我真的应该返回220值吗?重要,只有一个220的值,如Hausbus_taster_1395_temperature = 19日5,其他219个值仅仅是忽略了在这种情况下吗?

再次:请原谅我有时很愚蠢的问题,也许我应该投入更多的时间在google,但是很难,当你不知道正确的术语。我希望我的无知会帮助别人有一天同样的问题。

我不认为你可以这样做。也许你可以用MQTT HA一边做点什么。最后我认为66个传感器是最简单的事情。你可以做到相对干净代码如果你在代码中生成传感器。

我真的不明白你得到220个传感器?你有22 multitaster 9传感器设备和他们都有?

我们谈论ESP8266吗?你应该考虑切换到一个ESP32有更多的内存。

这是你不能做的事在c++中(或其他静态语言)。编译后的变量真的不存在了。我将称之为某种形式的元编程。你把这个程序在运行时。

但是:你的问题有一个解决方案。你应该看看std:: unordered_map。允许您存储一个对象在一个地图连同一个关键(例如一个字符串)和拿回对象使用的关键。

几个提示让你开始。

/ /你要添加一个包括顶部的文件# include < unordered_map > / /作为一个变量在类std:: unordered_map < std:: string,传感器* > sensor_map;/ /类的构造函数中(在{}的公共后第一行:)/ /你可以生成所有内部的传感器和把他们的地图。这只是一个/ /的例子。你可以在一个循环或但它在另一个方法。(我将编写一个方法,总是将所有传感器一个device_id添加地图)。/ /例子为一个传感器(你可以聪明只有每天必须改变亮度传感器)sensor_map [“1395”_brs] =新的传感器(“Hausbus_taster_1395_brightness”);/ /在update()方法(你应该分成多个方法传感器* outputsensor = sensor_map [device_id +“_”+ sensor_type];outputsensor - > publish_state (sensor_value);

yaml。我不是一个100%确定这作品名称c++中的传感器把需要添加“传感器”。我希望,你必须自己试一试。
总的想法是只有这个:

传感器:平台:定制λ:| -汽车my_hausbus = new Hausbusread (id (HausbusUART));App.register_component (my_hausbus);std::矢量传感器* < >传感器;(汽车const sensor_entry: my_hausbus - > sensor_map) {sensors.push_back (sensor_entry.second);}返回传感器;

这应该映射到ESPHome添加所有的传感器。

我没有不测试。他们可能是错误或不100%工作的事情。

祝你好运。

首先:@danielw谢谢你这么多!我真的很感激你的帮助,你推我的进一步的比我预期!我从来没想过,我解决这个练习在这么短的时间,仍然理解大部分的我在做什么。我确实欠你一杯啤酒!啤酒:

以前从来没有听说过…听起来像炼金术:crazy_face:

我肯定会这样做,因为它听起来非常有前途。昨日的编码会话我思考问题,最终尝试用一个数组,但无序的地图看起来像一个更好的解决方案。另一个啤酒:为你眨眼:
我会发布一个更新,它是一种工作。

下一个酷的想法啤酒:,λ的实现代码仍有点nibulous我和这部分目前是一个简单的复制粘贴工作。

我取代了ESP8266 ESP32处于早期阶段的发展。最主要的原因是,您可以使用以太网非常容易与ESP32(我甚至不知道它的工作原理与8266年)和WT32-ETH01董事会——最便宜的ESP与集成以太网和ESPHome支持目前我能找到的,是基于一个ESP32。除此之外,我喜欢董事会提高性能和与我的选择感到非常幸运——但仍然增长,就是一个很好的提示的代码变得更加苛刻。

我很抱歉,我有点不清楚。每个Multitaster 6按钮和一个亮度,都有一个温度和湿度传感器。这个总结9实体每Multitaster(6开关,3传感器)。此外,我有3 I / O模块,每个模块都有16 - 16输出插脚。只传感器输入,输出只可写的我认为,所以316 + 922 = 246 /变量定义的实体。
我将在我的实验室,然后开始只有一个Multitaster扩大的全套工作。我将与你保持联络啤酒:

好吧,这么多啤酒,这可能会惨淡收场眨眼:

一件事你现在应该:

传感器* outputsensor = sensor_map [device_id +“_”+ sensor_type];outputsensor - > publish_state (sensor_value);

会崩溃,如果没有传感器device_id和sensor_type地图。

你下面是拯救崩溃:

汽车它= sensor_map.find (device_id +“_”+ sensor_type);如果(它! = sensor_map.end) {(*) - > publish_state (sensor_value);其他}{ESP_LOGW (“Hausbus”、“不能findesensor device_id % s和sensor_type % s”, device_id.c_str (), sensor_type.c_str ());}

你不想拒绝一个或两个(升)啤酒,你想要的?眨眼:
我去槽你提示和开始的第一个实现unordered_map轻松。你的c++代码是近乎完美,走了出去。建立传感器的yaml没有麻烦,一个简单的复制工作。这是你写的吗?帽子!
所以,现在是在我的实验室工作环境,但有一次在ESP是不可到达的(和因此没有更新传感器),绝对是你提到的碰撞后造成的。
不幸的是,我完全失去了与变量定义汽车它和找不到太多(或者至少我理解和可以使用)。我想实现它时,编译器抱怨

src / hausbus。h:成员函数的虚拟空HausbusRead:: update (): src / hausbus。h: 54:20:错误:无法与运营商!= '(操作数类型是“std:: __detail: _Node_iterator < std::一对< const std:: __cxx11:: basic_string < char >, esphome:: text_sensor:: TextSensor * >,假的,真正的>”和“<解决重载函数类型>”)如果(它! = sensor_map.end) ^

据我理解,操作员! =是未知的,但…只有在这种比较还是一般?我想这是与变量类型有关汽车没有其他比较操作符在这里工作。
也许你可以帮我另一个时间吗?我觉得这是最后一个得到完整的一部分

Haus-bus.de组件集成

运行:partying_face:

Edit1:我只是和一个额外的去围绕这个问题进行进一步的测试如果(sensor_type = =“集团”){发布…}并且可以确认ESP不再崩溃。
因为它是一个组合device_idsensor_type代码匹配,似乎最优雅的解决方案,与操作者当我们解决了这个问题。
我认为我应该订一个整体啤酒卡车直到我们完成啤酒: