Advertisement
Guest User

storageMonitor.lua

a guest
Feb 8th, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.21 KB | None | 0 0
  1. vos.loadApi('core.api')
  2. vos.loadApi('ui.api')
  3.  
  4. local ME = vos.loadApi('me.api')
  5. ME.setDevice(peripheral.wrap('back'))
  6. local turtleInventory = peripheral.wrap('left')
  7.  
  8. local ME_direction = 'north'
  9.  
  10. local autocraft = true
  11.  
  12. local jobListGrid
  13.  
  14. if device.wireless_modem then
  15.   vos.loadApi('relay.api')
  16.   Relay.find()
  17. end
  18.  
  19. multishell.setTitle(TAB_ID, 'Storage Manager')
  20.  
  21. Logger.disable()
  22.  
  23. function getItem(items, id, dmg)
  24.   for _,item in pairs(items) do
  25.     if item.id == id and item.dmg == dmg then
  26.       return item
  27.     end
  28.   end
  29. end
  30.  
  31. function mergeResources(t)
  32.   local resources = Util.readTable('resource.limits')
  33.   resources = resources or { }
  34.  
  35.   for _,v in pairs(resources) do
  36.     local item = getItem(t, v.id, v.dmg)
  37.     if item then
  38.       item.limit = tonumber(v.limit)
  39.       item.low = tonumber(v.low)
  40.     end
  41.   end
  42. end
  43.  
  44. function filterItems(t, filter)
  45.   local r = {}
  46.   if filter then
  47.     filter = filter:lower()
  48.     for k,v in pairs(t) do
  49.       if  string.find(v.lname, filter) then
  50.         table.insert(r, v)
  51.       end
  52.     end
  53.   else
  54.         return t
  55.   end
  56.   return r
  57. end
  58.  
  59. function updatePanel()
  60.  
  61.   pcall(function()
  62.     local pStorage = 100 -
  63.       math.floor(ME.getFreeBytes() * 100 /
  64.                  ME.getTotalBytes())
  65.     local pItemsFree = ME.getRemainingItemTypes()
  66.  
  67.     Relay.send("status",
  68.       string.format("Storage: %d%% (%d free slots)",
  69.         pStorage, pItemsFree))
  70.     local percent = math.min(64, pItemsFree)
  71.     percent = math.floor(percent / 64 * 100)
  72.     local color = colors.green
  73.     if percent < 50 then
  74.       color = colors.orange
  75.     elseif percent < 25 then
  76.       color = colors.red
  77.     end
  78.     Relay.send('panelUpdate', {
  79.       uid = 'storage',
  80.       type = 'meter',
  81.       text = 'Storage',
  82.       value = percent,
  83.       color = color,
  84.     })
  85.   end)
  86. end
  87.  
  88. function craftItems(itemList)
  89.   for _,item in pairs(itemList) do
  90.     if not craft(item.id, item.dmg, item.qty) then
  91.       ME.craft(item.id, item.dmg, item.qty)
  92.     end
  93.   end
  94. end
  95.  
  96. function isCrafting(jobList, id, dmg)
  97.   for _, job in pairs(jobList) do
  98.     if job.id == id and job.dmg == dmg then
  99.       return job
  100.     end
  101.   end
  102. end
  103.  
  104. local function jobMonitor(jobList)
  105.  
  106.   local mon = UI.Device({
  107.     deviceType = 'monitor',
  108.     textScale = .5,
  109.   })
  110.  
  111.   jobListGrid = UI.Grid({
  112.     parent = mon,
  113.     sortColumn = 'name',
  114.     columns = {
  115.       { 'Amount', 'qty', 6 },
  116.       { 'Crafting', 'name', mon.width - 10 },
  117.     },
  118.   })
  119. end
  120.  
  121. function craft(id, dmg, qty)
  122.   local recipes = Util.readTable('recipes') or { }
  123.   local key = id .. ':' .. dmg
  124.   local recipe = recipes[key]
  125.   if not recipe then
  126.     return
  127.   end
  128.  
  129.   local function selectOpenSlot()
  130.     for i = 1, 16 do
  131.       if turtle.getItemCount(i) == 0 then
  132.         return i
  133.       end
  134.     end
  135.   end
  136.  
  137.   local function clearGrid()
  138.     for i = 1, 16 do
  139.       local count = turtle.getItemCount(i)
  140.       if count > 0 then
  141.         ME.insert(i, count, ME_direction)
  142.         if turtle.getItemCount(i) ~= 0 then
  143.           return true
  144.         end
  145.       end
  146.     end
  147.   end
  148.  
  149.   clearGrid()
  150.  
  151.   for i = 1, math.ceil(qty / recipe.qty) do
  152.     local failed = false
  153.     for k,v in pairs(recipe.ingredients) do
  154.       if not ME.extract(v.id, v.dmg, v.qty, ME_direction, k) then
  155.         failed = true
  156.         break
  157.       end
  158.     end
  159.     if failed then
  160.       break
  161.     end
  162.     turtle.craft()
  163.     for i = 1, 16 do
  164.       local count = turtle.getItemCount(i)
  165.       if count > 0 then
  166.         ME.insert(i, count, ME_direction)
  167.       end
  168.     end
  169.   end
  170.   return true
  171. end
  172.  
  173. function watchResources()
  174.  
  175.   local items = ME.getAvailableItems()
  176.   local jobList = ME.getJobList()
  177.   local messages = { }
  178.   local itemList = { }
  179.  
  180.   if Util.size(items) == 0 then
  181.     return
  182.   end
  183.  
  184.   local t = Util.readTable('resource.limits') or { }
  185.   for k, res in pairs(t) do
  186.     local item = getItem(items, res.id, res.dmg)
  187.     res.limit = tonumber(res.limit)
  188.     res.low = tonumber(res.low)
  189.     if not item then
  190.       item = {
  191.         id = res.id,
  192.         dmg = res.dmg,
  193.         name = res.name,
  194.         qty = 0
  195.       }
  196.     end
  197.     if res.limit and item.qty > res.limit then
  198.       Logger.debug("Purging " .. item.qty-res.limit .. " " .. res.name)
  199.       if not ME.extract(item.id, item.dmg, item.qty - res.limit, 'west') then
  200.         table.insert(messages, 'Failed to purge ' .. res.name)
  201.       end
  202.     elseif res.low and item.qty < res.low then
  203.       table.insert(itemList, {
  204.         id = item.id,
  205.         dmg = item.dmg,
  206.         qty = res.low - item.qty,
  207.         name = item.name
  208.         })
  209.     end
  210.   end
  211.   if #messages and Relay then
  212.     Relay.send('panelUpdate', {
  213.       type = 'message',
  214.       message = messages,
  215.       uid = 'Crafting'
  216.     })
  217.   end
  218.   return itemList
  219. end
  220.  
  221. itemPage = UI.Page({
  222.   x = 4,
  223.   y = math.floor((UI.term.height - 9) / 2) + 1,
  224.   height = 9,
  225.   width = UI.term.width - 6,
  226.   backgroundColor = colors.lightGray,
  227.   titleBar = UI.TitleBar({
  228.     title = 'Limit Resource',
  229.     previousPage = true,
  230.   }),
  231.   form = UI.Form({
  232.     fields = {
  233.       { label = 'ID', key = 'iddmg', width = 12, display = UI.Form.D.static },
  234. --      { label = 'Name', key = 'name', width = 25, display = UI.Form.D.static },
  235. --      { label = 'Quantity', key = 'qty', display = UI.Form.D.static },
  236.       { label = 'Low', key = 'low', width = 8, display = UI.Form.D.entry },
  237.       { label = 'Limit', key = 'limit', width = 8, display = UI.Form.D.entry,
  238.         validation = UI.Form.V.number, dataType = UI.Form.T.number },
  239.       { text = 'Accept', event = 'accept', display = UI.Form.D.button,
  240.           x = 5, y = 5, width = 10 },
  241.       { text = 'Cancel', event = 'cancel', display = UI.Form.D.button,
  242.           x = 19, y = 5, width = 10 },
  243.     },
  244.     labelWidth = 12,
  245.     x = 5,
  246.     y = 3,
  247.     height = 6
  248.   }),
  249.   statusBar = UI.StatusBar({
  250.     columns = {
  251.       { '', 'msg', 25 },
  252.       { '', 'slots', 12 },
  253.       { '', 'space', 12 }
  254.     },
  255.     status = statusBarValues
  256.   })
  257. })
  258.  
  259. function itemPage:enable()
  260.   self:focusFirst()
  261. end
  262.  
  263. function itemPage:eventHandler(event)
  264.   if event.type == 'cancel' then
  265.     UI.pager:setPreviousPage()
  266.   elseif event.type == 'accept' then
  267.     --resourceDB.update(self.item)
  268.     --resourceDB.flush()
  269.     local values = self.form.values
  270.     local t = Util.readTable('resource.limits') or { }
  271.     for k,v in pairs(t) do
  272.       if v.id == values.id and v.dmg == values.dmg then
  273.         table.remove(t, k)
  274.         break
  275.       end
  276.     end
  277.     table.insert(t, values)
  278.     Util.writeTable('resource.limits', t)
  279.     UI.pager:setPreviousPage()
  280.   else
  281.     return UI.Page.eventHandler(self, event)
  282.   end
  283.   return true
  284. end
  285.  
  286. listingPage = UI.Page({
  287.   grid = UI.Grid({
  288.     columns = {
  289.       --{ 'ID', 'iddmg', 8 },
  290.       { 'Name', 'name', 24 },
  291.       { 'Qty', 'qty', 5 },
  292.       { 'Low', 'low', 5 },
  293.       { 'High', 'limit', 6 },
  294.     },
  295.     sortColumn = 'name',
  296.     width = UI.term.width,
  297.     autoSpace = true,
  298.     pageSize = UI.term.height-2
  299.   }),
  300.   statusBar = UI.StatusBar({
  301.     backgroundColor = colors.gray,
  302.     width = UI.term.width,
  303.     --y = UI.term.height,
  304.     filterText = UI.Text({
  305.       value = 'Filter',
  306.       x = 2,
  307.       width = 6,
  308.     }),
  309.     filter = UI.TextEntry({
  310.       width = 10,
  311.       limit = 50,
  312.       x = 9,
  313.     }),
  314.     learn = UI.Button({
  315.       text = 'Learn',
  316.       event = 'learn',
  317.       x = 22,
  318.       width = 7
  319.     }),
  320.     refresh = UI.Button({
  321.       text = 'Refresh',
  322.       event = 'refresh',
  323.       x = 30,
  324.       width = 8
  325.     }),
  326.   }),
  327.   accelerators = {
  328.     r = 'refresh',
  329.     q = 'quit',
  330.   }
  331. })
  332.  
  333. function listingPage.statusBar:draw()
  334.   return UI.Window.draw(self)
  335. end
  336.  
  337. function listingPage.statusBar.filter:eventHandler(event)
  338.   if event.type == 'mouse_rightclick' then
  339.     self.value = ''
  340.     self:draw()
  341.     local page = UI.pager:getCurrentPage()
  342.     page.filter = nil
  343.     page:applyFilter()
  344.     page.grid:draw()
  345.     page:setFocus(self)
  346.   end
  347.   return UI.TextEntry.eventHandler(self, event)
  348. end
  349.  
  350. function listingPage:eventHandler(event)
  351.   if event.type == 'quit' then
  352.     Event.exitPullEvents()
  353.   elseif event.type == 'grid_select' then
  354.     itemPage.form:setValues(self.grid:getSelected())
  355.     itemPage.titleBar.title = self.grid:getSelected().name
  356.     UI.pager:setPage('item')
  357.   elseif event.type == 'refresh' then
  358.     self:refresh()
  359.     self.grid:draw()
  360.   elseif event.type == 'learn' then
  361.     local t = Util.readTable('recipes') or { }
  362.     local recipe = { }
  363.     local ingredients = turtleInventory.getAllStacks(false)
  364.     if  ingredients then
  365.       if turtle.craft() then
  366.         recipe = turtleInventory.getAllStacks(false)
  367.         if recipe and recipe[1] then
  368.           recipe = recipe[1]
  369.           local key = recipe.id .. ':' .. recipe.dmg
  370.           recipe.ingredients = ingredients
  371.           t[key] = recipe
  372.           Util.writeTable('recipes', t)
  373.           self.statusBar:timedStatus('learned ' .. recipe.name, 3)
  374.         end
  375.       else
  376.         self.statusBar:timedStatus('Failed to craft', 3)
  377.       end
  378.     else
  379.       self.statusBar:timedStatus('No recipe defined', 3)
  380.     end
  381.   elseif event.type == 'text_change' then
  382.     self.filter = event.text
  383.     if #self.filter == 0 then
  384.       self.filter = nil
  385.     end
  386.     self:applyFilter()
  387.     self.grid:draw()
  388.     self.statusBar.filter:focus()
  389.   else
  390.     UI.Page.eventHandler(self, event)
  391.   end
  392. end
  393.  
  394. function listingPage:enable()
  395.   self:refresh()
  396. end
  397.  
  398. function listingPage:refresh()
  399.   self.allItems = ME.getAvailableItems('all')
  400.   Util.each(self.allItems, function(item)
  401.     item.lname = item.name:lower()
  402.   end)
  403.   mergeResources(self.allItems)
  404.   self:applyFilter()
  405. end
  406.  
  407. function listingPage:applyFilter()
  408.   local t = filterItems(self.allItems, self.filter)
  409.   for _,v in pairs(t) do
  410.     v.iddmg = v.id .. ':' .. v.dmg
  411.   end
  412.   self.grid:setTable(t)
  413. end
  414.  
  415. UI.pager:setPages({
  416.   listing = listingPage,
  417.   item = itemPage
  418. })
  419.  
  420. UI.pager:setPage(listingPage)
  421. listingPage:setFocus(listingPage.statusBar.filter)
  422.  
  423.  
  424. jobMonitor()
  425.  
  426. Event.heartbeat(5,
  427.   function()
  428.     local itemList = watchResources()
  429.     jobListGrid.t = itemList -- ME.getJobList()
  430.     jobListGrid:draw()
  431.     craftItems(itemList)
  432.   end
  433. )
  434.  
  435. Event.pullEvents()
  436.  
  437. UI.term:reset()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement