SDK Guard 1.0.1
SDK для связи с сетевыми контроллерами Iron logic
controller_events/main.cpp

Демонстрирует чтение журнала контроллера.

#include <exception>
#include <fstream> // для std::fstream
#include <iomanip> // для std::put_time
#include <iostream> // для std::cout и std::cin
// #define ILG_LOG // Раскомментируйте, чтобы включить показ отладочных сообщений
#define ILG_LOG_FILE // Писать лог в файл
using namespace ilg;
// Глобальные переменные:
size_t g_nMaxEvents = 0;
uint32_t g_nCtrFlags = 0;
ssize_t g_nEvReadIdx = -1;
ssize_t g_nEvWriteIdx = -1;
// Названия типов событий контроллера
const char* kEventTypeNames[] = {"Неизвестное событие",
"Открыто кнопкой изнутри",
"Ключ не найден в банке ключей",
"Ключ найден, дверь открыта",
"Ключ найден, доступ не разрешен",
"Открыто оператором по сети",
"Ключ найден, дверь заблокирована",
"Попытка открыть заблокированную дверь кнопкой",
"Дверь взломана",
"Дверь оставлена открытой (таймаут)",
"Проход состоялся",
"Перезагрузка контроллера",
"Заблокирована кнопка открывания",
"Попытка двойного прохода",
"Дверь открыта",
"Дверь закрыта",
"Пропало питание",
"Появилось питание",
"Включение замка (триггер)",
"Отключение замка (триггер)",
"Изменено состояние режима \"Электроконтроль\"",
"Переключение режима контроллера",
"Изменено состояние режима \"Пожар\"",
"Изменено состояние режима \"Охрана\"",
"Совершён вход в шлюз",
"Заблокирован вход в шлюз (занят)",
"Разрешен вход в шлюз",
"Заблокирован проход (Антипассбек)",
"Hotel (Изменен режим работы)",
"Hotel (Отработка карт)",
"Номер ключа"};
static_assert(ILG_EVENT_TYPE_SIZE == 31);
// Названия режимов контроллера
const char* kModeNames[] = {"Неактивный", "Норма", "Блок", "Свободно", "Ожидание"};
#ifdef ILG_LOG
const char kLogLevelChars[] = {'-', 'E', 'W', 'I', 'D'};
const char kLogFileName[] = "ilguard.log"; // Путь к лог файлу
void ILG_CALL LogCallback(ilg_log_level level, const char* pContext, const char* pMessage, void*) {
#if 1 // Запись в файл
std::fstream file(kLogFileName, std::ios_base::out | std::ios_base::app);
auto& out = file;
#else // иначе в консоль
auto& out = std::cout;
#endif
auto t = std::time(nullptr);
auto tmb = std::localtime(&t);
out << std::put_time(tmb, "%d-%m-%Y %H:%M:%S") << " [" << kLogLevelChars[level] << ' '
<< pContext << "] " << pMessage << std::endl;
}
#endif
void ILG_CALL MessageCallback(ilg_controller_msg nMsg, const void*, void* pUserData) {
try {
auto pController = static_cast<CController*>(pUserData);
pController->GetRtcParams(rRtc);
size_t nNewCount;
if (rRtc.nEventWriteIdx >= g_nEvReadIdx)
nNewCount = static_cast<size_t>(rRtc.nEventWriteIdx - g_nEvReadIdx);
else
nNewCount =
(g_nMaxEvents - static_cast<size_t>(g_nEvReadIdx - rRtc.nEventWriteIdx));
if (nNewCount != 0) {
std::cout << "{!} " << nNewCount << " новых событий" << std::endl;
g_nEvWriteIdx = rRtc.nEventWriteIdx;
}
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
}
// Показывает диапазон событий контроллера
void ShowEvents(CController& oController, size_t nIdx, size_t nCount) {
std::cout << "Чтение событий..." << std::endl;
auto tStartTime = now();
std::vector<uint64_t> oEvents(nCount);
oController.ReadEvents(nIdx, oEvents.data(), oEvents.size());
auto fWiegand = (g_nCtrFlags & ILG_CTR_F_WIEGAND) != 0;
ilg_direction nDirection;
uint8_t nKeyBankN;
ssize_t nKeyIdx;
ilg_key rKey;
uint8_t nFlags;
uint8_t nTrigger;
ilg_key_number rKeyNumber;
for (size_t i = 0; i < nCount; ++i) {
auto& nEvent = oEvents[i];
nType = oController.DecodeEventType(nEvent, &nFormat);
nDirection = ILG_DIRECTION_UNKNOWN;
memset(&rTime, 0, sizeof(rTime));
switch (nFormat) {
oController.DecodePassageEvent(nEvent, rTime, nDirection, nKeyBankN, nKeyIdx);
if (nKeyIdx != -1)
oController.ReadKeys(nKeyBankN, static_cast<size_t>(nKeyIdx), &rKey, 1);
break;
oController.DecodeTimeEvent(nEvent, rTime);
break;
oController.DecodeControllerModeEvent(nEvent, rTime, nMode, nFlags, nTrigger);
break;
oController.DecodeStateEvent(nEvent, rTime, nFlags, nTrigger);
break;
oController.DecodeKeyNumber(nEvent, rKeyNumber);
break;
break;
}
std::cout << std::setw(4) << (nIdx + i) % g_nMaxEvents << ". " << std::setw(2)
<< (uint)rTime.nDay << '.' << std::setw(2) << (uint)rTime.nMonth << ' '
<< std::setw(2) << (uint)rTime.nHour << ':' << std::setw(2) << (uint)rTime.nMinute
<< ':' << std::setw(2) << (uint)rTime.nSecond << ' ' << kEventTypeNames[nType];
switch (nDirection) {
std::cout << "|< ";
break;
std::cout << "|> ";
break;
break;
}
switch (nFormat) {
if (nKeyIdx != -1) {
if (rKey.fErased)
std::cout << "Ключ (банк " << (uint)nKeyBankN << ", позиция " << nKeyIdx
<< "): стёрт";
else
std::cout << "Ключ: " << KeyNumberToStr(rKey.rNumber, rKey.nFlags, fWiegand);
}
break;
std::cout << "режим: " << kModeNames[nMode] << ", флаги: " << std::showbase << std::hex
<< std::setw(2) << (uint)nFlags << ", триггер: " << std::dec
<< (uint)nTrigger;
break;
std::cout << "флаги: " << std::showbase << std::hex << std::setw(2) << (uint)nFlags
<< ", триггер: " << std::dec << (uint)nTrigger;
break;
std::cout << "Ключ: " << KeyNumberToStr(rKeyNumber, 0, fWiegand);
break;
break;
}
std::cout << std::endl;
}
std::cout << "Выполнено за " << since(tStartTime).count() << " мс" << std::endl;
}
// Показывает все события контроллера
void ShowAllEvents(CController& oController) {
ShowEvents(oController, 0, g_nMaxEvents);
}
// Показывает новые события контроллера
void ShowNewEvents(CController& oController) {
size_t nNewCount;
if (g_nEvWriteIdx >= g_nEvReadIdx)
nNewCount = static_cast<size_t>(g_nEvWriteIdx - g_nEvReadIdx);
else
nNewCount = g_nMaxEvents - static_cast<size_t>(g_nEvReadIdx - g_nEvWriteIdx);
if (0 == nNewCount) {
std::cout << "Нет новых событий" << std::endl;
return;
}
ShowEvents(oController, static_cast<size_t>(g_nEvReadIdx), nNewCount);
g_nEvReadIdx =
static_cast<ssize_t>((static_cast<size_t>(g_nEvReadIdx) + nNewCount) % g_nMaxEvents);
}
// Открывает дверь
void OpenDoor(CController& oController, bool fOut) {
auto tStartTime = now();
oController.OpenDoor(fOut);
std::cout << "Выполнено за " << since(tStartTime).count() << " мс" << std::endl;
}
// Подключается к конвертеру
bool DoConnectToConverter(CILG& oILR, CConverter& oConverter) {
// Ищем конвертеры
CConverterSearch oSearch(oILR.GetSearch());
std::cout << "Поиск конвертеров..." << std::endl;
oSearch.Scan();
auto nCount = oSearch.GetConverterCount();
if (0 == nCount) {
std::cout << "Конвертер не найден" << std::endl;
return false;
}
std::cout << "Найдено конвертеров: " << nCount << std::endl;
std::cout << std::endl << "Выберите конвертер:" << std::endl;
for (size_t i = 0; i < nCount; i++) {
oSearch.GetConverterInfo(i, rInfo);
std::stringstream ss;
ss << kConverterModelNames[rInfo.nModel];
if (rInfo.nSn != -1)
ss << " с/н:" << rInfo.nSn;
if (rInfo.nFwVersion != 0)
ss << " прошивка:" << VersionToStr(rInfo.nFwVersion);
if (rInfo.nFwBuildDate != 0)
ss << " сборка " << TimeToStr(rInfo.nFwBuildDate);
ss << " режим: " << kConverterModeNames[rInfo.nMode];
std::cout << 1 + i << ". " << rInfo.pszPortName << " [" << rInfo.pszConnect
<< "]: " << ss.str() << std::endl;
}
std::cout << "0 - Выйти из программы" << std::endl;
int nCommand;
std::cin >> nCommand;
if (std::cin.fail()) {
std::cin.clear();
nCommand = -1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if ((nCommand <= 0) || (static_cast<size_t>(nCommand) > nCount))
return false;
oSearch.GetConverterInfo(static_cast<size_t>(nCommand - 1), rInfo);
std::cout << "Подключение к конвертеру [" << kPortTypeNames[rInfo.nPortType] << ": "
<< rInfo.pszPortName << "]..." << std::endl;
oConverter = oILR.GetConverter(rInfo.nPortType, rInfo.pszPortName);
oConverter.GetOptions(rOptions);
rOptions.nConnectModel = rInfo.nModel;
oConverter.SetOptions(rOptions);
// Подключаемся к конвертеру
oConverter.Connect();
// Получаем информацию о конвертере
oConverter.GetConverterInfo(rInfo);
std::stringstream ss;
ss << kConverterModelNames[rInfo.nModel];
if (rInfo.nSn != -1)
ss << " с/н:" << rInfo.nSn;
if (rInfo.nFwVersion != 0)
ss << " прошивка:" << VersionToStr(rInfo.nFwVersion);
if (rInfo.nFwBuildDate != 0)
ss << " сборка " << TimeToStr(rInfo.nFwBuildDate);
ss << " режим: " << kConverterModeNames[rInfo.nMode];
std::cout << "Конвертер успешно подключён [" << ss.str() << ']' << std::endl;
return true;
}
// Подключается к контроллеру
bool DoConnectToController(CConverter& oConverter, CController& oController) {
// Поиск контроллеров
int nCommand;
while (true) {
printf("Выберите контроллер:\n");
oConverter.Scan();
auto nCount = oConverter.GetControllerCount();
for (size_t i = 0; i < nCount; i++) {
oConverter.GetControllerInfo(i, rInfo);
std::cout << i + 1 << ". #" << (uint)rInfo.nAddress << ": "
<< kControllerModelNames[rInfo.nModel] << " с/н:" << rInfo.nSn
<< " прошивка:" << VersionToStr(rInfo.nFwVersion) << std::endl;
}
if (0 == nCount)
std::cout << "1 - Искать снова" << std::endl;
std::cout << "0 - Выйти из программы" << std::endl;
std::cin >> nCommand;
if (std::cin.fail()) {
std::cin.clear();
nCommand = -1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (0 == nCommand)
return false;
if ((nCommand >= 1) && (static_cast<size_t>(nCommand) <= nCount))
break;
}
oConverter.GetControllerInfo(static_cast<size_t>(nCommand - 1), rInfo);
oController = oConverter.GetController(rInfo.nModel, rInfo.nSn);
// Подключаемся к контроллеру
std::cout << "Подключение к контроллеру [" << kControllerModelNames[rInfo.nModel] << ": "
<< rInfo.nSn << "]..." << std::endl;
oController.Connect();
// Получаем информацию о контроллере
oController.GetControllerInfo(rInfo);
std::cout << "Контроллер успешно подключён [#" << (uint)rInfo.nAddress << ' '
<< kControllerModelNames[rInfo.nModel] << " с/н:" << rInfo.nSn
<< " прошивка:" << VersionToStr(rInfo.nFwVersion) << ']' << std::endl;
// Выключаем авто поиск контроллеров (не обязательно)
oConverter.SetAutoScan(false);
return true;
}
int main() {
try {
#ifdef ILG_LOG
#ifdef ILG_LOG_FILE
// Очищаем лог файл
std::ofstream file(kLogFileName, std::ios_base::out | std::ios_base::trunc);
file.close();
#endif
// Включаем лог отладки
CILG::SetLogCallback(LogCallback);
CILG::SetLogLevel(ILG_LOG_LEVEL_DEBUG);
#endif
CILG oILG;
// Подключаемся к конвертеру
CConverter oConverter;
if (!DoConnectToConverter(oILG, oConverter))
return 0;
// Подключаемся к контроллеру
CController oController;
if (!DoConnectToController(oConverter, oController))
return 0;
oController.SetMessageCallback(MessageCallback, &oController);
// Получаем информацию о контроллере
oController.GetControllerInfo(rInfo);
g_nMaxEvents = (rInfo.nBankSize / 8);
g_nCtrFlags = rInfo.nCtrFlags;
oController.ReadRtcParams(rRtc);
g_nEvWriteIdx = rRtc.nEventWriteIdx;
g_nEvReadIdx = g_nEvWriteIdx;
while (true) {
std::cout << "-----" << std::endl;
std::cout << "Введите номер команды:" << std::endl;
std::cout << "1 - Показать все события" << std::endl;
std::cout << "2 - Показать новые события" << std::endl;
std::cout << "3 - Открыть дверь (вход)" << std::endl;
std::cout << "4 - Открыть дверь (выход)" << std::endl;
std::cout << "0 - Выйти из программы" << std::endl;
int nCommand;
std::cin >> nCommand;
if (std::cin.fail()) {
std::cin.clear();
nCommand = -1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
switch (nCommand) {
case 0:
return 0;
case 1:
ShowAllEvents(oController);
break;
case 2:
ShowNewEvents(oController);
break;
case 3:
OpenDoor(oController, false);
break;
case 4:
OpenDoor(oController, true);
break;
default:
std::cout << "Неправильный ввод" << std::endl;
break;
}
}
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Класс контроллера.
Definition: ilg_cpp_helpers.h:680
void SetMessageCallback(ilg_controller_message_callback pCallback, void *pUserData=nullptr)
Устанавливает функцию обратного вызова для уведомлений контроллера.
Definition: ilg_cpp_helpers.h:2171
void GetControllerInfo(ilg_controller_info &rInfo) const
Возвращает информацию о контроллере.
Definition: ilg_cpp_helpers.h:2220
void ReadKeys(uint8_t nBankN, size_t nIdx, ilg_key *pBuf, size_t nCount, size_t *pRead=nullptr)
Читает ключи из памяти контроллера.
Definition: ilg_cpp_helpers.h:2358
void DecodeControllerModeEvent(const uint64_t &nEvent, ilg_controller_time &rTime, ilg_controller_mode &nMode, uint8_t &nFlags, uint8_t &nTrigger)
Декодирует событие переключения режима контроллера.
Definition: ilg_cpp_helpers.h:2750
void DecodeTimeEvent(const uint64_t &nEvent, ilg_controller_time &rTime)
Декодирует событие с датой и временем.
Definition: ilg_cpp_helpers.h:2746
void Connect(bool fReconnect=false)
Подключается к контроллеру.
Definition: ilg_cpp_helpers.h:2194
void DecodeStateEvent(const uint64_t &nEvent, ilg_controller_time &rTime, uint8_t &nFlags, uint8_t &nTrigger)
Декодирует событие изменения состояния.
Definition: ilg_cpp_helpers.h:2758
void DecodePassageEvent(const uint64_t &nEvent, ilg_controller_time &rTime, ilg_direction &nDirection, uint8_t &nKeyBankN, ssize_t &nKeyIdx)
Декодирует событие прохода.
Definition: ilg_cpp_helpers.h:2739
void DecodeKeyNumber(const uint64_t &nEvent, ilg_key_number &rKeyNumber)
Декодирует событие с номером ключа.
Definition: ilg_cpp_helpers.h:2763
ilg_event_type DecodeEventType(const uint64_t &nEvent, ilg_event_format *pFormat=nullptr)
Определяет тип события контроллера и формат записи события.
Definition: ilg_cpp_helpers.h:2732
void ReadRtcParams(ilg_rtc_params &rParams)
Читает параметры RTC из контроллера.
Definition: ilg_cpp_helpers.h:2462
void ReadEvents(size_t nIdx, uint64_t *pBuf, size_t nCount, size_t *pRead=nullptr)
Читает события из памяти контроллера.
Definition: ilg_cpp_helpers.h:2437
void OpenDoor(bool fOut)
Открывает дверь.
Definition: ilg_cpp_helpers.h:2544
Класс поиска конвертеров.
Definition: ilg_cpp_helpers.h:265
Класс конвертера.
Definition: ilg_cpp_helpers.h:2778
CController GetController(ilg_controller_model nModel, int nSn)
Возвращает дескриптор подключения к контроллеру.
Definition: ilg_cpp_helpers.h:3410
void Scan(bool fReset=false, bool fForce=false)
Ищет контроллеры.
Definition: ilg_cpp_helpers.h:3362
void GetControllerInfo(size_t nIdx, ilg_controller_info &rInfo) const
Возвращает инфо о найденном контроллере.
Definition: ilg_cpp_helpers.h:3379
void SetOptions(const ilg_converter_options &rOptions)
Устанавливает параметры конвертера.
Definition: ilg_cpp_helpers.h:3255
void SetAutoScan(bool fEnable=true, bool fWait=false)
Вкл/выкл режим авто поиска контроллеров.
Definition: ilg_cpp_helpers.h:3383
void GetConverterInfo(ilg_converter_info &rInfo) const
Возвращает информацию о конвертере.
Definition: ilg_cpp_helpers.h:3289
void Connect(bool fReconnect=false)
Подключается к конвертеру.
Definition: ilg_cpp_helpers.h:3263
size_t GetControllerCount() const
Возвращает количество найденных контроллеров.
Definition: ilg_cpp_helpers.h:3373
void GetOptions(ilg_converter_options &rOptions) const
Возвращает параметры конвертера.
Definition: ilg_cpp_helpers.h:3259
Класс для инициализации/финализации библиотеки SDK.
Definition: ilg_cpp_helpers.h:3425
CConverterSearch GetSearch()
Создаёт дескриптор поиска конвертеров.
Definition: ilg_cpp_helpers.h:3575
CConverter GetConverter(ilg_port_type nPortType, const char *pszPortName)
Создаёт дескриптор конвертера.
Definition: ilg_cpp_helpers.h:3581
ilg_event_format
Definition: ilguard.h:1251
ilg_event_type
Definition: ilguard.h:1183
ilg_controller_msg
Сообщение контроллера.
Definition: ilguard.h:972
ilg_direction
Definition: ilguard.h:1270
@ ILG_CTR_F_WIEGAND
Definition: ilguard.h:849
@ ILG_EVENT_TYPE_SIZE
Definition: ilguard.h:1247
@ ILG_CONTROLLER_MSG_RTC_CHANGED
Definition: ilguard.h:995
@ ILG_DIRECTION_UNKNOWN
Definition: ilguard.h:1272
@ ILG_DIRECTION_IN
Definition: ilguard.h:1274
@ ILG_DIRECTION_OUT
Definition: ilguard.h:1276
Заголовочный файл SDK Guard с классами-помощниками C++.
std::chrono::steady_clock::time_point now()
Definition: ilg_cpp_helpers.h:3605
auto since(std::chrono::time_point< clock_t, duration_t > const &start)
Возвращает интервал времени в миллисекундах от времени start до текущего времени.
Definition: ilg_cpp_helpers.h:3616
Заголовочный файл API SDK Guard.
#define ILG_CALL
Макрос, определяющий соглашение о вызове функций.
Definition: ilguard.h:68
@ ILG_CONVERTER_MODE_UNKNOWN
Definition: ilguard.h:327
ilg_controller_mode
Definition: ilguard.h:907
@ ILG_CONTROLLER_MODE_INACTIVE
Definition: ilguard.h:909
ilg_log_level
Уровень лога.
Definition: ilguard.h:434
@ ILG_LOG_LEVEL_DEBUG
Отладочные сообщения.
Definition: ilguard.h:464
@ ILG_CONVERTER_MODEL_UNKNOWN
Definition: ilguard.h:287
@ ILG_EVENT_FORMAT_PASSAGE
Definition: ilguard.h:1255
@ ILG_EVENT_FORMAT_UNKNOWN
Definition: ilguard.h:1253
@ ILG_EVENT_FORMAT_TIME
Definition: ilguard.h:1257
@ ILG_EVENT_FORMAT_STATE
Definition: ilguard.h:1261
@ ILG_EVENT_FORMAT_CONTROLLER_MODE
Definition: ilguard.h:1259
@ ILG_EVENT_FORMAT_KEY_NUMBER
Definition: ilguard.h:1263
Информация о контроллере.
Definition: ilguard.h:937
uint32_t nCtrFlags
Definition: ilguard.h:953
uint32_t nBankSize
Definition: ilguard.h:949
int nSn
Definition: ilguard.h:947
uint8_t nAddress
Definition: ilguard.h:943
uint32_t nFwVersion
Definition: ilguard.h:945
ilg_controller_model nModel
Definition: ilguard.h:939
Definition: ilguard.h:1323
uint8_t nHour
Час.
Definition: ilguard.h:1328
uint8_t nDay
День.
Definition: ilguard.h:1327
uint8_t nMinute
Минута.
Definition: ilguard.h:1329
uint8_t nMonth
Месяц.
Definition: ilguard.h:1325
uint8_t nSecond
Секунда.
Definition: ilguard.h:1330
Информация о конвертере.
Definition: ilguard.h:527
ilg_port_type nPortType
Definition: ilguard.h:529
const char * pszPortName
Definition: ilguard.h:531
int64_t nFwBuildDate
Definition: ilguard.h:545
ilg_converter_model nModel
Definition: ilguard.h:536
const char * pszConnect
Definition: ilguard.h:534
ilg_converter_mode nMode
Definition: ilguard.h:547
uint32_t nFwVersion
Definition: ilguard.h:542
int nSn
Definition: ilguard.h:538
Настройки конвертера.
Definition: ilguard.h:801
ilg_converter_model nConnectModel
Definition: ilguard.h:803
Номер ключа.
Definition: ilguard.h:1021
Definition: ilguard.h:1156
uint8_t fErased
Definition: ilguard.h:1158
uint8_t nFlags
Definition: ilguard.h:1160
ilg_key_number rNumber
Definition: ilguard.h:1175
Definition: ilguard.h:1306
ssize_t nEventWriteIdx
Definition: ilguard.h:1310