This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Zatilla7's profile picture

Tank Monitor code

Started by Zatilla7, 17 April 2014 - 05:44 PM
Zatilla7 #1
Posted 17 April 2014 - 07:44 PM
Heya. I've just started messing around with open peripheral and monitors. So after trying to create a code to read what's in a tank I had to call in a friend to help. We managed to create a code and then I tried to edit it into a code to show it on the monitor. I managed, well somewhat. It only shows it in one line.

So what I would like you to help me with is threefold:
  1. Help me make it so the different pieces of information on different rows.
  2. There is a bug which after I run it, I can't edit anything until I reboot the computer
  3. Please tell me just what is going on in this code… I don't really understand and my friend won't tell me…
Here is the code:

m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
table = {}
table = m.getTankInfo("top")
table1 = table[1]

l.write(table)
l.write(#table)
for i,j in pairs(table1) do
l.write(i..":"..j)
end

Thanks -Zat
Dog #2
Posted 17 April 2014 - 07:50 PM
Hey, Zatilla7,

Regarding your issue of only getting output on one line - you aren't setting the cursor position before each write, so it's all being output on the same line. Try adding term.setCursorPos(x,y) before each of your write statements; where x and y are the actual positions at which you want to write your text.

e.g.

term.setCursorPos(2,3)

In regard to your second issue, please post your full code (if this is not the full thing) so we can try to figure out what's going on. I suspect 'edit' is being reassigned globally within the program somewhere. I don't see anything within the code you posted that would prevent editing from working…to the best of my knowledge.

As for your third question: I'll give it a shot:

This wraps the tank on the top of the computer (as 'm' for some reason) so it can be accessed via its API calls

m = peripheral.wrap("top")

I've lumped these two lines together because they are commented out and do nothing

--m = tank
--l = monitor(confusing, I know)

This wraps the monitor (as 'l') so it can be accessed via its API calls

l = peripheral.wrap("right")

This delcares 'table' as an empty table, then uses 'm' to call 'getTankInfo' and fill the table with that info (but it appears to be doing it incorrectly since 'm' is already wrapped to the top)

table = {}
table = m.getTankInfo("top")

This sets the variable 'table1' to the value stored in the first key of your table named 'table'

table1 = table[1]

This writes the information in the table and the number of table entries. Although I doubt this will work either. Usually the textutils api is used to tease information out of tables (look specifically at 'serialize' and 'unserialize').

l.write(table)
l.write(#table)

This is a loop that displays the key/value data in the table named table1 (which is the information taken from table[1])

for i,j in pairs(table1) do
l.write(i..":"..j)
end

As for using the correct syntax with the OpenP calls, I'll have to leave that to someone with actual OpenP experience. I hope the information I've provided is helpful (and accurate). If I've made any mistakes, please call me out on them.
Edited on 17 April 2014 - 06:11 PM
Anavrins #3
Posted 17 April 2014 - 07:53 PM
Simply add " l.setCursorPos(1,i) " before " l.write(i..":"..j) " and it should do it.

edit: ninja'd
Edited on 17 April 2014 - 05:54 PM
CometWolf #4
Posted 17 April 2014 - 07:55 PM
you're overwriting the global table functions here

table = {} --also this line is pointless >.>
table = m.getTankInfo("top")
That's why it messes up your computer. Either change the variable name or use a local variable.
Dog #5
Posted 17 April 2014 - 08:13 PM
you're overwriting the global table functions here

table = {} --also this line is pointless >.>
table = m.getTankInfo("top")
That's why it messes up your computer. Either change the variable name or use a local variable.
That's what it was - thanks for that, CometWolf :)/>
Zatilla7 #6
Posted 17 April 2014 - 08:32 PM
Thanks guys. Also about the edit prob is says: edit:60: attempt to call nil
Maybe I messed up a varriable within edit… No idea
Dog #7
Posted 17 April 2014 - 08:36 PM
Thanks guys. Also about the edit prob is says: edit:60: attempt to call nil
Maybe I messed up a varriable within edit… No idea
Zat, read CometWolf's explanation - you really should rename your table to some other name (like myTable) and also localize your variables

e.g.

local myTable = m.getTankInfo("top")

instead of

table = { }
table = m.getTankInfo("top")
Edited on 17 April 2014 - 06:39 PM
Zatilla7 #8
Posted 17 April 2014 - 08:39 PM
Simply add " l.setCursorPos(1,i) " before " l.write(i..":"..j) " and it should do it.

edit: ninja'd

Well that didn't work. It says expeted number… No idea!

Thanks guys. Also about the edit prob is says: edit:60: attempt to call nil
Maybe I messed up a varriable within edit… No idea
Zat, read CometWolf's explanation - you really should rename your table to some other name (like myTable) and also localize your variables

e.g.

local myTable

as opposed to


table = { }

Yeah. Thanks alot, it worked
Dog #9
Posted 17 April 2014 - 08:41 PM
You're welcome - glad I could be of assistance :)/> Credit should go to CometWolf though, he's the one who identified the actual problem.
Zatilla7 #10
Posted 17 April 2014 - 08:45 PM
You're welcome - glad I could be of assistance :)/> Credit should go to CometWolf though, he's the one who identified the actual problem.

I still have the line problem though
Dog #11
Posted 17 April 2014 - 08:46 PM
See my first reply, regarding term.setCursorPos(x,y)
Zatilla7 #12
Posted 17 April 2014 - 08:48 PM
I mean for the last part. This one:


l.write(i..":"..j)
Dog #13
Posted 17 April 2014 - 08:53 PM
Please post your edited code so I can see it.
Zatilla7 #14
Posted 17 April 2014 - 08:57 PM

m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]

l.setCursorPos(1,i)
l.write(pertable)
l.write(#pertable)
for i,j in pairs(pertable1) do
l.write(i..":"..j)
end

Here you are
madGoldfish #15
Posted 17 April 2014 - 09:03 PM
Here you are


m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]

l.write(pertable)
l.write(#pertable)
for i,j in pairs(pertable1) do
l.setCursorPos(1,i)
l.write(i..":"..j)
end

there you go
Dog #16
Posted 17 April 2014 - 09:10 PM
So what do you mean by 'line problem' - are you getting an error or are you still seeing everything printed on the same line? If you're getting an error, please post the entire text of the error you are receiving. If you are still referring to everything being printed on the same line, I will again point you back to my first reply - the first part regarding term.setCursorPos(x,y) - everything is right there.

Either way, if you're still stuck, please don't hesitate to ask for clarification and I'll do my best to get you where you want to go.
Zatilla7 #17
Posted 17 April 2014 - 09:17 PM
So what do you mean by 'line problem' - are you getting an error or are you still seeing everything printed on the same line? If you're getting an error, please post the entire text of the error you are receiving. If you are still referring to everything being printed on the same line, I will again point you back to my first reply - the first part regarding term.setCursorPos(x,y) - everything is right there.

Either way, if you're still stuck, please don't hesitate to ask for clarification and I'll do my best to get you where you want to go.

Where should I place: l.setCursorPos(x,y)
I suck at monitors…
Also what would the x and y be?
Edited on 17 April 2014 - 07:26 PM
Dog #18
Posted 17 April 2014 - 09:27 PM
Place l.setCursorPos(x,y) before each l.write so you can tell the computer exactly where, on the screen, to write the data

x is your row (left/right)
y is your column (up/down)
Edited on 17 April 2014 - 07:28 PM
Zatilla7 #19
Posted 17 April 2014 - 09:35 PM
But what for the last part?

for i,j in pairs(pertable1) do
l.write(i..":"..j)
That one
Edited on 17 April 2014 - 07:36 PM
Dog #20
Posted 17 April 2014 - 09:39 PM
Ah, I see where you're stuck - my bad for not noticing that. Try this:


local k = 1 -- or whatever you want your first Y position to be
for i,j in pairs(pertable1) do
l.setCursorPos(2,k)
l.write(i..":"..j)
k = k + 1
end
Edited on 17 April 2014 - 07:41 PM
Zatilla7 #21
Posted 17 April 2014 - 10:17 PM
Well thanks alot, I'll try it out
Dog #22
Posted 17 April 2014 - 10:21 PM
Happy to help :)/>
Zatilla7 #23
Posted 17 April 2014 - 10:27 PM
Ah, I see where you're stuck - my bad for not noticing that. Try this:


local k = 1 -- or whatever you want your first Y position to be
for i,j in pairs(pertable1) do
l.setCursorPos(2,k)
l.write(i..":"..j)
k = k + 1
end

We have a prob: attempt to perform aritmetic __ add on nil and number. I got that On k = k + 1
Dog #24
Posted 17 April 2014 - 10:30 PM
post your code as it is now and I'll take a look
Zatilla7 #25
Posted 17 April 2014 - 10:36 PM
Here it is

m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]

l.setCursorPos(1,1)
l.write(pertable)
l.setCursorPos(1,2)
l.write(#pertable)
local h = 3
for i,j in pairs(pertable1) do
l.setCursorPos(1,h)
l.write(i..":"..j)
k=k+1
end
Dog #26
Posted 17 April 2014 - 10:38 PM
The problem is that you set h=3 instead of k - see the code below for the correction - that should fix it for ya.

m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]

l.setCursorPos(1,1)
l.write(pertable)
l.setCursorPos(1,2)
l.write(#pertable)
local k = 3
for i,j in pairs(pertable1) do
l.setCursorPos(1,h)
l.write(i..":"..j)
k=k+1
end
Zatilla7 #27
Posted 17 April 2014 - 10:42 PM
The problem is that you set h=3 instead of k - see the code below for the correction - that should fix it for ya.

m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]

l.setCursorPos(1,1)
l.write(pertable)
l.setCursorPos(1,2)
l.write(#pertable)
local k = 3
for i,j in pairs(pertable1) do
l.setCursorPos(1,h)
l.write(i..":"..j)
k=k+1
end

I shouldn't be coding at 11 at night…

Well we have one last problem…
There is still that top line…
the rest is fine though
Dog #28
Posted 17 April 2014 - 10:45 PM
I shouldn't be coding at 11 at night…
lol

Well we have one last problem…
There is still that top line…
the rest is fine though
OK, by 'top line' do you mean "l.write(pertable)" just below l.setCursorPos(1,1) ?
Edited on 17 April 2014 - 08:47 PM
Zatilla7 #29
Posted 17 April 2014 - 10:48 PM
No I mean that code on the monitor. My first prob I needed help with.
Dog #30
Posted 17 April 2014 - 10:49 PM
OK, I think I see what's up - looks like you have two tables you need to print onscreen. Try this and tell me if this is what you are looking for…


IMPORTANT NOTE:
the line "l.write(a .. " : " .. B )/>" is wrong - the forum software here keeps doing that to the code - the line should read:

l.write( a .. " : " .. b )


m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]
local h = 1
for a,b, in pairs(pertable) do
  l.setCursorPos(1,h)
  l.write(a .. " : " .. B)/>
  h = h + 1
