Самовар поддерживает автоматизацию на основе скриптового языка программирования 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