Controlling a computercraft turtle remotely

Screen Shot 2015-10-18 at 7.16.59 PM
Screen Shot 2015-10-18 at 7.17.30 PM

  1. Install Redis: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-redis
  2. Install Webdis
  3. Start a minecraft server with computercraft. You will need to have the http API enabled, which is the default.
  4. Put down a turtle I recommend a turtle with a crafting square and a pickaxe. I also recommend giving it a label. If you’re not trying the turtle replication challenge, either disable fuel or get a fair bit of starting fuel. Write down the computer’s id.
  5. Put down a chunk loader, if you’re in a modpack that has them, or DON’T log out. Computers and turtles can’t operate unless the chunks are loaded. If you’re putting down a chunkloader, I surrounded them with bedrock for foolproofing.
  6. Open the turtle and download the following script, changing “redis.example.com” to your own redis instance: pastebin get 8FjggG9w startup
    After you have the script saved as ‘startup’, run it or reboot the computer, and it should start listening for instructions.

    redis = "http://redis.example.com" 
    queue = "sshbot" .. os.getComputerID()
    return_queue = queue .. "_return"
    print("Remote webdis queues on icyego: " .. queue .. " and " .. return_queue)
    print("Receiving remote commands.")
    
    function exec(str)
      print("Running: " .. str)
      f = fs.open("tmp", "w")
      f.write(str)
      f.close()
      p = loadfile("tmp")
     status, err = pcall(function () p = loadfile("tmp"); return p() end)
      if status then
        status, ret = pcall(function() return textutils.serialize(err) end)
        if status then
          result = ret
        else
          result = ""
        end
      else
        result = "Error: " .. err
      end
      print(result)
      return result
    end
    
    print("Now receiving remote commands.")
    while true do
      handle = http.get(redis .. "/BRPOP/" .. queue .. "/5.txt")
      if (handle and handle.getResponseCode() == 200) then 
        str = handle.readAll()
        handle.close()
        str = string.sub(str, string.len(queue) + 1)
        result = exec(str)
        if string.find(result, "Error: ") then
          result2 = exec("return " .. str)
          if string.find(result2, "Error: ") then a=0 else result=result2 end
        end
        http.post(redis, "LPUSH/" .. return_queue .. "/" .. result)
      end
    end
    
  7. On your local machine, save the following, again replacing “redis.example.com”:

    #!/bin/bash
    function send() {
      curl -s -X POST -d "LPUSH/sshbot${1}/${2}" "http://redis.example.com" >/dev/null
    
    }
    
    function get() {
      curl -s -X GET "http://redis.example.com/BRPOP/sshbot${1}_return/20.json" | jq .BRPOP[1]
    }
    
    if [ $# -ne 1 ]; then
      echo "Usage: rlwrap ./sshbot <COMPUTER_ID>"
      exit 1
    fi
    ID=$1
    
    while read LINE; do
      send ${ID} "$LINE"
      get ${ID}
    done
    
  8. Run: rlwrap ./sshbot , where is the turtle’s ID. You should be able to send commands to the computer now.

Tagged , ,

Linux Print Server

So have you ever used a web printer and it was great?

Yeah, me neither. It’s probably possible on windows, but try to add more than one OS to the network and it’s horrible. And actually printing is a major pain in Linux anyway. Theoretically ‘lp’ and the like have no problem with remote printers, but I wanted something I understood. So today I’m going to post my setup I use instead.

I have a computer physically connected to the printer. Let’s call it ‘printserver’. On that server there is a folder, /printme, which is constantly monitored by inode. Any file added to that directory is printed.

Suppose I downloaded cutecats.pdf and I want to print it. Then I run:

scp cutecats.pdf printserver:/printme

And voila, the cute cats get printed.


Here’s the setup for the server:

  1. Get the printer to work. This is the hard step.
  2. Make a directory /printme. Add any missing users, add a new group called ‘print’ and add everyone who needs to print to that, etc.
  3. Set up /printme to be a tmpfs with the sticky bit set. (So we don’t fill up the hard drive)

    /etc/fstab
    tmpfs           /printme        tmpfs   rw,nodev,nosuid,noexec,uid=nobody,gid=print,mode=1770,size=1G  0       0
    
  4. Install incron and add this to the incrontab (of user ‘print’ or ‘sudo’):

    # incrontab -l
    /printme IN_CLOSE_WRITE,IN_MOVED_TO lp $@/$#
    

    Note that this will preserve files after they’re printed, because my server is low-volume enough I don’t need to care.

Tagged , ,

Installing Canon imageClass LBP-6000 on 64-bit Debian

(From Stack Overflow)

  1. 64 bit requirements for pre-made binaries:

    sudo dpkg --add-architecture i386
    sudo apt-get update
    sudo apt-get install libstdc++6:i386 libxml2:i386 zlib1g:i386 libpopt0:i386
    
  2. Install CUPS

    sudo apt-get update
    sudo apt-get install cups
    
  3. Download DriverGo to http://support-au.canon.com.au/contents/AU/EN/0100459602.html and download driver

    64e2d00f0c8764d4032687d29e88f06727d88825 Linux_CAPT_PrinterDriver_V270_uk_EN.tar.gz
    
  4. Extract and enter extracted folder

    tar xf Linux_CAPT_PrinterDriver_V270_uk_EN.tar.gz
    cd Linux_CAPT_PrinterDriver_V270_uk_EN
    
  5. Install the custom drivers and ccpd

    sudo dpkg -i 64-bit_Driver/Debian/*.deb
    
  6. Add the printer to CUPS and ccpd

    sudo lpadmin -p CANON_LBP6000 -m CNCUPSLBP6018CAPTS.ppd -v ccp://localhost:59687
    sudo lpadmin -p CANON_LBP6000 -E
    
    sudo ccpdadmin -p CANON_LBP6000 -o /dev/usb/lp0
    
  7. Set the default printer

    sudo lpoptions -d CANON_LBP6000
    
  8. Set ccpd to start on boot

    sudo update-rc.d ccpd defaults
    
Tagged , , ,

Cardboard mail holders

Our house has seven people, so today I made some mail holders to put on our doors.

cardboard_near0.5

I basically had some long cardboard boxes, and cut them in half. Then I added new ends and separators in the middle.

I’m not sure if they’ll actually get used. Mail on the floor looks bad, but these aren’t that hot either. If you make some and want to improve the look, you can cover everything in paper or cardstock.

Tagged , , , ,

SQL views

I decided I wanted to show (restricted) data views on the web in table form. Specifically, ‘stylish.db’ is a database provided by a chrome plugin. Here’s an example script, stylish.view, which displays the contents of that. It contains a comment saying which database it’s a query on, together with the query.

-- stylish.db
SELECT style, code, GROUP_CONCAT(section_meta.value) as 'website(s)' FROM
 (SELECT styles.name AS style,
 sections.code AS code,sections.id AS sections_id
 FROM styles INNER JOIN sections ON sections.style_id = styles.id)
LEFT JOIN section_meta
 ON section_meta.section_id = sections_id
GROUP BY style;

The cool part here is that none of this was specific to stylish. I can quickly throw together a .view file for any database and put it on the web.

I add put any databases in cgi-bin/db, and add view.cgi to cgi-bin:

#!/bin/bash
# view.cgi
echo "Content-type: text/html"
echo

QUERY_FILE="${PATH_TRANSLATED}"
DB_NAME=$(head -n1 "${QUERY_FILE}" | sed -e 's/--\s*//')
DB="/home/za3k/cgi-bin/db/${DB_NAME}"

echo "<html><head><title>Query on #{DB_NAME}</title><link rel="stylesheet" type="text/css" href="db.css"></head><body><table id=\"${DB_NAME}\">"
sqlite3 "$DB" -html -header <"${QUERY_FILE}"
echo "</table></body></html>"

I add this to apache’s `.htaccess`:

Action view /cgi-bin/view.cgi
AddHandler view .view
Tagged , , ,

Rationality Techniques 1

CFAR usually designs their techniques to help people Get Stuff Done. I have a failure mode of Getting The Wrong Stuff Done, so this time through their workshop, I focused on improving techniques to explicitly have steps around pursuing the correct terminal goals (which I’ll here call “terminal goal techniques”).

Original technique: Goal-factor
New terminal goal technique:

  1. Find an instrumental goal toward another instrumental goal.
  2. Embark on that goal provisionally, while also making a plan to acquire more information about whether it’s a good idea and better plans are available.
  3. Periodically re-evaluate to make sure it’s the best goal and you’re gathering information.

Original Technique: Murphy-jitsu

  1. Come up with a plan to achieve your goal.
  2. Use pre-hindsight to ask “How did this go wrong?”.
  3. Fix that. Go to 2 until fixed.

Revised terminal goal technique: Murphy-jitsu with terminal goal check

  1. Come up with a plan.
  2. Use pre-hindsight to ask “How was I disappointed when this went as planned?”
  3. Fix that. Go to 2 until fixed.
  4. Use pre-hindsight to ask “How did this go wrong?”.
  5. Fix that. Go to 2 until fixed.

Another technique: Positive murphyjitsu (“Why didn’t this go even better?”)
Another technique: Aversion murphyjitsu (“Imagine none of the positive listed factors happened. Why was it still possible?”) for cases when I can’t think about how to overcome a aversion directly.

Instrumental failure TAP:

  • Notice executive planning fails  -> Look for lack of motivation or motivation propagation
  • Notice motivation / motivation propogation fails -> Look to see if the goal you’re pursuing is what you want (or exactly what you want)

Technique: Exactboxing

  1. Find a thing to do
  2. Set a 15-minute timer
  3. Do the thing
  4. If you finish early, keep doing the thing anyway. (For example, figure out how to do it better in the future or for the problem to never happen again.
  5. If you don’t finish in time, stop anyway. It’s done. If you don’t know how it’s done, that’s a failure mode–you should have at most one task which takes an unbounded amount of time in your life. (I find this makes my brain accept ‘line of retreat’)

Technique: Do the Obvious Thing

  1. Ask a question, for example how to pursue a goal you want achieved (I recommend a Hamming Question)
  2. Figure out the most obvious solution.
  3. Acknowledge that it is the most obvious solution.
  4. Decide whether or not to do it.
  5. If you don’t want to, contradiction. Debug steps 1,2,3,4 and see where you went wrong until they’re in accord.

Theory on how to avoid lost purposes (mostly from Eliezer): Use Litany of Tarski a lot until you get the magic effect where you don’t start rationalizing to begin with (and generally don’t flinch away from learning about things/mistakes). Then, develop an aversion to lost purposes. The naive failure mode is to avoid noticing lost purposes if you have an aversion. (The simpler technique is Alien in a Body)

Tagged , , ,