SDK Guard 1.1.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
#include "../ilg_cpp_helpers.h"
// #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 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 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& oILG, CConverter& oConverter) {
// Ищем конвертеры
CConverterSearch oSearch(oILG.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 = oILG.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;
}
ilg_event_format
Definition: ilguard.h:1238
ilg_event_type
Definition: ilguard.h:1170
ilg_controller_msg
Сообщение контроллера.
Definition: ilguard.h:959
ilg_direction
Definition: ilguard.h:1257
@ ILG_CTR_F_WIEGAND
Definition: ilguard.h:836
@ ILG_EVENT_TYPE_SIZE
Definition: ilguard.h:1234
@ ILG_CONTROLLER_MSG_RTC_CHANGED
Definition: ilguard.h:982
@ ILG_DIRECTION_UNKNOWN
Definition: ilguard.h:1259
@ ILG_DIRECTION_IN
Definition: ilguard.h:1261
@ ILG_DIRECTION_OUT
Definition: ilguard.h:1263
Заголовочный файл API SDK Guard.
@ ILG_CONVERTER_MODE_UNKNOWN
Definition: ilguard.h:314
ilg_controller_mode
Definition: ilguard.h:894
@ ILG_CONTROLLER_MODE_INACTIVE
Definition: ilguard.h:896
ilg_log_level
Уровень лога.
Definition: ilguard.h:421
@ ILG_LOG_LEVEL_DEBUG
Отладочные сообщения.
Definition: ilguard.h:451
@ ILG_CONVERTER_MODEL_UNKNOWN
Definition: ilguard.h:274
@ ILG_EVENT_FORMAT_PASSAGE
Definition: ilguard.h:1242
@ ILG_EVENT_FORMAT_UNKNOWN
Definition: ilguard.h:1240
@ ILG_EVENT_FORMAT_TIME
Definition: ilguard.h:1244
@ ILG_EVENT_FORMAT_STATE
Definition: ilguard.h:1248
@ ILG_EVENT_FORMAT_CONTROLLER_MODE
Definition: ilguard.h:1246
@ ILG_EVENT_FORMAT_KEY_NUMBER
Definition: ilguard.h:1250
Информация о контроллере.
Definition: ilguard.h:924
uint32_t nCtrFlags
Definition: ilguard.h:940
uint32_t nBankSize
Definition: ilguard.h:936
int nSn
Definition: ilguard.h:934
uint8_t nAddress
Definition: ilguard.h:930
uint32_t nFwVersion
Definition: ilguard.h:932
ilg_controller_model nModel
Definition: ilguard.h:926
Definition: ilguard.h:1310
uint8_t nHour
Час.
Definition: ilguard.h:1315
uint8_t nDay
День.
Definition: ilguard.h:1314
uint8_t nMinute
Минута.
Definition: ilguard.h:1316
uint8_t nMonth
Месяц.
Definition: ilguard.h:1312
uint8_t nSecond
Секунда.
Definition: ilguard.h:1317
Информация о конвертере.
Definition: ilguard.h:514
ilg_port_type nPortType
Definition: ilguard.h:516
const char * pszPortName
Definition: ilguard.h:518
int64_t nFwBuildDate
Definition: ilguard.h:532
ilg_converter_model nModel
Definition: ilguard.h:523
const char * pszConnect
Definition: ilguard.h:521
ilg_converter_mode nMode
Definition: ilguard.h:534
uint32_t nFwVersion
Definition: ilguard.h:529
int nSn
Definition: ilguard.h:525
Настройки конвертера.
Definition: ilguard.h:788
ilg_converter_model nConnectModel
Definition: ilguard.h:790
Номер ключа.
Definition: ilguard.h:1008
Definition: ilguard.h:1143
uint8_t fErased
Definition: ilguard.h:1145
uint8_t nFlags
Definition: ilguard.h:1147
ilg_key_number rNumber
Definition: ilguard.h:1162
Definition: ilguard.h:1293
ssize_t nEventWriteIdx
Definition: ilguard.h:1297