An Arduino/esp8266/esp32 library to directly interface with DSC security systems.
GPL-3.0 License
This library directly interfaces Arduino, esp8266, esp32, and esp32-s2 microcontrollers to DSC PowerSeries and Classic series security systems for integration with home automation, remote control as a virtual keypad, notifications on alarm events, unlocking installer codes, and emulating DSC panels to use DSC keypads as general purpose input devices.
This enables existing DSC security system installations to retain the features and reliability of a hardwired system while integrating with modern devices and software for under $5USD in components.
The built-in examples can be used as-is or as a base to adapt to other uses:
Example integrations:
DSC
in the Library Manager - Sketch > Include Library > Manage Libraries
DSC
in the PlatformIO Library Registryplatformio lib install "dscKeybusInterface"
git clone
or download the repo .zip to the Arduino/PlatformIO library directory to keep track of the latest changes.I Had: A DSC security system not being monitored by a third-party service. I Wanted: Notification if the alarm triggered.
I was interested in finding a solution that directly accessed the pair of data lines that DSC uses for their proprietary Keybus protocol to send data between the panel, keypads, and other modules (instead of using the DSC IT-100 serial module). Tapping into the data lines is an ideal task for a microcontroller and also presented an opportunity to work with the Arduino and FreeRTOS (via esp-open-rtos) platforms.
While there has been excellent discussion about the DSC Keybus protocol and several existing projects, there were a few issues that remained unsolved:
This library uses a combination of hardware and timer interrupts to accurately capture Keybus data, and has lead to reverse engineering much of the Keybus protocol.
src/dscKeybusPrintData.cpp
.delay
or delayMicroseconds
KeypadInterface
and KeypadInterface-MQTT
example sketches - emulate a DSC panel to connect DSC PowerSeries and Classic keypads as physical input devices for any general purpose, without needing a DSC panel.HomeKit-HomeSpan
example sketch (esp32) - integrate directly with Apple HomeKit as a native standalone accessory using HomeSpan
KeypadInterface
.Homebridge-MQTT
supports switching armed modes while armedTwilio-SMS
handlePanel()
VirtualKeypad-Web
updated notes to switch to this fork of ESPAsyncWebServer to resolve crashes with iOS and macOS clients.Pushbullet
example sketch updated TLS security certificate fingerprintHomebridge-MQTT
handling exit delay states while multiple partitions are armingUnlocker
example sketch - determines the panel installer codeTimeSyncNTP
example sketch - uses NTP to automatically set the panel timeextras
directory) - thanks to Dilbert66 for this contribution!TinyGSM-SMS
example sketch - sends status via SMS with a GSM modem - thanks to jvitkauskas for this contribution!KeybusReaderIP
example sketch enables Keybus data access over IP, thanks to aboulfad for this contribution!ready
and disabled
track partition statussetTime()
sets the panel date and timepgmOutputs[]
tracks the status of PGM outputs 1-14timestampChanged
tracks when the panel sends a timestampaccessCode
tracks the access code used to arm/disarmresetStatus()
triggers a full status update of all partitions and zones - for example, after initialization or a lost network connection.pauseStatus
pauses status updates if set to true
- for example, holding status changes during a lost network connectionstop()
disables the interface - for example, prior to starting OTA updatesappendPartition()
in example sketches simplifies adding partition numbers to messagespanelVersion
tracks the panel version number*1 bypass/re-activate
used to change stay/away mode while armedVirtualKeypad-Blynk
and VirtualKeypad-Web
display alarm memory, programming zone lights, and event bufferHomeAssistant-MQTT, Homebridge-MQTT, OpenHAB-MQTT
include PGM outputs 1-14 statuswrite()
for multiple keys can now be set to block until the write is complete with an optional parameter if the char array is ephemeralwriteReady
is typically no longer needed in the sketch, the library will block if a previous write is in progress - this can be checked if the sketch needs to wait until the library can perform a nonblocking writeHomeAssistant-MQTT
sketch now includes night arm and for esp8266/esp32 includes a sensor with partition status messageshandlePanel()
is now loop()
Homebridge-MQTT
sketch not handling HomeKit target stateswrite
keybusConnected
to check if data is being received from the DSC panelprocessModuleData
disabledconfiguration.yaml
error for alarm_control_panel
dscPartitions
and dscZones
in dscKeybusInterface.h
0xE6
and 0xEB
processRedundantData
now true by default to prevent storing repetitive data, reduces memory usage.dscBufferSize
to dscKeybusInterface.h
to allow configuration of how many panel commands are buffered to customize memory usage (uses 18 bytes of memory per command buffered).The included examples demonstrate how to use the library and can be used as-is or adapted to integrate with other software. Post an issue/pull request if you've developed (and would like to share) a sketch/integration that others can use.
Status: Processes and prints the security system status to a serial interface, including reading from serial for the virtual keypad. This demonstrates how to determine if the security system status has changed, what has changed, and how to take action based on those changes. Post an issue/pull request if you have a use for additional system states - for now, only a subset of all decoded commands are being tracked for status to limit memory usage:
HomeKit-HomeSpan (esp32): Integrates directly with Apple HomeKit as a native accessory (for the Home app and Siri) using HomeSpan, without needing a separate service or device. Demonstrates arming/disarming partitions, zones status, fire alarms, PGM outputs status, and controlling panel command outputs.
Homebridge-MQTT: Interfaces with Homebridge via MQTT to integrate with Apple HomeKit (including the iOS Home app and Siri) and Google Home. Demonstrates arming/disarming partitions and for HomeKit, viewing the status of zones, PGM outputs, and fire alarms.
HomeAssistant-MQTT: Interfaces with Home Assistant via MQTT. Demonstrates arming/disarming partitions and viewing the status of zones, PGM outputs, fire alarms, and trouble. For esp8266/esp32, the partition status is available as a text message for display.
OpenHAB-MQTT: Interfaces with OpenHAB via MQTT. Demonstrates using the panel and partitions states as OpenHAB switches and zone states as OpenHAB contacts. For esp8266/esp32, a panel status message is also sent as a string to OpenHAB. See https://github.com/jimtng/dscalarm-mqtt for an integration using the Homie convention for OpenHAB's Homie MQTT component.
ESPHome (esp8266): Integrates with ESPHome as a custom component - note that this example is located in the extras
directory. Thanks to Dilbert66 for this contribution!
Homey: Integrates with Athom Homey and the Homeyduino library, including armed, alarm, and fire states (currently limited to one partition), and zone states. Thanks to MagnusPer for contributing this example!
Telegram (esp8266/esp32): Demonstrates sending status updates as push notifications and arming/disarming the security system via a Telegram bot. Supports iOS, Android, and macOS/Windows/Linux desktop notifications (free).
Pushover (esp8266/esp32): Demonstrates sending status updates as push notifications via Pushover. Supports iOS, Android, macOS native desktop notifications, and Chrome/Firefox/Safari browser popups ($4.99USD one-time purchase per client platform).
Pushbullet (esp8266/esp32): Demonstrates sending status updates as push notifications via Pushbullet. Supports Android, Windows desktop notifications, and Chrome/Firefox browser popups (free). Note that iOS is no longer supported.
Pushsafer (esp8266/esp32): Demonstrates sending status updates as push notifications via Pushsafer. Supports iOS, Android, Windows desktop notifications, and Chrome/Firefox/Edge/Opera/Yandex browser popups (€0.99EUR or less per 1000 notifications).
Twilio-SMS (esp8266/esp32): Demonstrates sending status updates as SMS text messages via Twilio - thanks to ColingNG for contributing this example!
Email (esp8266/esp32): Demonstrates sending status updates as email. Email is sent using SMTPS (port 465) with SSL for encryption - this is necessary on the esp8266/esp32 until STARTTLS can be supported. For example, this will work with Gmail after changing the account settings to allow less secure apps.
This can be used to send SMS text messages if the number's service provider has an email to SMS gateway - examples for the US:
VirtualKeypad-Blynk (esp8266/esp32): Provides a virtual keypad interface for the free Blynk legacy app on iOS and Android, including viewing alarm memory, programming zone lights, and the event buffer. The newer generation Blynk app is not currently supported. Scan one of the following QR codes from within the Blynk app for an example keypad layout:
Note: Installing Blynk as a local server is recommended to keep control of the security system internal to your network.
VirtualKeypad-Web (esp8266/esp32): Provides a virtual keypad web interface, using the esp8266/esp32 itself as a standalone web server, including viewing alarm memory, programming zone lights, and the event buffer. Thanks to Elektrik1 for contributing this example!
TimeSyncNTP: Synchronizes and maintains time on PowerSeries panels via an NTP server, including DST adjustments.
Unlocker: Finds the 4-digit installer code for PowerSeries panels by checking all possible codes, including handling keypad lockout if enabled. The valid code is output to serial as well as repeatedly flashed with the built-in LED. Arduino checks each code sequentially but esp8266/esp32 may find the code more quickly as they check in order of the most commonly used general 4-digit codes.
KeypadInterface: Interfaces directly to DSC PowerSeries and Classic series (tested with PC1500RK) keypads (without a DSC panel) to enable using these as physical inputs for any general purpose. Examples included for interfacing via serial and MQTT. Note that this uses a different wiring setup from the standard Keybus interface, refer to the wiring diagram in the example sketch.
KeybusReader: Decodes and prints data from the Keybus to a serial interface, including reading from serial for the virtual keypad. This can be used to help decode the Keybus protocol and is also handy as a troubleshooting tool to verify that data is displayed without errors. For esp8266/esp32, KeybusReaderIP
enables connectivity over WiFi.
See src/dscKeybusPrintData.cpp
for all currently known Keybus protocol commands and messages. Issues and pull requests with additions/corrections are welcome!
DSC Aux(+) ---+--- Arduino Vin pin
|
+--- 5v voltage regulator --- esp8266 NodeMCU / Wemos D1 Mini 5v pin
esp32 development board 5v pin
DSC Aux(-) --- Arduino/esp8266/esp32 Ground
Arduino +--- dscClockPin (Arduino Uno: 3)
DSC Yellow ---+--- 15k ohm resistor ---|
| +--- 10k ohm resistor --- Ground
|
| esp8266/esp32 +--- dscClockPin (esp8266: D1, GPIO 5 / esp32: 18)
+--- 33k ohm resistor ---|
+--- 10k ohm resistor --- Ground
Arduino +--- dscReadPin (Arduino Uno: 5)
DSC Green ----+--- 15k ohm resistor ---|
| +--- 10k ohm resistor --- Ground
|
| esp8266/esp32 +--- dscReadPin (esp8266: D2, GPIO 4 / esp32: 19)
+--- 33k ohm resistor ---|
+--- 10k ohm resistor --- Ground
Classic series only, PGM configured for PC-16 output:
DSC PGM ------+--- 1k ohm resistor --- DSC Aux(+)
|
| Arduino +--- dscPC16Pin (Arduino Uno: 4)
+--- 15k ohm resistor ---|
| +--- 10k ohm resistor --- Ground
|
| esp8266/esp32 +--- dscPC16Pin (esp8266: D7, GPIO 13 / esp32: 17)
+--- 33k ohm resistor ---|
+--- 10k ohm resistor --- Ground
Virtual keypad (optional):
DSC Green ---- NPN collector --\
|-- NPN base --- 1k ohm resistor --- dscWritePin (Arduino Uno: 6 / esp8266: D8, GPIO 15 / esp32: 21)
Ground --- NPN emitter --/
This allows a sketch to send keys to the DSC panel to emulate the physical DSC keypads and enables full control of the panel from the sketch or other software.
Keys are sent to partition 1 by default and can be changed to a different partition. The following keys can be sent to the panel - see the examples for usage:
0-9 * #
s
w
n
f
a
p
c
r
x
/
+ partition number
or set writePartition
to the partition number. Examples:
/2
+ 1234
/1
dsc.writePartition = 8;
[
]
{
}
Panel options affecting this interface, configured by *8 + installer code
- see the Unlocker
sketch if your panel's installer code is unknown. Refer to the DSC installation manual for your panel to configure these options:
PC1555MX/5015 section 370
, PC1616/PC1832/PC1864 section 377
:
Swinger shutdown: By default, the panel will limit the number of alarm commands sent in a single armed cycle to 3 - for example, a zone alarm being triggered multiple times will stop reporting after 3 alerts. This is to avoid sending alerts repeatedly to a third-party monitoring service, and also affects this interface. As I do not use a monitoring service, I disable swinger shutdown by setting this to 000
.
AC power failure reporting delay: The default delay is 30 minutes and can be set to 000
to immediately report a power failure.
PC1500/PC1550 Classic series - the following configuration is required to get the security system status:
12
, option 1
to support PC16-OUT mode13
, option 4
to set the PGM output to PC16-OUT mode to send required panel status data on the Keybus.24
, option 08
to set the PGM output to trigger while the system alarm is tripped (works together with PC16-OUT mode).For OTA updates on esp8266 and esp32, you may need to stop the interface using dsc.stop();
:
void setup() {
...
ArduinoOTA.onStart([]() {
dsc.stop();
...
Memory usage can be adjusted based on the number of partitions, zones, and data buffer size specified in src/dscKeybus.h
or src/dscClassic.h
. Default settings:
PCB layouts are available in extras/PCB Layouts
- thanks to sjlouw for contributing these designs!
Support for other platforms depends on adjusting the code to use their platform-specific timers. In addition to hardware pin-change interrupts to capture the DSC clock, this library uses platform-specific timer interrupts to capture the DSC data line in a non-blocking way 250μs after the clock changes (without using delayMicroseconds()
). This is necessary because the clock and data are asynchronous - I've observed keypad data delayed up to 160μs after the clock falls.
Resource utilization:
If you are running into issues:
KeybusReader
example sketch and view the serial output to verify that the interface is capturing data successfully without reporting CRC errors.
KeybusReader
example sketch and enter keys through serial and verify that the keys appear in the output and that the panel responds.
Status
example sketch and view the serial output to verify that the interface displays events from the security system correctly as partitions are armed, zones opened, etc.For general discussions, feature requests, or how-to issues, you can post in Discussions, or post an Issue if it looks like an issue with the library code itself.
AVR Freaks - DSC Keybus Protocol: An excellent discussion on how data is sent on the Keybus.
stagf15/DSC_Panel: A library that nearly works for the PC1555MX but had timing and data errors. Writing this library from scratch was primarily a programming exercise, otherwise it should be possible to patch the DSC_Panel library.
dougkpowers/pc1550-interface: An interface for the DSC Classic series.