Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Скрипт openComputers, для мониторинга заряда Power Sub-Station батарейки из GT++
- --Автор: aka_zaratustra весна 2021
- --Версия сборки под которую писался скрипт: GTNH 2.1.0.0-2.1.1.3
- --Минимальная конфигурация компьютера openComputers - любой минимальный сэтап со сдвоенным монитором T1.
- --Для цветного вывода рекомендуемая конфигурация компьютера openComputers - Т2 видеокарта, сдвоенный монитор Т2, остальное может быть минимальным.
- --Адаптер с пустым внутренним слотом установлен в смежном блоке с контроллером Power Sub-Station.
- --Никаких других адаптеров, подключенных к греговским механизмам в сети компьютера openComputers быть не должно.
- local ver = "1.5" -- версия программы
- --История изменений версий приведена внизу скрипта
- --начальный режим работы мониторинга:
- --1 - сальдо расход/приход
- --2 - отдельно расход/приход
- local mode = 2
- --разрешение монитора
- local Width = 20
- local Height = 4
- if mode == 2 then
- Width = 22
- end
- local component = require("component")
- local computer = require("computer")
- local event = require('event')
- --local ADDRESS_PSS = "9885"
- local object = {}
- object.PSS = {}
- local PSS = object.PSS
- --Найдем компонент батареи
- for address, name in component.list("gt", false) do
- local componentGT = component.proxy(address)
- local info = componentGT.getSensorInformation()
- if string.find(info[1], "substation") then
- PSS.component = componentGT
- --print(info[1])
- end
- end
- --PSS.component = component.proxy(component.get(ADDRESS_PSS))
- local gpu = component.gpu
- local PrintChargePercent --процент заряда батареи
- local PrintChargeAmount -- количество заряда в eu
- -- скорость изменения заряда eu/t
- local PrintChargeChange
- local iChargeChange = 0
- local AvarageChargeChange = 0
- -- скорость прихода и расхода заряда eu/t
- local PrintChargeIncome
- local iChargeIncome = 0
- local AvarageChargeIncome = 0
- local PrintChargeOutcome
- local iChargeOutcome = 0
- local AvarageChargeOutcome = 0
- local PrintChargeTime -- время за которое произойдет полная зарядка/разрядка
- local LastTime = computer.uptime() -- счетчик времени
- local iLastChargeAmount = 0 -- количество заряда в eu, которое было на прошлой итерации
- local iLastChargeIncome = 0 -- количество притока заряда в eu, которое было на прошлой итерации
- local iLastChargeOutcome = 0 -- количество оттока заряда в eu, которое было на прошлой итерации
- local AvarageDimSize = 10 -- количество хранимых последних значений скорости заряда. Используется для сглаживания скачков
- local current_i = 1
- local iChargeChangeDim = {} -- массив последних значений скорости зарядки
- --инициализируем массив
- for i = 1, AvarageDimSize do
- iChargeChangeDim[i] = 0
- end
- local iChargeIncomeDim = {} -- массив последних значений прихода заряда
- --инициализируем массив
- for i = 1, AvarageDimSize do
- iChargeIncomeDim[i] = 0
- end
- local iChargeOutcomeDim = {} -- массив последних значений расхода заряда
- --инициализируем массив
- for i = 1, AvarageDimSize do
- iChargeOutcomeDim[i] = 0
- end
- local info = object.PSS.component.getSensorInformation() --получаем таблицу с текстом состояния батареи
- function howManyYears(t) -- преобразовать секунды в количество лет, месяцев, дней, часов, минут, секунд
- if t < 60 then --если осталось меньше минуты
- return tostring(math.floor(t)) .. " сек"
- elseif t < 60*60 then --если осталось меньше часа
- local minutes = math.floor(t/60)
- local seconds = math.floor(math.fmod(t, 60))
- return tostring(minutes) .. " мин " .. tostring(seconds) .. " сек"
- elseif t < 60*60*24 then --если осталось меньше суток
- local hours = math.floor(t/(60*60))
- local minutes = math.floor(math.fmod(t, 60*60)/60)
- return tostring(hours) .. " ч " .. tostring(minutes) .. " мин"
- elseif t < 60*60*24*30 then --если осталось меньше месяца
- local days = math.floor(t/(60*60*24))
- local hours = math.floor(math.fmod(t, 60*60*24)/(60*60))
- return tostring(days) .. " д " .. tostring(hours) .. " ч"
- elseif t < 60*60*24*30*12 then --если осталось меньше года
- local months = math.floor(t/(60*60*24*30))
- local days = math.floor(math.fmod(t, 60*60*24*30)/(60*60*24))
- return tostring(months) .. " мес " .. tostring(days) .. " д "
- else --если осталось больше года
- local years = math.floor(t/(60*60*24*30*12))
- local months = math.floor(math.fmod(t, 60*60*24*30*12)/(60*60*24*30))
- return tostring(years) .. " г " .. tostring(months) .. " мес"
- end
- end
- function draw1() --отрисовать значения на экране по варианту 1
- if gpu ~= nil then
- gpu.fill(1,1,Width,Height,' ')
- gpu.setForeground(0xFFFFFF)
- gpu.set(1,1, "Заряд: "..PrintChargePercent)
- gpu.set(1,2, " "..PrintChargeAmount)
- if AvarageChargeChange < 0 then
- gpu.setForeground(0xFF0000)
- elseif AvarageChargeChange > 0 then
- gpu.setForeground(0x00FF00)
- end
- gpu.set(1,3, " "..PrintChargeChange)
- gpu.setForeground(0xFFFFFF)
- gpu.set(1,4, "Время: "..PrintChargeTime)
- end
- end
- function draw2() --отрисовать значения на экране по варианту 2
- if gpu ~= nil then
- gpu.fill(1,1,Width,Height,' ')
- gpu.setForeground(0xFFFFFF)
- gpu.set(1,1, "Заряд: "..PrintChargePercent)
- gpu.set(1,2, " "..PrintChargeAmount)
- if AvarageChargeIncome < 0 then
- gpu.setForeground(0xFF0000)
- elseif AvarageChargeIncome > 0 then
- gpu.setForeground(0x00FF00)
- end
- local spaces = string.rep(" ", 9 - string.len(PrintChargeIncome))
- gpu.set(1,3, spaces..PrintChargeIncome)
- gpu.setForeground(0xFFFFFF)
- if AvarageChargeOutcome < 0 then
- gpu.setForeground(0xFF0000)
- elseif AvarageChargeOutcome > 0 then
- gpu.setForeground(0x00FF00)
- end
- local spaces = string.rep(" ", 9 - string.len(PrintChargeOutcome))
- gpu.set(10,3, spaces..PrintChargeOutcome)
- gpu.setForeground(0xFFFFFF)
- gpu.set(19,3, "eu/t")
- if AvarageChargeIncome + AvarageChargeOutcome < 0 then
- gpu.setForeground(0xFF0000)
- elseif AvarageChargeIncome + AvarageChargeOutcome > 0 then
- gpu.setForeground(0x00FF00)
- end
- gpu.set(1,4, "Время: "..PrintChargeTime)
- end
- end
- function formatGrade(n, postscriptum) --преобразует число в выводимую строку с сокращением триад 123456789 -> 123 M, присоединяет в концу строки второй параметр
- local sn = ""
- if math.abs(n) < 1000 then
- sn = tostring(math.floor(n*100)/100).." "
- elseif math.abs(n) < 1000000 then
- sn = tostring(math.floor(n/10)/100).."K "
- elseif math.abs(n) < 1000000000 then
- sn = tostring(math.floor(n/10000)/100).."M "
- elseif math.abs(n) < 1000000000000 then
- sn = tostring(math.floor(n/10000000)/100).."G "
- else
- sn = tostring(math.floor(n/10000000000)/100).."T "
- end
- return sn..postscriptum
- end
- function cutSpaces(s)
- s,_ = s:gsub(' ','') --вырезаем пробелы (для 2.1.1.3)
- s,_ = s:gsub(',','') --вырезаем запятые (для 2.1.1.0)
- return s
- end
- function update() --обновление инфы о состоянии батареи
- --ротация по массиву значений последних значений изменения заряда
- current_i = current_i + 1
- if current_i > AvarageDimSize then
- current_i = 1
- end
- local ThisTime = computer.uptime()
- local deltaTicks = (ThisTime - LastTime)*20 --сколько времени в тиках прошло после последнего обновления
- LastTime = ThisTime
- --print(deltaTicks)
- info = object.PSS.component.getSensorInformation() --получаем таблицу с текстом состояния батареи
- --########################ДЛЯ ДЭБАГА
- --for name, val in pairs(info) do --просмотрим таблицу
- --print(name, val)
- --os.sleep(0.5)
- --end
- --goto done
- --########################
- local s = info[3] --строчка с текущим зарядом
- s = string.sub(s,15,string.len(s)-3) --отрезаем лишние куски от строки
- s = cutSpaces(s)
- --print(s)
- local iChargeAmount = tonumber(s)
- --print(iChargeAmount)
- local s = info[10] --строчка с текущим приходом заряда
- s = string.sub(s,16,string.len(s)-6) --отрезаем лишние куски от строки
- s = cutSpaces(s)
- --print(s)
- local iChargeIncomeAmount = tonumber(s)
- --print(iChargeIncomeAmount)
- local s = info[11] --строчка с текущим расходом заряда
- s = string.sub(s,17,string.len(s)-6) --отрезаем лишние куски от строки
- s = cutSpaces(s)
- --print(s)
- local iChargeOutcomeAmount = tonumber(s)
- --print(iChargeOutcomeAmount)
- local s = info[4] --строчка с полной емкостью батареи
- s = string.sub(s,14,string.len(s)-3) --отрезаем лишние куски от строки
- s = cutSpaces(s)
- --print(s)
- local iBatteryCap = tonumber(s)
- --print(iBatteryCap)
- local dChargePercent = iChargeAmount / iBatteryCap * 100 --процент заряда батареи неокругленный
- dChargePercent = math.floor(dChargePercent*100)/100 --округляем с масштабированием, так чтобы получилось два знака после запятой (например 33.33%)
- PrintChargePercent = tostring(dChargePercent) .. " %"
- --print(PrintChargePercent)
- PrintChargeAmount = formatGrade(iChargeAmount, "eu") --форматируем в выводимую строку
- --print(PrintChargeAmount)
- --
- if iLastChargeAmount == 0 then
- iLastChargeAmount = iChargeAmount
- end
- if iLastChargeIncome == 0 then
- iLastChargeIncome = iChargeIncomeAmount
- end
- if iLastChargeOutcome == 0 then
- iLastChargeOutcome = iChargeOutcomeAmount
- end
- iChargeChange = math.floor((iChargeAmount - iLastChargeAmount)/deltaTicks) -- скорость зарядки батареи в eu/t
- iChargeIncome = math.floor((iChargeIncomeAmount - iLastChargeIncome)/deltaTicks) -- скорость зарядки батареи в eu/t
- iChargeOutcome = -math.floor((iChargeOutcomeAmount - iLastChargeOutcome)/deltaTicks) -- скорость зарядки батареи в eu/t
- --print(iChargeChange, iChargeAmount, iLastChargeAmount)
- --вычислим среднее значение скорости заряда исходя из последних AvarageDimSize значений
- iChargeChangeDim[current_i] = iChargeChange
- AvarageChargeChange = 0
- for i = 1, AvarageDimSize do
- AvarageChargeChange = AvarageChargeChange + iChargeChangeDim[i]
- --print (i, iChargeChangeDim[i])
- end
- AvarageChargeChange = AvarageChargeChange / AvarageDimSize
- PrintChargeChange = formatGrade(AvarageChargeChange, "eu/t") --форматируем в выводимую строку
- if AvarageChargeChange > 0 then --добавим плюс в начале, если идет прирост энергии
- PrintChargeChange = "+"..PrintChargeChange
- end
- --вычислим среднее значение скорости прихода заряда исходя из последних AvarageDimSize значений
- iChargeIncomeDim[current_i] = iChargeIncome
- AvarageChargeIncome = 0
- for i = 1, AvarageDimSize do
- AvarageChargeIncome = AvarageChargeIncome + iChargeIncomeDim[i]
- --print (i, iChargeChangeDim[i])
- end
- AvarageChargeIncome = AvarageChargeIncome / AvarageDimSize
- PrintChargeIncome = formatGrade(AvarageChargeIncome, "") --форматируем в выводимую строку
- if AvarageChargeIncome > 0 then --добавим плюс в начале, если идет прирост энергии
- PrintChargeIncome = "+"..PrintChargeIncome
- end
- --вычислим среднее значение скорости расхода заряда исходя из последних AvarageDimSize значений
- iChargeOutcomeDim[current_i] = iChargeOutcome
- AvarageChargeOutcome = 0
- for i = 1, AvarageDimSize do
- AvarageChargeOutcome = AvarageChargeOutcome + iChargeOutcomeDim[i]
- --print (i, iChargeChangeDim[i])
- end
- AvarageChargeOutcome = AvarageChargeOutcome / AvarageDimSize
- PrintChargeOutcome = formatGrade(AvarageChargeOutcome, "") --форматируем в выводимую строку
- if AvarageChargeOutcome > 0 then --добавим плюс в начале, если идет прирост энергии
- PrintChargeOutcome = "+"..PrintChargeOutcome
- end
- --print(PrintChargeChange)
- iLastChargeAmount = iChargeAmount
- iLastChargeIncome = iChargeIncomeAmount
- iLastChargeOutcome = iChargeOutcomeAmount
- --время, оставшееся до полной зарядки или полной разрядки батареи
- local ticksRemain
- if AvarageChargeChange < 0 then --если батарея разряжается
- ticksRemain = -iChargeAmount/AvarageChargeChange
- elseif AvarageChargeChange > 0 then --если батарея заряжается
- ticksRemain = (iBatteryCap - iChargeAmount)/AvarageChargeChange
- else --если батарея разрядилась до нуля
- ticksRemain = 0
- end
- --print(ticksRemain/20)
- PrintChargeTime = howManyYears(ticksRemain/20)
- --print(PrintChargeTime)
- --отрисовываем на экране вариант вывода в зависимости от выбранного режима
- if mode == 1 then
- draw1()
- else
- draw2()
- end
- ::done::
- end
- local needToChangeMode = false
- function handleEvent() --вызывается событием
- needToChangeMode = true
- end
- --for name, val in pairs(PSS.component) do --просмотрим таблицу
- --print(name, val)
- --os.sleep(2)
- --end
- require("component").gpu.setResolution(Width, Height)
- event.listen("key_down", handleEvent) -- listen for keypress
- while true do --вечный главный цикл программы
- os.sleep(1)
- --если, пока спали, была нажата кнопка, то меняем режим
- if needToChangeMode == true then
- if mode == 1 then
- mode = 2
- Width = 22 --меняем ширину разрешения экрана, чтобы в режиме 2 все влезло на экран
- else
- mode = 1
- Width = 20 --меняем ширину разрешения экрана на самый крупный
- end
- require("component").gpu.setResolution(Width, Height)
- needToChangeMode = false
- end
- update() --выводим на экран инфу
- end
- -- Версия 1.1
- -- Добавлены в вывод общего заряда и скорости заряда два разрадя после запятой: 12K eu/t -> 12.56K eu/t
- -- Указание ширины и высоты разрешения экрана вынесены в константы и указываются в начале скрипта
- -- Версия 1.2
- -- Добавлено сглаживание значения скорости заряда батареи. Теперь выводится средняя скорость за последнее количество секунд, указанное в константе AvarageDimSize
- -- Устранена проблема отказа запуска программы из-за наличия вокруг блока адаптера других блоков Грега, например электрических проводов
- -- Версия 1.3
- -- Добавлен режим вывода информации на экран, при котором входящая и исходящая скорости заряда батареи отображаются отдельно.
- -- Добавлена возможность переключения между режимами вывода информации на экран непосредственно во время работы программы. Переключение между режимами происходит по нажатию любой клавиши.
- -- Версия 1.4
- -- Усовершенствованно цветовое отображение информации времени оставшегося до заряда/разряда батареи. Теперь время выводится зеленым если батарея заряжается, и красным если разряжается.
- -- Начальный режим работы мониторинга установлен в "отдельно расход/приход" (задается константой mode)
- -- Версия 1.5
- -- Учтено изменение формата информации в таблице состояния батареи для версии 2.1.1.3 (на версии 2.1.1.0 разделители триад были запятые, а в 2.1.1.3 стали пробелом)
Add Comment
Please, Sign In to add comment