В данном разделе представлены примеры наиболее востребованных правил и скриптов. С их помощью вы можете на реальных примерах понять принципы автоматизации и настроить автоматизацию в своей системе видеонаблюдения. К каждому примеру прилагается описание, также в примерах описаны возможности применения правила/скрипта.
Отправка e-mail при потере сигнала с камеры
В данном примере будет рассмотрено правило, которое предназначено для своевременного оповещения о неполадках на сервере, в частности об отсутствии сигнала с какой-либо приоритетной камеры в системе: при потере сигнала с выбранной камеры будет отсылаться e-mail с уведомлением об этом событии.
- Предварительно, необходимо создать учетную запись e-mail. После этого создайте новое правило и выберите тип активации По событию, в появившемся окне найдите раздел Канал и поставьте галочку в чекбоксе Сигнал потерян.
- Далее нужно определить объекты, на событие от которых будет реагировать правило. Для этого в окне правила нажмите на ссылку Фильтр и в списке объектов выберите интересующую Вас камеру. В нашем случае это камера с названием "Склад".
-
После этого нажмите на ссылку Отправить письмо - появится форма для создания шаблона письма. В результате у Вас должно получиться правило примерно такого вида:

На следующем изображении показан пример правила с противоположным действием: в том случае, если сигнал с камеры "Склад" будет восстановлен, будет отправлено письмо с информацией о том, что сигнал на этой камере был восстановлен.

Ниже представлен пример скрипта с расширенным функционалом: письмо будет отправляться при потере сигнала с любой камеры, и в письме будет указано название соответствующего канала:
def send_message(event):
message_text = '''На сервере [имя сервера] пропал сигнал на камере "%s".\
Нужно позвонить на охрану по номеру 123456789.'''\
% event.origin_object.name
send_mail_from_account("sender@mail.net", ["addressee@mail.net"],\
"Тема письма: нет сигнала с камеры '%s'" % event.origin_object.name,\
message_text, [])
activate_on_events("Signal Lost", "", send_message)
Отображение камеры на весь экран при детекции движения
В этом примере мы рассмотрим правило, которое предназначено для привлечения внимания оператора к тем камерам, на которых сам факт наличия движения является тревожным событием: при возникновении движения на определенной камере, она будет разворачиваться на весь экран на выбранном мониторе.
- Предварительно, необходимо включить генерацию событий о появлении движения на нужной камере. Для этого в настройках сервера зайдите в раздел Каналы, выберите нужный канал и поставьте галочку в чекбоксе Генерировать события о появлении движения. После этого в журнал событий начнут поступать события о движении на данном канале.
- Далее создайте новое правило и выберите тип активации По событию. В появившемся окне найдите раздел Канал и поставьте галочку в чекбоксе Движение обнаружено.
- После этого нужно определить объекты, на событие от которых будет реагировать правило. Для этого в окне правила нажмите на ссылку Фильтр и выберите интересующую Вас камеру. В нашем случае это камера с названием "Холодный склад".
- Далее нажмите на ссылку Вызвать действие, в появившемся окне слева выберите раздел Интерфейс оператора [имя сервера], а в правом выберите строку show_channel. После этого в правиле появится возможность указать канал и монитор.

Ниже представлен пример скрипта с расширенным функционалом: любая камера, на которой будет возникать движение, будет разворачиваться на второй монитор. Для этого нужно поставить галочку Генерировать события о появлении движения в настройках нужных каналов, создать новый скрипт и вставить в него следующий код:
def show_channel_with_motion(event):
object("Интерфейс оператора [имя сервера]").\
show_channel(event.origin,2)
activate_on_events("Motion Start", "", show_channel_with_motion)
Воспроизведение звука при размыкании тревожного входа
В этом примере мы рассмотрим правило, которое предназначено для привлечения внимания оператора к тревожной ситуации путем воспроизведения звукового файла. Согласно примеру, при размыкании тревожного входа будет воспроизводиться звуковое оповещение. С помощью тревожного входа можно контролировать, например, дверь или окно, а также какие-либо датчики.
- Создайте новое правило и выберите тип активации По событию. В появившемся окне найдите раздел GPIO вход и поставьте галочку в чекбоксе Сигнал на входе пропал.
- Далее нажмите на ссылку Фильтр и в списке объектов выберите интересующий Вас тревожный вход. В нашем случае это объект с названием "Запасный выход(дверь)".
- После этого нажмите на ссылку Проиграть звук и в выпадающем списке выберите один из предустановленных звуков.

