taligentx / dscKeybusInterface

An Arduino/esp8266/esp32 library to directly interface with DSC security systems.
GNU General Public License v3.0
514 stars 130 forks source link

Is it possible to send disarm code via MQTT? #304

Open Rickerdo opened 2 years ago

Rickerdo commented 2 years ago

I am successfully running the Arduino HomeAssistant-MQTT.ino example with Home Assistant (HA). For the life of me I cannot figure out how to force the HA alarm keypad to send a user code to disarm the system. If I hard code a user code into the sketch, compile, and upload to the Arduino, I can enter any number into the HA keypad to disarm the system. Even a single digit works.

I would like the HA alarm keypad to just pass the user code via MQTT to the Arduino, which then passes the code to the alarm panel. What am I missing?

HA config:

mqtt:
  alarm_control_panel:
    - name: Alarm Partition 1
      state_topic: dsc/Get/Partition1
      command_topic: dsc/Set
      availability:
        topic: dsc/Status
      code: REMOTE_CODE
      payload_disarm: 1D
      payload_arm_home: 1S
      payload_arm_away: 1A
      payload_arm_night: 1N

  binary_sensor:
    - name: Security Trouble
      state_topic: dsc/Get/Trouble
      device_class: problem
      payload_on: 1
      payload_off: 0

    - name: Front Door
      state_topic: dsc/Get/Zone1
      device_class: door
      payload_on: 1
      payload_off: 0

    - name: Down Front Bedroom Window
      state_topic: dsc/Get/Zone2
      device_class: window
      payload_on: 1
      payload_off: 0
...
Dilbert66 commented 2 years ago

The example ino mqtt file does not support direct keypad entry. If you have some coding familiarity you can try adding support for it by adding the code snippet below to the ino file in the "mqttcallback" function after the disarm if statement. Note that that I have not tested this on a dsc system as I use something similar to the code below on my vista implementation so adapted it for this use. You might need to tweak it and debug it. This should add the ability to recognize when a direct keypad command is sent by using an exclamation mark '!' as a trigger . eg. !1234 where 1234 is your code to be sent directly to the panel. You can then send anything you want. If you want to send to as specific partition, you would enter 1!1234 where the first character is the partition, then the ! as the direct code flag, then your digits. For example to disarm partition 1, instead of sending "1D", you would send 1!1234 where 1234 is your disarm code.

// direct command
    if (payload[payloadIndex] == '!' && payloadIndex+1<length) {
      payload[length] = '\0';
      dsc.write((char * ) &payload[payloadIndex+1]);
    }
Rickerdo commented 2 years ago

My HomeAssistant-MQTT.ino file now looks like:

  // Arm night
  else if (payload[payloadIndex] == 'N' && !dsc.armed[partition] && !dsc.exitDelay[partition]) {
    dsc.writePartition = partition + 1;         // Sets writes to the partition number
    dsc.write('n');                             // Virtual keypad arm away
  }

  // Disarm
  else if (payload[payloadIndex] == 'D' && (dsc.armed[partition] || dsc.exitDelay[partition] || dsc.alarm[partition])) {
    dsc.writePartition = partition + 1;         // Sets writes to the partition number
    dsc.write(accessCode);
  }

  // direct command
  // Added per https://github.com/taligentx/dscKeybusInterface/issues/304
  if (payload[payloadIndex] == '!' && payloadIndex+1<length) {
    payload[length] = '\0';
    dsc.write((char * ) &payload[payloadIndex+1]);
  }

And my HA config now looks like:

mqtt:
  alarm_control_panel:
    - name: Alarm Partition 1
      state_topic: dsc/Get/Partition1
      command_topic: dsc/Set
      availability:
        topic: dsc/Status
      code: REMOTE_CODE
      command_template: >
        {{ action }}{{ code }}
      payload_disarm: 1!
      payload_arm_home: 1S
      payload_arm_away: 1A
      payload_arm_night: 1N

Now I can successfully pass the user code to disarm the panel. However, this creates a new issue with HA where it wants to pass "1S{code}" to MQTT. Of course this is expected given the "command_template", so that begs the question... What would be the direct command for "S", "A", and "N" for home, away, and night respectively? I looked through the code, but couldn't find an obvious answer.

Side note: This whole project is amazing. Great work on both the hardware and software! I had an AD2Pi module that was damaged due to a close lightning strike. I was tempted to replace it with an EV4 from EyezOn, but with some components I had laying around, an old Arduino Uno, and an Ethernet shield, I have a fully functioning MQTT based interface for my PC1864. The best part - no proprietary firmware limitations!

Rickerdo commented 2 years ago

The following snippet works on the HA side as a hackish way to solve the issue I mentioned above:

mqtt:
  alarm_control_panel:
    - name: Alarm Partition 1
      state_topic: dsc/Get/Partition1
      command_topic: dsc/Set
      availability:
        topic: dsc/Status
      code: REMOTE_CODE
      command_template: >
        {% if action == "1D" %}
          1!{{ code }}
        {% else %}
          {{ action }}
        {% endif %}
      payload_disarm: 1D
      payload_arm_home: 1S
      payload_arm_away: 1A
      payload_arm_night: 1N
Dilbert66 commented 2 years ago

The S, A and N are the direct commands for those modes as they simulate the DSC panel keys assigned to those functions.

Since you are using homeassistant you might also be interested in using ESPHome instead of MQTT. Here's a link to my implementation of this library adapted to ESPHome.

https://github.com/Dilbert66/esphome-dsckeybus/tree/new

Edit: Other direct commands you can send such as 0 to quick arm your system (that's assuming quick arming is enabled on your panel).
9 will arm your system in Stay mode with no entry delay, *1 to bypass zones,etc. See your user manual for those.

Rickerdo commented 2 years ago

@Dilbert66 I saw your ESPHome implementation before I built my Arduino shield. Nice work there, especially with the example PCBs. The only thing that stopped me, aside from not having the hardware on hand, was a lack of simple implementation using Ethernet instead of WiFi. I really need a hard wired Ethernet connection. Perhaps I should ask about that on your github repo instead of here.

Dilbert66 commented 2 years ago

There's a few boards that are out that include an esp32 with built in ethernet connectivity such as :

https://www.aliexpress.com/item/4001122992446.html

https://www.cnx-software.com/2020/06/10/ttgo-t-internet-poe-board-provides-ethernet-poe-wifi-bluetooth/

Then you configure esphome to use ethernet:

https://esphome.io/components/ethernet.html

Edit: the WT32-ETH01 is also a good less expensive board but needs an external usb to serial adapter to flash initially.

sbrown4 commented 1 year ago

@Dilbert66 I tried your direct command example to bypass a zone with the following changes:

  1. I changed '!' to "|" to be able to use mosquitto_pub for testing. '!' is sort of reserved in bash.
  2. I also had to set blockingWrite to true in the dsc.write() call.

With these changes "|*102#" bypasses zone 2. Thanks for the suggestion .