PiXLFAIL

cc_uu_mon_ae_6

May 10th, 2026 (edited)
30
0
Never
4
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.65 KB | None | 0 0
  1. -- ==========================================
  2. -- UU DASHBOARD v4 - Persistent + Scrap Stats + Fast Warmup
  3. -- ==========================================
  4.  
  5. os.loadAPI("ocs/apis/sensor")
  6.  
  7. local SAVE_FILE = "/uu_save.dat"
  8. local LONG_WINDOW = 6 -- 6 x 5s = 30s pro Long-Kerze
  9.  
  10. local UUDashboard = {}
  11. UUDashboard.__index = UUDashboard
  12.  
  13. function UUDashboard:new(sensorSide, monitorSide)
  14. local obj = {
  15. sen = sensor.wrap(sensorSide),
  16. mon = peripheral.wrap(monitorSide),
  17.  
  18. w = 0, h = 0,
  19. pollInterval = 0.5,
  20. sampleWindow = 5,
  21. smoothPoints = 24,
  22.  
  23. -- UU Stats
  24. totalProduced = 0,
  25. targetTotal = 10000,
  26. currentStock = 0,
  27. currentPerMin = 0,
  28. smoothPerMin = 0,
  29. minPerMin = 0,
  30. maxPerMin = 0,
  31. historyShort = {},
  32. historyLong = {},
  33. longAccum = 0,
  34. longCount = 0,
  35.  
  36. -- Scrap Stats
  37. currentScrap = 0,
  38. scrapInPerMin = 0,
  39. smoothScrapPerMin = 0,
  40. minScrapPerMin = 0,
  41. maxScrapPerMin = 0,
  42. scrapHistShort = {},
  43. scrapHistLong = {},
  44. scrapLongAccum = 0,
  45. scrapLongCount = 0,
  46.  
  47. -- Scrap Pulse
  48. scrapOutputSide = "bottom",
  49. scrapMin = 64,
  50. pulseDuration = 5,
  51. pulseCooldown = 30,
  52. pulseTimer = 0,
  53. cooldownTimer = 999,
  54. isPulsing = false,
  55.  
  56. -- UI
  57. zoomMode = 1,
  58. lastProgress= 0,
  59. statusText = "Lade...",
  60. spinner = {"|", "/", "-", "\\"},
  61. spinIndex = 1,
  62. }
  63. setmetatable(obj, UUDashboard)
  64. return obj
  65. end
  66.  
  67. -- ============================================================
  68. -- PERSISTENZ
  69. -- ============================================================
  70.  
  71. function UUDashboard:save()
  72. local data = {
  73. totalProduced = self.totalProduced,
  74. historyShort = self.historyShort,
  75. historyLong = self.historyLong,
  76. scrapHistShort = self.scrapHistShort,
  77. scrapHistLong = self.scrapHistLong,
  78. smoothPerMin = self.smoothPerMin,
  79. smoothScrapPerMin= self.smoothScrapPerMin,
  80. minPerMin = self.minPerMin,
  81. maxPerMin = self.maxPerMin,
  82. minScrapPerMin = self.minScrapPerMin,
  83. maxScrapPerMin = self.maxScrapPerMin,
  84. }
  85. local f = fs.open(SAVE_FILE, "w")
  86. if f then
  87. f.write(textutils.serialize(data))
  88. f.close()
  89. end
  90. end
  91.  
  92. function UUDashboard:load()
  93. if not fs.exists(SAVE_FILE) then return end
  94. local f = fs.open(SAVE_FILE, "r")
  95. if not f then return end
  96. local raw = f.readAll()
  97. f.close()
  98. local ok, data = pcall(textutils.unserialize, raw)
  99. if not ok or type(data) ~= "table" then return end
  100.  
  101. self.totalProduced = data.totalProduced or 0
  102. self.historyShort = data.historyShort or {}
  103. self.historyLong = data.historyLong or {}
  104. self.scrapHistShort = data.scrapHistShort or {}
  105. self.scrapHistLong = data.scrapHistLong or {}
  106. self.smoothPerMin = data.smoothPerMin or 0
  107. self.smoothScrapPerMin = data.smoothScrapPerMin or 0
  108. self.minPerMin = data.minPerMin or 0
  109. self.maxPerMin = data.maxPerMin or 0
  110. self.minScrapPerMin = data.minScrapPerMin or 0
  111. self.maxScrapPerMin = data.maxScrapPerMin or 0
  112. end
  113.  
  114. -- ============================================================
  115. -- HILFSFUNKTIONEN
  116. -- ============================================================
  117.  
  118. function UUDashboard:fmt(n)
  119. n = math.floor(tonumber(n) or 0)
  120. local s = tostring(n)
  121. local sign = ""
  122. if string.sub(s,1,1) == "-" then sign="-"; s=string.sub(s,2) end
  123. local out = ""
  124. while string.len(s) > 3 do
  125. out = "." .. string.sub(s,-3) .. out
  126. s = string.sub(s,1,-4)
  127. end
  128. return sign .. s .. out
  129. end
  130.  
  131. function UUDashboard:avgTable(tbl, count)
  132. if #tbl == 0 then return 0 end
  133. local from = math.max(1, #tbl - count + 1)
  134. local sum, c = 0, 0
  135. for i = from, #tbl do sum = sum + tbl[i]; c = c + 1 end
  136. return c > 0 and (sum/c) or 0
  137. end
  138.  
  139. function UUDashboard:minTable(tbl, count)
  140. if #tbl == 0 then return 0 end
  141. local from = math.max(1, #tbl - count + 1)
  142. local m = tbl[from]
  143. for i = from+1, #tbl do if tbl[i] < m then m = tbl[i] end end
  144. return m
  145. end
  146.  
  147. function UUDashboard:maxTable(tbl, count)
  148. if #tbl == 0 then return 0 end
  149. local from = math.max(1, #tbl - count + 1)
  150. local m = tbl[from]
  151. for i = from+1, #tbl do if tbl[i] > m then m = tbl[i] end end
  152. return m
  153. end
  154.  
  155. function UUDashboard:getPeak(arr)
  156. local m = 1
  157. for i=1,#arr do if arr[i]>m then m=arr[i] end end
  158. return m
  159. end
  160.  
  161. function UUDashboard:pushTable(tbl, v, limit)
  162. table.insert(tbl, v)
  163. while #tbl > limit do table.remove(tbl, 1) end
  164. end
  165.  
  166. function UUDashboard:etaText()
  167. if self.totalProduced >= self.targetTotal then return "Fertig!" end
  168. if self.smoothPerMin <= 0 then return "Warte..." end
  169. local remaining = self.targetTotal - self.totalProduced
  170. local mins = math.ceil(remaining / self.smoothPerMin)
  171. local h = math.floor(mins/60); local m = mins%60
  172. if h > 0 then return h.."h "..m.."m" else return m.."m" end
  173. end
  174.  
  175. -- ============================================================
  176. -- ZEICHEN ENGINE (Zero-Flicker)
  177. -- ============================================================
  178.  
  179. function UUDashboard:tc(col)
  180. pcall(function() self.mon.setTextColor(col) end)
  181. end
  182. function UUDashboard:bc(col)
  183. pcall(function() self.mon.setBackgroundColor(col) end)
  184. end
  185.  
  186. function UUDashboard:fillRect(x1,y1,x2,y2,bg)
  187. self:bc(bg)
  188. local line = string.rep(" ", x2-x1+1)
  189. for y=y1,y2 do self.mon.setCursorPos(x1,y); self.mon.write(line) end
  190. end
  191.  
  192. function UUDashboard:writeAt(x,y,text,tc,bg)
  193. local pad = self.w - x + 1
  194. if pad < 1 then return end
  195. self.mon.setCursorPos(x,y)
  196. self:bc(bg); self:tc(tc)
  197. self.mon.write(string.sub(tostring(text),1,pad))
  198. end
  199.  
  200. -- Kachel: Label oben links, Wert unten rechts, Unterzeile fuer Stats
  201. function UUDashboard:drawTile(x, y, tw, label, value, minV, avgV, maxV, lblCol, valCol)
  202. self:fillRect(x, y, x+tw-1, y+2, colors.gray)
  203.  
  204. -- Label
  205. self:writeAt(x+1, y, label, lblCol, colors.gray)
  206.  
  207. -- Hauptwert (gross, rechts-buendig)
  208. local valStr = type(value)=="number" and self:fmt(value) or tostring(value)
  209. local vx = x + tw - string.len(valStr) - 1
  210. if vx < x+1 then vx = x+1 end
  211. self:writeAt(vx, y+1, valStr, valCol, colors.gray)
  212.  
  213. -- Min / Avg / Max (kleine Zeile)
  214. local stats = "v"..self:fmt(minV).." ~"..self:fmt(avgV).." ^"..self:fmt(maxV)
  215. -- kuerzen wenn zu lang
  216. if string.len(stats) > tw-2 then
  217. stats = "~"..self:fmt(avgV)
  218. end
  219. self:writeAt(x+1, y+2, stats, colors.lightGray, colors.gray)
  220. end
  221.  
  222. -- Einfache 2-Zeilen-Kachel ohne Stats (fuer Werte ohne Verlauf)
  223. function UUDashboard:drawTile2(x, y, tw, label, value, sub, lblCol, valCol, subCol)
  224. self:fillRect(x, y, x+tw-1, y+2, colors.gray)
  225. self:writeAt(x+1, y, label, lblCol, colors.gray)
  226. local valStr = type(value)=="number" and self:fmt(value) or tostring(value)
  227. local vx = x + tw - string.len(valStr) - 1
  228. if vx < x+1 then vx = x+1 end
  229. self:writeAt(vx, y+1, valStr, valCol, colors.gray)
  230. local sub2 = tostring(sub)
  231. self:writeAt(x+1, y+2, sub2, subCol or colors.lightGray, colors.gray)
  232. end
  233.  
  234. function UUDashboard:drawHeader()
  235. local text = " UU-MATTER & SCRAP HUB "
  236. local lp = math.max(0, math.floor((self.w - string.len(text))/2))
  237. local rp = math.max(0, self.w - lp - string.len(text))
  238. self.mon.setCursorPos(1,1)
  239. self:bc(colors.cyan); self:tc(colors.white)
  240. self.mon.write(string.rep(" ",lp)..text..string.rep(" ",rp))
  241. end
  242.  
  243. function UUDashboard:drawProgress(y, ratio)
  244. local width = self.w - 2
  245. if width < 1 then return end
  246. local fill = math.floor(width * ratio + 0.5)
  247. local empty = width - fill
  248. self.mon.setCursorPos(2, y)
  249. if fill > 0 then self:bc(colors.lime); self.mon.write(string.rep(" ",fill)) end
  250. if empty> 0 then self:bc(colors.lightGray); self.mon.write(string.rep(" ",empty)) end
  251. self:bc(colors.black)
  252. end
  253.  
  254. function UUDashboard:drawGraph(x1,y1,x2,y2, arr, smoothVal)
  255. local gw = x2-x1+1; local gh = y2-y1+1
  256. if gw < 10 or gh < 4 then return end
  257.  
  258. local plotX1=x1+2; local plotY1=y1+1
  259. local plotX2=x2-1; local plotY2=y2-1
  260.  
  261. local peak = self:getPeak(arr)
  262. if peak < 1 then peak = 1 end
  263. local avg = smoothVal or 0
  264. local plotH = plotY2 - plotY1
  265. if plotH < 1 then plotH = 1 end
  266. local avgY = plotY2 - math.floor((avg/peak)*plotH + 0.5)
  267. local capacity = plotX2 - plotX1 + 1
  268. local startIndex = math.max(1, #arr - capacity + 1)
  269.  
  270. for y = plotY1, plotY2 do
  271. self.mon.setCursorPos(plotX1, y)
  272. for i = 1, capacity do
  273. local val = arr[startIndex+i-1]
  274. local col = colors.black
  275. if val then
  276. local barH = math.floor((val/peak)*plotH + 0.5)
  277. local barTopY = plotY2 - barH
  278. if y >= barTopY then
  279. col = colors.blue
  280. if (startIndex+i-1) == #arr then col = colors.orange
  281. elseif val >= avg then col = colors.lightBlue end
  282. elseif y == avgY then col = colors.gray end
  283. elseif y == avgY then col = colors.gray end
  284. self:bc(col); self.mon.write(" ")
  285. end
  286. end
  287. self:bc(colors.black)
  288.  
  289. self:writeAt(plotX1, plotY1, "max "..self:fmt(peak), colors.white, colors.black)
  290. self:writeAt(plotX1, plotY2, "0", colors.white, colors.black)
  291. local at = "avg "..self:fmt(math.floor(avg+0.5))
  292. self:writeAt(plotX2 - string.len(at)+1, plotY1, at, colors.lightGray, colors.black)
  293. end
  294.  
  295. -- ============================================================
  296. -- SENSOR
  297. -- ============================================================
  298.  
  299. function UUDashboard:getInventories()
  300. if not self.sen then return 0,0 end
  301. local targets = self.sen.getTargets()
  302. if not targets then return 0,0 end
  303. local tid = nil
  304. for id, info in pairs(targets) do
  305. if info.Name == "ME Wireless Access Point" then tid=id; break end
  306. end
  307. if not tid then self.statusText="Fehler: Kein AP"; return 0,0 end
  308.  
  309. local det = self.sen.getTargetDetails(tid)
  310. local uu,sc = 0,0
  311. local uf,sf = false,false
  312. if det and det.Items then
  313. self.statusText = "Online"
  314. for _,item in pairs(det.Items) do
  315. local n = string.lower(tostring(item.Name))
  316. if string.find(n,"uu") then uu=item.Size; uf=true end
  317. if string.find(n,"scrap") then sc=item.Size; sf=true end
  318. if uf and sf then break end
  319. end
  320. end
  321. return uu, sc
  322. end
  323.  
  324. -- ============================================================
  325. -- PULSE LOGIK
  326. -- ============================================================
  327.  
  328. function UUDashboard:updatePulseLogic()
  329. if self.isPulsing then
  330. self.pulseTimer = self.pulseTimer + self.pollInterval
  331. if self.pulseTimer >= self.pulseDuration then
  332. self.isPulsing = false
  333. self.cooldownTimer = 0
  334. redstone.setOutput(self.scrapOutputSide, false)
  335. end
  336. else
  337. self.cooldownTimer = self.cooldownTimer + self.pollInterval
  338. if self.cooldownTimer >= self.pulseCooldown and self.currentScrap >= self.scrapMin then
  339. self.isPulsing = true
  340. self.pulseTimer = 0
  341. redstone.setOutput(self.scrapOutputSide, true)
  342. end
  343. end
  344. end
  345.  
  346. -- ============================================================
  347. -- EVENT LOOP (Touch Support)
  348. -- ============================================================
  349.  
  350. function UUDashboard:sleepWithTouch(duration)
  351. local tid = os.startTimer(duration)
  352. while true do
  353. local ev,p1 = os.pullEvent()
  354. if ev=="timer" and p1==tid then break
  355. elseif ev=="monitor_touch" then
  356. self.zoomMode = (self.zoomMode==1) and 2 or 1
  357. self:render(self.lastProgress, true)
  358. end
  359. end
  360. end
  361.  
  362. -- ============================================================
  363. -- RENDER
  364. -- ============================================================
  365.  
  366. function UUDashboard:render(progressRatio, drawFullGraph)
  367. self.lastProgress = progressRatio
  368. self:drawHeader()
  369.  
  370. -- Kachel-Layout
  371. local tw = math.floor((self.w - 3) / 2)
  372. local t1X = 2
  373. local t2X = t1X + tw + 1
  374.  
  375. -- Zeile A: Lager UU | Lager Scrap (y=2..4)
  376. self:drawTile2(t1X, 2, tw,
  377. "Lager UU", self.currentStock,
  378. "Prod: "..self:fmt(self.totalProduced),
  379. colors.lightGray, colors.white, colors.cyan)
  380.  
  381. -- Scrap Pulse Status
  382. local pulseStr
  383. if self.isPulsing then
  384. pulseStr = "PUMPEN "..math.ceil(self.pulseDuration - self.pulseTimer).."s"
  385. elseif self.cooldownTimer < self.pulseCooldown then
  386. pulseStr = "WARTE "..math.ceil(self.pulseCooldown - self.cooldownTimer).."s"
  387. elseif self.currentScrap < self.scrapMin then
  388. pulseStr = "Scrap fehlt"
  389. else
  390. pulseStr = "BEREIT"
  391. end
  392. self:drawTile2(t2X, 2, tw,
  393. "Lager Scrap", self.currentScrap,
  394. pulseStr,
  395. colors.lightGray, colors.yellow,
  396. self.isPulsing and colors.lime or colors.orange)
  397.  
  398. self:fillRect(1,5,self.w,5, colors.black)
  399.  
  400. -- Zeile B: UU/Min Stats | Scrap In/Min Stats (y=6..8)
  401. self:drawTile(t1X, 6, tw,
  402. "UU/Min",
  403. math.floor(self.currentPerMin+0.5),
  404. self.minPerMin, math.floor(self.smoothPerMin+0.5), self.maxPerMin,
  405. colors.green, colors.lime)
  406.  
  407. self:drawTile(t2X, 6, tw,
  408. "Scrap In/Min",
  409. math.floor(self.scrapInPerMin+0.5),
  410. self.minScrapPerMin, math.floor(self.smoothScrapPerMin+0.5), self.maxScrapPerMin,
  411. colors.orange, colors.yellow)
  412.  
  413. self:fillRect(1,9,self.w,9, colors.black)
  414.  
  415. -- Zeile C: ETA | Zoom-Info (y=10..12)
  416. local zoomLabel = (self.zoomMode==1) and "5s Kerzen [Touch=Zoom]" or "30s Kerzen [Touch=Zoom]"
  417. self:drawTile2(t1X, 10, tw,
  418. "ETA 10k UU", self:etaText(),
  419. "Avg UU: "..self:fmt(math.floor(self.smoothPerMin+0.5)).."/min",
  420. colors.lightBlue, colors.white, colors.lightGray)
  421.  
  422. local spin = self.spinner[self.spinIndex]
  423. self:drawTile2(t2X, 10, tw,
  424. "Graph Zoom", zoomLabel,
  425. "Status: "..self.statusText.." "..spin,
  426. colors.cyan, colors.white, colors.gray)
  427.  
  428. -- Progress Bar (y=13)
  429. self:fillRect(1,13,self.w,13, colors.black)
  430. self:drawProgress(13, progressRatio or 0)
  431.  
  432. -- Graph (y=14 ... h-1)
  433. local graphTop = 14
  434. if self.h >= graphTop + 3 and drawFullGraph then
  435. local arr = (self.zoomMode==1) and self.historyShort or self.historyLong
  436. local smoothV = self.smoothPerMin
  437. self:drawGraph(1, graphTop, self.w, self.h-1, arr, smoothV)
  438. end
  439.  
  440. -- Status Zeile (y=h)
  441. self:fillRect(1,self.h,self.w,self.h, colors.black)
  442. self:writeAt(2, self.h, "Status: "..self.statusText.." | "..pulseStr, colors.gray, colors.black)
  443. end
  444.  
  445. -- ============================================================
  446. -- WARMUP: Graph sofort mit aktuellen Werten vorbelegen
  447. -- ============================================================
  448.  
  449. function UUDashboard:warmup(graphCap)
  450. local warmVal = self.smoothPerMin > 0 and self.smoothPerMin or 0
  451. local warmScrap = self.smoothScrapPerMin > 0 and self.smoothScrapPerMin or 0
  452. -- Nur vorbelegen wenn der Verlauf leer ist (Erster Start, keine Save-Datei)
  453. if #self.historyShort == 0 then
  454. for i=1, math.min(graphCap, self.smoothPoints) do
  455. table.insert(self.historyShort, warmVal)
  456. end
  457. end
  458. if #self.historyLong == 0 then
  459. for i=1, math.min(graphCap, self.smoothPoints) do
  460. table.insert(self.historyLong, warmVal)
  461. end
  462. end
  463. if #self.scrapHistShort == 0 then
  464. for i=1, math.min(graphCap, self.smoothPoints) do
  465. table.insert(self.scrapHistShort, warmScrap)
  466. end
  467. end
  468. if #self.scrapHistLong == 0 then
  469. for i=1, math.min(graphCap, self.smoothPoints) do
  470. table.insert(self.scrapHistLong, warmScrap)
  471. end
  472. end
  473. end
  474.  
  475. -- ============================================================
  476. -- MAIN LOOP
  477. -- ============================================================
  478.  
  479. function UUDashboard:run()
  480. if not self.sen or not self.mon then
  481. print("Fehler: Sensor oder Monitor nicht gefunden!")
  482. return
  483. end
  484.  
  485. pcall(function() self.mon.setTextScale(0.5) end)
  486. self.w, self.h = self.mon.getSize()
  487. self.mon.clear()
  488.  
  489. -- Gespeicherten Stand laden
  490. self:load()
  491.  
  492. redstone.setOutput(self.scrapOutputSide, false)
  493.  
  494. self.currentStock, self.currentScrap = self:getInventories()
  495. local lastUU = self.currentStock
  496. local lastScrap = self.currentScrap
  497.  
  498. local graphCap = self.w - 4
  499. if graphCap < 8 then graphCap = 8 end
  500.  
  501. -- Graph sofort vorbelegen (Warmup)
  502. self:warmup(graphCap)
  503.  
  504. -- Min/Max initialisieren wenn noch leer
  505. if self.minPerMin == 0 and self.smoothPerMin > 0 then
  506. self.minPerMin = self.smoothPerMin
  507. self.maxPerMin = self.smoothPerMin
  508. end
  509. if self.minScrapPerMin == 0 and self.smoothScrapPerMin > 0 then
  510. self.minScrapPerMin = self.smoothScrapPerMin
  511. self.maxScrapPerMin = self.smoothScrapPerMin
  512. end
  513.  
  514. local pollsPerWindow = math.floor(self.sampleWindow / self.pollInterval)
  515. local saveCounter = 0
  516.  
  517. self:render(0, true)
  518.  
  519. while true do
  520. local uuProduced = 0
  521. local scrapProduced = 0
  522.  
  523. for i = 1, pollsPerWindow do
  524. self:sleepWithTouch(self.pollInterval)
  525.  
  526. local curUU, curScrap = self:getInventories()
  527.  
  528. if curUU > lastUU then
  529. local d = curUU - lastUU
  530. uuProduced = uuProduced + d
  531. self.totalProduced = self.totalProduced + d
  532. end
  533. if curScrap > lastScrap then
  534. scrapProduced = scrapProduced + (curScrap - lastScrap)
  535. end
  536.  
  537. lastUU = curUU
  538. lastScrap = curScrap
  539. self.currentStock = curUU
  540. self.currentScrap = curScrap
  541.  
  542. self:updatePulseLogic()
  543.  
  544. self.spinIndex = self.spinIndex + 1
  545. if self.spinIndex > #self.spinner then self.spinIndex = 1 end
  546.  
  547. self:render(i / pollsPerWindow, false)
  548. end
  549.  
  550. -- === 5s Kerze abschliessen ===
  551.  
  552. -- UU
  553. self.currentPerMin = uuProduced * (60 / self.sampleWindow)
  554. self:pushTable(self.historyShort, self.currentPerMin, graphCap)
  555. self.smoothPerMin = self:avgTable(self.historyShort, self.smoothPoints)
  556. self.minPerMin = self:minTable(self.historyShort, self.smoothPoints)
  557. self.maxPerMin = self:maxTable(self.historyShort, self.smoothPoints)
  558.  
  559. -- UU Long (30s = 6 x 5s)
  560. self.longAccum = self.longAccum + self.currentPerMin
  561. self.longCount = self.longCount + 1
  562. if self.longCount >= LONG_WINDOW then
  563. self:pushTable(self.historyLong, self.longAccum / LONG_WINDOW, graphCap)
  564. self.longAccum = 0
  565. self.longCount = 0
  566. end
  567.  
  568. -- Scrap
  569. self.scrapInPerMin = scrapProduced * (60 / self.sampleWindow)
  570. self:pushTable(self.scrapHistShort, self.scrapInPerMin, graphCap)
  571. self.smoothScrapPerMin = self:avgTable(self.scrapHistShort, self.smoothPoints)
  572. self.minScrapPerMin = self:minTable(self.scrapHistShort, self.smoothPoints)
  573. self.maxScrapPerMin = self:maxTable(self.scrapHistShort, self.smoothPoints)
  574.  
  575. -- Scrap Long
  576. self.scrapLongAccum = self.scrapLongAccum + self.scrapInPerMin
  577. self.scrapLongCount = self.scrapLongCount + 1
  578. if self.scrapLongCount >= LONG_WINDOW then
  579. self:pushTable(self.scrapHistLong, self.scrapLongAccum / LONG_WINDOW, graphCap)
  580. self.scrapLongAccum = 0
  581. self.scrapLongCount = 0
  582. end
  583.  
  584. -- Alle 6 Kerzen (= 30s) speichern
  585. saveCounter = saveCounter + 1
  586. if saveCounter >= LONG_WINDOW then
  587. self:save()
  588. saveCounter = 0
  589. end
  590.  
  591. self:render(1, true)
  592. end
  593. end
  594.  
  595. -- ============================================================
  596. -- START
  597. -- ============================================================
  598. local app = UUDashboard:new("left", "bottom")
  599. app:run()
  600.  
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment