Модуль dev
Взаимодействие с ресурсами контроллера
Классы
Reg
Класс Reg(n)
предназначен для работы с пользовательскими регистрами контроллера.
Инициализация:
При создании объекта класса Reg
необходимо указать номер регистра, начиная с 0
.
# Импортируем класс Reg из модуля dev
from dev import Reg
# Создать объект, связанный с регистром #0
r0 = Reg(0)
# Вывести значение регистра #0
print(r0.val()) # Пример вывода: 1
# Создать объект, связанный с регистром #5
r5 = Reg(5)
# Вывести доступные методы объекта
print(dir(r5)) # Пример вывода: ['__class__', 'val', 'on', 'off', 'toggle', 'conf']
Метод conf()
Метод conf()
используется для конфигурации регистра, включая его тип, минимальные и максимальные значения, уровень доступа и другие параметры.
Важно: Регистры можно также настроить вручную через веб-интерфейс на странице Настройки > Регистры.
Доступные параметры конфигурации:
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
name |
Имя регистра | str |
Будет отображаться в веб-интерфейсе. |
type |
Тип регистра | str |
Допустимые значения: bool , int , uint , float , list , enum . |
min |
Минимальное значение | int |
Только для типов int , float , list . |
max |
Максимальное значение | int |
Только для типов int , float , list . |
step |
Шаг изменения значения | int |
Только для типов int , float , list . |
default |
Значение по умолчанию | int |
Устанавливается, если текущее значение не соответствует настройкам конфигурации. |
web |
Уровень доступа через веб-интерфейс | str |
Допустимые значения: - (не отображается), r (только чтение), w (чтение и запись). |
ext |
Уровень доступа для внешних служб, например Modbus | str |
Аналогично параметру web . |
items |
Список значений для регистра типа enum |
list |
Только для типа enum . |
dec |
Число знаков после запятой (для типов float ) |
int |
Только для чисел с плавающей точкой. |
Примеры конфигурации регистров:
from dev import Reg
# Конфигурация регистра #0 как переключателя (True/False):
rPower = Reg(0).conf(name='Питание', type='bool', web='w')
# Конфигурация регистра #1 как выпадающего списка ("Вентиляция" или "Нагрев"):
rMode = Reg(1).conf(name='Режим', type='enum', items=['Вентиляция', 'Нагрев'], web='w')
# Регистратор уставки температуры (диапазон [10-45], по умолчанию 25):
rUstavka = Reg(2).conf(name='Уставка', type='int', min=10, max=45, default=25)
# Конфигурация регистра скорости вентилятора (1-5):
rFanSpeed = Reg(3).conf(name='Вентилятор', type='list', min=1, max=5, step=1, default=5)
# Конфигурация регистра статуса с переключением строк (отображается только для чтения):
STATUSES = ['Выкл', 'Открытие заслонки', 'Работа', 'Продувка ТЭНов', 'Останов вентиляторов', 'Закрытие заслонки']
rStatus = Reg(4).conf(name='Статус', type='enum', items=STATUSES, web='r')
Метод val()
Метод val()
используется для чтения или изменения значения регистра. Тип значения зависит от конфигурации.
Использование:
- Чтение значения: вызов метода без параметров.
- Изменение значения: передача нового значения в качестве параметра.
from dev import Reg
r = Reg(3)
# Установить значение регистра
r.val(1)
# Прочитать текущее значение регистра
print(r.val()) # Пример вывода: 1
Можно также использовать сокращённый вызов r()
вместо r.val()
:
from dev import Reg
r = Reg(3)
r(1) # Установка значения
print(r()) # Пример вывода: 1
Методы on()
, off()
, toggle()
on()
: Устанавливает значение регистра вTrue
(1
).off()
: Устанавливает значение регистра вFalse
(0
).toggle()
: Инвертирует текущее значение (True → False, False → True).
Пример:
from dev import Reg
r = Reg(0).conf(type='bool')
r.on() # Включить
print(r.val()) # Пример вывода: True
r.toggle() # Инвертировать
print(r.val()) # Пример вывода: False
Do
Класс Do(n)
предназначен для работы с цифровыми выходами контроллера.
При инициализации класса необходимо указать номер цифровыми выходами.
Некоторые выводы могут работать в режиме ШИМ, реализованном на аппаратном уровне.
Значение (состояние) цифрового выхода в python имеет тип bool
и int
для выводов с поддрежкой ШИМ.
# Импортируем модули dev и time
import dev
# Объявляем бесконечные цикл
while True:
# Изменяем состояние цифрового выхода #0 на противоположное
dev.Do(0).toggle()
# Ждем 1 секунду
time.sleep(1)
# Импортируем классы Ai и Do из модуля dev
from dev import Ai, Do
#
temp = Ai(0).conf(type='ntc')
do = Do(1)
while True:
if temp.val() < 25:
do.on()
else:
do.off()
Метод conf()
предназначен для изменения конфигурации цифровых входов.
Изменение конфигурации возможно в ручную, на странице Настройки > Входы/выходы в веб-интерфейсе.
Доступны следующие аргументы.
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
name |
Имя входа | str |
Отображается в веб-интерфейсе |
type |
Тип входа: с поддрежкой ШИМ или без | str |
Допустимые значения: pwm , nopwm |
web |
Уровень доступа через веб-интерфейс | str |
Допустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять |
ext |
Уровень доступа для внешних служб | str |
Допустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять |
period |
Период ШИМ в секундах | float |
Только для выводов с поддержкой ШИМ |
from dev import Do
# Цифровой выход #0 сконфигурирован с поддержкой ШИМ, периодом равным 30 секунд.
# Значение выхода нельзя изменять черех веб-интерфейс
# Допустимые значения [0..100]
doHeater = Do(0).conf(name='Нагреватель', type='pwm', period=30, web='r')
# Цифровой выход #0 сконфигурирован
# Значение выхода нельзя изменять черех веб-интерфейс
# Допустимые значения False и True, (0 и 1)
doCap = Do(1).conf(name='Заслонка', web='r')
Метод val()
позволяет читать и изменять состояние цифрового выхода контроллера.
Для чтения значения метод вызывается без параметров. Что бы изменить значение, его необходимо передать в качестве параметра метода.
from dev import Do
from time import sleep
do = Do(1)
do.val(1)
sleep(1)
do.val(0)
sleep(1)
do.val(1)
Метод on()
устанавливает значение регистра в True
(1
).
Эквивалентно Reg.val(True)
Метод off()
устанавливает значение регистра в False
(0
).
Эквивалентно Reg.val(False)
Метод toggle()
изменяет текущее значение регистра на противоположное.
Di
Класс Di(n)
предназначен для работы с цифровыми входами контроллера.
При инициализации класса необходимо указать номер цифрового входа.
Значение (состояние) цифрового входа в python имеет тип bool и доступны только для чтения.
Каждый вход может быть сконфигурирован как:
- нормальное открытий (НО), имеет значение True если вход разомкрут;
- нормально закрытый (НЗ), имеет значение False если вход замкнут.
Метод conf()
позволяет изменять конфигурацию цифровых входов.
Изменение конфигурации возможно в ручную, на странице “Настройки > Входы/выходы” в веб-интерфейсе.
Доступны следующие аргументы
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
name |
Имя входа | str |
Отображается в веб-интерфейсе |
type |
Тип входа | str |
Допустимые значения: no - нормально открытый, nz - нормально закрытый |
web |
Уровень доступа через веб-интерфейс | str |
Допустимые значения: - - регистр не отображается, r - только чтение |
ext |
Уровень доступа для внешних служб | str |
Допустимые значения: - - регистр не отображается, r - только чтение |
Метод Di.val()
позволяет читать состояние цифрового входа контроллера.
from dev import Di
from time import sleep
while True:
# Используем генератор списов, что бы получить список состояний цифровых входов
vals = [Di(i).val() for i in range(5)]
# Вывести в консоль значения vals
print(vals)
sleep(1)
Ao
Класс Ao(n)
предназначен для работы с аналоговыми выходами контроллера.
При инициализации класса необходимо указать номер аналогового выхода.
Аналоговый выход контроллер способен выдавать напряжение в диапазоне от 0 до 10 В.
Значение в python имеет тип float
.
Метод conf()
позволяет изменять конфигурации цифровых входов.
Изменение конфигурации возможно в ручную, на странице “Настройки > Входы/выходы” в веб-интерфейсе.
Доступны следующие аргументы.
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
name |
Имя входа | str |
Отображается в веб-интерфейсе |
type |
Тип входа | str |
Допустимые значения: no - нормально открытый, nz - нормально закрытый |
web |
Уровень доступа через веб-интерфейс | str |
Допустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять |
ext |
Уровень доступа для внешних служб | str |
Допустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять |
Метод val([v])
позволяет читать и изменять значение на аналоговом выходе.
from dev import Reg, Ao
# Определяем регист с вещественным типом данных
r = Reg(0).conf(type="float", min=0, max=10, dec=1)
ao = Ao(0)
last = 0.0
while True:
ao.val(r.val())
if last != ao.val():
last = ao.val()
print(last)
Ai
Класс Ai(n)
предназначен для работы с аналоговыми входами контроллера.
При инициализации класса необходимо указать номер аналогового входа.
К аналогову входу может быть подключен датчик температуры NTC10K или источник напряжения в диапазоне от 0 до 10 В.
Класс имеет только два метода val()
и conf()
.
Метод conf()
предназначен для изменения конфигурации аналоговых входов.
Изменение конфигурации возможно в ручную, на странице “Настройки > Входы/выходы” в веб-интерфейсе.
Доступны следующие аргументы.
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
name |
Имя входа | str |
Отображается в веб-интерфейсе |
type |
Тип входа | str |
Допустимые значения: ntc - датчик температуры NTC10K; raw - источник напряжения 0-10В |
web |
Уровень доступа через веб-интерфейс | str |
Допустимые значения: - - регистр не отображается, r - только чтение |
ext |
Уровень доступа для внешних служб | str |
Допустимые значения: - - регистр не отображается, r - только чтение |
from dev import Ai
ntcTemp = Ai(0).conf(name='Tемп. в канале', type='ntc', web='r', ext='r')
print(ntcTemp.val())
Метод val()
позволяет читать значение на аналоговом выходе.
# Импортируем класс Ai из модуля dev
from dev import Ai
# Вспомагательная переменная last, для хранения последнего значения Ai
last = 0
# Бесконечный цикл
while True:
# Если текущее значение Ai не равно last
if (Ai(0).val() != last):
# Сохраняем значение Ai в last и выводим его в консоль
last = Ai(0).val()
print('Ai={}'.format(last))
Event
Класс Event(n)
предназначен для работы с пользовательскими событиями.
При инициализации класса необходимо указать номер события.
Журнал событий для просмотра доступен в веб-интерфейсе контроллера на странице События.
from dev import Event
e = Event(0)
print(dir(e))
Метод conf()
имеет всего один аргумент name и позволяет задать имя пользовательского события.
Метод add()
добавляет новое событие в журнал событий контроллера и, опционально, в облако на сервере.
При добавлении события возможно указать один или два числовых значения, а так же источник события.
Доступны следующие аргументы.
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
par |
Параметр события | int |
|
par2 |
Второй параметр события | int |
|
reason |
Источник/причина события | str |
Допустимые значения: error - ошибка; user - пользователь; regular - Ok/успешное выполение операции; time - время/рассписание; ext - внешняя служба |
from dev import Event
e = Event(0).conf(name="Тестовое событие")
# Добавляем событие без параметров
e.add()
# Добавляем событие с двумя параметрами
e.add(par=1, par2=2)
# Добавляем событие с указанием источника/причины
e.add(par=1, par2=2, reason="regular")
Alarm
Класс Alarm(n)
предназначен для работы с пользовательскими авариями.
При инициализации класса необходимо указать номер аварии. Нумерация начинается с 0.
Метод conf(name)
имеет всего один аргумент name
и позволяет задать имя аварии.
Метод on()
активирует аварию на контроллере. При активации аварии добавляется соответствующее событие, поэтому агрументы этого метода идентичны Event.add()
.
Метод off()
снимает аварию.
PID
Класс PID()
реализует работу ПИД регулятора.
При инициализации класса, он принимает следующие аргументы:
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
kP |
Пропорциональный коэффициент | float |
|
kI |
Интегральный коэффициент | float |
|
kD |
Диффиренциальный коэффициент | float |
|
limits |
Диапазон допустимых значений управляемой величины | tuple или list |
Ожидается кортеж/список из двух значений, например: (мин_значение, макс_значение) |
Метод step(invalue, setpoint)
— выполняет шаг расчёта ПИД-регулятора.
Аргументы:
invalue
— фактическое значение управляемой величины.setpoint
— заданное (желаемое) значение.
Возвращает управляющий сигнал.
Если вызов метода безымянный, то вызывается __call__
.
# Пример использования класса PID
from dev import PID
pid = PID(kP=1.0, kI=0.5, kD=0.1, limits=(-100, 100))
invalue = 75
setpoint = 100
control_signal = pid.step(invalue, setpoint)
print(f'Управляющий сигнал: {control_signal}')
Periodic
Класс Periodic(interval)
обеспечивает исполнение пользовательского кода через заданные промежутки времени без вызова сборщика мусора.
Конструктор класса принимает единственный аргумент:
interval
— промежуток времени в секундах (тип —float
), через который будет вызываться пользовательский код.
Метод run(func)
— принимает функцию как аргумент и активирует её циклическое выполнение.
# Импортируем классы Periodic и Led
from dev import Periodic, Led
# Функция step, которая изменяет состояние светодиода на противоположный
def step():
Led(0).toggle()
# Используем класс Periodic для цикличного вызова фукнции step с интервалом 1 секунда.
Periodic(1).run(step)
Modbus
Класс Modbus
предназначен для взаимодействия с внешними устройствами и системами с помощью протокола Modbus RTU.
Контроллера выступает в качестве мастера.
Конструктор:
При инициализации принимаются следующие аргументы:
Аргумент | Описание | Тип | Комментарий |
---|---|---|---|
baudrate |
Скорость передачи данных | int |
Указывается в битах в секунду. Часто используемые значения: 9600, 19200, 38400, 115200. |
stopbits |
Количество стоп-битов | int |
Возможные значения: 1 или 2. |
timeout |
Таймаут | float |
Максимальное время ожидания ответа от устройства (в секундах). |
parity |
Параметр чётности | str |
Возможные значения: none (без чётности), even (чётная), odd (нечётная). |
slaveaddr |
Адрес slave-устройства Modbus | int |
Адрес устройства, с которым будет установлено соединение. |
Методы:
Метод read(start, count)
осуществляет чтение count
регистров начиная с start
.
Результат возвращается в виде кортежа значений. Если возникла ошибка, вызывается исключение.
from dev import Modbus
mb = Modbus(baudrate=38400, stopbits=2, timeout=1, parity="none", slaveaddr=1)
try:
# Прочитать значения 5 регистров начиная с 0
values = mb.read(0, 5)
# Вывести результат чтения в консоль
print('values', values)
except Exception as err:
# Если в процессе чтения произшла ошибка, вывести ее в консоль
print('read', err, mb.err())
Метод write(start, values)
записывает кортеж values
в регистры, начиная с адреса start
.
В случае ошибки вызывается исключение.
from dev import Modbus
mb = Modbus(baudrate=38400, stopbits=2, timeout=1, parity="none", slaveaddr=1)
try:
# Создаем кортеж из 8 значений
values = (1,2,3,4,5,6,7,8)
# Записать значения в 8 регистров начиная с 20
mb.write(20, values)
# Сообщить об успешном выполнеии операции записи
print('done')
except Exception as err:
# Если в процессе записи произшла ошибка, вывести ее в консоль
print('read', err, mb.err())
Функции
count
Функция count()
позволяет задать лимиты на количество доступных пользовательских регистров, событий, аварий и других элементов, используемых в сценарии.
Компоненты, для которых установлено значение 0
, не отображаются в веб-интерфейсе.
Аргументы функции:
Аргумент | Описание | Тип |
---|---|---|
Reg |
Количество пользовательских регистров | int |
Alarm |
Количество пользовательских аварий | int |
Event |
Количество пользовательских событий | int |
Ai |
Количество аналоговых входов | int |
Ao |
Количество аналоговых выходов | int |
Di |
Количество цифровых выходов | int |
Do |
Количество цифровых входов | int |
Значения должны быть в диапазоне от 0 до предельного количества для модели контроллера.
from dev import count, Reg
# Ограничи
count(Reg=10)
#
r = Reg(11)
# Сценари завершится с ошибкой:
#Traceback (most recent call last):
# File "<stdin>", line 3, in <module>
#ValueError: invalid value 11, it should be in [0, 9]
conv
Функция conv()
выполняет линейное преобразование (масштабирование) значения из одного диапазона в другой.
from dev import conv
# Пример собственной реализации функции conv
def convMy(inVal, inMin, inMax, outMin, outMax):
if (inVal >= inMax or inMin == inMax):
return outMax
if (inVal <= inMin):
return outMin
return (inVal - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
# Проебразуем значение в % в вольты 2-10V
valPer = 33
# с использование встроенной функции
valV = conv(valPer, 0, 100, 2.0, 10.0)
# с использование собственной функции
valV2 = convMy(valPer, 0, 100, 2.0, 10.0)
print('{}% -> {}V by conv'.format(valPer, valV))
print('{}% -> {}V by convMy'.format(valPer, valV2))
Это полезно, например, при преобразовании значений датчиков или выходного сигнала.