end
--l.write(pertable)
l.setCursorPos(1,h)
l.write(#pertable)
h = h + 1
for i,j in pairs(pertable1) do
  l.setCursorPos(1,h)
  l.write(i..":"..j)
  h = h + 1
end
Edited on 17 April 2014 - 08:57 PM
Zatilla7 #31
Posted 17 April 2014 - 10:56 PM
Thanks alot.
I'll be uploading this to pastebin, I'll be giving you credits for pretty much ironing it out.
Dog #32
Posted 17 April 2014 - 10:59 PM
I'm happy to help. Thank you, kindly, for the credit - while it's always nice to get a little recognition, it was truly my pleasure :)/>
Edited on 17 April 2014 - 09:00 PM
Zatilla7 #33
Posted 17 April 2014 - 11:01 PM
Here it is. Check out row 23

http://pastebin.com/RfurqZLv
Edited on 17 April 2014 - 09:01 PM
Dog #34
Posted 17 April 2014 - 11:01 PM
Don't forget to change this line:

l.write(a .. " : " .. B )/>

to

l.write (a .. " : " .. b )
Edited on 17 April 2014 - 09:02 PM
Zatilla7 #35
Posted 17 April 2014 - 11:02 PM
Wat?

Ah
Dog #36
Posted 17 April 2014 - 11:03 PM
Yeah - the forum software here was causing an one line of code to be borked and nothing I did seemed to fix it - it's on line 10 of your program.
Zatilla7 #37
Posted 17 April 2014 - 11:04 PM
Done

Well… This just may be the longet "Ask a pro" thread ever.
Dog #38
Posted 17 April 2014 - 11:06 PM
make that 'B' on line 10 a lower case 'b' (capitalization matters in Lua)
Edited on 17 April 2014 - 09:07 PM
Zatilla7 #39
Posted 17 April 2014 - 11:07 PM
And it's not done yet: bios:339: [string "Tanks"]:8: ´<name>´ expected
Dog #40
Posted 17 April 2014 - 11:11 PM
And it's not done yet: bios:339: [string "Tanks"]:8: ´<name>´ expected
lol

OK, I'm going to setup a quick creative world and check this out. You are using the basic 'tank' that is like a glass cube, right? And ComputerCraft 1.58?
Edited on 17 April 2014 - 09:11 PM
Zatilla7 #41
Posted 17 April 2014 - 11:13 PM
Well the craft os is 1.5 and yea a basic
CometWolf #42
Posted 17 April 2014 - 11:13 PM
remove the extra ","

for a,b, in pairs(pertable) do

for a,b in pairs(pertable) do
Edited on 17 April 2014 - 09:15 PM
Dog #43
Posted 17 April 2014 - 11:17 PM
Thanks for catching that CometWolf - I've been doing that to myself a lot lately :\
Zatilla7 #44
Posted 17 April 2014 - 11:18 PM
Yea that was the problem
Here is another: Tanks:10: attempt to concentrate string and table

Btw, I called the program tanks
Edited on 17 April 2014 - 09:19 PM
Dog #45
Posted 17 April 2014 - 11:22 PM
I at the same error now. Apparently OpenP returns a LOT of tables. I need to sit down with this and work on it a little. I'll post something up when I'm done. If I'm more than 5 minutes I'll go ahead and double post so you know I'm back with something.
Zatilla7 #46
Posted 17 April 2014 - 11:23 PM
Ok
Dog #47
Posted 17 April 2014 - 11:41 PM
OK, I think this is what you're looking for. I set the text scale on the monitor to 0.5 (default is 1.0) so more info can fit on a single screen. If it's too small for you, just delete that line and it should be what you expect.


m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
l.setTextScale(0.5)
l.clear()
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]
local h = 1
for i,j in pairs(pertable1) do
  l.setCursorPos(1,h)
  l.write(tostring(i)..":"..tostring(j))
  h = h + 1
end
Edited on 17 April 2014 - 09:48 PM
Zatilla7 #48
Posted 17 April 2014 - 11:42 PM
OK, I think this is what you're looking for. I've left the commented code in so you can uncomment it and see why I removed it (it's essentially keys for the table entries - they aren't of any informational use to you for what you want). I set the text scale on the monitor to 0.5 (default is 1.0) so more info can fit on a single screen. If it's too small for you, just delete that line and it should be what you expect.


m = peripheral.wrap("top")
--m = tank
l = peripheral.wrap("right")
l.setTextScale(0.5)
l.clear()
--l = monitor(confusing, I know)
pertable = m.getTankInfo("top")
pertable1 = pertable[1]
local h = 1
for a,b in pairs(pertable) do
  --l.setCursorPos(1,h)
  --l.write(tostring(a) .. "  ")
  --h = h + 1
  for t,u in pairs(B)/>/> do
	l.setCursorPos(1,h)
	l.write(tostring(u))
	h = h + 1
  end
  h = h + 1
end
--l.setCursorPos(1,h)
--l.write(tostring(#pertable))
--h = h + 1
for i,j in pairs(pertable1) do
  l.setCursorPos(1,h)
  l.write(tostring(i)..":"..tostring(j))
  h = h + 1
end

It's one in the morning to me…
I may need an explanation
Zatilla7 #49
Posted 17 April 2014 - 11:50 PM
99 little bugs in the code
99 little bugs
you take one down and patch it around
127 little bugs in the code

20: ´<eof>´ expected
and
14: bad argument: table expected, got nil
Edited on 17 April 2014 - 10:01 PM
Zatilla7 #50
Posted 18 April 2014 - 12:06 AM
You have any ideas MR_nesquick?
Dog #51
Posted 18 April 2014 - 12:07 AM
Yeah - go back and look at my post again - I fixed the code - what you got was incomplete and also broken by the forum posting. I also removed all the unnecessary code so it is easier to read.
Edited on 17 April 2014 - 10:08 PM
Zatilla7 #52
Posted 18 April 2014 - 12:09 AM
Could you pastebin the good code? My brain has maybe 10kilobytes left of ram is overheating…
Edited on 17 April 2014 - 10:09 PM
Dog #53
Posted 18 April 2014 - 12:12 AM
lol, no prob - I was just there the other night…

pastebin Jdfd0T1X

also for reference:

--m = tank
--l = monitor(confusing, I know)
local m = peripheral.wrap("top")
local l = peripheral.wrap("right")
l.setTextScale(0.5)
l.clear()
local pertable = m.getTankInfo("top")
local pertable1 = pertable[1]
local h = 1
for i,j in pairs(pertable1) do
  l.setCursorPos(1,h)
  l.write(tostring(i)..":"..tostring(j))
  h = h + 1
end
Edited on 17 April 2014 - 10:15 PM
Zatilla7 #54
Posted 18 April 2014 - 12:13 AM
Thanks. It's 1:30 In the morning. I'll be testing it and then slepping
Dog #55
Posted 18 April 2014 - 12:17 AM
Enjoy your sleep :)/> I updated the script a bit, so if you're reading this after your sleep you might want to re-download the script to have the 'better' version.
Zatilla7 #56
Posted 18 April 2014 - 12:24 AM
So short…

Yawn

Wanna go upload this in the programs section then?
Dog #57
Posted 18 April 2014 - 12:27 AM
It's all you, Zat. You wrote it, I just helped you get it working. I think you should post it. No need to do it tonight - get some sleep.
Zatilla7 #58
Posted 18 April 2014 - 12:37 AM
Now's the time I have too much adrenaline from finally making this work…
How about we upgrade it a bit?
I just finished putting in something but it's nothing fancy.
How about we put the thing on a repeat so it auto updates

Now's the time I have too much adrenaline from finally making this work…
How about we upgrade it a bit?
I just finished putting in something but it's nothing fancy.
How about we put the thing on a repeat so it auto updates
Let's do that tomorrow… I think my pillow just talked to me so I need some sleep. Night. Let's keep working tomorow
Dog #59
Posted 18 April 2014 - 12:40 AM
You got it. Adding a loop won't be difficult at all :)/> Talk to you tomorrow.
Zatilla7 #60
Posted 18 April 2014 - 02:53 AM
Ahhh
That feeling of not being able to sleep and just turning around
Zatilla7 #61
Posted 18 April 2014 - 07:17 PM
Well time to finish the code I guess
Dog #62
Posted 18 April 2014 - 07:24 PM
OK, so when adding a loop you want to keep in mind which parts of the code you *want* to repeat (tank monitoring code) and which parts only need to happen once (wrapping peripherals, setting textScale, etc.).

You can use 'while true do / end' or 'repeat / until' to create your loop - either will work for what you are doing.

The next problem you will run into is that the loop will eventually cause the program to error out because the program will 'fail to yield' - in other words, the program never 'gives up time' to other processes and basically tries to hog all the processing time for itself. Please understand this is a very basic (and not entirely accurate) description to get the general concept across.

The way we solve that problem is by having the program yield at the end of every loop with a short sleep. In this case I recommend 1 second [ sleep(1) ] - this means the information onscreen will update every second since that's how often the loop will be able to run with a 1 second sleep after every iteration.

With that in mind (and based on your last PM), see if you can come up with a loop that works and we'll go from there. I'll be in and out all day so my responses may not always be prompt. Don't forget to post your code so we can review it.
Zatilla7 #63
Posted 18 April 2014 - 07:27 PM
Hmmm. I think I will do the repeat loop. That brings up the problem: what do I do with until?
I want to do it so that if I press tex. x it will end
Edited on 18 April 2014 - 05:31 PM
Dog #64
Posted 18 April 2014 - 07:36 PM
Since you want this to repeat indefinitely, we'll provide a condition that'll never be met, that way the loop will continue forever.

repeat

<code>

until h = 1000

Since 'h' in your code will never reach 1000 this should work fine.

The next problem you're going to run into will involve 'stray' characters left on screen when values decrease. For example, when a value drops from 4 digits to 3 digits, you are going to want to find a way to clear that 4th digit from the screen. There's a simple way to approach this, but I'd like you to also take a stab at that while you're at it.
Edited on 18 April 2014 - 05:38 PM
Zatilla7 #65
Posted 18 April 2014 - 07:41 PM
ok thanks

Well I finished. Here is the code:

--m = tank
--l = monitor(confusing, I know)
local m = peripheral.wrap("top")
local l = peripheral.wrap("right")
l.setTextScale(2)
l.clear()
    repeat
	  l.setCursorPos(1,1)
	    l.write("Tank 1:")
		  local pertable = m.getTankInfo("top")
		    local pertable1 = pertable[1]
			  local h = 2
			    for i,j in pairs(pertable1) do
				  l.setCursorPos(1,h)
				    l.write(tostring(i)..":"..tostring(j))
					  h = h + 1
					    sleep(1)
  end
until h = 1000
Dog #66
Posted 18 April 2014 - 07:54 PM
Looks mostly good. A couple of 'not big' things:

First, don't step your code out with each line - that makes it difficult to follow and difficult to find missing 'end' or other statements. Stick with indenting out for functions/loops/etc and back in at the end.

Second, where you placed your sleep would cause the program to sleep after each iteration of your pertable1 loop instead of the main loop - it would display a line, sleep, display the next line, sleep, etc. I moved your sleep down outside of that loop. I also moved your first write statement out of the loop since that won't change and doesn't need to be constantly re-written. Now it should 'just work' with one final thing (that I can think of). As values decrease you could end up with stray characters on the screen that you don't want (you'll notice that 'l.clear' is not in the loop - this is good) - go back and read the last part of my previous post for an explanation. I already have an easy fix in mind, but I'm curious as to how you think it should be handled.


