Access control systems in IoT – we know how, we know, we practice

Hello again world!

In the last article about the IoT Christmas tree in the voting, many noted that the topic of controlling devices depending on the number of people in the room is interesting. This is a fairly large-scale task, and we propose to divide its solution into several stages. Today we’ll talk about an access control system (ACS), which, being connected to the Internet of Things platform Rightech IoT Cloud (hereinafter referred to as the platform), is a basic element in the system for counting the number of people in the office. We have already superficially covered this case in one of the articles, but today we will consider this project in more detail and dive into the specifics of execution.


Access control system, ACS (Physical Access Control System, PACS) – a set of software and hardware control and management, the main purpose of which is to restrict and register the entry and exit of objects (people, vehicles) on a given territory through “points of passage “: Doors, gates, checkpoint.

How it all started

The task of ensuring control over the entrance and exit in the office arose back in the days when we had an exit to the roof with an excellent view of Moscow, and therefore people who were not our employees often came. Then we decided to take some security measures and install an access control system.


Card door opening system

GATE-8000 was chosen as the module responsible for processing information on reading contactless cards.

The main advantages of the controller:

  • formation and storage of the necessary information about the fact of opening the door using the card and the time of a person’s passage to the office;

  • the possibility of autonomous operation and protection against freezing;

  • storage of 16 thousand keys and 8 thousand events;

  • easy connection and control;

  • Russian manufacturer, good documentation describing the operation of the controller.

External view of the board with the controller
External view of the board with the controller

The basic principle of operation: the controller processes the information coming from the reader, and with the help of the built-in relay switches the actuator – the electromagnetic door lock.

Platform interaction system

After the controller was installed in the system according to the general connection scheme, and the cards were written into memory, we already secured ourselves from outsiders entering the office. And then the question arose of how to connect this controller to the Rightech ioT Cloud platform. After all, it’s very cool to have a) a graphical interface in which you can look through the history of all passages, b) the ability to send commands to open the door remotely, without leaving the workplace, for example, for guests or a food delivery man.

The controller has no Internet access and no visible connectivity to the platform; moreover, all events must be read from its circular buffer forcibly. However, it has its own communication protocol with the control computer, thanks to which it is possible to send commands to the controller, such as read from the controller, write to the controller, open / close the lock, and others. This means that you need to make some software and hardware layer between the controller and the platform – an agent that will send commands to read events and control the controller.

Please note that in this architecture, the function of opening the door when the card is applied will not stop being performed in the absence of the Internet. The ACS controller is responsible for opening the door and collecting information, so in the event of a loss of the Internet, the only thing that threatens us is that the agent that delivers data to the platform will not function, since it will not be able to receive commands to read the buffer. However, when the connection is restored, all events are counted in full and will not be lost, since they will be saved in the buffer of the ACS controller.


To begin with, it was necessary to select a device that will always be in an active state with an enabled agent program in the immediate vicinity of the ACS board. From a variety of microcomputers the first thing that came to hand the choice fell on the Raspberry Pi.

Then the question arose of how to connect the GATE-8000 to the Raspberry – that is, how to connect the RS485 serial interface from the GATE to the USB from the microcomputer. The search for a USB-RS485 adapter has begun. The first option we tried was – Espada for 200 rubles. There was little hope that the little flimsy Chinese adapter would work. It didn’t work. Instead of the necessary data, something similar in appearance and size came, but … still not that. What was the matter: the lack of a galvanic isolation, the impossibility to maintain a speed of 19200 bps, or simply a poor-quality element base is a mystery. But after contacting the manufacturer GATE-8000, we received a recommendation for a more expensive (10 times) and bulky (but neat, even in the case) adapter Z-397that worked right there and then.

▍Programming part

We start developing a program by defining what functions it should perform.

  1. What you need is interaction with GATE-8000 to send commands and receive data.

    How we decide – we will study the GATE protocol, write a serializer and a data deserializer, connect a library for working with a serial port.

  2. What you need is interaction with the platform to receive commands and send data.

    How we decide – we will choose a protocol for communication MQTT, in the code we will use the ready-made Paho MQTT library.

So, we have begun to study the GATE-8000 protocol, which is closed, therefore, only some of its features are described below. It is quite low-level, and you need to access the device memory registers directly. The document on this protocol describes frames for requests from a computer to a controller and frames for responses from a controller to a computer. By changing the fields in the request frame, you can send various commands to the device and receive information from the registers.

One of the features of the protocol is that the computer is always the initiator of the exchange. Therefore, there are two approaches to working with the device:

1) set all the logic of work in the agent;

2) use external requests (from the platform).

We chose the second option and brought the logic from the end device to the platform (more about the service automation scripts >>>). So it is easy to adapt and fine-tune, while the program code remains compact and allows you to simply form commands for the device, and the platform, in turn, coordinates the sending of commands and their frequency.

Do you always need to remove the logic of work from the device?

Such a solution, of course, will not work if the device is required to take action instantly (for example, when it comes to human life), but even in this case, some of the logic can be brought to the platform. Alternatively, to select pre-programmed patterns of behavior.

After we carefully studied this protocol, frame format, and command list, the first difficulty arose. There were no commands for reading the buffer, which contains events about who came and what time. But getting this information is a top priority. It was necessary to examine the memory card of the controller to determine the addresses at which to read the data.

Controller memory card? WTF?

The controller memory card (a term from the protocol) means a table describing the filling of memory registers, and not a micro-flash drive =).

The next feature of working with the controller is that in one read cycle you can receive only 12 events, 8 bytes each. And for each passage of a person to the office, two events are already generated:

