2017-07-11

Busy week

A week ago I started on this fun little alarm project, and I am quite pleased with progress.

The list of things to do is dwindling, and the functionality of an alarm system is all there now. I have to improved the keypad UI to show which inputs were triggered, but I have a log for that. I could start using it now.

I have inputs and outputs and tampers and faults and warnings and fire alarm and latching things and resets by the user and login on the keypad and beeping and exit routes and entry routes and timed set and part set and instant set and delayed bell and bell time limit and rest time and almost all of the door control features I planned plus several more and, well, a compete alarm system really :-)

The next stage really is lots of testing and working with my friends who are making bench tests and the like. I need to look at the SSAIB stuff and see if we can meet their specs too.

It has been fun, and has had lots of back tracking and tidying up and re-thinks.

So now is a good time to actually try this outside I hear about, and go for a meal with some friends this evening. Should be fun. It looks wet out there though :-)

2017-07-09

SolarSystem?

I have been doing this alarm project for a few days now, and it started as a bit of fun, but is turning in to something quite interesting I think, so I'll keep posting updates.

As with many systems there are a lot of layers involved, and I have been working my way up the layers (which is how I usually do things). I usually get bored by the time we are talking about what colour the icon for a PIR is on the web page :-)

The low level layers are all about the RS485 bus, and the reverse engineering of a normal Holywell Galaxy alarm panel. That has gone well, but even today I was revisiting a few bits like control of the backlight on the keypad. Over the weekend I have slept on the design and as I expected re-done several parts of the low level library to handle the bus and "door state machine" logic.

One of the main reasons for a re-work like this is that things are never quite the same when you come to using a library. I made my initial design, but when using it I found I was having to make messy code, which is always a bad sign, so I went back and made changes. The result is something I am a lot happier with.

I have now started the higher level design of an alarm panel. I had to pick a name. I have started with a name of SolarSystem, as it is a lot smaller than a whole Galaxy. That said, it is likely to be a lot more powerful to be honest. This also meant a lot of documentation and more sleeping on things and a lot of changing my mind as I started to code things.

The nuts and bolts of an alarm panel are damn simple - you configure shit, which is not that hard, and you have a lot of inputs which set an "alarm" state if triggered when the alarm is "set". You make bells ring, and you send text messages and so on. OK, that is simplified a bit, but not rocket science.

This is where we get to another part of coding, and especially for embedded systems, you need a shit load of error checking, and you need ways to report errors without simply aborting. For most code in a typical environment, using errx(...) is fine - aborts the programme and tells the user what went wrong. For an alarm panel that means the doors stop working and you are locked in or locked out of your office. So you need to take a lot more creative approaches to error handling.


The other big issue, even at this stage, is "user interface". For the most part I am working on the actual operation. However, even that has the keypads, and they represent a user interface. So I have to have a way to use them sensibly - modes and states and partial inputs of data - all good fun.

So, in summary - I have the low level RS485 handling for RIO, MAX, and Keypad all working. I have a design for the alarm panel operation. I have a start on the code for the alarm panel operation.

What next - well, lots of work at this stage still, and a lot of testing. I decided the alarm panel code runs from a config file, which can be re-loaded, and is XML (or JSON). So the actual config is to be done later - perhaps a nice web interface or mysql database, whatever. I said I get bored at the high levels, but I have people that will code that all if I want. For now I am using vim on an XML file :-)

I also need to start using this in practice, which means setting up better bench tests than I have now. Ideally a board with some doors on it (small ones) with lock release and buttons and reed switches and max readers, and a keypad, and something to simulate PIRs and a bell and so on. Make a dummy system and try out the logic, and also to demo the way it works and use in videos!

One small step to that which I may do is fit door entry and alarm to this :-


It is nearly finished (thanks to all my family who have worked hard on this), but has a door, and so could be set up with a full alarm system - why not. Indeed, I suspect my grandsons will love it if the door needs a key fob and will take great delight showing their friends and locking them out even.

Changing my house is also a key step. I have a Galaxy panel now, but will change to a new system. I need a key switch so I can cut power to the fail safe door on my office here at home for when early versions do manage to crash in some way. Even I am not brave enough to lock myself, yet.

Them the next big step will be changing the office over. I expect that is weeks away, but when we do it, it will allow a lot of new features.

One of the key things we can do a lot better is door management, which I have already coded. Actually being able to use "lock engaged" inputs, and allowing secondary deadlock on a door, and handling door forced events way better as well as door propped.

It is probably worth explaining slightly. When the certified alarm installers did the office, they did not connect the door open sensors to the Max readers. Why? Because it causes door forced events. Grab a door as it is closing, or bounce a door shut then open (depends on type of lock), or even just pull hard enough on a mag locked door to trip the reed switch, and you have a door forced alarm. So they, as a matter of policy, don't enable the sensor as way fewer support calls. Bear in mind, for a lot of systems, this sort of issue may mean calling the installer to have them reset it.

