So I left my little contraption running over night, with the hope that it'd finish emptying out my ores. Well, it was half right. I came down to a casting basin half full... This wasn't meant to happen! It was only supposed to cast when there was enough in the smeltery to fill a basin. I looked at my code again:
if quantity > 1296 then
print(quantity)
redstone.setOutput("front",true)
sleep(5)
redstone.setOutput("front",false)
print(quantity)
sleep(5)
end
Nope, that clearly says if the quantity is greater than 1294 (9 ingots, or enough for a block of that material), then it should open the valve, so why is it still opening when there is less than 9 ingots available?
Because the quantity value doesn't update.
If we refer back to our main code:
local tankTable = tank.getTankInfo()[1]
local contentsTable = tankTable["contents"]
local quantity = contentsTable["amount"]
while true do
if quantity > 1296 then
print(quantity)
redstone.setOutput("front",true)
sleep(5)
redstone.setOutput("front",false)
print(quantity)
sleep(5)
end
end
The first bit, the local variables, are only called at the start of the program - so the value does not change! I should've noticed this when I looked at the printed quantity on the screen, but truth be told, I didn't look.
So, solutions? I could just move the variables into the "while true do" so they're called every cycle - but that's not very elegant. Instead, I went for the complex approach, and made some functions while I was at it...
First off, I timed how long I actually needed for the casting table to fill, cool and empty (15 seconds), and made a function that would just open the faucet for exactly 15 seconds. The faucet is rising edge triggered - so it only goes off when the redstone input goes high, you can drop it straight back down to low again, ready for the next lot - so my function just pulses it on for 1 seconds, then switches it off again for for a set amount of time. I wanted to be able to easily reuse the function, so I didn't hardcode the time into the function.
function on(side,time)
redstone.setOutput(side,true)
sleep(1)
redstone.setOutput(side,false)
sleep(time-1)
end
What does it do?! So, the name of the function is "on" - imaginative! and it takes 2 variables to run it - the side your rednet cable is on (or whatever way you're transmitting your redstone signal), and the time you need it on for. In my case, the rednet cable was on the back of the computer, and it was on for 15 seconds, so calling the command was a simple matter of writing - on("back", 15) and it'd
switch the faucet on for exactly the right amount of time to fill, cool and empty.
So the function takes those 2 variables, and first sets the side you gave it to high for 1 second - then it goes back to low. Now it waits for the time you gave it (minus the 1 seconds it spent setting it high). That's it for that bit!
So, next function I made took care of the issue I had with the first one - that the quantity wasn't updating. in this one, I just moved all the tank/table variables into there... So it looks like this:
function getQuantity(drainObject)
local tank = drainObject.getTankInfo()[1]
local contentsTable = tank["contents"]
local quantity = contentsTable["amount"]
return quantity
end
I made a new variable - drainObject, which passes the wrapped drain block to the function. This way, if I use something like a wired modem to do it more remotely, I can just pass it that, rather than specifically giving it a side, or hardcoding the side.
So next up - it makes a bunch of local variables that are only accessible from within the function, and don't affect anything outside it. (so I could have another quantity variable used in another function or main script, and it wouldn't take the same value)
The key thing here is the return quantity bit. Basically, I can use the function getQuantity(drainObject) as a variable - so my if statement from the previous one (if quantity > 1296 then do stuff) can use the getQuantity instead of having to define another variable.
I did make another variable for the ingot/casting volume, which is 1296mB or 9 ingots. I did this so I can just change that value to 144 if I wanted to cast single ingots or 576 if I wanted to cast gears.
local ingotVol = 1296 -- 1296 is volume of a full block in mB, for ingots use 144, for gears use 576
The -- bit just is a comment, so it doesn't have any effect on the code, and is only there for the user.
Then I have my loop and if statement:
while true do
if getQuantity(drain) > ingotVol then
print("Contents is: "..getQuantity(drain))
on("back",15)
print("Contents is now: "..getQuantity(drain))
else
print("Quantity is less than 1 block")
sleep(15)
end
end
So I'm using my getQuantity() function instead of making a new quantity variable, and I'm using my ingotVol variable to tell me the size of the ingot/block/gear I'm making. Then I'm just printing off the quantity again before, switching the faucet on (with our on() function), and printing the quantity again after, to verify that it went down by the correct volume (maybe I should've done a difference... nvm, next time).
Another new thing is the else bit. This is my catch for if there isn't enough metal in the smeltery to make another ingot/gear/block. If that is the case, it just writes on the screen that there isn't enough for a block, and waits for 15 seconds before trying again.
So, future plans for it? Multi- faucet maybe... and maybe get it to plan if there is enough material for full blocks, and if not, uses a ingot instead of a block, ensuring a fully empty smeltery...
Modems as well, so I can centralise it.. And maybe a monitor to show how much material there is in the tank, and how many ingots it has made? Or maybe I'll just leave it there.
Link as always: https://pastebin.com/1vFwdPNm