A home automation project
A control panel
for my house.
Before going to bed, I wanted to see at a glance whether everything in the house was in order and lock all the doors with a button. I also wanted a way to acknowledge the trash reminder after taking the trash out.
Ignition already tracked the household systems and emailed me on trash days. This panel gives me physical controls for those jobs, using a PLC (programmable logic controller), three buttons and two lights, with room to expand.
- PLC model
- Arduino Opta
- Integration
- OPC UA · Ignition
- Power
- 24 V DC
Assembling and wiring the panel
Arranging the parts
and running the wires
I traced the removable backplate onto a piece of wood and arranged the real parts within the outline. Once the layout fit, I cut the rails and duct, moved everything to the metal plate and marked the mounting holes through the parts.
I wired the controller and terminal blocks on the bench, where everything was easy to reach. Each wire got a number and an entry in the wire list, so I could follow its connection through the duct later.
Planning the door
Putting the layout on paper
I arranged the lights and buttons on paper before making any holes in the door. The two lights went at the top, the green and blue buttons below, and the black button on a third row.
The drawing gave me positions I could measure and transfer to the metal. I left spare positions on the paper for future additions, then taped the template to the door and marked the five centers I needed.
The black button is fitted and wired, but I have left its function open for now.
Fitting the lights and buttons
I used a knockout punch to make the five mounting holes, then fitted the lights and buttons and secured them from behind the door. This was the point where the cabinet started to look like something I could use every day.
Connecting the door to the cabinet
With the controls in place, I ran their wires back to the terminal blocks inside. I left enough slack near the hinge for the door to open and close freely, then secured the wires and checked the movement.
Power and Ethernet connect underneath the cabinet. The panel runs on 24 V DC from an enclosed external adapter, while Ethernet links the PLC to Ignition.
Reading button presses from the PLC
Reading PLC button
presses in software
The green button tells Ignition that I have taken the trash out, so it can clear the reminder. The blue button sends the command to lock all the doors. Ignition controls the lights according to the household status, so acknowledging the trash reminder returns the panel to green when nothing else needs attention.
I press the button.
The controller records it.
The application handles it.
The panel shows the result.
The PLC and Ignition exchange button readings and light commands over OPC UA. The PLC’s relay outputs switch the lights on and off.
Counting presses between polls
A button tap can start and finish between two software reads. If the software only asks whether the button is down right now, both reads can say “released” and the tap goes unseen.
The PLC keeps a running count of presses for each button. Ignition reads those counts over OPC UA roughly every half-second and compares them with its previous reading. A higher count tells it that a press happened, even after the button has been released. The animation below shows that exchange.
Follow one blue-button press
The button is released.
The count still remembers.
Start with 41 presses recorded by the PLC and 41 already seen by Ignition. The next tap happens entirely between polls. Step through it to see what each side knows.
Poll500 ms
Poll1,000 ms
Poll
Reading this value does not clear it.
Saved from the previous poll.
No new press to handle. Ignition waits until its next poll.
- Baseline
- Count the press
- Release
- Read and compare
- Remember and dispatch
- Read again
The animation runs slowly so you can follow it. It shows one blue-button tap during a healthy connection, with no lock command already running. Polls are drawn exactly 500 ms apart; the real Ignition timer waits 500 ms after each run finishes.
What travels between the two systems
The PLC keeps a separate count for each of the three buttons. It counts a press after the input has stayed steady for 30 ms. Holding the button down adds nothing more; releasing it prepares it for the next press.
Ignition reads all three counts in one OPC UA snapshot and compares them with the values it saved last time. If the blue count was 41 and is now 42, one new press has happened—even if the button is already released. Ignition saves 42 before asking the application to lock the doors. Reading 42 again produces no new command.
Ignition’s saved value is a bookmark in the PLC’s count. It does not count physical presses itself or clear the PLC’s counters. The snapshot also carries an identifier that changes whenever the PLC boots, so a restart cannot be mistaken for a huge change in the count.
The snapshot and the rules behind it
One read, three counts
The read-only OPC UA String node HousePanel.ButtonEvents returns JSON. This example uses made-up values and a made-up boot identifier:
{
"version": 1,
"boot": "0123456789abcdef0123456789abcdef",
"counts": [7, 42, 2],
"pressed": 0
}The counts are in green, blue, black order. pressed is a bit mask: 1 for green, 2 for blue and 4 for black; zero means all are released. The firmware copies the counts and button states together under a lock, so the snapshot is consistent.
Comparing without replaying
For each button, Ignition calculates delta = (current − previous) modulo 2³². This handles the unsigned 32-bit counter wrapping back to zero. A delta above 64 is rejected as implausible and establishes a new baseline.
The first read, a different boot identifier, a polling gap over three seconds or a clock moving backwards also establishes a baseline without issuing commands. Bad or malformed data clears the remembered session; the next healthy read starts afresh. Presses made while disconnected are deliberately not replayed.
A count is not a command queue
If the count rises by three between polls, Ignition records three presses but makes at most one request for that button. Blue presses received while a lock operation or its acknowledgement feedback is active are consumed without being queued. Black presses are recorded but have no assigned action.
The green button can acknowledge only the same pending trash reminder that Ignition saw in the preceding healthy sample. A press cannot clear a newly arrived reminder.
Command execution
Ignition remembers the new counts before dispatching commands to avoid handling the same read twice. If it fails between those two steps, that action can be lost. This protocol does not guarantee successful execution or retry an uncertain lock command automatically.
The panel in use
Built for today,
with room to grow
I can now check the house before bed, lock all the doors from the panel and acknowledge the trash reminder after taking it out. The panel gives those daily jobs a permanent place in the house, and I can add more functions as I need them.