We were robbed, and there was a complex sequence of errors on our part, but one of them is that we would have seen door forced and come running if those sensors were fitted.

Now they are - but we have a false alarm on this once a day at least and it is annoying. We have the system so we can reset the alarm, but still it is annoying people.

So simple things can be changed. One is a short timer on the input for the "tugged the door hard", though, to be honest, on the outer doors I would rather know someone is doing that. Actually, D'Oh, I need that only during the day when alarm not set. When alarm set I want that to trip instantly. /me makes note. This means we eliminate a lot of the errors.

The other is a door closing timer and integration with lock engaged inputs where available. This would allow door open just after closed without being a door forced.

Just those simple little things would stop the staff cursing the Galaxy system every day!

Another issue is door propped events. The Galaxy does this - a door left open too long is considered propped. A useful alert.... Except sometimes you want to prop a door. Hence we have it disabled. My design allows a propped alert to be cancelled (and to record who did it) by someone allowed to cancel propped alerts using a key fob on the Max for that door. That way we can prop doors if we want, and record who did it, but a door that has not quite closed for other unconfirmed reasons raises an alert.

By creating a door object as a concept and not restricting ourselves to what the Max does, we can allow all sorts of new things. One of which is air-lock door sets. I.e. two doors where one must never be open if the other is open. This is a requirement in many places, and indeed, one of the doors does not even need a Max reader at all, just buttons and sensors.

Another is cases of max reader both sides, which doubles as a time recording system for staff. My design allows these with ease.

All good fun. I'll post more on this next week I expect. Still considering the best way to open source the project.

2017-07-07

PARMRK

One for the techies...

On linux, serial port processing has a lot of options, and I mean a lot. It is scary. In order to do this RS485 stuff I was setting the most raw, basic, just give me the bytes mode I could.

However, in a fit if stupidity I set the PARMRK setting in termios. It seemed like a useful thing to tell me if I was getting a BREAK or other framing error on the bus.

All was well, pretty much, but I had not realised, PARMRK does no just prefix framing and parity errors with a sequence like FF 00 so you can see them, it escapes a received FF byte as FF FF.

This makes sense, else how can you tell it is marked or not. I should have thought of that!

The problem is that the Honeywell Galaxy serial stuff uses a 1s complement checksum. Only if the checksum should be 00 would an extra FF byte matter making it FF. In all other cases FF wraps adding 1 more, and causing the checksum not to change.

So I was getting messages, and some would contain FF, and I would see as FF FF, but the checksum would be fine. I was assuming the messages I was debugging were meant to have FF FF. It did strike me as odd in one case, I have to admit. And most of the messages did not contain FF.

Only when I started on the RIO where I had things like tamper reported FF and resistance reported as FF FF (infinity) did it stick out, with the message length being inconsistent. Have eight lots of FF FF escaped by PARMRK in one message and it very quickly looks silly.

I could de-esacpe the input, but simpler was not use that feature. Well done using 1s complement checksums!!!

So far I quite like the RIO

One of the key pieces of equipment for this alarm panel project is a RIO (Remote I/O, I assume).

It is what handles the inputs and outputs for the alarm system itself, and one or two of these are normally included on the panel itself.

The basic set up has 4 outputs and 8 inputs. There is an RF RIO where the inputs are remote radio things - like battery powered PIRs. It seems to work in the same way, thankfully.

The outputs were noddy, I just send a message to tell it the state of the outputs, even if that has some overkill of 3 bytes per output rather than one bit.

The inputs were a tad more fun. The concept is that you have a pair of wires to a remote device, or more than one maybe, and you have switches - e.g. reed switch, and you have resistors. It seems (sorry Borg) resistance is not futile.

The typically config is a 1kΩ means "closed" and 2kΩ means "open". So you used 2 x 1kΩ resistors with one shorted by the reed switch. Simple.

The reason for this is to prevent tampering. Simply short circuiting or open circuiting the wiring would create a "tamper" condition. You can, of course, bodge it by measuring the voltage and fitting a few zenor diodes to match then removing the wiring, but apparently criminals are too dumb to work that out.

What is quite nice is that the RIO works out the resistance, to the Ω and reports that periodically. It also reposts the battery voltage to the mV. It is rather nice when something like this goes to the bother of converting data to nice usable units like this.

There are, however, a couple of config items, which are slightly fiddly. One of which actually needs the message sending twice, FFS. Why?!?! Does that pre-date checksums?

Anyway, one setting per input is response time, and again it converts from nice units an can be set is multiples of 10ms to 2550ms per input. Nice.

Another is the resistance thresholds, in multiples of 100Ω. These define the range for the 1kΩ "closed" and the 2kΩ "open", but also a band for "low res" and "high res" to report issues. This means in total five different resistance values defined, and so six states, two of which are "tamper" (open and closed circuit).

