Поддержка lua скриптов

Самовар поддерживает автоматизацию на основе скриптового языка программирования Lua. Редактор скриптов доступен на странице Настроек – Редактор.

Текущая версия Lua 5.4.4

По умолчанию поддержка Lua в скетче отключена, нужно в Samovar_ini.h изменить строку

//#define USE_LUA

на

#define USE_LUA

В скриптах реализована поддержка модуля PCF8575 – это расширитель на 16 цифровых портов, и расширителя аналоговых портов PCF8591. Они оба подключаются по I2C.

На расширитель портов можно вешать любые исполнительные устройства или кнопки (датчики, которые работают как кнопки), и самому определить, что должно происходить в тот или иной момент при работе Самовара. А так же получать значение аналогового сигнала с датчиков.
Инициализационный скрипт запускается при старте Самовара, а дальше раз в секунду запускается другой скрипт. В первом можно описать необходимые устройства, во втором описать их поведение. Например, в нем можно сделать проверку по температуре или текущему статусу Самовара, и, например, включить/выключить насос, или открыть/закрыть клапан, или управлять дополнительным тэном. Можно проверить, что не сработал датчик безопасности, а если сработал, то прямо из скрипта можно выключить Самовар, увеличить или остановить подачу воды. Сценариев может быть много. Определяются они конкретным оборудованием.
При этом базовый функционал Самовара не меняется.

Подробнее о работе скриптов.

Обратите внимание! При перезаписи веб-интерфейса скрипты тоже перезаписываются, поэтому обязательно сохраняйте их у себя на компьютере, и после обновления веб-интерфейса не забывайте восстанавливать скрипты. Так же их можно подложить в каталог data, тогда при обновлении веб-интерфейса они будут загружены в Самовар.

При запуске Самовара выполняется файл init.lua. Его назначение – включить/выключить секундный цикл выполнения скриптов, а также проинициализировать переменные, которые будут использоваться в других скриптах.

Если включен запуск скриптов в цикле, каждую секунду запускается два скрипта: сначала – script.lua, после него скрипт с именем, которое определяется в зависимости от режима работы: beer.lua (Пиво), bk.lua (Бражная колонна), dist.lua (Дистилляция), rectificat.lua (Ректификация). Так же их можно запустить разово, обратившись по адресу http://samovar.local/lua. Если до следующего запуска скрипт не успеет выполниться, то текущий запуск будет пропущен, т. е. работающий скрипт не прерывается.

Из скриптов можно получить доступ к внутренним переменным Самовара (часть из них менять нельзя, они доступны только на чтение), а также вызывать функции Самовара

pinMode(pin) – аналогично одноименной функции Arduino, устанавливает режим работы заданного входа/выхода(pin) как входа или как выхода. Изменение режима доступно только для этих портов: RELE_CHANNEL1, RELE_CHANNEL4, RELE_CHANNEL3, RELE_CHANNEL2 (описание пинов можно взять тут). Обратите внимание – здесь и далее нужно передавать их числовое значение. Т. е. если нужно установить порт RELE_CHANNEL4 как вход – надо вызвать функцию pinMode(13)

digitalWrite(pin, Value) – аналогично одноименной функции Arduino, подает HIGH или LOW значение на цифровой вход/выход (pin). Т. е. если нужно установить на выходе RELE_CHANNEL4 высокое значение, надо вызвать digitalWrite(13, 1)

digitalRead(pin) – аналогично одноименной функции Arduino, считывает значение с заданного входа – HIGH или LOW. Т. е. если нужно прочитать установленное на входе или выходе RELE_CHANNEL4 значение, надо вызвать digitalRead (13)

analogRead – аналогично одноименной функции Arduino, считывает значение с аналогового входа. Напряжение, поданное на аналоговый вход, будет преобразовано в значение от 0 до 4095. ВНИМАНИЕ! Подача напряжения на вход больше, чем 3.3 вольта может привести к выходу порта из строя, или всей ESP32. На данный момент эта функция работает только с портом LUA_PIN.

exp_pinMode(pin) – аналогично pinMode(pin), но для управления расширителем портов PCF8575, pin– номер порта расширителя. Все порты расширителя доступны для выбора типа – чтение или вывод.

exp_digitalWrite(pin, Value) – аналогично digitalWrite (pin, Value), но для управления расширителем портов PCF8575, pin – номер порта расширителя, Value 1 или 0. Все порты расширителя доступны для записи.

exp_digitalRead – аналогично digitalRead (pin), но для управления расширителем портов PCF8575, pin– номер порта расширителя. Все порты расширителя доступны для чтения.

delay(ms) – аналогично одноименной функции Arduino, останавливает выполнение программы на заданное в параметре количество миллисекунд (1000 миллисекунд в 1 секунде).

millis() –  аналогично одноименной функции Arduino, возвращает количество миллисекунд с момента начала работы Самовара.