1) a key was found in the key bank (the key bank is another block in the distributed memory of the controller);

2) the passage took place (if, of course, it took place).

Below is a C ++ code snippet that implements a method for one buffer read cycle.

bool SerialPortInlet::readBufferCycle(unsigned short& bottom, unsigned short const& top, unsigned char& u_lowerBound,
    	unsigned char& l_lowerBound, std::vector<unsigned char>& readBuffer, std::string& result)
	// Подсчет байтов, которые необходимо считать
	unsigned short byteCountTmp = top - bottom;
	BOOST_LOG_SEV(log_, logging::info) << "Need read " << byteCountTmp << " byte";
	unsigned char byteCount;
	// За один цикл нельзя прочитать более 12 событий (96 байт)
	byteCount = byteCountTmp > 0x60 ? 0x60 : (unsigned char)byteCountTmp;
	BOOST_LOG_SEV(log_, logging::info) << "Read " << +byteCount << " byte";
	// Описываем тело команды
	std::vector<unsigned char> body = {0x02, 0xA0, byteCount, u_lowerBound, l_lowerBound};
	std::vector<unsigned char> command;
	// Получаем полный текст команды
	generateComplexCommand(command, Command::BYTE_CODE_READ, body);
	// Если не удалось по каким-то причинам отправить команду (например, конечное устройство не подключено), возвращается false
	if (!sendCommand(command, result))
    	return false;
	// Иначе отправляем ответ с устройства на парсинг по событиям
	SerialPortType::Answer answerEvents;
	if(!Parsers::parserAnswer(log_, result, answerEvents, Command::BYTE_CODE_READ))
    	BOOST_LOG_SEV(log_, logging::error) << "Failed parse buffer reading";
    	return false;
	readBuffer.insert(readBuffer.end(), answerEvents.body.begin(), answerEvents.body.end());
	// Сдвигаем нижнюю границу буфера для чтения следующих событий
	bottom = bottom + byteCount;
	u_lowerBound = (unsigned char)(bottom >> 8) ;
	l_lowerBound = (unsigned char)bottom;
	return true;

A little added to the hassle is that, finally pulling out the necessary bytes, at the location of the card information, we saw not the card number, but the address at which it is located. Therefore, then each key number has to be read separately by address. Also, we did not immediately notice the presence of bytestaffing, we introduced its processing after the first testing with the board.


The bytestaffing procedure consists in replacing the reserved characters in the packet body with a special sequence that does not contain these characters.

An example of bytestaffing from the documentation
An example of bytestaffing from the documentation

The complete block diagram of the developed system looks like this.

It was very convenient to check the performance of all devices using a graphical serial terminal СuteCom… After successful testing, the program was set to autorun, and Raspberry went to live on the ceiling next to the ACS board.

One does, the other looks, the third takes pictures - a real teamwork =)
One does, the other looks, the third takes pictures – a real teamwork =)

Work on the Rightech IoT Cloud platform


The main data from the controller are events, they come to the platform in JSON format and include fields

  • eventTime – the time when the event occurred;

  • eventCode – event code;

  • keyNumber – employee card number (the field can be empty if the event was not triggered by a card).

The device model looks like this.

View original >>>

Possible events:

  • the bell button is pressed;

  • unidentified key at the entrance;

  • unidentified key at the exit;

  • the key was found in the key bank at the entrance;

  • the key was found in the key bank upon exiting;

  • opening by the operator over the network;

  • the door is locked by the operator;

  • the door is left open after entering;

  • the door is left open after exiting;

  • the passage took place at the entrance;

  • the passage took place at the exit;

  • reboot the controller.

An object

The object interface is completely formed according to the developed model.

Object log history interface
Object log history interface

View original >>>

Command interface
Command interface

Hurray, now, having gathered in the office kitchen waiting for pizza for the holiday, you can not go anywhere, but just open mobile app and press the button to open the door for the courier!


You can see that there is a command not only for reading the event buffer, but also for writing new boundaries. The memory of the controller stores the buffer boundaries – the beginning and the end. When a read command comes to the device, these boundaries are taken from memory and read from the event buffer occurs within them. The boundary of the end of the buffer is shifted automatically on the controller when new events are received. But the initial boundary of the buffer must be overwritten (by specifying the final boundary after the last read) so as not to read the same data again. But this needs to be done only after the event data has been successfully sent to the platform.

It is convenient to record the successful receipt of data and then send a command to overwrite the initial boundary in the machine.

View original >>>

Here you can see the cycle (now events are read every 30 seconds).

  1. In the “Read events” state, we read new events.

  2. In the “Clear buffer” state, write a new border.

  3. In the “Await timer…” state, we are waiting for the start of a new cycle.

There are also additional feedbacks for the states in which commands are sent. If the command has not been successfully executed during the timer operation, the timer is triggered and a corresponding message is sent to the operator, after which the command is re-sent.

Further use of the collected data

This project has found its continuation in integration with our internal CRM system, in which the employee information tab always displays up-to-date information about who is or is absent from the office.

The time of entry / exit from the office is also displayed, the total number of hours per month is considered.

View original >>>

Every day it is written to the Slack messenger that the office is open when the first person arrives to take the keys at the reception.

Data collection from the platform is performed using the REST API. The platform API provides the ability to work, interact and use the platform entities and their data in such external systems as web portals, mobile and web applications, or, in our case, CRM systems.

Look a project with an example of setting up interaction and receiving data from the platform >>>

Now we know a little more about how ACS can work in IoT projects. In the following materials, we will consider how to calculate the number of people in the office based on the information received and what practical applications this idea has.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *