Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Fingercomp

Members
  • Content Count

    120
  • Joined

  • Last visited

  • Days Won

    35

Posts posted by Fingercomp

  1. This program was posted on the Russian forums. It's an automatic market. That means prices are calculated by the program itself. Calculations are based on amount of items sold and bought.

    If you think this is exactly what you were looking for, I'm calling @Log, the author of the program, here.

    I'm also sure that there were a few markets that allow the owner to set prices, also posted on the Russian forums. I can try to contact their authors if you want.

  2. Suppose you are creating some monitoring program: tank monitor, energy monitor or whatever. It should print how much energy (or fluid) is stored, draw a progress bar and a few histograms with different update intervals (1 second, 30 seconds, 1 minute and 10 minutes).

    I don't think printing will cause any programs, so I'll skip it. But what about progress bars and histograms? Well, it isn't not rocket science, of course. But not a really easy thing either. Anyway, a few months ago I've written a small library that makes it easy to draw histograms and progress bars, called "charts".

    Install the library from OpenPrograms using oppm (oppm install charts), or from the Hel Repository using hpm (hpm install charts).

    I can't insert images directly because the editor is broken. So here's the link to the album. As you can see, progress bars and histograms have the precision up to 1/8 of character.

    API

    The library exports Container, Histogram, ProgressBar and sides.

    Container
    Contains child objects (histograms or progress bars) and provides some common options like width, height, top-left corner coordinates and so on.

    • Container(), Container{...} — create a container object. When called as Container{...}, you can set object parameters on the fly: Container{x = 2, y = 3, payload=Histogram()}.

    Properties

    • container.gpu — the proxy of the gpu to use when drawing. Uses the primary gpu by default.
    • container.fg — default foreground color. Default: 0xFFFFFF.
    • container.bg — default background color. Default: 0x000000.
    • container.x, container.y — coordinates of the top-left corner of container. Default: 1, 1.
    • container.payloadX, container.payloadY — coordinates of payload, relative to the top-left corner of container. Default: 1, 1.
    • container.width, container.height — width and height of container. Default: 80, 25.
    • container.payload — histogram or progress bar object.

    Methods

    • container:draw() — draw the chart.

    Histogram

    • Histogram(), Histogram{...} — constuct a histogram object. The second way of initialization works the same as Container{...}.

    Properties

    • histogram.values — table that contains numeric values. Default: {}.
    • histogram.align defines the alignment of the chart (one of sides.LEFT or sides.RIGHT, see sides below). Default: sides.LEFT.
    • histogram.colorFunc — the function that returns a foreground color and a background color for each bin of histogram. Arguments passed to the function are: an index of bin (in histogram.values), a normalized value (from 0 to 1), a value itself, a histogram object, a container object. Default: function() end.
    • histogram.min — the minimum value of chart. Default: 0.
    • histogram.max — the maximum value of chart. Default: 1.
    • histogram.level.y — the height of histogram level. If level is in range (0; 1), it's treated as the relative height (e.g., 0 is the bottom, 0.5 is the middle). If it's less than 0, it's treated as the absolute offset from the top (with -1 meaning the top, -2 — one character under the top, and so on). Otherwise it's treated as the absolute offset from the bottom (for example, 1 is one character above the bottom). Default: 0.
    • histogram.level.value — the value that corresponds the chart. Values less than this will be drawn below the level, values greater than this will be drawn above the level. If set to nil, it defaults to histogram.min. Default: nil.

    Progress bar

    • ProgressBar(), ProgressBar{...} — construct a progress bar object.

    Properties

    • progressBar.direction — the direction of progress bar (sides.TOP, sides.BOTTOM, sides.LEFT, sides.RIGHT). Default: sides.RIGHT.
    • progressBar.min — the minimum value of progress bar. Default: 0.
    • progressBar.max — the maximum value of progress bar. Default: 1.
    • progressBar.value — the current value of progress bar. Default: 0.
    • progressBar.colorFunc — the function that returns a foreground color and a background color of progress bar. Arguments passed to the function are: a value, a normalized value (from 0 to 1), a progress bar object, a container object.

    Examples

    local charts = require("charts")
    
    local container = charts.Container()
    local payload = charts.Histogram {
      max = 80,
      align = charts.sides.RIGHT,
      colorFunc = function(index, norm, value, self, container)
        return 0x20ff20
      end
    }
    container.payload = payload
    
    for i = 1, 400, 1 do
      table.insert(payload.values, math.random(0, 80))
      container:draw()
    
      os.sleep(.05)
    end
    local charts = require("charts")
    local term = require("term")
    local event = require("event")
    
    local cleft = charts.Container {
      x = 1,
      y = 1,
      width = 50,
      height = 2,
      payload = charts.ProgressBar {
        direction = charts.sides.LEFT,
        value = 0,
        colorFunc = function(_, perc)
          if perc >= .9 then
            return 0x20afff
          elseif perc >= .75 then
            return 0x20ff20
          elseif perc >= .5 then
            return 0xafff20
          elseif perc >= .25 then
            return 0xffff20
          elseif perc >= .1 then
            return 0xffaf20
          else
            return 0xff2020
          end
        end
      }
    }
    
    local cright = charts.Container {
      x = 1,
      y = 4,
      width = 50,
      height = 2,
      payload = charts.ProgressBar {
        direction = charts.sides.RIGHT,
        value = 0,
        colorFunc = cleft.payload.colorFunc
      }
    }
    
    local ctop = charts.Container {
      x = 55,
      y = 1,
      width = 2,
      height = 20,
      payload = charts.ProgressBar {
        direction = charts.sides.TOP,
        value = 0,
        colorFunc = cleft.payload.colorFunc
      }
    }
    
    local cbottom = charts.Container {
      x = 59,
      y = 1,
      width = 2,
      height = 20,
      payload = charts.ProgressBar {
        direction = charts.sides.BOTTOM,
        value = 0,
        colorFunc = cleft.payload.colorFunc
      }
    }
    
    for i = 0, 100, 1 do
      term.clear()
      cleft.gpu.set(5, 10, "Value: " .. ("%.2f"):format(i / 100) .. " [" .. ("%3d"):format(i) .. "%]")
      cleft.gpu.set(5, 11, "Max:   " .. cleft.payload.min)
      cleft.gpu.set(5, 12, "Min:   " .. cleft.payload.max)
    
      cleft.payload.value, cright.payload.value, ctop.payload.value, cbottom.payload.value = i / 100, i / 100, i / 100, i / 100
    
      cleft:draw()
      ctop:draw()
      cright:draw()
      cbottom:draw()
    
      if event.pull(0.05, "interrupted") then
        term.clear()
        os.exit()
      end
    end
    
    event.pull("interrupted")
    term.clear()

    My EU monitor is available here.

    See the Hel Repository's package page for the up-to-date documentation and changelog.

  3. Yes, that's right. internet.open creates a TCP socket. They are useful when you need to communicate with a non-HTTP server (you probably know things like SSH, FTP -- those are all non-HTTP protocols).

    But when you want to send a request to an HTTP server, you need to use internet.request. It's a nice wrapper for component.internet.request that allows to interate over the response body. Like this:

    local inet = require("internet")
    
    local response = inet.request("https://google.com")
    local body = ""
    for chunk in response do
      body = body .. chunk
    end
    
    print(body)

    Chunk is a small piece of response, one, maybe a few (I can't remember) kilobytes in size, or even empty. If a connection problem occurs, an error is thrown.

    No one forbids you to use sockets to connect to an HTTP server. I do that in my simple http library. But that is slow and requires a TLS library with many dependencies when you want to use HTTPS. It can be useful (you can set the request method and control exactly what happens during the connection), although I recommend to use internet.request.

    And, finally, internet.request supports HTTP and HTTPS.

  4. What did you run? Was it require("internet").request("https://google.com:443"), or require("internet").connect("https://google.com:443"), or require("component").internet.request("https://google.com:443"), or require("component").internet.connect("https://google.com:443"), or what?

  5. Place an adapter next to the ender chest and use cables to connect the adapter to the computer. The "ender_storage" component should become available. Type lua to start Lua interpreter and run component.ender_storage.setFrequency(FREQ), replacing FREQ with the frequency you want to set.

    As for the second question, unless reading the source code of OpenComputers (and other mods that provide OC integration) is an option for you, no. Try to connect blocks to adapter and see if a component appears.

    1. Start the program.
    2. Switch to RT mode (i.e. click on the screen).
    3. Calculate the difference between the time displayed on the screen, and the real UTC time, in hours (for example, -1 means the real time is 1 hour behind the time shown).
    4. Open the program (edit programname.lua) and go to line 10, the one that starts with "CORRECT =".
    5. Replace 0 with the difference you've calculated in step 3.
    6. On the previous line, replace 0 with the timezone you want (sample values: -6, +3, -10, +11).
    7. Save the file (Ctrl+S) and quit (Ctrl+W).
    8. Restart the program.
  6. computer.getDeviceInfo was created exactly for this purpose: provide information about devices that don't have a component (processors, solar generators, memory banks).

    computer.getDeviceInfo returns a table. Its keys are addresses of devices, values that correspond to these keys are tables filled with basic information about a device. So you need to iterate over the returned table and compare fields of tables to expected values.

    For the solar generator upgrade, class is "power", and description is "Solar panel". Here's how you can check if the solar panel is installed.

    local solarGenDetected = false
    for addr, info in pairs(computer.getDeviceInfo()) do
      if info.class == "power" and info.description == "Solar panel" then
        solarGenDetected = true
        break
      end
    end
    
    if solarGenDetected then
      print("solar generator is installed")
    end

     

  7. Machine is stopped by calling computer.shutdown which is a "low-level" function brought to OpenOS from the bios environment. It becomes obvious that no event is fired when a computer is shutting down. You can override computer.shutdown to fire an event, wait for it to be processed, and then finally stop the machine.

  8. That's because you're missing " before and after the string. Instead of just minecraft:barrier, you need to use "minecraft:barrier".

    Also I'm pretty sure you don't need that minecraft: at the start of the particle name.

    component.particle.spawn("barrier", 1, 1, 1)

     

  9. The Lua table can't be just printed -- you'll get the address of the table in memory. Fortunately, there's the serialization library that can serialize a table (convert it into a string).

    The function to use is serialization.serialize(tbl: table). Or serialization.serialize(tbl: table, math.huge) that will make the returned string way more readable.

    Before you can use the library in your script, you need to require() the library.

    local component = require("component")
    local serialization = require("serialization")
    
    print(serialization.serialize(component.me_controller.getItemsInNetwork(), math.huge))

    But there's an easier way. In Lua interpreter (the lua program), you can put = into the beginning of the line to pretty-print the return value. Also the interpreter automatically require()'s all libraries, so you don't need to do it yourself.

    =component.me_controller.getItemsInNetwork()

     

  10. Ah, right. When robot returns to the start, it receives the redstone_changed event and immediately repeats the code. The fix is to consume this event before pulling -- this can be done with os.sleep().

    while true do
      local e, addr, side, prev, current = event.pull("redstone_changed")
      if e and side == sides.back and prev == 0 then
        farmTrees()
      end
      os.sleep(0.25)
    end

     

  11. When a redstone input changes, the "redstone_changed" event is fired. It contains the redstone card address, the side, the previous input strength, and the current strength.

    To wait for an event, use event.pull. You need to require("event") before you use any of the event library's functions.

    Here's an example.

    local event = require("event")
    local sides = require("sides")
    
    while true do
      local e, addr, side, prev, current = event.pull("redstone_changed")
      if e and side == sides.back and prev == 0 then
        -- your code here
        collectFruits()
      end
    end

     

  12. The problem is on the 65th line. For some reason (it's probably a bug) when running OC 1.6.1, you have to pass the boolean argument to robot.compare. If the argument is true, it will ignore metadata when comparing. If you need the same behavior as on OC 1.5, the argument should be false.

    So, replace this line with the following code.

    while not robot.compare(false) do o.sleep(wait) end

     

  13. I've updated hpm once again. This time the update brings some really useful features.

    • First, I've changed the way you install and remove non-hel packages. Instead of hpm install oppm:package you need to run hpm oppm:install package. This made it incredibly easier to implement the other features.
    • save command no longer exist. To install a package to the current directory, pass the -s flag to install (or oppm:install).
    • Added hel:upgrade that tries to install the up-to-date versions of the installed packages. This is one of the main features of this update, although it was simple to implement, as it turned out.
    • Added hel:search. When it's run without any arguments, it simply lists all packages in the Hel Repository. By passing arguments you can filter out unwanted results. Don't forget to add | less at the end of command if the output is loo large.
    • Added oppm:search. It works similarly to the hel:search.
    • Added oppm:info. Previously there only was the hel:info command, and that was a little confusing.
    • Multiple arguments for install and remove commands are handled correctly now. In previous version it was pretty spammy.
    • Dependent packages are not removed when the reinstalling a package now.
    • hpm builds are now minified using the wonderful LuaMinify program. I've managed to reduce the size from 192 kB to 72 kB without changing any program logic.
    • Plans are confirmed only when there are no pending changes to approve.
    • Fixed a few minor bugs.

    To update, simply run the following command:

    $ pastebin run vf6upeAN
  14. load is a function that's a part of the Lua standard library. This means that you can use it even in EEPROM programs.

    The signature of the function is load(chunk[, chunkname[, mode[, env]]]).

    • The first argument is either a string of code you want to run, or an iterator function that returns a Lua code.
    • The second argument is the name of the chunk. It's used for error messages.
    • The third argument is the mode: either "bt" (both binary and text), "t" (text), and "b" (binary). In standard Lua implementations, "b" mode is used to load pre-compiled code returned by string.dump. In OpenComputers, however, this feature is disabled by default for security reasons.
    • The fourth argument is the environment to run the code with. The environment is a table that contains some values that can be used in the code. If you make {hello=function(name) print("Hello, " .. tostring(name) .. "!") end} the environment, the hello function can be called from within the code: load("hello('world')", nil, nil, {hello=function(name) print("Hello, " .. tostring(name) .. "!") end}) prints "Hello, world!" when run.

    load doesn't run the code. It checks it for syntax errors, and returns a function that, when called, runs the code. Here's an example.

    load([[
      print("Hello")
      local x = math.sin(45 / 180 * math.pi)
      print("The sine of 45° is " .. x)
    ]])()
    
    --> Hello
    --> The sine of 45° is 0.70710678118655
  15. local function splitEvery(str, n)
      local result = {}
      for i = 1, #str, n do
        local substr = str:sub(i, i + n - 1)
        table.insert(result, substr)
      end
      return result
    end
    
    print(table.unpack(splitEvery("abcdefghi", 3)))
    --> abc     def     ghi
    
    print(table.unpack(splitEvery("hello, world!", 4)))
    --> hell    o, w    orld    !
    local function splitHalf(str)
      local leftLen = math.ceil(#str / 2)
      return str:sub(1, leftLen), str:sub(leftLen + 1, -1)
    end
    
    print(splitHalf("abcdef"))
    --> abc     def
    
    print(splitHalf("helloworld"))
    --> hello   world
    
    print(splitHalf("programming"))
    --> progra  mming

     

  16. Creating a script in /boot is a poor idea unless the program must be run only when computer starts. Boot scripts are intended to initialize the system. Using /home/.shrc is preferred (this will run the program each time the shell boots, though).

    @novotd00 I'd just put resolution <x> <y> to /home/.shrc. That's much better than adding code to a file with a completely different purpose (in your case the purpose is to initialize the rc system).

     

    By the way, payonel listed the ways to make a program run automatically here.

  17. IIRC, OpenOS 1.6 doesn't load authorun.lua at root fs. This means that you either should add a command to /home/.shrc (this's the preferred way), or modify boot scripts.

    I guess the program you want to start automatically on boot doesn't require to be run before the shell loads, so just write the path to your program to /home/.shrc.

    /home/bin/my-program.lua

     

  18. First, replace local function = hex.toHex(input) to function hex.toHex(input).

    Second, you can't use = in if condition. If you want to check for equality, use ==.

    Third, you must end the function with the end operator.

    Fourth, the return hex line is incorrect. You didn't define the hex variable so the line will make the function return nil.

    Fifth, you can't do if a,b,c < 42 then. You must check every variable and then "sum" the answer using and, or, not. E.g., a < 42 and b < 42 and c < 42 checks that a, b, c all less than 42.

    Sixth, this is the most inefficient dec-to-hex algorithm I've seen so far. The whole function can be replaced with this:

    function hex.toHex(num)
      return ("%x"):format(num)
    end

     

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.