setTimer(Num, Sec) – установить таймер номер Num на Sec секунд. Доступно 10 таймеров с 1 по 10. Т. е. одновременно скрипты могут работать не больше, чем с 10 таймерами.

getTimer(Num) – получить оставшееся время по таймеру номер Num. Если таймер не установлен, или время закончилось, функция вернет 0.

sendMsg(Msg, Level) – Если Level = -1, сообщение Msg будет выведено в com-port и в консоль браузера, удобно для отладки. Если Level 0,1,2 – сообщение отправляется в консоль и в Blynk.

setPower(Power) – включает/выключает Самовар. setPower(0) – выключит, setPower(1) – включит.

setCurrentPower(Volt) – установить Volt на регуляторе. Если используется регулятор с управленем по мощности, то тогда Volt – это мощность, которую нужно установить.

setBodyTemp – установить температуру тела в процессе ректификации. Работать будет только в режиме ректификации. В других режимах будет отправлять в Blynk и выводить сообщение в консоль о невозможности установить температуру тела.

setMixer(Val) – включить/выключить мешалку. setMixer(0) – выключить, setMixer(1) – включить.

openValve(Val) – открыть/закрыть клапан воды. openValve(0) – закрыть, openValve(1) – открыть.

setAlarm() – установить режим тревоги. Самовар выключит питание, закроет клапан воды и отключит насос воды.

setNextProgram() – перейти на следующую программу. Аналогично нажатию на кнопку в интерфейсе -Следующая программа.

setPauseWithdrawal(Val) – поставить/снять отбор на паузу. setPauseWithdrawal(0) – снять с паузы, setPauseWithdrawal(1) – поставить на паузу.

getState() – получить статус Самовара (число), удобно для определения, в каком статусе находится Самовар.

setNumVariable(“Variable”, Val) – установить внутреннюю числовую переменную Самовара. Не все переменные доступны для установки значений. setNumVariable(“TankTemp”, 85) – установит температуру куба равной 85 градусам. Внимание! Если не понимаете, как работает Самовар, эту функцию лучше не использовать, так как потенциально можно нарушить логику работы Самовара.

setStrVariable(“Variable”, Val)  – установить внутреннюю строковую переменную Самовара. Не все переменные доступны для установки значений. setStrVariable(“SamovarStatus”, “Тестовый статус Самовара”).

getNumVariable(“Variable”) – получить внутреннюю числовую переменную Самовара. TankTemp = getNumVariable(“TankTemp”) – присвоит переменной скрипта TankTemp значение температуры куба.

getStrVariable(“Variable”) – получить внутреннюю строковую переменную Самовара. 

program_type = getStrVariable(“program_type”) – присвоит переменной скрипта program_type тип текущей выполняемой программы.

setPumpPwm(p) – регулирование производительности насоса воды, p=0 – насос выключен, p=1023 – максимальная производительность.

Переменные скрипта существуют только в момент выполнения скрипта. При следующем запуске их значения не сохранятся. Иногда бывает необходимо запомнить значение переменной в одном запуске скрипта и считать его в другом. Для этого есть две функции – setObject(“Object”,Val) и getObject(“Object”)/ getObject(“Object”,”NUMERIC”). Значения переменных сохраняются до перезагрузки.

setObject("Object",Val) – запомнит объект Object  со значением Val в памяти Самовара.

getObject(“Object”) – получит ранее сохраненное значение объекта Object. Если такой объект не был сохранен, вернется пустая строка. При попытке работать с пустой строкой как с числом, оно примет значение nil – не определено. Для того, чтобы было удобнее работать с числовыми значениями, и не проверять на nil, можно эту функцию вызвать с дополнительным параметром “NUMERIC”, в этом случае, если объект еще был не инициализирован, вернется 0.

Пример работы с setObject/getObject:

n = 156
setObject("MyObject", n)
print (n)
n = n + 5
print (n)
n = getObject("MyObject")
print (n)

Если запустить этот скрипт, он в мониторе порта Arduino выведет

156
161
156

http_request(Url) – выполнить запрос по адресу Url. Например, можно отправить сообщение в Телеграм (работает только на новой версии SDK).

http_request("http://test.com:80/post?foo1=bar1", "POST", "Content-Type: text/text; charset=utf-8\r\n", "body")

Пример скрипта, который отправит в чат Telegram температуру куба:

local char_to_hex = function(c)
  return string.format("%%%02X", string.byte(c))
end

local function urlencode(url)
  if url == nil then
    return
  end
  url = url:gsub("\n", "\r\n")
  url = url:gsub("([^%w ])", char_to_hex)
  url = url:gsub(" ", "+")
  return url
end

local hex_to_char = function(x)
  return string.char(tonumber(x, 16))
end

function SendTelegram(text)
  local token = "5177...:AAG0b...."  --
  local chat_id = "38806....."
  http_request("http://212.237.16.93/bot" .. token .. "/sendMessage?chat_id=" .. chat_id .. "&text=" .. urlencode(text))
end  


local text = "Текущая температура куба = ".. getNumVariable("TankTemp")

