Здравствуйте.
Если задать поиск в сети Internet по ключевым словам PERCo-Web и 1С Вы найдете совсем немного статей на эту тему. А те что найдете, будут касаться устаревшей версии PERCo-S-20. Про PERCo-Web будет лишь информация, что где-то есть написанный модуль для 1С, и что его нужно будет купить.
Если Вам нужно получить данные из этой СКУД, то у Вас есть 2 пути: делать запросы к MySQL, на которой, скорее всего, "крутится" PERCo-Web или использовать API.
MySQL хоть и дает полный доступ к данным, но по умолчанию, не дает доступа с других ПК и моих знаний не хватило, как победить этот момент. API, к сожалению, ограничен данными, и выдает лишь только те, которые предусмотрел разработчик.
Все API инструкции Вы можете увидеть по адресу ВашСерверPERCo-Web/dev. Инструкций довольно много, но кому-то их может и не хватить.
Данные в этой статье мы будем получать через API путем HTTPЗапросов. HTTPЗапросов будет два вида: POST и GET. На самом деле, их больше, но для старта нам этого хватит. Остальное - сами или в комментариях.
Небольшое отступление. В 1С есть метод ВызватьHTTPМетод, в котором можно указать, какой в запросе метод post или get. Но он используется только для относительно новых версий платформы и только на сервере. Будем стремиться к универсальности. Поэтому, мы будем использовать методы: ОтправитьДляОбработки для post и Получить для get. По этой же причине, я буду показывать код для простого приложения. Для управляемого Вы переделаете его сами.
Для начала, нужно понять, что для получения данных, как и в любом другом случае, нам нужно авторизоваться на сервере. Авторизация здесь происходит не по логину паролю, а по длинной строке различных символов. Такая строка называется ключом или токеном. А вот сам токен уже можно получить по логину и паролю.
Вы можете получить токен, при помощи API запроса /system/auth. В документации есть подробный раздел даже с примерами для разных языков программирования, но, видимо, разработчик 1С за язык не считает, потому его (примера) для 1С нет. В документации написано, что следует использовать метод POST. Для получения токена я написал такую функцию:
Функция ВернутьТокен (server, login, password)
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer null");
	
	// Запрос     
	АдресЗапроса = "/system/auth";
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	
	// Параметры запроса.
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("login", login);
	ПараметрыЗапроса.Вставить("password", password);
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.ПроверятьСтруктуру = Ложь;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
	тхтJSON = ЗаписьJSON.Закрыть();
	Запрос.УстановитьТелоИзСтроки(тхтJSON);
	
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.ОтправитьДляОбработки(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть();
			Возврат Данные.token;
		Иначе
			Возврат Неопределено;
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
		Возврат Неопределено;
	КонецПопытки;
КонецФункции
Теперь для получения токена следует выполнить код вида:
Токен = ВернутьТокен("server/api","login","password"); //вставьте реальные данные вместо server, login, password  
Затем, желательно, проверить, что токен это не Неопределено и только тогда использовать его для авторизации (аутентификации). Способы передачи токена для запроса:
- В заголовке «Авторизация»: «Bearer [ТОКЕН]»
- В параметре запроса ?token=[ТОКЕН]
Способ передачи токена в параметре запроса небезопасен, поэтому эта возможность будет удалена в ближайшее время.
Токен имеет короткое время действия, по окончании которого, он перестает действовать. Поэтому, мы будем его получать перед каждым запросом, и каждый раз он будет разным.
Теперь получим список сотрудников. Метод GET:
Процедура СписокСотрудников(Кнопка)
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Запрос     
	АдресЗапроса = "/users/staff/fullList";
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
		
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть(); 
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
Данные будут в массиве Данные. Разработчик понимает, что все сотрудники нам не нужны, поэтому в эту инструкцию встроен отбор по ids. Это параметр, но вставить его в тело, как в POST не получится, поэтому, добавим его просто изменив URL. Приведу пример для ids=2450,2040:
Процедура ОтборПоID(Кнопка)
	idсотрудников = "2450,2040"; //вставьте реальные данные вместо 2450,2040. можно один, можно больше двух
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Запрос     
	АдресЗапроса = "/users/staff/fullList";
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	Запрос.АдресРесурса = Запрос.АдресРесурса + "?ids=" + idсотрудников;
		
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть();
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
Третий пример - получение картинки. Там есть свои нюансы.
Процедура Картинка(Кнопка)
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	idсотрудника = "2450"; //вставьте реальные данные вместо 2450
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Запрос     
	АдресЗапроса = "/users/" + idсотрудника + "/image";
	АдресЗапроса = АдресЗапроса + "?field_id=1";
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть();
			ДД = Base64Значение(СтрЗаменить(Данные.image,"data:image/jpeg;base64,", "")); //убираем лишние данные из Base64строки, они в картинку не входят, в отличие от строки 
			кр = Новый Картинка(ДД);
			ЭлементыФормы.Картинка.Картинка = кр; //не забудьте на форме создать элемент управления поле картинки  "Картинка"
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
Адрес запроса формируется довольно сложно. Упростить его у меня не получилось.
Следующий пример - получение подробной информации о сотруднике:
Процедура ПодробнаяИнформация(Кнопка)
	ОчиститьСообщения();
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	id = "121"; //вставьте реальные данные вместо 121
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Запрос     
	АдресЗапроса = "/users/staff";
	АдресЗапроса = АдресЗапроса + "/" + id;
	//
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение,Истина); //обратите внимание на параметр Истина. Получаем данные в виде соответствий
			Чтение.Закрыть();
			Сообщить("Код:" + id);
			Сообщить("Найдены карты:");
			Для Каждого identifier Из Данные["identifier"] Цикл
				Сообщить("КодПропуска:" + identifier["identifier"]);
			КонецЦикла;
			Сообщить("Фото:" + Данные["photo"]);
			HTTPСоединение = Новый HTTPСоединение("server"); //вставьте реальные данные вместо server
			HTTPЗапрос = Новый HTTPЗапрос(Данные["photo"]);
			HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
			ДвоичныеДанныеКартинки = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
			ЭлементыФормы.Картинка.Картинка = Новый Картинка(ДвоичныеДанныеКартинки); //не забудьте на форме вставить картинку
			Сообщить("ТабНомер:" + Данные["tabel_number"]);
			Сообщить("Фамилия:" + Данные["last_name"]);
			Сообщить("Имя:" + Данные["first_name"]);
			Сообщить("Отчество:" + Данные["middle_name"]);
			Сообщить("Подразделений у сотрудника тут может быть несколько. Найдены следующие:");
			Для Каждого division Из Данные["division"] Цикл
				Сообщить(division.Значение);
			КонецЦикла;
			Сообщить("ДействительноПо:" + Данные.Получить("end_datetime"));			
			Сообщить("Найдены доступы:");
			Для Каждого access_template Из Данные["access_template"] Цикл
				Для Каждого Элемент Из access_template Цикл
					Сообщить(Элемент.Ключ + ":" + Элемент.Значение);
				КонецЦикла;
			КонецЦикла;			
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
Покажу, как использовать фильтр. Фильтр представляет собой неформатированный JSON - в одну строчку вида: {"type": "", "rows": [{"column": "", "value": ""}]} type: 'and' или 'or' - условие выборки, логическое И или ИЛИ. rows - массив объектов, содержащий название колонки и значение для поиска. Например, найдем сотрудника не по ID, а по табельному номеру "007", использовав фильтр {"type": "and","rows": [{"column": "tabel_number","value": "007"}]}
Процедура ПоискПоТабельному(Кнопка)
	ОчиститьСообщения();
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	tabel_number = "007"; //вставьте реальные данные вместо 007
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Параметры запроса.
	Фильтр = Новый Структура;
	Фильтр.Вставить("column","tabel_number");
	Фильтр.Вставить("value",tabel_number);
	Колонки = Новый Массив;
	Колонки.Добавить(Фильтр);
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("type", "and");
	ПараметрыЗапроса.Вставить("rows", Колонки);
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.ПроверятьСтруктуру = Ложь;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
	тхтJSON = ЗаписьJSON.Закрыть();
	//Уберем форматирование в JSON, сделаем в одну строку
	тхтJSON = СтрЗаменить(СтрЗаменить(тхтJSON,Символы.ПС,""),Символы.ВК,"");
	
	// Запрос     
	АдресЗапроса = "/users/staff/table";
	АдресЗапроса = АдресЗапроса + "?status=active" + "&filters=" + тхтJSON; //данная инструкция позволяет искать или только действующих, или только уволенных сотрудников, вставляем параметр действующих, второй параметр идет через знак &
	//
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть();
			Сообщить(ТекстОтвета);
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
Будьте внимательны! Фильтр ищет не по строгому соответствию, а по вхождению, то есть будут найдены все сотрудники, у которых в табельном встречается 007, например, не только 007, а еще и 0007 и 0070...
И последний пример - запись в СКУД - поменяем табельный номер 007, на 001. Тут следует использовать метод POST:
Процедура КнопкаВыполнитьНажатие(Кнопка)
	server = "server/api"; //вставьте реальные данные вместо server
	Токен = ВернутьТокен(server,"login","password"); //вставьте реальные данные вместо login, password
	ID = "007"; //вставьте реальные данные вместо 007
	 
	// Заголовок запроса.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-type", "application/json; charset=UTF-8");
	Заголовки.Вставить("Authorization", "Bearer " + Токен);
	
	// Запрос     
	АдресЗапроса = "/users/staff";
	АдресЗапроса = АдресЗапроса + "/" + ID;
	Запрос = Новый HTTPЗапрос(АдресЗапроса, Заголовки);
	
	// Параметры запроса.
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("tabel_number", "001"); //вставьте реальные данные вместо 001
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.ПроверятьСтруктуру = Ложь;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
	тхтJSON = ЗаписьJSON.Закрыть();
	Запрос.УстановитьТелоИзСтроки(тхтJSON);
		
	// Соединение
	Соединение  =  Новый HTTPСоединение(server);
	Попытка
		Ответ = Соединение.ОтправитьДляОбработки(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
		Если Ответ.КодСостояния = 200 Тогда
			Чтение = Новый ЧтениеJSON;
			Чтение.УстановитьСтроку(ТекстОтвета);
			Данные = ПрочитатьJSON(Чтение);
			Чтение.Закрыть(); 
		КонецЕсли;
	Исключение
		Соединение = Неопределено;
		Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
	КонецПопытки;
КонецПроцедуры
На сегодня это все! Жду вопросов, ответов на них, критики и пожеланий.... Вопрос от меня: Как получить доступ к MySQL PERCo-Web? Кто знает - пишите!
Вступайте в нашу телеграмм-группу Инфостарт