Ниже представлен пример правила с противоположной активацией: в том случае, если сработает замыкание тревожного входа, будет воспроизведен звуковой файл для оповещения оператора о закрытии двери запасного выхода.

Увеличение FPS на камере при изменении состояния устройства Орион
В этом примере мы рассмотрим правило, которое предназначено для увеличения детализации видеоряда в случае возникновения тревожных ситуаций для их последующего подробного анализа. Согласно данному правилу, при изменении состояния устройства АРМ Орион, будет увеличиваться FPS на одной из камер.
- Создайте новое правило и выберите тип активации По изменению состояния. В появившемся окне найдите раздел Orion и поставьте галочку в чекбоксе нужного устройства.
- После этого нажмите на ссылку Изменить настройки. В окне Вставка настроек нужно раскрыть раздел IP-устройства, выбрать нужное IP-устройство и выбрать строку channel00_fps. После этого в появившемся поле введите нужное количество FPS.

Ниже представлен пример скрипта с расширенным функционалом, согласно которому при изменении состояния устройства АРМ Орион, будет увеличиваться FPS на всех камерах.
def set_fps_on_all_devices(fps):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
for c in range(0, 16):
d["channel%02d_fps" % c] = fps
for b in settings("boards").ls():
for i in range(0, 16):
b["channel%02d_fps" % i] = fps
def condition():
if object_sh1p127.state("state") == "Alarm"
set_fps_on_all_devices(25)
elif object_sh1p127.state("state") == "Armed"
set_fps_on_all_devices(12)
object_sh1p127 = object("ШС 1, Прибор 127")
object_sh1p127.activate_on_state_changes(condition)
Отправка e-mail при изменении индикатора здоровья сервера
В данном примере будет рассмотрено правило, согласно которому при отключении базы данных и/или при возникновении ошибок диска на сервере, будет отсылаться e-mail с уведомлением.
- Предварительно, необходимо создать учетную запись e-mail. После этого создайте новое правило и выберите тип активации По событию, в появившемся окне найдите раздел Сервер и поставьте галочку в чекбоксе Здоровье сервера испортилось.
- Далее нажмите на ссылку Фильтр и в окне Вставка объекта поставьте галочку в чекбоксе нужного сервера.
-
Для того, чтобы письма отсылались только в случае отключения базы данных и/или при возникновении ошибок диска, нужно задать соответствующие условия:
- Найдите раздел Здоровье и выберите строку disks_error_count. Затем нужно указать значение для параметра disks_error_count: для этого в поле ввода допишите " == 1" без кавычек.
- Найдите раздел Здоровье и выберите строку db_connected. Затем нужно указать значение для параметра db_connected: для этого в поле ввода допишите " == 0" без кавычек.
Между условиями выберите связку or.
-
Далее нажмите на ссылку Отправить письмо - появится форма для создания шаблона письма. В результате у Вас должно получиться правило примерно следующего вида:

Ниже представлено правило, согласно которому при изменении состояния сервера на нормальное будет отправлено письмо с уведомлением об этом.

Включение сирены при размыкании тревожного входа ночью
В этом примере мы рассмотрим правило, которое предназначено для поднятия тревоги в случае проникновения на объект в ночное время. В рассматриваемом примере используется расписание, контакты тревожного входа на двери запасного выхода и контакты тревожного выхода, подключенные к сирене - таким образом, если дверь запасного выхода будет открыта в ночное время, включится сирена.
-
Предварительно, необходимо создать расписание.

