Advertisement
aka_zaratustra

Мониторинг заряда Lapotronic Capacitor v.1.9 для GTNH 2.7.

Dec 29th, 2024 (edited)
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.96 KB | None | 0 0
  1. --Скрипт openComputers, для мониторинга заряда Lapotronic Capacitor батарейки из GT++
  2. --Автор: aka_zaratustra 2021-2024
  3. --Версия сборки под которую писался скрипт: GTNH 2.7
  4. --Лицензия: MIT
  5.  
  6. --Минимальная конфигурация компьютера openComputers - любой минимальный сэтап со сдвоенным монитором T1.
  7. --Для цветного вывода рекомендуемая конфигурация компьютера openComputers - Т2 видеокарта, сдвоенный монитор Т2, остальное может быть минимальным.
  8. --Адаптер с пустым внутренним слотом установлен в смежном блоке с контроллером Lapotronic Capacitor.
  9. --Никаких других адаптеров, подключенных к греговским механизмам в сети компьютера openComputers быть не должно.
  10.  
  11. local ver = "1.9" -- версия программы
  12. --История изменений версий приведена внизу скрипта
  13.  
  14. --начальный режим работы мониторинга:
  15. --1 - сальдо расход/приход
  16. --2 - отдельно расход/приход
  17. local draw_mode = 2
  18.  
  19. --период расчета прихода расхода (5 сек, 5 мин, 1 час)
  20. local mode = 2
  21.  
  22.  
  23.  
  24.  
  25. --разрешение монитора
  26. local Width = 20
  27. local Height = 5
  28. if draw_mode == 2 then
  29.     Width = 22
  30. end
  31.  
  32.  
  33.  
  34. local component = require("component")
  35. local computer = require("computer")
  36. local event = require('event')
  37.  
  38.  
  39.  
  40. --local ADDRESS_PSS = "9885"
  41.  
  42.  
  43.    
  44. local object = {}
  45. object.PSS = {}
  46. local PSS = object.PSS
  47.  
  48. --Найдем компонент батареи
  49. for address, name in component.list("gt", false) do
  50.     local componentGT = component.proxy(address)
  51.     local info = componentGT.getSensorInformation()
  52.     --print(info[1])
  53.     if string.find(info[1], "Operational Data") then
  54.         PSS.component = componentGT
  55.         --print(info[1])
  56.     end
  57. end
  58.  
  59. --PSS.component = component.proxy(component.get(ADDRESS_PSS))
  60. local gpu = component.gpu
  61.  
  62.  
  63.  
  64. local PrintChargePercent  --процент заряда батареи
  65. local PrintChargeAmount  -- количество заряда в eu
  66.  
  67. -- скорость изменения заряда eu/t
  68. local PrintChargeChange  
  69. local iChargeChange = 0
  70. local AvarageChargeChange = 0
  71.  
  72. -- скорость прихода и расхода заряда eu/t
  73. local PrintChargeIncome
  74. local iChargeIncome = 0
  75. local AvarageChargeIncome = 0
  76. local PrintChargeOutcome
  77. local iChargeOutcome = 0
  78. local AvarageChargeOutcome = 0
  79.  
  80.  
  81. local PrintChargeTime  -- время за которое произойдет полная зарядка/разрядка
  82.  
  83.  
  84. local LastTime = computer.uptime() -- счетчик времени
  85. local iLastChargeAmount = 0  -- количество заряда в eu, которое было на прошлой итерации
  86. local iLastChargeIncome = 0  -- количество притока заряда в eu, которое было на прошлой итерации
  87. local iLastChargeOutcome = 0  -- количество оттока заряда в eu, которое было на прошлой итерации
  88.  
  89. local AvarageDimSize = 20 -- количество хранимых последних значений скорости заряда. Используется для сглаживания скачков
  90. local current_i = 1
  91. local iChargeChangeDim = {} -- массив последних значений скорости зарядки
  92. --инициализируем массив
  93. for i = 1, AvarageDimSize do
  94.    iChargeChangeDim[i] = 0
  95. end
  96.  
  97. local iChargeIncomeDim = {} -- массив последних значений прихода заряда
  98. --инициализируем массив
  99. for i = 1, AvarageDimSize do
  100.    iChargeIncomeDim[i] = 0
  101. end
  102.  
  103. local iChargeOutcomeDim = {} -- массив последних значений расхода заряда
  104. --инициализируем массив
  105. for i = 1, AvarageDimSize do
  106.    iChargeOutcomeDim[i] = 0
  107. end
  108.  
  109.  
  110. local info = object.PSS.component.getSensorInformation() --получаем таблицу с текстом состояния батареи
  111.  
  112. function Log(s)
  113.     LogFile = io.open("debugLog.txt", "a")
  114.     LogFile:write(s .. "\n")
  115.     LogFile:close()
  116. end
  117.  
  118. function howManyYears(t) -- преобразовать секунды в количество лет, месяцев, дней, часов, минут, секунд
  119.  
  120.     if t < 60 then --если осталось меньше минуты
  121.         return tostring(math.floor(t)) .. " сек"
  122.     elseif t < 60*60 then --если осталось меньше часа
  123.         local minutes = math.floor(t/60)
  124.         local seconds = math.floor(math.fmod(t, 60))
  125.         return tostring(minutes) .. " мин " .. tostring(seconds) .. " сек"
  126.     elseif t < 60*60*24 then --если осталось меньше суток
  127.         local hours = math.floor(t/(60*60))
  128.         local minutes = math.floor(math.fmod(t, 60*60)/60)
  129.         return tostring(hours) .. " ч " .. tostring(minutes) .. " мин"
  130.     elseif t < 60*60*24*30 then --если осталось меньше месяца
  131.         local days = math.floor(t/(60*60*24))
  132.         local hours = math.floor(math.fmod(t, 60*60*24)/(60*60))
  133.         return  tostring(days) .. " д " .. tostring(hours) .. " ч"
  134.     elseif t < 60*60*24*30*12 then --если осталось меньше года
  135.         local months = math.floor(t/(60*60*24*30))
  136.         local days = math.floor(math.fmod(t, 60*60*24*30)/(60*60*24))
  137.         return  tostring(months) .. " мес " .. tostring(days) .. " д "
  138.     else --если осталось больше года
  139.         local years = math.floor(t/(60*60*24*30*12))
  140.         local months = math.floor(math.fmod(t, 60*60*24*30*12)/(60*60*24*30))
  141.         return  tostring(years) .. " г " .. tostring(months) .. " мес"
  142.     end
  143. end
  144.  
  145. function draw1() --отрисовать значения на экране по варианту 1
  146.     if gpu ~= nil then
  147.         gpu.fill(1,1,Width,Height,' ')
  148.         gpu.setForeground(0xFFFFFF)
  149.         gpu.set(1,1, "Заряд: "..PrintChargePercent)
  150.         gpu.set(1,2, "       "..PrintChargeAmount)
  151.         if AvarageChargeChange < 0 then
  152.             gpu.setForeground(0xFF0000)
  153.         elseif AvarageChargeChange > 0 then
  154.             gpu.setForeground(0x00FF00)
  155.         end
  156.         gpu.set(1,3, "       "..PrintChargeChange)
  157.         gpu.setForeground(0xFFFFFF)
  158.         gpu.set(1,4, "Время: "..PrintChargeTime)
  159.     end
  160. end
  161.  
  162. function draw2() --отрисовать значения на экране по варианту 2
  163.     if gpu ~= nil then
  164.         gpu.fill(1,1,Width,Height,' ')
  165.         gpu.setForeground(0xFFFFFF)
  166.         gpu.set(1,1, "Charge:    "..PrintChargePercent)
  167.         gpu.set(1,2, "         "..PrintChargeAmount)
  168.  
  169.         if AvarageChargeIncome < 0 then
  170.             gpu.setForeground(0xFF0000)
  171.         elseif AvarageChargeIncome > 0 then
  172.             gpu.setForeground(0x00FF00)
  173.         end
  174.         local spaces = string.rep(" ", 9 - string.len(PrintChargeIncome))
  175.         gpu.set(1,3, spaces..PrintChargeIncome)    
  176.         gpu.setForeground(0xFFFFFF)
  177.        
  178.         if AvarageChargeOutcome < 0 then
  179.             gpu.setForeground(0xFF0000)
  180.         elseif AvarageChargeOutcome > 0 then
  181.             gpu.setForeground(0x00FF00)
  182.         end
  183.         local spaces = string.rep(" ", 9 - string.len(PrintChargeOutcome))
  184.         gpu.set(10,3, spaces..PrintChargeOutcome)
  185.        
  186.         gpu.setForeground(0xFFFFFF)
  187.         gpu.set(19,3, "eu/t")
  188.  
  189.         if mode == 0 then
  190.             last_s = "(last 5 seconds)"
  191.         elseif mode == 1 then
  192.             last_s =  "(last 5 minutes)"
  193.         else
  194.             last_s =  "(last 1 hour)"
  195.         end
  196.         gpu.setForeground(0xFFFFFF)    
  197.         gpu.set(3,4, last_s)
  198.  
  199.        
  200.         if AvarageChargeIncome + AvarageChargeOutcome < 0 then
  201.             gpu.setForeground(0xFF0000)
  202.         elseif AvarageChargeIncome + AvarageChargeOutcome > 0 then
  203.             gpu.setForeground(0x00FF00)
  204.         end
  205.         gpu.set(1,5, "Time:   "..PrintChargeTime)      
  206.     end
  207. end
  208.  
  209.  
  210. function formatGrade(n, postscriptum) --преобразует число в выводимую строку с сокращением триад 123456789 -> 123 M, присоединяет в концу строки второй параметр
  211.     local sn = ""
  212.     if math.abs(n) < 1000 then
  213.         sn = tostring(math.floor(n*100)/100).." "
  214.     elseif math.abs(n) < 1000000 then
  215.         sn = tostring(math.floor(n/10)/100).."K "
  216.     elseif math.abs(n) < 1000000000 then
  217.         sn = tostring(math.floor(n/10000)/100).."M "
  218.     elseif math.abs(n) < 1000000000000 then
  219.         sn = tostring(math.floor(n/10000000)/100).."G "
  220.     elseif math.abs(n) < 1000000000000000 then
  221.         sn = tostring(math.floor(n/10000000000)/100).."T "
  222.     elseif math.abs(n) < 1000000000000000000 then
  223.         sn = tostring(math.floor(n/10000000000000)/100).."P "
  224.     elseif math.abs(n) < 1000000000000000000000 then
  225.         sn = tostring(math.floor(n/10000000000000000)/100).."E "
  226.     else
  227.         sn = tostring(math.floor(n/10000000000000000000)/100).."Z "
  228.     end
  229.     return sn..postscriptum
  230. end
  231.  
  232. function cutSpaces(s)
  233.     --for i = 1, #s do
  234.     --  local c = s:sub(i,i)
  235.     --  print(string.byte(c))
  236.     --end  
  237.    
  238.     --s,_ = s:gsub(' ','') --вырезаем пробелы (для 2.1.1.3)
  239.     --s,_ = s:gsub(',','') --вырезаем запятые (для 2.1.1.0)
  240.     --s,_ = s:gsub(string.char(194),'') --вырезаем какие-то непонятные символы (для 2.1.2.0) «Перемещение курсора в начало строки»
  241.     --s,_ = s:gsub(string.char(160),'') --вырезаем какие-то непонятные символы (для 2.1.2.0) Вроде похож на пробел, но не пробел - «неразрывный пробел»
  242.     s,_ = s:gsub("%D+", "") --оставляем только цифры
  243.     return s
  244. end
  245.  
  246. function update() --обновление инфы о состоянии батареи
  247.    
  248.  
  249.    
  250.  
  251.     info = object.PSS.component.getSensorInformation() --получаем таблицу с текстом состояния батареи
  252.  
  253.     --########################ДЛЯ ДЭБАГА
  254.      -- debugFile = io.open("debugFile.txt", "w")
  255.      -- for name, val in pairs(info) do --просмотрим таблицу
  256.          -- -- --print(name, val)
  257.           -- debugFile:write(name, val .. "\n")
  258.           -- --os.sleep(0.5)
  259.       -- end
  260.       -- debugFile:close()
  261.      --goto done
  262.     --########################
  263.  
  264.     local s = info[2] --строчка с текущим зарядом
  265.     --s = string.sub(s,15,string.len(s)-3) --отрезаем лишние куски от строки
  266.     s = cutSpaces(s)
  267.     local iChargeAmount = tonumber(s)
  268.     local s = info[23] --строчка с текущим wireless зарядом
  269.     s = cutSpaces(s)
  270.     iChargeAmount = iChargeAmount + tonumber(s)
  271.    
  272.    
  273.  
  274.     local s = info[10+mode] --строчка с текущим приходом заряда в секунду
  275.     --s = string.sub(s,16,string.len(s)-6) --отрезаем лишние куски от строки
  276.     s,_ = s:gsub("(last 5", "")
  277.     s,_ = s:gsub("(last 1", "")
  278.     s = cutSpaces(s)
  279.     AvarageChargeIncome = tonumber(s)
  280.    
  281.  
  282.     local s = info[13+mode] --строчка с текущим расходом заряда
  283.     --s = string.sub(s,17,string.len(s)-6) --отрезаем лишние куски от строки
  284.     s,_ = s:gsub("(last 5", "")
  285.     s,_ = s:gsub("(last 1", "")
  286.     s = cutSpaces(s)
  287.     --print(s)
  288.     AvarageChargeOutcome = tonumber(s)
  289.     AvarageChargeOutcome = AvarageChargeOutcome * -1
  290.    
  291.  
  292.  
  293.     --строчка с процентным использованием батарейки
  294.     local s = info[5] --общий объем хранилища
  295.     s,_ = s:gsub("Total Capacity: ", "")
  296.     s = cutSpaces(s)
  297.     local TotalCapacity = tonumber(s)
  298.     local ChargePercent = iChargeAmount/TotalCapacity*100
  299.     --Log("TotalCapacity "..TotalCapacity)
  300.     --Log("iChargeAmount "..iChargeAmount)
  301.     --Log("PrintChargePercent "..PrintChargePercent)
  302.    
  303.     PrintChargePercent = string.sub(tostring(ChargePercent),1,6).."%"
  304.    
  305.     --print(PrintChargePercent)
  306.  
  307.     PrintChargeAmount = formatGrade(iChargeAmount, "eu") --форматируем в выводимую строку
  308.    
  309.     --print(PrintChargeAmount)
  310.    
  311.     --
  312.  
  313.    
  314.    
  315.  
  316.    
  317.     PrintChargeIncome = formatGrade(AvarageChargeIncome, "") --форматируем в выводимую строку
  318.        
  319.     if AvarageChargeIncome > 0 then --добавим плюс в начале, если идет прирост энергии
  320.         PrintChargeIncome = "+"..PrintChargeIncome
  321.     end
  322.    
  323.     PrintChargeOutcome = formatGrade(AvarageChargeOutcome, "") --форматируем в выводимую строку
  324.    
  325.  
  326.     local s = info[16] --Time to Full
  327.     local TimeToFull = tonumber(s)
  328.     s,_ = s:gsub("Time to Full: ", "")
  329.     s,_ = s:gsub("Time to Empty: ", "")
  330.     PrintChargeTime = s
  331.    
  332.    
  333.     --отрисовываем на экране вариант вывода в зависимости от выбранного режима
  334.     if draw_mode == 1 then
  335.         draw1()
  336.     else   
  337.         draw2()
  338.     end
  339.     ::done::
  340. end
  341.  
  342.  
  343. local needToChangeMode = false
  344.  
  345. function handleEvent() --вызывается событием
  346.     needToChangeMode = true
  347.    
  348. end
  349.  
  350. --for name, val in pairs(PSS.component) do --просмотрим таблицу
  351.         --print(name, val)
  352.         --os.sleep(2)
  353. --end
  354.  
  355. require("component").gpu.setResolution(Width, Height)
  356.  
  357.  
  358.  
  359. event.listen("key_down", handleEvent) -- listen for keypress
  360. while true do --вечный главный цикл программы
  361.     os.sleep(1)
  362.    
  363.     --если, пока спали, была нажата кнопка, то меняем режим
  364.     if needToChangeMode == true then
  365.        
  366.         mode = mode + 1
  367.         if mode > 2 then
  368.             mode = 0
  369.         end
  370.         needToChangeMode = false
  371.         --Log("mode:" .. mode)
  372.     end
  373.    
  374.    
  375.     update() --выводим на экран инфу
  376.    
  377. end
  378.  
  379.  
  380.  
  381.  
  382. -- Версия 1.1
  383. -- Добавлены в вывод общего заряда и скорости заряда два разрадя после запятой: 12K eu/t -> 12.56K eu/t
  384. -- Указание ширины и высоты разрешения экрана вынесены в константы и указываются в начале скрипта
  385.  
  386. -- Версия 1.2
  387. -- Добавлено сглаживание значения скорости заряда батареи. Теперь выводится средняя скорость за последнее количество секунд, указанное в константе AvarageDimSize
  388. -- Устранена проблема отказа запуска программы из-за наличия вокруг блока адаптера других блоков Грега, например электрических проводов
  389.  
  390. -- Версия 1.3
  391. -- Добавлен режим вывода информации на экран, при котором входящая и исходящая скорости заряда батареи отображаются отдельно.
  392. -- Добавлена возможность переключения между режимами вывода информации на экран непосредственно во время работы программы. Переключение между режимами происходит по нажатию любой клавиши.
  393.  
  394. -- Версия 1.4
  395. -- Усовершенствованно цветовое отображение информации времени оставшегося до заряда/разряда батареи. Теперь время выводится зеленым если батарея заряжается, и красным если разряжается.
  396. -- Начальный режим работы мониторинга установлен в "отдельно расход/приход" (задается константой mode)
  397.  
  398. -- Версия 1.5
  399. -- Учтено изменение формата информации в таблице состояния батареи для версии 2.1.1.3 (на версии 2.1.1.0 разделители триад были запятые, а в 2.1.1.3 стали пробелом)
  400.  
  401. -- Версия 1.6
  402. -- Учтено изменение формата информации в таблице состояния батареи для версии 2.1.2.0
  403.  
  404. -- Версия 1.7
  405. -- Учтено изменение формата информации в таблице состояния батареи для версии 2.1.2.3 (количество увеличения и уменьшения заряда батареи переместились на другие строчки)
  406.  
  407. -- Версия 1.8 Теперь поддерживает Lapotronic Capacitor, но не поддерживает Power Sub Station! Для PSS пользуйтесь прошлой версией!
  408.  
  409. -- Версия 1.9
  410. -- Адаптировано под GTNH 2.7.
  411. -- Добавлено 3 режима отображения усреднения значений: 5 секунд, 5 минут, 1 час. Переключается нажатием любой кнопки глядя в монитор OpenComputers.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement