I was trying to get into the ESPHome Alarm Control Panel and started with the official “ESPHome Template Alarm Control Panel”.
So far … so good.
Now I wanted to add a feature:
In “ARMED_AWAY” state I want a red LED to blink every second
In “ARMED_HOME” state I want the red LED to blink every 5 seconds
In “DISARM” state I want a green LED to be on continuously
When I want to run it on the ESP32 I always get following error: error: comparison between distinct pointer types 'const esphome::LogString*' and 'const char*' lacks a cast [-fpermissive]
I have tried it in a lot of different ways (casting to string, …) and searched the internet, but I can’t find any solution to solve the problem.
what confuses me is, that in the “ESP_LOGD” function it works to use alarm_control_panel_state_to_string(id(acp1)->get_state()) but in the payload for the mqtt part it doesn’t.
The error is the above mentioned casting issue from “LogString*” to a basic scring:
Here’s the error message:
error: could not convert 'esphome::alarm_control_panel::alarm_control_panel_state_to_string(((int)acp1->esphome::template_::TemplateAlarmControlPanel::<anonymous>.esphome::alarm_control_panel::AlarmControlPanel::get_state()))' from 'const esphome::LogString*' to 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'}
I would very appreciate any help or hints on this particular issue!
Requesting State and then converting to a string that is then used as the payload is very clean and efficient. I get that its sexy and clean but, if its not cooperating and throwing errors, you can also use if/else statements. Its not as sexy but, it gets the job done and its easier to come back and refine your automations in the future. For example if you want a new action(s) to trigger on certain alarm panel states, you just go add it to whichever ones you need. Sometimes keeping it simple isnt a bad thing.
@Fallingaway24 thanks, I appreciate your efforts in solving this topic!
Meanwhile I’ve solved in a different way, due to other requirements.
I’ve solved by using a “script component” with a “switch case”:
script:
- id: send_arm_state
then:
- mqtt.publish:
topic: ${mqtt_topic}/arm/state
payload: !lambda |-
switch (id(acp1)->get_state()) {
case ACP_STATE_DISARMED:
return "DISARMED";
case ACP_STATE_ARMED_HOME:
return "ARMED HOME";
case ACP_STATE_ARMED_AWAY:
return "ARMED AWAY";
case ACP_STATE_TRIGGERED:
return "TRIGGERED";
default:
return "UNKNOWN";
}
One of the main reasons to do it with a script is due to following requirement:
Current State should always be displayed in NodeRed as text
In case the NodeRed service has been restarted (due to e.g. reboot of the hardware) then the dashboard of NodeRed can’t show the current state of the alarm panel.
For this I added a mqtt.publish in NodeRed which is triggered when NodeRed starts.
This MQTT message is being received by the ESP and executes the above posted script.
I now always have the current State displayed in NodeRed.
So mine wasnt good enough for you? Are you saying im slow in the head?!?!
Lol JK. Thats awesome! Im familiar with using switch/case but, i dont think using it for this would have even crossed my mind so, its good it crossed someones mind.
Helping people ultimately helps me keep learning and retain information. You found a better solution than what i came up with but, as far as im concerned this is a Win for both of us because I learned something too.
Just a suggestion… I would avoid using “unknown” for a state option intentionally. It makes it hard to distinguish between a potential issue(unknown) that needs investigated and something harmless. I kind of think “Disarmed” would be a good fit. If it isnt any of the Armed modes then it is by default Disarmed and not unkown, right?
You’re right, “unknown” might not be a good default option. I guess I’ll change it to “not set” just to be able to distinguish if the desired state has been set or if there is a failure.