Anyway, all coded, with events passed up to the application, and inputs that can be used for the door entry system if needed.

This basically means I have the key components now for an alarm panel. Next step is the higher level logic for setting zones, and so on. I'll ponder over the weekend. I suspect I'll do a bit of tidying up of existing code before moving on.

2017-07-06

More coding

I have been having fun, and yes, it is fun.

There have been many set backs. Today I spend two hours assuming the damn Max Reader was being daft before finding a loose connector. Yesterday was an faulty RS485 lead.

I have discovered that the Max reader really does want around 10ms gap between messages on the bus else it gets confused and sulks. Shame, as keypad is happy with way less.

My code design has evolved - it now works as a library which creates a per bus thread to do the polling, and a separate "doorman" thread to handle logical "door" objects. By default these are created from new Max readers it finds.

My idea is that a "door" is a lot more than just what a Max reader can do. They are pretty simple, with two inputs (exit button and door open) and one output (door release relay).

I think a "door" needs more, so the design allows (optionally) a Max reader and then a number of inputs and outputs (which may be on that Max reader, or on a RIO), to make the door complete.

So you have the basics, a door exit button, and a door open sensor, as well as a lock control relay. But the logical door can have more. Indeed, those basic inputs do not need to be on the Max - its inputs and outputs can be for anything, just defaulting to their normal use.

Extra I/O for a "door" includes things like a door bell button input and a door bell output. Simple stuff. But also a door "lock engaged" input (which many locks can do), so you know you are not locked. This allows a "door ajar" state if door shows closed, by lock not engaged in a sensible time.

I also created the idea of a deadlock, so an output for that and a deadlock engaged input. This allows for doors to have extra locks when alarm set.

The system also allows for the notion that a closing door can take time to close, either for lock to engage or simply a time of a few seconds, and opening during that is NOT a door forced event! The source of so many texts I get from our Galaxy system. I will be really glad to kill the event!

The keypad code is fun - an event for key presses, but a simple memory mapped text area for display- sending new display text on next poll if changed. Makes for easy app coding.

At this stage my library has low level code for Max readers and keypads, and will soon have RIOs. It also has logical system management for doors.

Next step is "alarm panel" logic, and deploy on some Raspberry PIs, and RS485 USB cables, and sorted!

This is basically a complete alarm system coded in less that a week, I know! My plan is changing my house over this weekend.

The video blog of progress :-

2017-07-05

Alarm panel code

Now I am over the whole broken RS485 cable, I am making a lot more progress.

I have pondered the design a few times and eventually came up with the idea of a C library to manage the low level polling as threads with real time scheduling priority. The library links in to an application.

The threads have shared data structures that allow the application to set things as needed, and the polling system picks up that something has changed and sends the messages needed. It handles resends and waiting for the reply for the message to confirm it is processed.

This means that the application can see the display for a keypad as no more than a char array to which it can write what it likes, and, as if by magic, that text ends up on the display within a few hundred milliseconds, if that. It makes for really easy application coding.

I do have the logic of "events" from the low level system as a queue to the application - being things like devices discovered or missing, tamper alerts, changes of state of inputs, keypad press events, etc... But for the application, all of the low level timing and sequencing is all hidden. It can see a key fob event and set an "open the door" bit, and it just happens.

I have coded the keypad logic so far and should be able to connect a max reader and a RIO soon to code those. Then I can make a proper "alarm panel" application with whatever integration of external systems I wish. I am thinking of a mysql backend for basic config and a web based system to edit and manage that - as that is pretty simple stuff.

Next step - do I open source my library? Maybe when it is finished.

2017-07-04

Techie: How would I do it?

One of the things with the hacking I am doing on this alarm panel is the fact that the messaging is more sort of state based, and means keep sending the same message in case it did not arrive. No sequence numbers or acknowledgments or such.

To be fair, it is not that bad - you poll (and send some message) and expect a response - so not getting one is a clue. But it is not ideal.

Now, the max readers. They have a number of outputs, being 7 LEDs, a beeping noisy thing, and the door release relay. They have a number of inputs such as door exit switch and door open sensor and tamper sensor.

If I was making a simple system to work on a state basis I would report a single status that covered all of those inputs and outputs. I would have a simple message that controlled all of those outputs.

Technically there is one extra input which could be added which is 4 bytes BCD code of nearby key fob code - present or not...

Now, that means you could keep sending the command to set the outputs until you see the status showing the outputs are what you expect.

It means that if something else sent a command to impact the output, like me hacking, or the device reset, or any circumstance where the outputs are not what is expected, you simple send the message to set the outputs as wanted.

This is a simple system.

It means tamper is just an input not a different damn message!
It means you cannot get stuck bleeping forever.

It is not what Honeywell / Galaxy do. Oh well. "legacy"

Wallot inspector

What is fun with a nice UV ink jet printer is on what you can print... One thing is a bank card. This is now my Monzo card, oops. Yeh, I can...