Классы

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', 'dec', 'inc', 'changed']
  

Метод conf() используется для конфигурации регистра.

Регистры можно также настроить вручную через веб-интерфейс на странице Настройки > Регистры.

Доступные параметры конфигурации:

АргументОписаниеТипКомментарий
nameИмя регистраstrОтображается в веб-интерфейсе на панели управления.
typeТип регистраstrДопустимые значения: bool, int, uint, float, enum.
accessУровни доступа для панели управления (веб-интерфейс) и внешних службstrДопустимые значения: - - нет доступа, r - только чтение, w - полный доступ. Первый символ - доступ для панели управления, второй (если задан) для внешних служб, например Modbus.
limitsДопустимый диапазон значенийlist, tupleТолько для типов int, uint, float
stepШаг изменения значенияintТолько для типов int, uint, float
defaultЗначение по умолчаниюintУстанавливается, если текущее значение не соответствует настройкам конфигурации, например не входит в заданный диапазон
itemsСписок значений для регистра типа enumlistТолько для типа enum.
decЧисло знаков после запятой (для типов float)intТолько для чисел с плавающей точкой.
webЭлемент управления для веб-интерфейса (панели управления)strДопустимые значения: select - раскрывающийся список, radio - переключатель, input - поле ввода
  from dev import Reg

# Конфигурация регистра #0 как переключателя (True/False)
# Уровень доступа из веб-интерфейса (панели управления) - только чтение
rPower = Reg(0).conf(name='Питание', type='bool', access='r')

# Конфигурация регистра #1 как выпадающего списка ("Вентиляция" или "Нагрев")
# Уровень доступа из веб-интерфейса (панели управления) - полный
rMode = Reg(1).conf(name='Режим', type='enum', items=['Вентиляция', 'Нагрев'], access='w')

# Регистр уставки температуры (диапазон [10-45], по умолчанию 25)
rUstavka = Reg(2).conf(name='Уставка', type='int', limits=[10, 45], default=25)

# Конфигурация регистра скорости вентилятора (1-5), по умолчанию 5
# Доступа из веб-интерфейса нет, доступ для внешних службы - полный
rFanSpeed = Reg(3).conf(name='Вентилятор', type='uint', limits=[1, 5], default=5, access='-w')

# Тип регистра - значение из списка
# Элемент панели управления - раскрывающийся список
STATUSES = ['Выкл', 'Открытие заслонки', 'Работа', 'Продувка ТЭНов', 'Останов вентиляторов', 'Закрытие заслонки']
rStatus = Reg(4).conf(name='Статус', type='enum', items=STATUSES, web='select')
  

Метод val([value]) используется для чтения или изменения значения регистра. Тип значения зависит от конфигурации.

Использование:

  • Чтение значения: вызов метода без параметров.
  • Изменение значения: передача нового значения в качестве параметра.
  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
  

Методы dec(), inc().

  • dec(): Инкремент значения, увеличивает на 1
  • inc(): Декремент значения, уменьшает на 1
  from dev import Reg

r = Reg(0).conf(type='int')

_ = r.val(1)
r.dec()
print(r.val())  # 2
  

Метод changed() возвращает True если значение регистра изменилось с момента последнего вызова changed(). Метод полезен если в теле цикла требуется определить, было ли изменено значение регистра.

  from dev import Reg

r = Reg(0).conf(type='int', access='w')

while True:
	if r.changed():
		print('Значение изменилось')
  

Do

Класс Do(n) предназначен для работы с цифровыми выходами контроллера. При инициализации класса необходимо указать номер цифрового выхода. Нумерация начинается с 0. Некоторые выводы могут работать в режиме ШИМ, реализованном на аппаратном уровне. Значение (состояние) цифрового выхода в 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
accessУровни доступа для панели управления (веб-интерфейс) и внешних службstrДопустимые значения: - - нет доступа, r - только чтение, w - полный доступ. Первый символ - доступ для панели управления, второй (если задан) для внешних служб, например Modbus.
periodПериод ШИМ в секундахfloatТолько для выводов с поддержкой ШИМ
  from dev import Do

# Цифровой выход #0 сконфигурирован
# Значение выхода нельзя изменять через веб-интерфейс
# Допустимые значения False и True, (0 и 1)
doCap = Do(1).conf(name='Заслонка', web='r')