- Далее создайте новое правило и выберите тип активации По событию. В появившемся окне найдите раздел GPIO вход и поставьте галочку в чекбоксе Сигнал на входе пропал.
- После этого нажмите Фильтр и в окне Вставка объекта поставьте галочку в чекбоксе тревожного входа, в нашем случае это "Запасный выход(дверь)".
- Далее нам необходимо связать это правило с расписанием, чтобы оно отрабатывало только ночью. Для этого в Условии выберите строку Состояния объектов, затем укажите ранее созданное расписание, нажмите color и выберите красный цвет.
-
После этого в окне правила нажмите на ссылку Вызвать действие, в окне Вставка объекта выберите тревожный выход, к которому подключена сирена, и строку set_output_high. В итоге правило должно выглядеть примерно следующим образом:

Ниже представлен пример правила с противоположной активацией: в том случае, если дверь запасного выхода закроется(тревожный вход будет замкнут), через 5 секунд сирена выключится(тревожный выход будет разомкнут).

Создание и отображение пользовательских сообщений в журнале СКУД
В этом примере мы рассмотрим правило, которое создает пользовательское событие и выводит его в журнале TRASSIR СКУД

-
Создайте новое правило и выберите тип активации По горячей клавише, в появившемся окне в поле На клавиатуре нажмите клавишу, при нажатии на которую будет выполняться данное правило.
-
Далее нажмите на ссылку Вызвать действие, в появившемся окне слева выберите раздел СКУД и Точку доступа, а в правом выберите строку emit_custom_event(string_title, string_color, string_person_guid, string_details_json). Нажмите ОК. После этого в правиле появится возможность указать параметры пользовательского события.

-
В качестве параметров пользовательского события укажите следующее:
-
В поле title введите заголовок пользовательского события.
-
В поле color введите цвет события (в формате HEX). Все события TRASSIR СКУД созданные этим правилом будут окрашены в этот цвет.
-
В поле person guid введите GUID персоны TRASSIR СКУД, от имени которой будут отображаться пользовательские события.
Процесс получения GUID объекта сервера описан TRASSIR SDK в разделе Работа с объектами.
Для отображения события от имени системы введите "" (пустые кавычки).
-
В поле details json введите параметры события (в формате JSON, в одинарных кавычках), которые будут отображаться в пользовательском событии в качестве дополнительной информации. При этом в качестве параметров вы можете использовать свойства персоны:
Например,
'{"card_id": "1234567890", "plate": "AA123BB456", "comment": "Alarm"}'Где,
card_id - номер карты;
plate - автомобильный номер;
comment - произвольный комментарий.
Подсказка
Если в поле person guid введен GUID персоны TRASSIR СКУД, то в свойствах card_id и plate должны быть указаны номер карты и автомобильный номер персоны, которые введены в параметрах этой персоны.
Если поле person guid пустое, то могут быть указаны любые значения.
-
Изменение FPS на всех каналах ночью
В этом примере мы рассмотрим скрипт, который предназначен для изменения FPS на всех каналах по расписанию: при наступлении ночи, FPS на всех каналах будет изменяться на 12 к/с, а при наступлении дня - на 25 к/с.
Предварительно, необходимо создать расписание. На скриншоте ниже показана настройка расписания для данного примера.

