Prologue: Can the System be Saved
A couple of months ago, our aging home security system failed to operate after a brief power outage. In its defense, the system is an Acron Corp AV-3000UL from 1986.
After running some tests we determined all the sensors were still functioning as was the siren board; a GE Moose MPI-11.
Armed with this information I set out to rebuild the system using CircuitPython and a Feather ESP32.
Here begins our story.
Chapter One: Transplant
The Parts
Pins Needed
Note: Your requirements may vary depending on how many zones your system has
My system has eight zones; unless I change the board, the three zones currently out of the design will stay that way
- Pin D33 is used by the Adalogger
- Pin D14 is used by Key A on the NeoKey FeatherWing
- Pin D32 is used by Key B on the NeoKey FeatherWing
That leaves me five pins available for zones and two for the relays for the sirens.
Pins A0, D13, D15, D27, and D12 will be used by the zones
Pins A1 and A5 will be used by the sirens
Pins A2, A3, and A4 currently do not put out enough power to reliably handle the changes in state. I haven't looked into using a resistor to enable these pins for use as a zone. Another option could be to modify the NeoKey to use pins other than D14 and D32. A bridge I shall cross later.
Assembly
My initial design didn't include the NeoKey FeatherWing and by the time we thought about adding it I had already soldered the headers on the ESP32 Feather v2. Not wanting to desolder the ESP32 to put stacking headers on it, I opted to use the NeoKey FeatherWing standalone and wired into the terminal blocks.
While not as cool as stacking it on to the ESP32 and Adalogger, it is working just fine. Maybe one day I'll order another board, who knows :)
Here's what it looks like on the "workbench"
Chapter Two: The Brains
Design
From a requirements perspective, the code needs to be responsive, reliable, and secure.
To meet the responsive requirement, I've chosen to use asyncio.
To meet the reliable requirement, I've implemented a watchdog.
To meet the secure requirement, the web workflow will be disabled. For phase one I'm using AdafruitIO for MQTT publish/subscribe. All feeds are private. In a later phase I may choose to implement an on-site MQTT broker.
Phase One Features
- Detect and publish changes in pin states for the sensors
- Provide relevant logging:
- MQTT
- SD Card
- Console
- Provide singletons for the siren, MQTT, logger, and each zone
- (not live in phase one roll-out) Provide a way to arm system and exclude zones
- (not live in phase one roll-out) Provide a panic button that will immediately enable the siren
- (not live in phase one roll-out) Provide a silence button that will immediately disable the siren
- (not live in phase one roll-out) Provide a way to enable/disable the siren using a 2-channel, 5V relay board
Phase One Code
Classes
- code.py - Responsible for initializing and running the system.
-
one_mqtt.py - Initializes MQTT singleton
- Configures and connects MQTT client to broker
- Handles publish and subscribe requests
-
time_lord.py - Handles all time-related functions
- Initializes the RTC
- Syncs the time with NTP
- Provides methods for retrieving date/time information
-
alarm_handler.py - Handles all functions related to arming/disarming the system
- Arms system based on proper code being provided
- Set zones to exclude when the system is armed
- Logs excluded zones and system state to SD card
- Set excluded zones and system state from SD card on restart
-
zone.py - Handles all functions related to the security system zones
- Uses zone data specified in external file to build an array of zone singletons (one per zone)
- Provides methods for
- Checking zone state
- Determining if it's changed
- Reporting on the changes
-
siren.py - Initializes the Siren singleton
- Provides methods for enabling siren(s)
- Provides method to disable siren(s)
- Provides method to retrieve state of siren(s)
-
local_logger.py - a wrapper class for Adafruit Logging. Provides a single logger instance.
- Initializes SD storage
- Methods to add/remove FileHandler, Console, and MQTT streams
- (not yet implemented) System log rotation method
- Using MQTT subscribe/publish will out put contents of files on SD so the card doesn't have be removed from the system
Data Files
It is possible to put all the required data in a single file. Personally, I found it easier to manage in separate files.
- data.py - Non-sensitive data
- mqtt_data.py - Data required for implementing MQTT (sensitive data!)
- system_data.py - Data required to set up the security system (implementation specific!)
Code and example data files are on Github
Completing Phase One
- 3D print mounting plate and install in security system housing
- Install sensors in terminal blocks
- Use AdafruitIO to send messages if zones are open at the end of the day
What's Next
- Test and implement arming the system and enable all features not live at roll-out
- Build keypads for primary bedroom, front door, and garage for managing the security system
- Add more sensors!