--m = tank
--l = monitor(confusing, I know)
local m = peripheral.wrap("top")
local l = peripheral.wrap("right")
l.setTextScale(2)
l.clear()
l.setCursorPos(1,1)
l.write("Tank 1:")
repeat
  local pertable = m.getTankInfo("top")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
	l.setCursorPos(1,h)
	l.write(tostring(i)..":"..tostring(j))
	h = h + 1
  end
  sleep(1)
until h = 1000
Edited on 18 April 2014 - 06:01 PM
Zatilla7 #67
Posted 18 April 2014 - 08:07 PM
I really have no idea. My best idea was that if the a value went lower than 1000 then "l.clear"
Dog #68
Posted 18 April 2014 - 08:11 PM
No prob - here's what I was thinking…

replace

l.write(tostring(i)..":"..tostring(j))

with

l.write(tostring(i)..":"..tostring(j).."  ")

All I did was ensure that each time the values are written, a couple of extra blank spaces are written after the end of the value - this way any 'stray' characters left on screen should be overwritten. Also of note: I used 'tostring' so that numbers will display as 1,2,3 not 1.0,2.0,3.0.

Let me know how that works for you.
Zatilla7 #69
Posted 18 April 2014 - 08:19 PM
I understand. He said with a posed look

Well here is the new code

--m = tank
--l = monitor(confusing, I know)
local m = peripheral.wrap("top")
local l = peripheral.wrap("right")
l.setTextScale(2)
l.clear()
l.setCursorPos(1,1)
l.write("Tank 1:")
repeat
  local pertable = m.getTankInfo("top")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
	    l.setCursorPos(1,h)
	    l.write(tostring(i)..":"..tostring(j).."  ")
	    h = h + 1
  end
  sleep(1)
until h = 1000
--Credits to Dog from the computer craft forums for alot of help on debugging and bettering this code
Dog #70
Posted 18 April 2014 - 08:22 PM
Let's say you had a value of 1000 that changed to 999. If you didn't write over that last '0' when you wrote '999' you would instead see '9990' onscreen and I'm guessing you don't want that.

Normally Lua displays numbers as 1.0, 2.0, 3.0, etc. By converting the numbers to strings, the '.0' is left off and the numbers show as 1, 2, 3 which is easier to read (especially when that .0 will 'probably' never change).

We still have some cleanup to do so your program is easier to read and maintain. Instead of wrapping the monitor as 'l' it should be wrapped with a meaningful name like 'mon'. The same goes for the tank - 'm' isn't very descriptive. How about 'tank' or 'fluidTank' ? Make those changes and post your code - we're almost done :)/>
Zatilla7 #71
Posted 18 April 2014 - 08:35 PM
Alright done.

--fluidTank = tank
--mon = monitor
local fluidTank = peripheral.wrap("top")
local mon = peripheral.wrap("right")
--Change what's in the quotation marks to top,bottom,front,back,right,back based on which side it the different parts are
l.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
l.clear()
l.setCursorPos(1,1)
l.write("Tank 1:")
repeat
  local pertable = m.getTankInfo("top")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
		l.setCursorPos(1,h)
		l.write(tostring(i)..":"..tostring(j).."  ")
		h = h + 1
  end
  sleep(1)
until h = 1000
--Credits to Dog from the computer craft forums for alot of help on debugging and bettering this code

I tried to make it as beginner friendly as possible. A program which is easy enough to use untill they learn how to make this by themselves.

I also got quite bored and drew this up

print "Booting up TurtleBomberV1"
print "How long would you like to explode?"
h = read()
for i=1,h,1 do
  turtle.select(1)
	turtle.forward()
	  turtle.placeDown()
		rs.setOutput("bottom",true)
		  sleep(0,1)
			rs.setOutput("bottom",false)
end
print "Bombing done. Shaftminer Shutting down"
Edited on 18 April 2014 - 06:36 PM
Dog #72
Posted 18 April 2014 - 08:39 PM
You still need to change all the calls to the wrapped peripherals. All the 'l' calls should become 'mon', and all 'm' calls should become 'fluidTank'. E.g. 'l.clear()' becomes 'mon.clear()'.

Also, try changing the following line

local pertable = m.getTankInfo("top")
to

local pertable = m.getTankInfo()

I'm curious if that will work - we've already wrapped the tank on top, so re-specifying 'top' shouldn't be necessary.
Edited on 18 April 2014 - 06:40 PM
Zatilla7 #73
Posted 18 April 2014 - 08:40 PM
Oh yeah… I'll fix that in a few. I have to fix something before that
Zatilla7 #74
Posted 18 April 2014 - 09:57 PM
Alright, It's done


--fluidTank = tank
--mon = monitor
local fluidTank = peripheral.wrap("top")
local mon = peripheral.wrap("right")
--Change what's in the quotation marks to top,bottom,front,back,right,back based on which side it the different parts are
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
		mon.setCursorPos(1,h)
		mon.write(tostring(i)..":"..tostring(j).."  ")
		h = h + 1
  end
  sleep(1)
until h==1000
--Credits to Dog from the computer craft forums for alot of help on debugging and bettering this code

I had to fix a few things.

First:
I had to change

until h = 1000
to

until h==1000

Second:
While

  local pertable = fluidTank.getTankInfo()
didn't work…
However this worked

  local pertable = fluidTank.getTankInfo("unknown")
I guess it just searches around for a compatible source.
Anyways I guess it's time to upload this then
Edited on 18 April 2014 - 07:58 PM
Zatilla7 #75
Posted 18 April 2014 - 10:05 PM
Actually. I have one more thing I want to put in: Compatibility with wired modems. I doubt you'll have a tank next to a computer and a monitor next to that.
Although it seems like you can only place wired modems on full blocks and not build craft tanks….
Guess we'll have to work with railcraft tanks from now on

And thats something else new I need to learn now…
Edited on 18 April 2014 - 08:25 PM
Dog #76
Posted 18 April 2014 - 10:51 PM
OK, I'm going to be in and out for the rest of the day (and possibly gone tonight) so my responses will be sporadic. With that in mind I'm going to give you a little more than I should so you don't have to wait for me.

A couple of things:

I'd replace "unknown" with "top" - I'm not familiar with OpenPeripherals so I don't know what it's looking for there (I'll look it up if I get the time), but stylistically, "top" looks nicer (and is representative of what we're doing) than "unknown". However, below I'm going to show you how to 'autodetect' the tank, so we may want to replace "unknown" with "side" or something equally vague but related.

Having to change 'until h = 1000' to 'until h == 1000' is right - sorry about that.

Compatibility with wired modems isn't that hard to add - another loop or two. We can also add an 'automatic' search for the tank and monitor if you'd like. This should get you started:


for _,side in pairs(rs.getSides()) do -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then  -- if we find a perhiperal...
	if peripheral.getType(side) == "monitor" then  -- then we try to identify if it's one of the peripherals we're looking for
	  mon = peripheral.wrap(side)						  -- if it's what we're looking for, we wrap it
	elseif peripheral.getType(side) == "tank" then
	  fluidTank = peripheral.wrap(side)
	end
  end
end

To add a check for wired modems and to look for attached peripherals, we do the following after identifying a peripheral as a modem (using the above technique):

if peripheral.getType(side) == "modem" then
  if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
  local mdm = peripheral.wrap(side)				-- temporarily wrap the modem

  for e,f in pairs(mdm.getNamesRemote()) do -- look for attached peripherals
	if string.sub(f,1,4) == 'tank' then				 -- if we find a tank
	  fluidTank = peripheral.wrap(f)				   -- wrap it
	elseif string.sub(f,1,7) == 'monitor' then
	  mon = perihperal.wrap(f)
	end
  end
end

Obviously, you'll need to 'merge' the two code blocks I've given you so that they can do the side and modem search in one big routine. This also has the shortcoming of being able to find multiple tanks and monitors but only wrap one of each (since we only have one name for each and aren't tracking how many things we find). Keep these things in mind when you post your program and need to list its requirements and limits.

In the mean time you might want to read up on the ComputerCraft modem api (google it) to learn more about it since I'm kind of short-cutting that part.
Edited on 18 April 2014 - 08:55 PM
Lyqyd #77
Posted 18 April 2014 - 10:54 PM
If OpenP is expecting a forge direction name for which side of the block to examine for tank accessibility purposes, the correct answer is always "unknown", unless it doesn't work.
Dog #78
Posted 18 April 2014 - 10:56 PM
Thanks, Lyqyd :)/>

"unknown" it is then
Edited on 18 April 2014 - 08:58 PM
Zatilla7 #79
Posted 18 April 2014 - 11:01 PM
Altough autodetecting sounds alot better
Zatilla7 #80
Posted 18 April 2014 - 11:08 PM
I have no idea how to merge these…

I'll try again tomorow.
Altough I could use some pointers
Dog #81
Posted 18 April 2014 - 11:17 PM
I'm happy to help :)/> Like I said I'll be in and out for the remainder of the day - just let me know when you're ready to continue. Also, we can go over the code snippets I posted so they make more sense to you. Again, google 'computercraft modem api' to get an idea of what we'll be dealing with.

As for the "unknown" bit - that won't be affected by autodetection - we'll be leaving that there.
Zatilla7 #82
Posted 19 April 2014 - 01:48 PM
Seems like I've started to learn this stuff a bit.
I managed to merge both codes
Here it is