# Цифровой выход #0 сконфигурирован с поддержкой ШИМ, периодом равным 30 секунд.
# Значение выхода нельзя изменять через веб-интерфейс
# Допустимые значения [0..100]
doHeater = Do(0).conf(name='Нагреватель', type='pwm', period=30, web='r')
  

Метод val([value]) позволяет читать и изменять состояние цифрового выхода контроллера. Для чтения значения метод вызывается без параметров. Чтобы изменить значение, его необходимо передать в качестве параметра метода.

  from dev import Do
from time import sleep
do = Do(1)
do.val(1)
sleep(1)
do.val(0)
sleep(1)
do.val(1)
  

Метод pwm() используется только для DO, сконфигурированных с поддержкой ШИМ. Метод позволяет читать и изменять скважность ШИМ. Для чтения значения метод вызывается без параметров. Чтобы изменить значение, его необходимо передать в качестве параметра метода. Тип значения float или int, допустимый диапазон [0..100].

  from dev import Ai, Reg, Do

print(Do(0).pwm())
Do(0).pwm(30)
print(Do(0).pwm()) # 30.0
  

Методы on(), off(), toggle(), changed() эквивалентны соответствующим методам пользовательского регистра.


Di

Класс Di(n) предназначен для работы с цифровыми входами контроллера. При инициализации класса необходимо указать номер цифрового входа. Нумерация начинается с 0. Значение (состояние) цифрового входа в Python имеет тип bool и доступно только для чтения. Каждый вход может быть сконфигурирован как:

  • нормально открытый (НО), имеет значение True, если вход разомкнут;
  • нормально закрытый (НЗ), имеет значение False, если вход замкнут.

Метод conf() позволяет изменять конфигурацию цифровых входов. Изменение конфигурации возможно вручную, на странице “Настройки > Входы/выходы” в веб-интерфейсе контроллера.

Доступные параметры конфигурации:

АргументОписаниеТипКомментарий
nameИмя входаstrОтображается в веб-интерфейсе
typeТип входаstrДопустимые значения: no - нормально открытый, nz - нормально закрытый
accessУровни доступа для панели управления (веб-интерфейс) и внешних службstrДопустимые значения: - - нет доступа, r - только чтение, w - полный доступ. Первый символ - доступ для панели управления, второй (если задан) для внешних служб, например Modbus.

Метод val([value]) позволяет читать состояние цифрового входа контроллера.

  from dev import Di
from time import sleep
while True:
	# Используем генератор списков, чтобы получить список состояний цифровых входов
    vals = [Di(i).val() for i in range(5)]
	# Вывести в консоль значения vals
    print(vals)
    sleep(1)
  

Метод changed() эквивалентен соответствующему методу пользовательского регистра.


Ao

Класс Ao(n) предназначен для работы с аналоговыми выходами контроллера. При инициализации класса необходимо указать номер аналогового выхода. Нумерация начинается с 0. Аналоговый выход контроллер способен выдавать напряжение в диапазоне от 0 до 10 В. Значение в python имеет тип float.

Метод conf() позволяет изменять конфигурации цифровых входов. Изменение конфигурации возможно вручную, на странице “Настройки > Входы/выходы” в веб-интерфейсе контроллера.

Доступные параметры конфигурации:

АргументОписаниеТипКомментарий
nameИмя входаstrОтображается в веб-интерфейсе
webУровень доступа через веб-интерфейсstrДопустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять
extУровень доступа для внешних службstrДопустимые значения: - - регистр не отображается, r - только чтение, w - значение можно изменять

Метод val([value]) позволяет читать и изменять значение на аналоговом выходе. Для чтения значения метод вызывается без параметров. Чтобы изменить значение, его необходимо передать в качестве параметра метода. Тип значения float, допустимый диапазон [0.0...10.0]

  from dev import Reg, Ao
r = Reg(0).conf(type="float", limits=[0.0...10.0], dec=1)
ao = Ao(0)
ao.val(r.val())
while True:
    if r.changed():
		ao.val(r.val())
        print(last)
    
  

Методы on(), off(), dec(), inc(), changed() эквивалентны соответствующим методам пользовательского регистра.


Ai

Класс Ai(n) предназначен для работы с аналоговыми входами контроллера. При инициализации класса необходимо указать номер аналогового входа. Нумерация начинается с 0. К аналогову входу может быть подключен датчик температуры 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='Темп. в канале', type='ntc', web='r', ext='r')
print(ntcTemp.val())
  