После этого нужно создать новый скрипт и скопировать в него следующий код.
def set_fps_on_all_devices(fps):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
for c in range(16):
d["channel%02d_fps" % c] = fps
for b in settings("boards").ls():
for i in range(16):
b["channel%02d_fps" % i] = fps
def condition():
if (object_schedule.state("color") == "Red") :
set_fps_on_all_devices(12)
elif (object_schedule.state("color") == "Green") :
set_fps_on_all_devices(25)
object_schedule = object("Ночь")
object_schedule.activate_on_state_changes(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В этой части скрипта указывается активатор, здесь активатором является расписание. Для привязки скрипта к любому другому расписанию достаточно заменить название расписания
object("Ночь").object_schedule = object("Ночь") object_schedule.activate_on_state_changes(condition) -
В функции condition описано условие, согласно которому если расписание находится в красной зоне, переменной "fps" задается значение 12, а если в зеленой, то 25.
def condition(): if (object_schedule.state("color") == "Red") : set_fps_on_all_devices(12) elif (object_schedule.state("color") == "Green") : set_fps_on_all_devices(25) -
В данной части скрипта для всех каналов всех устройств указывается количество кадров в секунду, равное переменной "fps".
def set_fps_on_all_devices(fps): for d in settings("ip_cameras").ls(): if d.type != "Grabber": continue for c in range(16): d["channel%02d_fps" % c] = fps for b in settings("boards").ls(): for i in range(16): b["channel%02d_fps" % i] = fps
Ниже представлена упрощенная версия скрипта, активатором которого будут горячие клавиши F5 и F6.
def set_fps_on_all_devices(fps):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
for c in range(16):
d["channel%02d_fps" % c] = fps
for b in settings("boards").ls():
for i in range(16):
b["channel%02d_fps" % i] = fps
def channel_fps_25():
set_fps_on_all_devices(25)
def channel_fps_12():
set_fps_on_all_devices(12)
activate_on_shortcut("F5", channel_fps_25)
activate_on_shortcut("F6", channel_fps_12)
Включение экономичного режима по всем устройствам типа "Lanser" в выходные дни
В этом примере мы рассмотрим скрипт, согласно которому все устройства семейства Lanser в будние дни будут работать в штатном режиме, а на выходных - в экономичном.
Предварительно, необходимо создать расписание. На скриншоте ниже показана настройка расписания для данного примера.

После этого нужно создать новый скрипт и скопировать в него следующий код.
def economy_mode_on_all_nvr(on):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
if d["family"] == "NVR":
d["economy_mode"] = on
def condition():
if (object_schedule.state("color") == "Red") :
economy_mode_on_all_nvr(1)
elif (object_schedule.state("color") == "Green") :
economy_mode_on_all_nvr(0)
object_schedule = object("Выходные дни")
object_schedule.activate_on_state_changes(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В этой части скрипта указывается активатор, здесь активатором является расписание. Для привязки скрипта к любому другому расписанию достаточно заменить название расписания
object("Выходные дни")object_schedule = object("Выходные дни") object_schedule.activate_on_state_changes(condition) -
В функции condition описано условие, согласно которому если расписание находится в красной зоне, переменной "on" задается значение 1, а если в зеленой, то 0.
def condition(): if (object_schedule.state("color") == "Red") : economy_mode_on_all_nvr(1) elif (object_schedule.state("color") == "Green") : economy_mode_on_all_nvr(0) -
В данной части скрипта параметру "economy_mode" для всех устройств семейства "Lanser" присваивается значение, равное переменной "on".
def economy_mode_on_all_nvr(on): for d in settings("ip_cameras").ls(): if d.type != "Grabber": continue if d["family"] == "NVR": d["economy_mode"] = on
Ниже представлен пример упрощенного скрипта, согласно которому устройства Lanser будут переходить в экономичный режим / выходить из него по горячим клавишам F5 и F6 соответственно.
def economy_mode_on_all_nvr(on):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
if d["family"] == "NVR":
d["economy_mode"] = on
def economy_mode_on():
economy_mode_on_all_nvr(1)
def economy_mode_off():
economy_mode_on_all_nvr(0)
activate_on_shortcut("F5", economy_mode_on)
activate_on_shortcut("F6", economy_mode_off)
Замыкание тревожного выхода при проезде машины из белого списка AutoTRASSIR
В этом примере мы рассмотрим скрипт, который предназначен для автоматического управления шлагбаумом: при проезде машин из белого списка шлагбаум будет открываться. Это реализовано при помощи функции "белый список" AutoTRASSIR и тревожного выхода.
Предварительно необходимо настроить внутренние списки номеров или подключить внешний список. После этого нужно создать новый скрипт и скопировать в него следующий код.
lock = False
class TaskLocker:
def __init__(self):
global lock
if lock:
self.have_lock = False
return
else:
self.have_lock = True
lock = True
gates_open(self)
def __del__(self):
if self.have_lock:
global lock
lock = not 1
def gates_close(lock):
object("Output 1").set_output_low()
def waiting(lock):
timeout(10 * 1000, lambda: gates_close(lock))
def gates_open(lock):
object("Output 1").set_output_high()
waiting(lock)
def aquire_lock():
TaskLocker()
def the_lpr_handler(event):
if event.flags & LPR_WHITELIST:
aquire_lock()
activate_on_lpr_events(the_lpr_handler)
Рассмотрим некоторые блоки подробнее.
-
В этой части скрипта указывается активатор, здесь активатором является событие от AutoTRASSIR.
activate_on_lpr_events(the_lpr_handler)
-
В функции the_lpr_handler(event) проверяется, найден ли номер в белом списке. Если распознанный номер найден в белом списке, запускается функция aquire_lock().
def the_lpr_handler(event): if event.flags & LPR_WHITELIST: aquire_lock() message("Машина в белом списке") -
Функция aquire_lock() вызывает класс TaskLocker().
def aquire_lock(): TaskLocker()
-
Класс TaskLocker предназначен для того, чтобы скрипт отрабатывал до конца. В том случае, если действия в скрипте достаточно продолжительны по времени исполнения, а активация скрипта инициализируется до окончания его предыдущего выполнения, класс TaskLocker предотвратит повторный запуск скрипта до тех пор, пока не будут выполнены все действия скрипта в рамках его предыдущей активации.
lock = False class TaskLocker: def __init__(self): global lock if lock: self.have_lock = False return else: self.have_lock = True lock = True gates_open(self) def __del__(self): if self.have_lock: global lock lock = not 1
-
Функция gates_open(lock) замыкает тревожный выход Output 1 и вызывает функцию waiting(lock).
def gates_open(lock): object("Output 1").set_output_high() waiting(lock) -
Функция waiting(lock) запускает ожидание, равное 10 секундам, после чего вызывает функцию gates_close(lock).
def waiting(lock): timeout(10 * 1000, lambda: gates_close(lock))
-
Функция gates_close(lock) размыкает тревожный выход Output 1.
def gates_close(lock): object("Output 1").set_output_low()
Ниже представлена версия скрипта, согласно которому при нахождении номера в черном списке будет воспроизводиться звуковой файл.
def play_sound(filename):
import platform
if platform.system() == 'Windows':
import winsound
winsound.PlaySound(filename, winsound.SND_FILENAME\
| winsound.SND_ASYNC | winsound.SND_NOWAIT)
else:
alert('Not implemented')
def the_lpr_handler(event):
if event.flags & LPR_BLACKLIST:
play_sound(r"C:\VMS\sounds\alarm.wav")
activate_on_lpr_events(the_lpr_handler)
Сохранение скриншотов AutoTRASSIR в разные папки
В этом примере будет рассмотрен скрипт, который предназначен для сохранения скриншотов машин из белого списка, черного списка или с недостаточно распознанным номером в разные папки. Это реализовано при помощи списков AutoTRASSIR и функции сохранения скриншотов.
Предварительно, необходимо настроить внутренние списки номеров или подключить внешний список. После этого нужно создать новый скрипт и скопировать в него следующий код.
def condition(event):
if event.quality == 0 :
obj(event.channel).screenshot_ex("", r"C:\VMS\Screenshots\Low_quality")
elif event.flags & LPR_WHITELIST :
obj(event.channel).screenshot_ex("", r"C:\VMS\Screenshots\Whitelist")
elif event.flags & LPR_BLACKLIST :
obj(event.channel).screenshot_ex("", r"C:\VMS\Screenshots\Blacklist")
activate_on_lpr_events(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В этой части скрипта указывается активатор, здесь активатором является событие от AutoTRASSIR.
activate_on_lpr_events(condition)
-
В функции condition описано условие, согласно которому:
- если процент распознавания хотя бы одного символа в знаке равен нулю, с канала сохраняется скриншот и помещается в папку "C:\VMS\Screenshots\Low_quality"
if event.quality == 0 : obj(event.channel).screenshot_ex\ ("",r"C:\VMS\Screenshots\Low_quality") - если распознанный номер найден в белом списке, с канала сохраняется скриншот и помещается в папку "C:\VMS\Screenshots\Whitelist"
elif event.flags & LPR_WHITELIST : obj(event.channel).screenshot_ex\ ("",r"C:\VMS\Screenshots\Whitelist") - если распознанный номер найден в черном списке, с канала сохраняется скриншот и помещается в папку "C:\VMS\Screenshots\Blacklist"
elif event.flags & LPR_BLACKLIST : obj(event.channel).screenshot_ex\ ("",r"C:\VMS\Screenshots\Blacklist")
- если процент распознавания хотя бы одного символа в знаке равен нулю, с канала сохраняется скриншот и помещается в папку "C:\VMS\Screenshots\Low_quality"
Скриншот при регистрации кассира
В этом примере мы рассмотрим скрипт, который будет активироваться по событию от СККО ActivePOS. В качестве события указана регистрация кассира, а в качестве действия - сохранение скриншота с ассоциированного канала. Таким образом, при регистрации на кассе будет сохранен скриншот с кассиром - это позволит при необходимости верифицировать личность кассира.
def shot(event):
if event.type == "POS_CASHIER_REGISTRATION":
obj(event.associated_channel).screenshot_ex("",r"C:\VMS\Screenshots\Cashiers")
activate_on_pos_events(shot)
-
В этой части скрипта указывается активатор, здесь активатором является событие от ActivePOS.
activate_on_pos_events(shot)
-
В функции shot(event) описано условие, согласно которому если событие является регистрацией кассира, с ассоциированного канала сохраняется скриншот в папку "C:\VMS\Screenshots\Cashiers".
def shot(event): if event.type == "POS_CASHIER_REGISTRATION": obj(event.associated_channel).screenshot_ex\ ("",r"C:\VMS\Screenshots\Cashiers")
Установка тревожной закладки в чек при продаже алкоголя ночью
В каждом магазине существуют определенные сценарии событий, которые являются тревожными и требуют проверки. ActivePOS позволяет помечать такие события с помощью тревожных закладок и дописывать к ним произвольный комментарий, после чего можно проводить выборку этих событий для их дальнейшего анализа. В этом примере мы рассмотрим скрипт, который помечает продажу алкоголя ночью как тревожное событие.
Предварительно, необходимо создать расписание. На скриншоте ниже показана настройка расписания для данного примера.

После этого создайте новый скрипт и вставьте в него следующий код:
def condition(ev):
if (object("Ночь").state("color") == "Red"): return
if ev.type!="POS_POSITION_ADD": return
u = ev.text.decode("utf-8").upper().encode("utf-8")
for w in ["ПИВО", "ВИНО", "ВОДКА", "КОНЬЯК"]:
if u.find(w) != -1:
pos_fraud(ev, "Внимание! Незаконная продажа алкоголя!")
return
activate_on_pos_events(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В данной части скрипта указывается активатор, здесь активатором является событие от ActivePOS.
activate_on_pos_events(сondition)
-
В функции condition проверяется, находится ли расписание "Ночь" в красной зоне, а также является ли событие добавлением позиции. В случае положительного результата, в названии товара осуществляется поиск таких слов, как "ПИВО", "ВИНО", "ВОДКА", "КОНЬЯК"(можно добавить и другие названия, которые встречаются в реализуемых товарах в Вашем магазине). Если одно из этих слов в названии товара будет найдено, с помощью метода pos_fraud в чек будет вставлена тревожная закладка, а под тревожным событием появится заданный комментарий.
def condition(ev): if (object("Ночь").state("color") == "Red"): return if ev.type!="POS_POSITION_ADD": return u = ev.text.decode("utf-8").upper().encode("utf-8") for w in ["ПИВО", "ВИНО", "ВОДКА", "КОНЬЯК"]: if u.find(w) != -1: pos_fraud(ev, "Внимание! Незаконная продажа алкоголя!") return
Экспорт архива при отмене чека
В этом примере мы рассмотрим скрипт, согласно которому при отмене чека или при отмене позиции будет запускаться экспорт архива с камеры над кассой, в экспортированный файл войдет запись, включающая в себя 15 секунд до события и 15 секунд после него.
Для начала необходимо создать новый скрипт и скопировать в него следующий код.
from time import strftime
from time import time
from time import localtime
from os import path
def export_wait(filename, callback):
status = get_archive_export_status(path.basename(filename))
if status==1:
timeout(1000, lambda: export_wait(filename, callback))
elif status==0 or status==2:
alert("AVI export failed")
callback()
else:
if not path.exists(decode(filename)):
alert("Exported file %s not found!" % filename)
callback()
def action0_2():
pass
def start_export(ev, t1, t2, filename):
object("Интерфейс оператора m-gilyazov").archive_export\
(ev.associated_channel, t1, t2, path.basename(filename), 0)
timeout(1000, lambda: export_wait(filename, lambda: action0_2()))
def condition(event):
if event.type == "POS_RECEIPT_CANCEL"\
or event.type == "POS_POSITION_CANCEL":
t = time()
t1 = '%.0f' % ((t-30)*1000000)
t2 = '%.0f' % (t*1000000)
shots_path = r"C:\VMS\Screenshots\cancel"
filename = event.pos_terminal_name + strftime('%Y%m%d_%H%M%S',\
localtime(t)) + '.avi'
filename = shots_path + '/' + filename
timeout(15000, lambda: start_export(event, t1, t2, filename))
activate_on_pos_events(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В данной части скрипта указывается активатор, здесь активатором является событие от ActivePOS.
activate_on_pos_events(сondition)
-
В функции condition проверяется, является ли событие отменой позиции или отменой чека. В случае положительного результата запускается функция start_export. В функции condition также указано ожидание(30 секунд), имя файла на выходе и путь к папке, куда будет сохранен экспортированный файл.
def condition(event): if event.type == "POS_RECEIPT_CANCEL"\ or event.type == "POS_POSITION_CANCEL": t = time() t1 = '%.0f' % ((t-30)*1000000) t2 = '%.0f' % (t*1000000) shots_path = r"C:\VMS\Screenshots\cancel" filename = event.pos_terminal_name +\ strftime('%Y%m%d_%H%M%S', localtime(t)) + '.avi' filename = shots_path + '/' + filename exported_files[event.pos_terminal_name] = filename timeout(15000, lambda: start_export\ (event, t1, t2, filename)) -
Функция start_export запускает экспорт архива с заданными ранее параметрами, а также запускает функцию export_wait.
def start_export(ev, t1, t2, filename): object("Интерфейс оператора m-gilyazov").archive_export\ (ev.associated_channel, t1, t2, path.basename(filename), 0) timeout(1000, lambda: export_wait(filename, lambda: action0_2())) -
Функция export_wait проверяет, ведется ли сейчас экспорт архива с прошлой активации скрипта и в случае отрицательного ответа запускает функцию action0_2.
def start_export(ev, t1, t2, filename): object("Интерфейс оператора m-gilyazov").archive_export\ (ev.associated_channel, t1, t2, path.basename(filename), 0) timeout(1000, lambda: export_wait(filename, lambda: action0_2()))
Изменение чувствительности детектора по расписанию
В этом примере мы рассмотрим скрипт, который предназначен для изменения чувствительности детектора движения по расписанию. Он позволяет снизить количество срабатываний детектора на шумы ночью.
Предварительно, необходимо создать расписание. На скриншоте ниже показана настройка расписания для данного примера.

После этого нужно создать новый скрипт и скопировать в него следующий код.
night = \
'''22 18
zone_mask Зона 1
2 0 0
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111'''
day = \
'''22 18
zone_mask Зона 1
5 0 0
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111
1111111111111111111111'''
def md_settings(md):
for d in settings("ip_cameras").ls():
if d.type != "Grabber": continue
if d["family"] == "Hikvision":
d["channel00_md_setup"] = md
def condition():
if (object_schedule.state("color") == "Red") :
md_settings(night)
elif (object_schedule.state("color") == "Green") :
md_settings(day)
object_schedule = object("From Dusk Till Dawn")
object_schedule.activate_on_state_changes(condition)
Рассмотрим некоторые части скрипта подробнее.
-
В этой части скрипта указывается активатор, здесь активатором является расписание. Для привязки скрипта к любому другому расписанию достаточно заменить название расписания
object("From Dusk Till Dawn")object_schedule = object("From Dusk Till Dawn") object_schedule.activate_on_state_changes(condition) -
В функции condition описано условие, согласно которому если расписание находится в красной зоне, переменной "md" задается значение "night", а если в зеленой, то "day".
def condition(): if (object_schedule.state("color") == "Red") : md_settings(night) elif (object_schedule.state("color") == "Green") : md_settings(day) -
В данной части скрипта параметру "channel00_md_setup" для всех устройств семейства "Hikvision" присваивается значение, равное переменной "md".
def md_settings(md): for d in settings("ip_cameras").ls(): if d.type != "Grabber": continue if d["family"] == "Hikvision": d["channel00_md_setup"] = md -
В переменных "day" и "night" прописаны настройки зон и чувствительности аппаратного детектора.
Ниже представлен пример скрипта, согласно которому по расписанию будет изменяться чувствительность программного детектора на всех каналах.
night = \
'''32 32
zone_mask Zone 1
5 0 0
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
'''
day = \
'''32 32
zone_mask Zone 1
10 0 0
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
'''
def md_settings(md):
for d in settings("channels").ls():
if d["archive_zombie_flag"] == 0:
d["software_md_setup"] = md
def condition():
if (object_schedule.state("color") == "Red") :
md_settings(night)
elif (object_schedule.state("color") == "Green") :
md_settings(day)
object_schedule = object("From_Dusk_Till_Dawn")
object_schedule.activate_on_state_changes(condition)
Изменение состояния сервера при продолжительной высокой загрузке CPU
В этом примере мы рассмотрим скрипт, который предназначен для изменения состояния сервера на тревожное в случае продолжительной высокой загрузки процессора.
Для начала необходимо создать новый скрипт и скопировать в него следующий код.
from collections import deque
a = deque()
i = 0
l = 15 #длина очереди a
t = 30000 #периодичность замеров в мс
k = 85 #критическая загрузка процессора
def iter_func():
global a, i, l, t, k
if len(a) >= l:
a.popleft()
i = settings("health")["cpu_usage"]
a.append(i)
s = 0
c = 0
for j in xrange(0, len(a)):
s += a[j]
c = s / l
if c >= k :
settings("health")["user_defined_health_indicator"] = 0
else :
settings("health")["user_defined_health_indicator"] = -1
timeout(t, iter_func)
def start_script():
iter_func()
start_script()
Рассмотрим некоторые части скрипта подробнее.
-
В этой части скрипта проверяется длина очереди a и записывается очередное значение загрузки процессора.
if len(a) >= l: a.popleft() a.append(i) i = settings("health")["cpu_usage"] -
В следующей части скрипта суммируются значения всех элементов двусторонней очереди a.
s = 0 c = 0 for j in xrange(0, len(a)): s += a[j]
-
В данной части скрипта вычисляется среднее значение загрузки процессора с и сравнивается с критическим значением k. Если среднее значение больше или равно критическому, состояние сервера вручную портится. Если среднее значение меньше критического, состояние сервера переключается на нормальное.
c = s / l if c >= k : settings("health")["user_defined_health_indicator"] = 0 else : settings("health")["user_defined_health_indicator"] = -1 timeout(t, iter_func)