for _,side in pairs(rs.getSides()) do -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then  -- if we find a perhiperal...
	    if peripheral.getType(side) == "monitor" then  -- then we try to identify if it's one of the peripherals we're looking for
		  mon = peripheral.wrap(side)											 -- if it's what we're looking for, we wrap it
	    elseif peripheral.getType(side) == "tank" then
		  fluidTank = peripheral.wrap(side)
	    elseif  peripheral.getType(side) == "modem" then
  if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
  local mdm = peripheral.wrap(side)							 -- temporarily wrap the modem

  for e,f in pairs(mdm.getNamesRemote()) do -- look for attached peripherals
	    if string.sub(f,1,4) == 'tank' then							  -- if we find a tank
		  fluidTank = peripheral.wrap(f)								   -- wrap it
	    elseif string.sub(f,1,7) == 'monitor' then
		  mon = perihperal.wrap(f)
		  end
	    end
	    end
	    end
    end
end
Not bad right?
Anyways I'll go on to implement this into the code
Zatilla7 #83
Posted 19 April 2014 - 02:47 PM
Well I have tried to merge them.

–fluidTank = tank
–mon = monitor
for _,side in pairs(rs.getSides()) do – this uses the redstone.getSides() call to look at each side of the computer
if peripheral.isPresent(side) then – if we find a perhiperal…
if peripheral.getType(side) == "monitor" then – then we try to identify if it's one of the peripherals we're looking for
mon = peripheral.wrap(side) – if it's what we're looking for, we wrap it
elseif peripheral.getType(side) == "tank" then
fluidTank = peripheral.wrap(side)
elseif peripheral.getType(side) == "modem" then
if not peripheral.call(side,"isWireless") then – eliminate wireless modems
local mdm = peripheral.wrap(side) – temporarily wrap the modem

for e,f in pairs(mdm.getNamesRemote()) do – look for attached peripherals
if string.sub(f,1,4) == 'tank' then – if we find a tank
fluidTank = peripheral.wrap(f) – wrap it
elseif string.sub(f,1,7) == 'monitor' then
mon = perihperal.wrap(f)
end
end
end
end
end
end
mon.setTextScale(2)
–Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
local pertable = fluidTank.getTankInfo("unknown")
local pertable1 = pertable[1]
local h = 2
for i,j in pairs(pertable1) do
mon.setCursorPos(1,h)
mon.write(tostring(i)..":"..tostring(j).." ")
h = h + 1
end
sleep(1)
until h==1000
–Credits to Dog from the computer craft forums for alot of help on debugging and bettering this code

there is a problem at line 30 though
attempt to call nil if I remember
Edited on 19 April 2014 - 01:56 PM
Dog #84
Posted 19 April 2014 - 07:17 PM
No problem. I've got some errands to run then I'll sit down and take a look at the code. Good job on giving it a try :)/>
Zatilla7 #85
Posted 19 April 2014 - 07:21 PM
Thanks.
Well I did manage the first one :3

There shouldn't be a problem with the fluidTank thing
Edited on 19 April 2014 - 06:50 PM
Dog #86
Posted 19 April 2014 - 08:56 PM
You did a great job - there were no errors in the actual code you posted - the only problem was identifying what the 'tank' was called (openblocks_tank). Here is your code with that small correction and the indentation corrected. Let me know how this works for you. Also, be sure to test it with modems/network cable to ensure that part of it works as well.


local fluidTank -- tank
local mon       -- monitor
for _,side in pairs(rs.getSides()) do                 -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then                  -- if we find a perhiperal...
    if peripheral.getType(side) == "monitor" then     -- then we try to identify if it's one of the peripherals we're looking for
      mon = peripheral.wrap(side)                     -- if it's what we're looking for, we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then
      fluidTank = peripheral.wrap(side)
    elseif  peripheral.getType(side) == "modem" then
      if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
        local mdm = peripheral.wrap(side)             -- temporarily wrap the modem
        for e,f in pairs(mdm.getNamesRemote()) do     -- look for attached peripherals
          if string.sub(f,1,15) == "openblocks_tank" then -- if we find a tank
            fluidTank = peripheral.wrap(f)            -- wrap it
          elseif string.sub(f,1,7) == "monitor" then
            mon = perihperal.wrap(f)
          end
        end
      end
    end
  end
end
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
    mon.setCursorPos(1,h)
    mon.write(tostring(i)..":"..tostring(j).."  ")
    h = h + 1
  end
  sleep(1)
until h==1000
Edited on 19 April 2014 - 06:57 PM
Zatilla7 #87
Posted 19 April 2014 - 09:42 PM
It dosn't work. Attempt to index ? (a nil value) at line 29 this time
Edited on 19 April 2014 - 07:50 PM
Dog #88
Posted 20 April 2014 - 12:37 AM
Are you using the OpenBlocks tank? If not, exactly which tank are you using?
Zatilla7 #89
Posted 20 April 2014 - 01:05 AM
rail craft ones
Dog #90
Posted 20 April 2014 - 01:58 AM
Run this and tell me what kind of tank it returns (it'll also return monitors, modems, etc. - just ignore those)


for _,side in pairs(rs.getSides()) do
  if peripheral.isPresent(side) then
    print(peripheral.getType(side))
  end
end
Zatilla7 #91
Posted 20 April 2014 - 02:11 AM
I will. But i think i should sleep now. I'll get up early and try to write some code myself
Zatilla7 #92
Posted 20 April 2014 - 02:43 AM
Well if you tell me how you searched through those modems for other peripherals
Dog #93
Posted 20 April 2014 - 06:05 AM
If you're asking how I looked at the wired modem's attached peripherals, look at the block that starts with 'for e,f, in pairs(mdm.getNamesRemote()) do' - that's what goes through the table of devices returned by the getNamesRemote call. If you mean something else, or would like further clarification; please let me know.
Zatilla7 #94
Posted 20 April 2014 - 03:41 PM
Well anyways
The code returned with "rcirontankvalvetile"
Zatilla7 #95
Posted 20 April 2014 - 03:50 PM
I tried to fix the code with these new tanks in mind.

local fluidTank -- tank
local mon	   -- monitor
for _,side in pairs(rs.getSides()) do				 -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then				  -- if we find a perhiperal...
    if peripheral.getType(side) == "monitor" then	 -- then we try to identify if it's one of the peripherals we're looking for
	  mon = peripheral.wrap(side)					 -- if it's what we're looking for, we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then
	  fluidTank = peripheral.wrap(side)
	    elseif peripheral.getType(side) == "rcirontankvalvetile" then
	  fluidTank = peripheral.wrap(side)
    elseif  peripheral.getType(side) == "modem" then
	  if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
	    local mdm = peripheral.wrap(side)			 -- temporarily wrap the modem
	    for e,f in pairs(mdm.getNamesRemote()) do	 -- look for attached peripherals
		  if string.sub(f,1,15) == "openblocks_tank" then -- if we find a tank
		    fluidTank = peripheral.wrap(f)		    -- wrap it
				 if string.sub(f,1,15) == "rcirontankvalvetile" then -- if we find a tank
		    fluidTank = peripheral.wrap(f)
		  elseif string.sub(f,1,7) == "monitor" then
		    mon = perihperal.wrap(f)
		  end
	    end
	  end
    end
  end
end
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
    mon.setCursorPos(1,h)
    mon.write(tostring(i)..":"..tostring(j).."  ")
    h = h + 1
  end
  sleep(1)
until h==1000
Unfortunally it comes back with attempt to index a nil vallue at line 34
Dog #96
Posted 20 April 2014 - 06:51 PM
OK - in an out again today (apologies) - not sure what's happening here - give me a little time to sit down with this and test it.

EDIT: I did find one error right away. On line 17 you had an 'if' where it should have been an 'elseif'. I doubt this'll fix the problem you're having (sounds like the tank isn't being identified), but you may want to try it just in case…

local fluidTank -- tank
local mon	   -- monitor
for _,side in pairs(rs.getSides()) do				 -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then				  -- if we find a perhiperal...
	if peripheral.getType(side) == "monitor" then	 -- then we try to identify if it's one of the peripherals we're looking for
	  mon = peripheral.wrap(side)					 -- if it's what we're looking for, we wrap it
	elseif peripheral.getType(side) == "openblocks_tank" then
	  fluidTank = peripheral.wrap(side)
    elseif peripheral.getType(side) == "rcirontankvalvetile" then
	  fluidTank = peripheral.wrap(side)
	elseif  peripheral.getType(side) == "modem" then
	  if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
		local mdm = peripheral.wrap(side)			 -- temporarily wrap the modem
		for e,f in pairs(mdm.getNamesRemote()) do	 -- look for attached peripherals
		  if string.sub(f,1,15) == "openblocks_tank" then -- if we find a tank
			fluidTank = peripheral.wrap(f)			-- wrap it
          elseif string.sub(f,1,15) == "rcirontankvalvetile" then -- if we find a tank
			fluidTank = peripheral.wrap(f)
		  elseif string.sub(f,1,7) == "monitor" then
			mon = perihperal.wrap(f)
		  end
		end
	  end
	end
  end
end
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
	mon.setCursorPos(1,h)
	mon.write(tostring(i)..":"..tostring(j).."  ")
	h = h + 1
  end
  sleep(1)
until h==1000
Edited on 20 April 2014 - 04:54 PM
Dog #97
Posted 20 April 2014 - 07:35 PM
OK, I can't find the problem. I tested this and it works fine for me. I made one change - I changed two of the 'elseif' statements looking for the tank into a single 'or' statement. I also found that you left the substring count at 15 when 'rcirontankvalvetile' is 19 characters long so I fixed that as well. Neither of those affected my test as I have everything directly connected.

There are still two elseif statements in the first part of the search (both related to the tank) that should be changed to an 'or' statement. Test the code 'as-is' and if it works, then make that change, test it again and let me know what happens.


local fluidTank -- tank
local mon       -- monitor
for _,side in pairs(rs.getSides()) do                 -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then                  -- if we find a perhiperal...
    if peripheral.getType(side) == "monitor" then     -- then we try to identify if it's one of the peripherals we're looking for
      mon = peripheral.wrap(side)                     -- if it's what we're looking for, we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then
      fluidTank = peripheral.wrap(side)
    elseif peripheral.getType(side) == "rcirontankvalvetile" then
      fluidTank = peripheral.wrap(side)
    elseif  peripheral.getType(side) == "modem" then
      if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
        local mdm = peripheral.wrap(side)             -- temporarily wrap the modem
        for e,f in pairs(mdm.getNamesRemote()) do     -- look for attached peripherals
          if string.sub(f,1,15) == "openblocks_tank" or string.sub(f,1,19) == "rcirontankvalvetile" then -- if we find a tank
            fluidTank = peripheral.wrap(f)            -- wrap it
          elseif string.sub(f,1,7) == "monitor" then
            mon = perihperal.wrap(f)
          end
        end
      end
    end
  end
end
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
    mon.setCursorPos(1,h)
    mon.write(tostring(i)..":"..tostring(j).."  ")
    h = h + 1
  end
  sleep(1)
until h==1000
Edited on 20 April 2014 - 05:36 PM
Zatilla7 #98
Posted 20 April 2014 - 08:20 PM
Well the code works. But it acts wierd with build craft tanks
Dog #99
Posted 20 April 2014 - 08:24 PM
How does it act weird? More detail, please :)/>
Zatilla7 #100
Posted 20 April 2014 - 08:26 PM
attempt to index a nil value at line 31
Dog #101
Posted 20 April 2014 - 08:42 PM
OK, it sounds like you don't have a 'valid' railcraft tank built. Can you right click on the tank and see the tank GUI?

For reference - Railcraft - Iron Tank
Edited on 20 April 2014 - 08:21 PM
Zatilla7 #102
Posted 21 April 2014 - 12:47 PM
No it works fine with Rail-Craft tanks.
Not with build craft tanks
(Those built out of 8 glass)
Dog #103
Posted 21 April 2014 - 12:55 PM
If you run that program I sent you earlier, adding Buildcraft tanks to your program should be easy (once you know what they're called). I'm ready to help if you'd like :)/>
Zatilla7 #104
Posted 21 April 2014 - 01:00 PM
Ok
Dog #105
Posted 21 April 2014 - 01:09 PM
In fact, with 3 types of tanks to look for, it makes sense to move the tank 'types' into a table and use that for reference in the tank search. This would also make adding future tank types easier. If you'd like to do that, post your current code and we'll make it happen :)/> It's 5AM here, so my reply may be a bit delayed as I'm going to grab some shuteye.
Zatilla7 #106
Posted 21 April 2014 - 02:37 PM
wat?
anyways the code returned with
net_minecraft_src_buildcraft_factory_tiletank
Dog #107
Posted 21 April 2014 - 03:07 PM
Right now your program is looking for OpenBlocks tanks and Railcraft tanks; adding BuildCraft tanks will make it 3 types of tanks we are looking for (or we can remove OpenBlocks support if you don't use that).

Now that you know what the BuildCraft tanks are called (net_minecraft_src_buildcraft_factory_tiletank) you should be able to add them yourself. Or I can show you how putting that information in a table (and using a loop to check for each type of tank) will make it easier for you to add additional types of tanks in the future (without the code getting messy).

It's completely up to you :)/> As always, which ever direction you choose, I'll be happy to help!
Edited on 21 April 2014 - 01:08 PM
Zatilla7 #108
Posted 21 April 2014 - 07:49 PM
I think I will take the way that will make it easier to add types.
And I have no idea how to do that
Dog #109
Posted 21 April 2014 - 07:52 PM
No problem. Post your code as it is now and we'll get started :)/>
Zatilla7 #110
Posted 21 April 2014 - 08:10 PM
Sure. I think mc is down though


local fluidTank -- tank
local mon	   -- monitor
for _,side in pairs(rs.getSides()) do				 -- this uses the redstone.getSides() call to look at each side of the computer
  if peripheral.isPresent(side) then				  -- if we find a perhiperal...
    if peripheral.getType(side) == "monitor" then	 -- then we try to identify if it's one of the peripherals we're looking for
	  mon = peripheral.wrap(side)					 -- if it's what we're looking for, we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then
	  fluidTank = peripheral.wrap(side)
    elseif peripheral.getType(side) == "rcirontankvalvetile" then
	  fluidTank = peripheral.wrap(side)
    elseif  peripheral.getType(side) == "modem" then
	  if not peripheral.call(side,"isWireless") then  -- eliminate wireless modems
	    local mdm = peripheral.wrap(side)			 -- temporarily wrap the modem
	    for e,f in pairs(mdm.getNamesRemote()) do	 -- look for attached peripherals
		  if string.sub(f,1,15) == "openblocks_tank" or string.sub(f,1,19) == "rcirontankvalvetile" then -- if we find a tank
		    fluidTank = peripheral.wrap(f)		    -- wrap it
		  elseif string.sub(f,1,7) == "monitor" then
		    mon = perihperal.wrap(f)
		  end
	    end
	  end
    end
  end
end
mon.setTextScale(2)
--Change the number in the parathanses up top to chose what size text you want(Goes up to 5)
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat
  local pertable = fluidTank.getTankInfo("unknown")
  local pertable1 = pertable[1]
  local h = 2
  for i,j in pairs(pertable1) do
    mon.setCursorPos(1,h)
    mon.write(tostring(i)..":"..tostring(j).."  ")
    h = h + 1
  end
  sleep(1)
until h==1000
Dog #111
Posted 21 April 2014 - 08:41 PM
OK, we need to do two things. We need to create a table and we need to create a loop to parse the table.

Before we get started, watch the first six and half minutes of this excellent tutorial by DireWolf20 and see if you can construct a table that includes just the tank types and a loop to parse the table for its data. Don't try to integrate it into your code yet, just post what you come up with and we'll go from there.
Zatilla7 #112
Posted 21 April 2014 - 08:54 PM
I get the idea but not how to implement it
Dog #113
Posted 21 April 2014 - 08:57 PM
FWIW, in the tutorial, he actually writes a table and loop exactly as we need it - so keep that in mind for reference.

Let's start with the table. Simply make a table that has all the tank names in it and post that (just the table).

e.g.

local tankList = { "tankType1", "tankType2", "tankType3", }
Edited on 21 April 2014 - 06:59 PM
Zatilla7 #114
Posted 21 April 2014 - 09:05 PM

local tankList = { "openblocks_tank", "rcirontankvalvetile", "net_minecraft_src_buildcraft_factory_tiletank" }
Dog #115
Posted 21 April 2014 - 09:10 PM
Yes! Based on that table, what would the value of tankList[2] be?

Next we'll cover the '#' operator and get into creating the loop.
Edited on 21 April 2014 - 07:14 PM
Zatilla7 #116
Posted 21 April 2014 - 09:15 PM
rcirontankvalvetile
Zatilla7 #117
Posted 21 April 2014 - 09:21 PM
Anyways. I'm gonna have to go for the night
Dog #118
Posted 21 April 2014 - 09:25 PM
Excellent. Tables aren't a mysterious once you start to mess around with them. Tables actually have a key and value for each 'entry' in the table. Since we're using an ordered table the keys are simply 1,2,3,4,etc. - we don't see them, but they are created in order as needed and will always start with 1. The values are the tank names. So we ask for the value of an assigned key by querying that key. e.g. tankList[2] is the second key and thus holds the second value in the table.

Before we start the loop, let's take a brief look at the '#' operator. This is a really handy tool for finding the length of things. # will return the length of a string or the number of items in a table (it's 'length'). For example, if we did this:

local tankList = { "openblocks_tank", "rcirontankvalvetile", "net_minecraft_src_buildcraft_factory_tiletank" }
local numberOfTanks = #tankList
What would the value of numberOfTanks be?

and if we did this:

local numberOfLetters = #tankList[2]
What would the value of numberOfLetters be?

Knowing this will make creating the loop much, much easier.

EDIT: No problem - get some sleep. We'll continue when you're ready :)/>
Edited on 21 April 2014 - 07:26 PM
Zatilla7 #119
Posted 22 April 2014 - 08:21 AM
I'm back. But I will be a bit in and out today.
Oh and numberOfTanks = 3
numberOfLetters = 19
Dog #120
Posted 22 April 2014 - 08:33 AM
Correct answers…again :)/>

I'm heading to bed soon, so it looks like we're going to miss each other today/tonight. However, all that's left is the loop. Using DireWolf20's example, try to put together a loop for querying the table you made. Don't integrate it into the code yet, just go for the loop and post it. Once that is worked out, we'll integrate it into the code and you'll have a tank monitor that supports multiple tank types and is relatively easy to maintain and edit!
Zatilla7 #121
Posted 22 April 2014 - 08:54 AM
Alright. One last thing that I would also like to put into the code will be the abillity to support multiple tanks.
Well good night
Zatilla7 #122
Posted 29 April 2014 - 09:58 PM
Altough that may be a bit too much for now
Dog #123
Posted 29 April 2014 - 10:27 PM
Multiple tanks is doable, it's just a little more work (another table and another loop or two). First, let's focus on making the loop (based on DireWolf20's example or my example below) that parses the table of tanks. Once we have that we can integrate it into the current code.

A basic 'for' loop looks like this:

for i = 1,<some number> do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == **what we are looking for** then  -- if table entry 'i' == **what we are looking for** then
    ** do something **  -- do what we need to do
  end
end

The real trick is knowing what <some number> should be. Using the '#' operator, replace <some number> with the proper syntax to parse all the entries in 'thisTable'.

Once you have that down, constructing a simple loop to parse the tank list will simply be a matter of replacing our variables with the ones in the above example.
Edited on 30 April 2014 - 07:35 PM
Dog #124
Posted 30 April 2014 - 09:18 PM
I went through the code, added some comments, and renamed some of the variables (so they make more sense and are easier to track). I also replaced part of the code that looks for network attached peripherals (it no longer temporarily wraps the wired modem, which was completely unnecessary - it now uses peripheral.call to bypass the need for wrapping the modem).

Take a look at the changes I made, and if you're happy with them, let's use this as our current 'base'…
pastebin Jdfd0T1X

--[[ Tank Monitor ]]--
local fluidTank -- tank
local mon       -- monitor
for _,side in pairs(rs.getSides()) do                             -- this calls redstone.getSides() to look at each side of the computer
  if peripheral.isPresent(side) then                              -- if we find a perhiperal, we then try to identify if it's one of the peripherals we're looking for...
    if peripheral.getType(side) == "monitor" then                 -- if we find a monitor...
      mon = peripheral.wrap(side)                                 -- ...we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then     -- if we find an openblocks tank...
      fluidTank = peripheral.wrap(side)                           -- ...wrap it
    elseif peripheral.getType(side) == "rcirontankvalvetile" then -- if we find a railcraft iron tank...
      fluidTank = peripheral.wrap(side)                           -- ...wrap it
    elseif peripheral.getType(side) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a buildcraft tank...
      fluidTank = peripheral.wrap(side)                           -- ...wrap it
    elseif  peripheral.getType(side) == "modem" then              -- if we find a modem, we...
      if not peripheral.call(side,"isWireless") then              -- ...eliminate wireless modems and...
        for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals
          if string.sub(device,1,15) == "openblocks_tank" or string.sub(device,1,19) == "rcirontankvalvetile" or string.sub(device,1,45) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a tank...
            fluidTank = peripheral.wrap(device)                   -- ...wrap it
          elseif string.sub(device,1,7) == "monitor" then         -- if we find a monitor...
            mon = peripheral.wrap(device)                         -- ...wrap it
          end
        end
      end
    end
  end
end
mon.setTextScale(2) -- valid text scales are 0.5, 1, 2, 3, 4, 5
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat                                                    -- do the following repeatedly until we match the 'until' parameter
  local tankInfo = fluidTank.getTankInfo("unknown")       -- get tank's info
  local tankStats = tankInfo[1]                           -- take just the table of info we want from the info returned by the tank
  local yPos = 2                                          -- set cursor Y position variable
  for k,v in pairs(tankStats) do                          -- start parsing the tank's information table
    mon.setCursorPos(1,yPos)                              -- set cursor position
    mon.write(tostring(k) .. ": " .. tostring(v) .. "  ") -- display key and value information for tank
    yPos = yPos + 1                                       -- increment cursor Y position variable
  end
  sleep(1)                                                -- sleep for 1 second before refreshing the tank info
until yPos == 1000                                        -- if our cursor Y position variable ever == 1000 we end

As you can see - trying to find even 3 tank types with 'if/or/then' can get difficult to read and maintain. The next step is to take the loop you create and integrate the loop and table into this code so you can add and remove tank types in one location. We'll also make some changes to some of the other code to take into account the new table. But first, just post the loop and we'll make sure we have it ready to put into the main program.
Edited on 08 May 2014 - 07:48 PM
Zatilla7 #125
Posted 01 May 2014 - 12:36 PM

for i = 1,#thisTable do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == **what we are looking for** then  -- if table entry 'i' == **what we are looking for** then
	fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end
Thats all I got…
Edited on 01 May 2014 - 10:40 AM
Dog #126
Posted 01 May 2014 - 09:04 PM

for i = 1,#thisTable do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == **what we are looking for** then  -- if table entry 'i' == **what we are looking for** then
	fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end
Thats all I got…
That's a good start. In this case, **what we are looking for** is the peripheral on that side - so we use peripheral.getType(side) to get the name of the device and compare it to what is in our table.

I realize how trivial some of the things I'm having you do seem, but I'm hoping with more hands on you will get more comfortable and familiar with the code.

With that, combine the info I gave you into the loop, then we'll merge the loop into your current program. Before we can merge the loop, though, we need to identify what code is being replaced. When you post the new loop, also post the chunk(s) of code you think will be replaced with our new loop.
Zatilla7 #127
Posted 01 May 2014 - 09:20 PM

for i = 1,#thisTable do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == side**what we are looking for** then  -- if table entry 'i' == **what we are looking for** then
	    fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end
And the code to be removed…

    elseif peripheral.getType(side) == "openblocks_tank" then	 -- if we find an openblocks tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
    elseif peripheral.getType(side) == "rcirontankvalvetile" then -- if we find a railcraft iron tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
    elseif peripheral.getType(side) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a buildcraft tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
 
About right?
Dog #128
Posted 01 May 2014 - 11:37 PM
I'm going to cover more than one thing in the following, so don't try to do it all at once. Take it a step at a time and if you have questions, let me know :)/>

for i = 1,#thisTable do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == side**what we are looking for** then  -- if table entry 'i' == **what we are looking for** then
	fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end

Instead of 'side**what we are looking for **', I was trying to describe this…

for i = 1,#thisTable do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if thisTable[i] == peripheral.getType(side) then  -- if table entry 'i' == **what we are looking at** then
	fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end
Note that I changed one word in one of the comments. Instead of **what we are looking for**, it now reads **what we are looking at**. My apologies for making that mistake. **what we are looking for** is represented by thisTable

Then we replace 'thisTable' with our list of tanks to complete the loop. Instead of tankList, I'm going to call our list of tanks 'validTanks' (this will make sense a little later)

validTanks = { "openblocks_tank", "rcirontankvalvetile", "net_minecraft_src_buildcraft_factory_tiletank", }
for i = 1,#validTanks do  -- we start our loop by counting from 1 (since 1 is the lowest entry number in Lua tables) - we use 'i' for our counting variable (our 'index')
  if validTanks[i] == peripheral.getType(side) then  -- if table entry 'i' == **what we are looking for** then
	fluidTank = peripheral.wrap(side)  -- do what we need to do
  end
end

You may have noticed that I put a comma after the last entry in validTanks. This is not required, but it is valid syntax and there is a good reason to get into the habit of doing it in ComputerCraft. So long as you *always* put a comma after every value in a table you'll avoid a lot of problems. Keys are followed by '=' and values are followed by ','

We now have our first of two loops. The loop for checking the sides of the computer is done. Now we need to move on to the loop for checking network attached peripherals…

And the code to be removed…
You missed the part where we look for network connected peripherals…

if string.sub(device,1,15) == "openblocks_tank" or string.sub(device,1,19) == "rcirontankvalvetile" or string.sub(device,1,45) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a tank...
fluidTank = peripheral.wrap(device)				   -- ...wrap it

This is a bit trickier and I'm not sure how to describe it, so I'm going to give you a basic framework and have you 'fill in the blanks'…

for i = 1, #validTanks do					 -- first we look for tanks (we re-use 'i' since we're done with it above)
  if validTanks[i] == string.sub(device,1, <we need a length to check here> ) then -- if we find a tank that is in the validTanks table...
	fluidTank = peripheral.wrap(device)		  -- ...we wrap it
  end
end

In the above code, we're using string.sub to find a substring (just a piece of the string/name). The syntax of string.sub is

string.sub(<string to check>,<start position>,<end position - optional>)
Our <string to check> is 'device' - the variable that holds the name of the peripheral we are currently looking at. Our starting position is 1, and our length should equal the length of the table entry (since we are trying to match our table entries).

Replace <we need a length to check here> with the proper syntax to check the length of the table entry we are comparing. You'll want to use the '#' operator.

Once that's done, we can revisit our main code and get it ready for our new code.
Edited on 01 May 2014 - 09:42 PM
Zatilla7 #129
Posted 01 May 2014 - 11:46 PM

string.sub(<#validTanks>,<1>,<#validTanks>)
No idea what I did there
Dog #130
Posted 01 May 2014 - 11:50 PM

string.sub(<#validTanks>,<1>,<#validTanks>)
No idea what I did there

Yeah - that's not what we want. Remember - we want to keep 'device' - that's the string we are comparing to our table entry. And you don't need the '<>' - I only put those there to show that those statements needed to be replaced. You're close…give it another try :)/>
Zatilla7 #131
Posted 01 May 2014 - 11:52 PM

string.sub(#validTanks,1,[size=4]7)[/size]
Like that?
Dog #132
Posted 02 May 2014 - 02:05 AM
Nope. Remember - everything was as it should be, you just needed to provide the length we are checking.

In your example you aren't looking at a string at all. You'd be trying to look at #validTanks which would return a number, then your starting position would be one, and your end position would be 7. Since we're actually trying to compare a substring of 'device' to validTanks, not every value is going to be 7 characters long. To clarify: We want to compare a substring of the value stored in our variable named 'device' to our validTanks value.

Here is the substring syntax again:

string.sub(<string to check>,<start position>,<end position - optional>)

It's important to note that without specifying an end position, string.sub will go to the end of the string. We want to ignore the end of the strings we'll be comparing, which I'll explain shortly - this means, however, that 'end position' is not optional for us.

The following loop uses peripheral.call to access the available methods of a peripheral without wrapping the peripheral. We are making this call because we've found a modem and verified that it is not a wireless modem. The call we are making is 'getNamesRemote' and the side is the current side we are looking at (represented by 'side').

Using this loop…

for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals
…we set 'device' = each value returned by getNamesRemote() in the order they are returned. We are using '_' for the key because we don't care about the keys, we only care about the values returned ('_' is commonly used as a throwaway variable name).

Using this loop inside the above loop…

for i = 1, #validTanks do					   -- first we look for tanks (we re-use 'i' since we're done with it above)
  if validTanks[i] == device then -- if validTanks table entry 'i' == device
	fluidTank = peripheral.wrap(device)		 -- ...we wrap it
  end
end
…we try to match each value assigned to 'device' to a corresponding value in validTanks (our table of tanks we are using for comparison)

The values returned by getNamesRemote() will be strings like "monitor_0" and "openblocks_tank_10" which presents a problem. We don't want to have to create a table with "openblocks_tank", "openblocks_tank_0", openblocks_tank_1", etc.

The solution is to ignore the end of the string that is returned by getNamesRemote() (we want to compare "openblocks_tank" to our list, not "openblocks_tank_10") thus we need to define an end position for string.sub.

So, instead of comparing 'device' to validTanks, what we really want to do is compare a substring of the value held in our variable 'device' to the value in validTanks and see if they match.

New problem. Since validTanks could be any value in the validTanks table we can't use a specific number for an end position as the string length will be different with each entry.

For example:

If validTanks == "rcirontankvalvetile", then the string length is 19 (19 characters in 'rcirontankvalvetile').
However, if validTanks == "openblocks_tank" then the string length is 15.

In order to know the length of the substring we need to take from 'device' we need to know the length of validTanks regardless of what value it holds.

Back to the example I gave you.

for i = 1, #validTanks do										-- first we look for tanks (we re-use 'i' since we're done with it above)
  if validTanks[i] == string.sub(device,1, <we need a length to check here> ) then -- if we find a tank that is in the validTanks table...
	fluidTank = peripheral.wrap(device)			   -- ...we wrap it
  end
end

Replace <we need a length to check here> with the length you think we should be using.
Edited on 02 May 2014 - 02:39 AM
Zatilla7 #133
Posted 02 May 2014 - 12:21 PM

for i = 1, #validTanks do																			   -- first we look for tanks (we re-use 'i' since we're done with it above)
  if validTanks[i] == string.sub(device,1,#validTanks[i] ) then -- if we find a tank that is in the validTanks table...
	    fluidTank = peripheral.wrap(device)					    -- ...we wrap it
  end
end
Sounds about right?
Dog #134
Posted 02 May 2014 - 06:59 PM
That's it. Now, before we continue I'd like to pause so you have an opportunity to ask any questions or address anything that you're unsure about. Feel free to ask whatever. When you're ready, we'll continue :)/>
Zatilla7 #135
Posted 02 May 2014 - 08:25 PM
Well the only thing really is how sub string works
Dog #136
Posted 02 May 2014 - 09:04 PM
What about string.sub confuses you? Is it the syntax, the whole concept, ??? If you're not sure, that's not a problem - we can go over string.sub until you're comfortable with it.

Here are the basics:

Part 1:
string.sub *requires* two values - the string you want to 'sub' (take a piece of) and the starting position.

e.g.

local newWord = string.sub("Testing",3)

This will take a substring of the string "Testing" starting at the 3rd character ("s") and assign the value to the variable newWord. Thus the value in newWord would be "sting"

Another example

local testString = "This is a test"
local myString = string.sub(testString,5)

In this example, we have a variable named testString that is holding the string "This is a test". We set myString to equal (hold the value of) a substring of testString, starting at the 5th character. Therefor, myString would = " is a test"

You'll notice that the first character in the string is a space, because that's the fifth character in testString.

Part 2:
Although string.sub *requires* two values, it can actually take 3 values - the third being the ending position of a substring.

e.g.

local testString = "This has four words"
local answerString = string.sub(testString,10,14)

Here we are looking for a substring of testString, starting at the 10th character and ending at the 14th character. The 10th character is "f" and the 14th character is "r" - so we take everything from the 10th character to the 14th character and answerString will = "four".

So when we parse our returned list of devices, we are trying to match our validTanks table entry to a substring of the returned device.

If the returned device name is "rcirontankvalvetile_5" we don't care about the "_5", we just want to match the name to our list of entries. The way we do that is limit our comparison to a substring of the returned name.

With this code…

if validTanks[i] == string.sub(device,1,#validTanks[i])

What we are doing here is comparing what is in validTanks with a substring of the value in the variable 'device'. We want to start at the first character and end at the last character of our validTanks entry. How does this play out?

If device = "rcirontankvalvetile_5" and validTanks == "openblocks_tank" we aren't going to have a match. #validTanks would return 15 (the length of "openblocks_tank") and we would be looking at characters 1-15 of device, which would return "rcirontankvalve". They wouldn't match.

But…as we loop through our validTanks list we will eventually come across "rcirontankvalvetile". When we do the same comparison we get a different result this time.

#validTanks will = 19 this time so our substring would start at the first character and end at the 19th character. Our substring of "rcirontankvalvetile_5" would return "rcirontankvalvetile" and we would have a match.

The syntax for string.sub is

string.sub(<string to sub>,<starting position>,<ending position>)

I hope that clarifies string.sub (and substrings in general) for you. If not, please don't hesitate to let me know. I'm here to help you learn :)/>
Zatilla7 #137
Posted 02 May 2014 - 09:33 PM
Well that explains it

Alright so shall we finish the code?
Dog #138
Posted 02 May 2014 - 10:20 PM
OK. Let's move on. Our next task is to replace our 'old' code with our 'new' code. Let's start with our program minus the 'old' code…

--[[ Tank Monitor ]]--
local fluidTank -- tank
local mon       -- monitor
for _,side in pairs(rs.getSides()) do                             -- this calls redstone.getSides() to look at each side of the computer
  if peripheral.isPresent(side) then                              -- if we find a perhiperal, we then try to identify if it's one of the peripherals we're looking for...
    if peripheral.getType(side) == "monitor" then                 -- if we find a monitor...
      mon = peripheral.wrap(side)                                 -- ...we wrap it


    elseif  peripheral.getType(side) == "modem" then              -- if we find a modem, we...
      if not peripheral.call(side,"isWireless") then              -- ...eliminate wireless modems and...
        for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals


          elseif string.sub(device,1,7) == "monitor" then         -- if we find a monitor...
            mon = peripheral.wrap(device)                         -- ...wrap it
          end
        end
      end
    end
  end
end

*** rest of program***

Without the 'old' code we have code that won't work. Putting our 'new' code into this code will do us no good until we get the current code working. What changes would you make to get this code working again?
Edited on 08 May 2014 - 07:47 PM
Zatilla7 #139
Posted 02 May 2014 - 10:30 PM
I have no idea what you mean
Dog #140
Posted 02 May 2014 - 10:43 PM
We removed all of our tank finding code in order to replace it with the table and loops we created. But, by removing the old code, we've broken the program. Before adding code to a broken program (and possibly introducing more problems) we need to fix our current code so it will work on its own. Once we have the program working again, then we will add our new code (our table and loops). This will make troubleshooting any problems we encounter a lot easier.

Here is the entire program, minus to old tank finding code. Before we can add our new tank finding code we need to fix the program so it works (it won't work as it is). Feel free to run the code and see what happens. Then show me how you would fix the code so it works again (without the tank finding code).


--[[ Tank Monitor ]]--
local fluidTank -- tank
local mon       -- monitor
for _,side in pairs(rs.getSides()) do                             -- this calls redstone.getSides() to look at each side of the computer
  if peripheral.isPresent(side) then                              -- if we find a perhiperal, we then try to identify if it's one of the peripherals we're looking for...
    if peripheral.getType(side) == "monitor" then                 -- if we find a monitor...
      mon = peripheral.wrap(side)                                 -- ...we wrap it


    elseif peripheral.getType(side) == "modem" then               -- if we find a modem, we...
      if not peripheral.call(side,"isWireless") then              -- ...eliminate wireless modems and...
        for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals


          elseif string.sub(device,1,7) == "monitor" then         -- if we find a monitor...
            mon = peripheral.wrap(device)                         -- ...wrap it
          end
        end
      end
    end
  end
end
term.clear()
mon.clear()
mon.setTextScale(2)    -- valid text scales are 0.5, 1, 2, 3, 4, 5
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat                                                    -- do the following repeatedly until we match the 'until' parameter
  local tankInfo = fluidTank.getTankInfo("unknown")       -- get tank's info
  local tankStats = tankInfo[1]                           -- take just the table of info we want from the info returned by the tank
  local yPos = 2                                          -- set cursor Y position variable
  for k,v in pairs(tankStats) do                          -- start parsing the tank's information table
    mon.setCursorPos(1,yPos)                              -- set cursor position
    mon.write(tostring(k) .. ": " .. tostring(v) .. "  ") -- display key and value information for tank
    yPos = yPos + 1                                       -- increment cursor Y position variable
  end
  sleep(1)                                                -- sleep for 1 second before refreshing the tank info
until yPos == 1000                                        -- if our cursor Y position variable ever == 1000 we end
Edited on 08 May 2014 - 07:45 PM
Zatilla7 #141
Posted 02 May 2014 - 10:48 PM
I will do that tomorrow

I need to sleep
Dog #142
Posted 02 May 2014 - 10:49 PM
No prob. Talk to you then :)/>
Zatilla7 #143
Posted 02 May 2014 - 10:57 PM
Good night
empty789 #144
Posted 03 May 2014 - 08:05 PM
hi,

is there a way to use your code with "Dynamic liquid tanks 2" ? i really like their tanks and they look way better than the others :)/>

I tried many things to get it to work, no chance… but i have to say my cc knowledge is not that big, i got the basic understanding and coding.

The peripheralname your testcode gives is "dynamictanks_tile_controllertile"


edit: i think i made a dumb mistake, but now its working…


Another thing i dont understand is how i can print out for example only the amount of the tank.


local tankInfo = fluidTank.getTankInfo("unknown")	   -- get tank's info
  local tankStats = tankInfo[1]						   -- take just the table of info we want from the info returned by the tank
  local yPos = 2										  -- set cursor Y position variable
  local k,v											   -- localize our variables (using k &amp; v for 'key' and 'value')
  for k,v in pairs(tankStats) do						  -- start parsing the tank's information table
	mon.setCursorPos(1,yPos)							  -- set cursor position
	mon.write(tostring(k) .. ": " .. tostring(v) .. "  ") -- display key and value information for tank
	yPos = yPos + 1									   -- increment cursor Y position variable
  end

I know you use a for loop to print it, but i dont really understand how this works to get the table content printed.

By the way, thanks for your detailed thread/answers so i can learn new things :)/>
thanks for your help
Edited on 03 May 2014 - 06:25 PM
Dog #145
Posted 06 May 2014 - 06:16 AM
Hi empty789 - apologies for the late response; I didn't see your post :/

The for loop we're using here asks for information to be returned in pairs (2 pieces of information with each answer). So we set two variables (in this case, k &amp; v) to capture the two pieces of information returned from tankStats. Basically, Lua tables store information in pairs - a key and a value.

In an ordered table the key is always a number.

local table1 = { "first", "second", "third", "fourth" }

is the same as

local table1 = { [1] = "first", [2] = "second", [3] = "third", [4] = "fourth" }

The table that our variable tankStats points to is not an ordered table (and the name escapes me atm). We want to see both the key and value in this table so we use 'pairs' in our 'for' loop

for k,v in pairs(tankStats) do
  mon.setCursorPos(1,yPos)
  mon.write(tostring(k) .. ": " .. tostring(v) .. "  ")
  yPos = yPos + 1
end

With each iteration of the loop our table will return a key to 'k' and a value to 'v'. The first key returned is 'rawName' and the value returned is the name of the fluid in the tank. To see just the rawName you do something like this

mon.write(tankStats.rawName)

Now, take a look at the other keys and values returned in the tank monitor program (you were interested in the amount) and see if you can figure out how you'd look at the amount in the tank.

If you have any questions or need further assistance, I'm happy to help :)/>
Edited on 08 May 2014 - 07:29 PM
empty789 #146
Posted 09 May 2014 - 07:13 PM
Thank you very much! This helped me a lot and its working now :)/>
Zatilla7 #147
Posted 13 May 2014 - 04:06 PM
And I'm back. Sorry I had alot of tests to do and had to study
Zatilla7 #148
Posted 07 November 2014 - 08:27 PM
Alright, Let's get back into this


--[[ Tank Monitor ]]--
local fluidTank -- tank
local mon	   -- monitor
for _,side in pairs(rs.getSides()) do							 -- this calls redstone.getSides() to look at each side of the computer
  if peripheral.isPresent(side) then							  -- if we find a perhiperal, we then try to identify if it's one of the peripherals we're looking for...
    if peripheral.getType(side) == "monitor" then				 -- if we find a monitor...
	  mon = peripheral.wrap(side)								 -- ...we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then	 -- if we find an openblocks tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
    elseif peripheral.getType(side) == "rcirontankvalvetile" then -- if we find a railcraft iron tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
    elseif peripheral.getType(side) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a buildcraft tank...
	  fluidTank = peripheral.wrap(side)						   -- ...wrap it
    elseif  peripheral.getType(side) == "modem" then			  -- if we find a modem, we...
	  if not peripheral.call(side,"isWireless") then			  -- ...eliminate wireless modems and...
	    for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals
		  if string.sub(device,1,15) == "openblocks_tank" or string.sub(device,1,19) == "rcirontankvalvetile" or string.sub(device,1,45) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a tank...
		    fluidTank = peripheral.wrap(device)				   -- ...wrap it
		  elseif string.sub(device,1,7) == "monitor" then		 -- if we find a monitor...
		    mon = peripheral.wrap(device)						 -- ...wrap it
		  end
	    end
	  end
    end
  end
end
mon.setTextScale(2) -- valid text scales are 0.5, 1, 2, 3, 4, 5
mon.clear()
mon.setCursorPos(1,1)
mon.write("Tank 1:")
repeat												    -- do the following repeatedly until we match the 'until' parameter
  local tankInfo = fluidTank.getTankInfo("unknown")	   -- get tank's info
  local tankStats = tankInfo[1]						   -- take just the table of info we want from the info returned by the tank
  local yPos = 2										  -- set cursor Y position variable
  for k,v in pairs(tankStats) do						  -- start parsing the tank's information table
    mon.setCursorPos(1,yPos)							  -- set cursor position
    mon.write(tostring(k) .. ": " .. tostring(v) .. "  ") -- display key and value information for tank
    yPos = yPos + 1									   -- increment cursor Y position variable
  end
  sleep(1)											    -- sleep for 1 second before refreshing the tank info
until yPos == 1000									    -- if our cursor Y position variable ever == 1000 we end

So as you said, Let's use this as a base. There seems to be an "Atempt to call nil" Issue at line 32 though
Dog #149
Posted 07 November 2014 - 09:16 PM
That's odd - I've tested that code and it worked fine for me.

If I'm counting correctly, line 32 is

local tankInfo = fluidTank.getTankInfo("unknown")

The only reason I know of that would cause the error your seeing would be because the method getTankInfo() is no longer available. That would only happen if you're using a different version of OpenPeripherals now than you were before. What versions of ComputerCraft and OpenPeripherals are you using now? What kind of tank are you using, and what version is that mod? Odds are you'll need to query a tank to get the available methods and update the script with the 'new/replacement' methods. Then we'll have to see if the data being returned is the same.
Edited on 07 November 2014 - 08:21 PM
Zatilla7 #150
Posted 07 November 2014 - 10:03 PM
For the moment I'm using:

Computer Craft: 1.6

Open Peripheral Core: 0.5.0

Open Peripheral Addons: 0.2.0

A tank from Buildcraft 6.1.3
Dog #151
Posted 07 November 2014 - 10:39 PM
Which ComputerCraft 1.6? 1.63? 1.64? 1.65?
Zatilla7 #152
Posted 07 November 2014 - 11:14 PM
1.6
Dog #153
Posted 07 November 2014 - 11:21 PM
I realize it's 1.6, but *which* 1.6? 1.63, 1.64 or 1.65?
Zatilla7 #154
Posted 07 November 2014 - 11:34 PM
Just 1.6
Dog #155
Posted 07 November 2014 - 11:52 PM
My apologies for the misunderstanding. If you're using ComputerCraft 1.6 (MC 1.6.4) then I'd recommend updating to ComputerCraft 1.63.

Also, according to the OpenMods website, the correct version of OpenPeripheralCore for MC 1.6.4 is 0.41, not 0.50 - OpenModsLib should be 0.51 and OpenPeripheral Addons should be 0.15 not 0.20.

Based on your version numbers, I have to ask - are you using MC 1.6.4 or MC 1.7.2 or MC 1.7.10?

With the getTankInfo() method no longer available, it'll take me a little time to gather the versions of the mods you're using so I can find the new methods. You can use the Lua prompt to discover the available methods yourself using peripheral.getMethods("side") where "side" is a string like "left", "right", "top", etc.
Edited on 07 November 2014 - 11:08 PM
Zatilla7 #156
Posted 08 November 2014 - 12:07 AM
Alright Thanks, I am currently using the newly updated direwolf20 pack which uses unstable mods(I think). Right now it's 1.7.10
Edited on 07 November 2014 - 11:07 PM
Dog #157
Posted 08 November 2014 - 12:16 AM
If you're on 1.7.10 then you aren't using ComputerCraft 1.6 - 1.6 is for MC 1.6.4. With MC 1.7.10, you're most likely using either CC 1.64 or CC 1.65 (there were some pre-releases for 1.64 but they were beta releases). Additionally, the OpenMods versions you provided didn't include the snapshot numbers (which I need to duplicate your setup). Please try to ensure the accuracy of your answers - I can't really help you if I have incomplete or inaccurate information.

It's my understanding that OpenPeripherals snapshots don't work right (if at all) in 1.7.10 so we may not be able to get this working with your current mod pack. I'll download the versions of the mods you're using and see if I can verify whether it works or not. First, please provide the snapshot numbers for your OpenMods files so I can work with the same versions you have.

EDIT: Unless OpenPerihperal AddOns contains support for the tanks, this won't work in 1.7.10 - read the WARNING statement on this page http://openmods.info...PeripheralCore/
Based on the 'attempt to call nil' error, I have the feeling that AddOns doesn't have what we need.
Edited on 08 November 2014 - 01:22 AM
Zatilla7 #158
Posted 08 November 2014 - 05:04 PM
I see, for the moment I've tried using the code in the newly updated 1.7.10 Direwolf pack. I'll be going back to the 1.6.4 packs so that when it mod is fully updated, it will work. Alright?

Edit: Also I'm plaining on trying to edit the code so that it will only say "Tank 1" when it finds one and "No tanks found" if it didn't find one.
Edited on 08 November 2014 - 04:08 PM
Dog #159
Posted 08 November 2014 - 05:19 PM
Those both sound like great ideas to implement - go for it! I (or somebody) will help you out if you get stuck.

Since OpenP doesn't have proper support for many things in MC 1.7.10 atm, MC 1.6.4 sounds like the best target for now.
Zatilla7 #160
Posted 08 November 2014 - 05:55 PM
I tried editing this. For the moment I don't have computer craft. Could you see if this seems good?

I put –Edited where I started to edit and –Edit finish where I finished to edit


--[[ Tank Monitor ]]--
local fluidTank -- tank
local mon		  -- monitor
for _,side in pairs(rs.getSides()) do												    -- this calls redstone.getSides() to look at each side of the computer
  if peripheral.isPresent(side) then													  -- if we find a perhiperal, we then try to identify if it's one of the peripherals we're looking for...
    if peripheral.getType(side) == "monitor" then							    -- if we find a monitor...
		  mon = peripheral.wrap(side)														    -- ...we wrap it
    elseif peripheral.getType(side) == "openblocks_tank" then    -- if we find an openblocks tank...
		  fluidTank = peripheral.wrap(side)											    -- ...wrap it
    elseif peripheral.getType(side) == "rcirontankvalvetile" then -- if we find a railcraft iron tank...
		  fluidTank = peripheral.wrap(side)											    -- ...wrap it
    elseif peripheral.getType(side) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a buildcraft tank...
		  fluidTank = peripheral.wrap(side)											    -- ...wrap it
    elseif  peripheral.getType(side) == "modem" then					  -- if we find a modem, we...
		  if not peripheral.call(side,"isWireless") then						  -- ...eliminate wireless modems and...
		    for _,device in pairs(peripheral.call(side,"getNamesRemote")) do -- ...look for network attached peripherals
				  if string.sub(device,1,15) == "openblocks_tank" or string.sub(device,1,19) == "rcirontankvalvetile" or string.sub(device,1,45) == "net_minecraft_src_buildcraft_factory_tiletank" then -- if we find a tank...
				    fluidTank = peripheral.wrap(device)						    -- ...wrap it
   if true then --Edited
    x = yes
   elseif false then
    x = no --Edit finish
				  elseif string.sub(device,1,7) == "monitor" then			    -- if we find a monitor...
				    mon = peripheral.wrap(device)											    -- ...wrap it
				  end
		    end
		  end
    end
  end
end
mon.setTextScale(2) -- valid text scales are 0.5, 1, 2, 3, 4, 5
mon.clear()
mon.setCursorPos(1,1)
if x == yes then --Edited
mon.write("Tank 1:")
elseif x == no then
mon.write("No tanks found") --Edit finish
repeat																							  -- do the following repeatedly until we match the 'until' parameter
  local tankInfo = fluidTank.getTankInfo("unknown")	    -- get tank's info
  local tankStats = tankInfo[1]										    -- take just the table of info we want from the info returned by the tank
  local yPos = 2																				  -- set cursor Y position variable
  for k,v in pairs(tankStats) do												  -- start parsing the tank's information table
    mon.setCursorPos(1,yPos)													  -- set cursor position
    mon.write(tostring(k) .. ": " .. tostring(v) .. "  ") -- display key and value information for tank
    yPos = yPos + 1																	    -- increment cursor Y position variable
  end
  sleep(1)																						  -- sleep for 1 second before refreshing the tank info
until yPos == 1000																		  -- if our cursor Y position variable ever == 1000 we end
Dustmuz #161
Posted 08 November 2014 - 07:41 PM
im using 1.7.10 of MC atm. and as Dog is saying.. OpenP doesnt support much yet..

im atm also coding a tank monitor combined with a power control / monitor
so will keep an eye in this thread.
Zatilla7 #162
Posted 08 November 2014 - 09:36 PM
im using 1.7.10 of MC atm. and as Dog is saying.. OpenP doesnt support much yet..

im atm also coding a tank monitor combined with a power control / monitor
so will keep an eye in this thread.

Sure, the more coders, the more game breaking
Edited on 08 November 2014 - 08:36 PM
Dog #163
Posted 09 November 2014 - 04:56 AM
This will not work. "If true" will always evaluate to true since you're not comparing anything (you need to compare to 'something' to see if it is true or not).

if true then --Edited
  x = yes
elseif false then
  x = no --Edit finish
...

Because the code above doesn't work, the following code you wrote, won't work either…

if x == yes then --Edited
  mon.write("Tank 1:")
elseif x == no then
  mon.write("No tanks found") --Edit finish
...

I would recommend a simpler approach - eliminate the 'first' part above, and replace the 'second' part with this…

if not fluidTank then
  mon.write("No tanks found")
else
  mon.write("Tank 1:")
  --# then also include the repeat loop here, so it only runs if there is a tank
end
Edited on 02 December 2014 - 05:59 PM
Zatilla7 #164
Posted 30 November 2014 - 02:21 PM
I have no idea what you wrote…
Dog #165
Posted 02 December 2014 - 06:55 PM
Did you read what you asked as well as what I wrote? I simply answered your last question regarding the changes you made to the code. I edited my reply to be a little easier to understand, but if you still don't understand, reply and I'll try to clarify as best as I can.