Метод val() позволяет читать значение на аналоговом выходе. Метод changed() эквивалентен соответствующему методу пользовательского регистра.

  # Импортируем класс Ai из модуля dev
from dev import Ai

# Бесконечный цикл
while True:
	# Если текущее значение Ai не равно last
    if (Ai(0).changed()):
		# Выводим его в консоль
        print('Ai={}'.format(Ai(0).val()))
  

Event

Класс Event(n) предназначен для работы с пользовательскими событиями. Журнал событий для просмотра доступен в веб-интерфейсе контроллера на странице События.

При инициализации класса необходимо указать номер события. Нумерация начинается с 0.

  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}')
  

Modbus

Класс Modbus предназначен для взаимодействия с внешними устройствами и системами с помощью протокола Modbus RTU. Контроллера выступает в качестве мастера.

Конструктр при инициализации принимаются следующие аргументы:

АргументОписаниеТипКомментарий
baudrateСкорость передачи данныхintУказывается в битах в секунду. Часто используемые значения: 9600, 19200, 38400, 115200.
stopbitsКоличество стоп-битовintВозможные значения: 1 или 2.
timeoutТаймаутfloatМаксимальное время ожидания ответа от устройства (в секундах).
parityПараметр чётностиstrВозможные значения: none (без чётности), even (чётная), odd (нечётная).
slaveaddrАдрес slave-устройства ModbusintАдрес устройства, с которым будет установлено соединение.

Метод 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())
  

Функции

run

Функция run(fn, [interval]) обеспечивает исполнение пользовательского кода fn через заданные промежутки времени interval. При этом сборщик мусора вызывается после выполнения пользовательской функции, что исключает его вызов при исполнении самой функции.

Агрументы:

  • fn - пользовательская функция.
  • interval - промежуток времени в секундах (тип — float), через который будет вызываться пользовательский код. По умолчанию одна секунда.
  # Импортируем функцию run и класс Periodic
from dev import run, Do

# Функция step, которая изменяет состояние цифрового выхода не противоположный
def step():
    Do(0).toggle()
	
# Используем функцию run для цикличного вызова функции step с интервалом 1 секунда.
run(step, 1)
  

С помощью функции run возможен запуск на периодическое исполнение нескольких функций, каждая со своим временным интервалом исполнения. Для этого для каждой функции составляется кортеж вида [fn, interval], который указывается в качестве аргумента при вызове функции run. Максимальное число таких аргументов - 8.

  from dev import run, Reg

# Конфигурируем три пользовательских регистра, которые будут выступать в качестве счетчиков, 
# а также обнуляем их значения
for i in range(3):
    _ = Reg(i).conf(name='counter'+str(i), type='int', access='r')
    Reg(i)(0)

# Объявляем две пользовательские функции, каждая из которых инкрементирует значение 
# соответствующего регистра
def fn1(): Reg(0).inc()
def fn2(): Reg(1).inc()

# Инициируем периодическое исполнение трех функций с разными интервалами
# Для примера, третья функция объявлена, как lambda функция
run([fn1, 1], [fn2, 0.25], [lambda: Reg(2).inc(), 0.33])
  

count

Функция count() позволяет задать лимиты на количество доступных пользовательских регистров, событий, аварий и других элементов, используемых в сценарии.
Компоненты, для которых установлено значение 0, не отображаются в веб-интерфейсе.

Аргументы функции:

АргументТипОписание
RegintКоличество пользовательских регистров
AlarmintКоличество пользовательских аварий
EventintКоличество пользовательских событий
AiintКоличество аналоговых входов
AointКоличество аналоговых выходов
DiintКоличество цифровых выходов
DointКоличество цифровых входов

Значения должны быть в диапазоне от 0 до предельного количества для модели контроллера.

  from dev import count, Reg
# Ограничи кол-во доступных пользовательских регистров числом 10
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]
  

webconf

Функция webconf() настраивает отображение элементов панели управления в веб-интерфейсе контроллера.

Аргументы функции:

АргументТипОписание
RegboolОтображение пользовательских регистров
PinboolОтображение входов/выходов
DisplayboolОтображение виртуального дисплея
ConsoleboolОтображение консоли
  from dev import webconf

# Отобразим все элементы панели управления
webconf(Reg=True, Pin=True, Display=True, Console=True)
  

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))