SendTelegram(text)

Пример скрипта, который получает значение от аналогового датчика уровня и управляем насосом воды (например, для перекачки браги в куб):

start_pump = getObject("start_pump", "NUMERIC") + 0 --получаем из ранее сохраненного объекта числовое значение и преобразуем в число

sensor = analogRead() --читаем аналоговое значение пина 34 (зарезервирован для lua)
--sensor = 1500

if sensor >= 1000 and sensor <= 2000 and start_pump == 0 then
   setObject("start_pump", 1) --сохраняем значение в объекте в памяти Самовара, чтобы его можно было использовать в следующем цикле запуска скрипта
   digitalWrite(4,1) --устанавливаем на 4 ноге высокий уровень
   print("Start pump") --[=[пишем в com-port. Так-же можно использовать команду sendMsg("Msg", Level). Если Level = -1, сообщение будет выведено в com-port и в консоль браузера, удобно для отладки.
                          Если Level 0,1,2 - сообщение отрпавляетя в консоль и в блинк]=]
   --sendMsg("Start pump",-1)                     
elseif sensor == 0 then
   setObject("start_pump", 0) --сохраняем значение в объекте в памяти Самовара, чтобы его можно было использовать в следующем цикле запуска скрипта
   if (start_pump == 1) then
     digitalWrite(4,0) --устанавливаем на 4 ноге низкий уровень
     print("Finish pump")
   end
end

Список внутренних переменных, которые по умолчанию доступны в скрипте:

bme_pressure –текущее значение атмосферного давления

capacity_num – номер емкости, в которую идет отбор

SamovarStatusInt – статус работы Самовара

ProgramNum – текущий номер программы

ProgramLen – количество строк в программе

currentvolume – отобранный объем в текущей строке программы

ActualVolumePerHour – текущая скорость отбора в литрах

WthdrwlProgress – прогресс текущего отбора

PowerOn – признак включенного/выключенного нагрева. 0 – выключено, 1 – включено

PauseOn – признак паузы. 0 – нет, 1 – да

StepperMoving – признак работы перистальтического насоса. 0 – не работает, 1 – работает

program_Pause – признак запущенной программы паузы. 0 – нет, 1 – да

program_Wait – признак, что программа стоит на паузе. 0 – нет, 1 – да

program_Wait_Type – причина постановки на паузу – превышение по царге или пару. Значения “(пар)” или “(царга)”

WthdrwTimeAll – оставшееся время отбора

WthdrwTime – время отбора текущей строки программы

WthdrwTimeAllS – оставшееся время отбора строкой

WthdrwTimeS – время отбора текущей строки программы строкой

pump_started – статус работы насоса воды. 0 – нет, 1 – да

setautospeed – признак для однократного снижения скорости насоса при паузе. 0 – не снижать, 1 – снижать

heater_state – статус нагрева при затирке. 0 – не нагревается, 1 – нагревается

mixer_status – статус работы мешалки. 0 – не работает, 1 – работает

alarm_event – признак сработавшей кнопки тревоги. 0 – нет, 1 – да

acceleration_heater – признак включенного разгонного тэна. 0 – выключен, 1 – включен

valve_status – статус клапана подачи воды. 0 – закрыт, 1 – открыт

program_type – тип текущей программы (из описания программ ректификации и пива)

program_volume – объем отбора в мл

program_speed – скорость отбора в л/ч

program_temp – температура, при которой отбирается эта часть погона. 0 – определяется автоматически

program_power – напряжение/мощность, при которой отбирается эта часть погона

program_time – время, необходимое для работы этой строки программы

program_capacity_num – номер емкости для отбора

SamSetup_Mode – режим работы Самовара

test_num_val – числовая переменная для отладки

test_str_val – строковая переменная для отладки

SteamTemp – температура датчика пара

PipeTemp – температура датчика царги

WaterTemp – температура датчика воды

TankTemp – температура датчика куба

ACPTemp – температура датчика ТСА

current_power_mode – текущий режим работы регулятора

target_power_volt – заданное напряжение работы регулятора

wp_count

Переменные для управления скриптами:

loop_lua_fl – значения 0 или 1. Если 0 – не выполнять ежесекундный цикл скриптов, 1 – выполнять.

show_lua_script – значения 0 или 1. Если 0 – не показывать выполняемый скрипт в консоли и мониторе порта, 1 – показывать. Можно использоваться при отладке. Так же покажет значения всех переменных, установленных для этого скрипта.

Например, если в скрипте init.lua вызвать эти две функции, то ежесекундно будет запускаться два скрипта (script.lua и определяемый текущим режимом Самовара), и каждый скрипт будет выводиться в монитор порта и консоль браузера

setNumVariable(“loop_lua_fl”,1)

setNumVariable(“show_lua_script”,1)

Документация по Lua

Маленькая книга о Lua

Если кому-то ближе визуальное программирование, можно использовать генератор Lua скриптов на основе Blockly

Добавить комментарий