Yes sure one can solve some of the issues by writing rules. I’ve done so in the past myself to compensate, but I would argue that common problems should be solved in a common way by the framework, and thus make it more accessible to less tech-savvy users.
And with the KNX example provided by @Udo_Hartmann in an earlier reply, a rule writer might experience some unexpected behaviour.
One of the beauty of openhab is that it doesn’t force you to do something a certain way. I prefer not to set my items to UNDEF whenever the things go offline, because the item’s current state is valuable to me.
Here’s a few lines to make all items go UNDEF 5 seconds after their thing is no longer online. If someone wants this behaviour, simply create a similar and very simple rule to gain that behaviour on their system.
rule "Make linked items UNDEF when things are no longer online" do
trigger "core.ThingStatusChangeTrigger", thingUID: "*", previousStatus: "ONLINE"
run do |event|
after 5.seconds do
next if event.thing.online?
event.thing.channels.each do |channel|
channel.items.each { |item| item.update UNDEF }
end
end
end
end
While I agree with your sentiment against dynamic channels, one would think that the esphome binding got the channel details directly from the esphome device, and that information should be exactly the same as configured in your esphome yaml. The only downside is that this adds a tiny bit of delay on the initial connection.
So I would love to see the esphome binding allow static channel configuration method and when it is done statically, skip this interrogation step. I don’t know the ins and outs of the binding to understand / appreciate the challenges this may present though, and since it is not my binding, I have very little say in it.
For the time being, I am perfectly happy using mqtt + manual channel definition for my esphome devices. I generate my things + items programmatically, so I just need one template for each device type, and this is done the same way with the esphome configuration.
One thing about the ESPHome API I have been meaning to investigate is the ability for one esphome device to directly issue a command to another, bypassing mqtt and openhab. This would be handy for a switch to control a light, when openhab is down. However, AFAIK this is not supported.
In the other topic,
What about a utility that queries the ESPHome (using API or mqtt discovery), and generate the .things file.
Not sure at all. And from the linked discussion there seems to be confusion. If you look at the official bindings source code, there is no clear answer as well as both NULL and UNDEF are being used. Personally I am happy with either.
Yes, but keep in mind that a single ESPHome component (ie climate) may provide multiple entities/channels, and retrieving those names from the esphome yaml would probably require parsing C++ code as well.
State updates from the device are done using a unique 32 bit key, and not by transmitting the full entity/channel name. The key is provided during the interrogation step. I’m not sure whether they are static across a reboot, but I’m pretty sure they won’t be static across a flashing process (ie version upgrade or modification).
So you cannot skip the interrogation step.
As I wrote in an earlier post:
Wouldn’t a “A python yaml to items generator” solve it?
Do you mean that if the device doesn’t actually provide all statically configured channels, the thing should refuse to go online? Opposed to some centralized logic checking for broken links every X seconds and informing you about the problem - and that applies for all kinds of thing types?
Oh I wasn’t suggesting to use the esphome yaml to generate the channel details. On the contrary, my point was that the channels provided by the binding as a result of its interrogation should be exactly the same as the yaml, so there should be no reason to define it statically, in theory, if we trust the binding to work correctly.
I was referring to the esphome yaml, and by that I don’t mean literally just what’s in the yaml, but the resulting esphome entities that would’ve otherwise been broadcasted through mqtt.
Having said that, the main reason I didn’t pursue using the esphome binding was because my esphome configs involve sending custom mqtt messages to communicate. I need (and tried) to refactor it into standard components, but there are some things that aren’t possible. I did ask the esphome folks about how to get around it but I was told that mqtt is the only way to do what I did. Hence I’m still using mqtt for now. It has been a while now, and I don’t remember the details exactly. I’d like to revisit it again one day.
I’m not suggesting anything. Just warning you that MQTT used to set the Item states to UNDEF when the Thing went offline and the maintainers made them take that behavior out as a misuse of the UNDEF state.
Honestly the reasoning never made sense to me and I personally continue to “misuse” UNDEF in this way. But I don’t need to get the maintainers to approve my personal rules.
And since switching to a status Item I really don’t want my items going to UNDEF just because the Thing went offline.
Why does everyone always assume the worst case when it comes to something like this?
If one is using managed Items it’s a simple script (6-10 lines at most, probably less in jRuby) to find all the equipment and add a status Item to them complete with links and profile config (I’ll post a rule template on request). Then you need one rule (template already posted) to detect when it goes offline and do something about it.
Me too now which is why I added the status Item.
Another approach is to use the Thing Status Reporting rule template to set the status Item or all the linked items to UNDEF too if you want.
I do that for a couple of Things with a status Item.
I was reading the other topic because I use a lot of ESP’s. Maybe this MQTT topic is not for this one but I still wonder why is MQTT preferred?
I agree polling is bad for stable values. So for stable values (think switch) I let the ESP call the openHAB API to update the item when it changes.
When values changes all the time (think most environmental sensors or power consumption) I poll in the desired update frequency with the http binding. My assumption is that there’s not much difference in network load. And if you let the ESP respond in JSON configuration is easy.
Reason for me is the simple setup, no new technology to learn. But of course I’m curious. What would be the advantage of MQTT over this setup?
That’s (always) right. But some sensors produce new data every 20 milliseconds. No point in sending that live-feed to openHAB. You decide what accuracy you need/want. And this is the case where I wonder. What’s the difference to ask openHAB to poll every 30 seconds OR let de sensor push every 30 seconds?
Don’t get my intention wrong … I try to understand what I would gain in switching to MQTT in a scenario like this. If there’s an advantage it’s worth considering …
If the data is important, then you’d want it every 20 milliseconds. If it’s not important, change the sensors (esphome? that’s in your control) not to flood the network and just provide the data at your desired interval.
And when this is done, then push is better than pull.
If you can’t change the sensor, and if by pulling, it will not flood the network, then I guess that’s the best you could do?
Maybe good to know I don’t use ESPHome, I got my own library for the ESP’s. Takes care of 95% of the standard things so you only add the code for the sensor/switch/whatever. It’s pretty standard, or maybe should I say … standard for an ESP programmer. The strength of ESPHome is avoiding this by the YAML config. Well, since you asked. Below are the two core functions.
@seime “The standard push message from the ESP”. You mean “my” push, a ESPHome push or a MQTT push? For fast changing data letting openHAB poll it every 30 (or whatever) seconds seemed the easiest option. And (but that’s my question) I can’t see the difference between pusing and pulling because in this scenario all the data is transferred periodically anyways.
//add a postrequest, it will be send asynchrone/later
void WebServerCommand::_addRequest(const String &url, const char *contentType, const int requestType,const String &content,void (*response)(PostResponse &postResponse)){
bool ok=false;
for (int i=0;i<HTTP_POST_MAX;i++){
if (_postRequests[i].url==""){
//empty slot, caller may erase vars, copy them
_postRequests[i] = {String(url),contentType,requestType,String(content),response};
ok=true;
break;
}
}
if (!ok){
//no more free slots, send error
PostResponse postResponse={-2,""};
response(postResponse);
}
}
/*
proces a PostRequest and sent result to callback
*/
void WebServerCommand::_doRequest(PostRequest &postRequest){
if (WiFi.status() == WL_CONNECTED){
WiFiClient client;
HTTPClient http;
PostResponse postResponse;
//start a client for call
bool ok=http.begin(client, postRequest.url); //HTTP
if (ok){
//URL accepted, add header
http.addHeader(F("Content-Type"), postRequest.contentType);
//http.addHeader(F("Content-Length"), String(value.length()));
// send content
if (postRequest.requestType==DO_POST){
postResponse.httpCode = http.POST(postRequest.request);
}else if (postRequest.requestType==DO_GET && postRequest.request==""){
postResponse.httpCode = http.GET();
} else {
postResponse.httpCode = -3;
}
//check result
if (postResponse.httpCode > 0) {
//accepted
if (postResponse.httpCode == HTTP_CODE_OK) {
//ok, get response
postResponse.response = http.getString();
} else {
//not ok, error code
postResponse.response="";
}
} else {
//error connection
postResponse.response="";
}
} else {
//url not accepted
postResponse.httpCode=-1;
postResponse.response="";
}
//end
http.end();
//processing done, send result to callback
postRequest.response(postResponse);
//clear command to take next request
postRequest = {"",_emptyContent,DO_NOTHING,"",_emptyHandler};
}
}
MQTT is more lightweight than http so you save client resources. Since the MQTT broker coordinates the pushs it’s also possible to react with multiples clients to the published message.
Additionally your device is decoupled from openHAB, so you can e.g. rename the item without having to deploy new firmware.
Once you have an mqtt broker running there are no reasons to directly make http calls from the device. Instead use the broker as a central data exchange platfrom.