ComputerCraft and Monitoring (and some RedNet stuff)

  • Please make sure you are posting in the correct place. Server ads go here and modpack bugs go here
  • The FTB Forum is now read-only, and is here as an archive. To participate in our community discussions, please join our Discord! https://ftb.team/discord

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
Ah. Fancy. That'd then allow you to plug this into any computer anywhere in the same world, but on a different network and it won't get any issues with numbers that aren't on that network, if you get what I mean. Thanks for that. I think I understand it now.

In that same for loop, I could add another if to search for nuclear reactors or ultimate hybrid panels to view my total energy creation too! Awesome.

Now to get my website for uni done and then onto MC programming. Haha! Why do I have to do uni work.... Why can't they just write out a piece of paper that says I've got a degree...? Haha
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
They should give you Lua assignments that you can do in Computercraft :)

Now wouldn't that be awesome!? And not only that, our college/university does actually have a Minecraft server. It'd be a simple issue of installing computercraft into the base file and into the server itself, and then we can code to our hearts content. But then we don't have all the awesome mods in MC to do fancy stuff with that you can do with all the mods installed. Well, whatever. I shall maybe mention to my tutors that there is a mod for Minecraft called ComputerCraft that runs on Lua and see what they say. Haha.

HTML, CSS and PHP just aren't as entertaining. You see, I have little to no creativity and just enjoy making fancy contraptions in a really boring cube that I build. So when I need to build a website, I just blank out and do some code that makes an awful website that sort of has functionality. Haha!

EDIT: Having a break from websites. I'm bored of it for now. So I'll try out the in pairs loops and see if I can fancy up my program!

EDIT2: I'm just implementing the improved for loop. As I'm entering it, I was thinking that I could have the for loop to work out the peripheral wrapping and then the working out the maxEUs and then separately have the storedEUs worked out to try and increase the program's efficiency. However, as I was doing so, I realised that this program would be modular this way and I can just add more MFSUs in to my power grid and it will automatically add them in when they're attached.

Speaking of power grids, there is a function for most of the IC2 machines called isAddedToEnergyNet(). What exactly does this function do?
 
Last edited:
  • Like
Reactions: casilleroatr

Bomb Bloke

New Member
Jul 29, 2019
612
0
0
I know I'm not your parents, but be wary - MineCraft won't teach you much in the way of real-world skills, don't blow off important stuff for it! ;)

Anyway, best I can make out, "isAddedToEnergyNet()" returns true if the block is plugged into an electric cable leading to other blocks.

Regarding dynamic updating of your MFSU list, the way to go there is to listen for events - in particular, the ones that fire when adding or removing peripherals, and perhaps a timer event for good measure.

First off, another note about tables: You don't have to use numeric indexes. Instead, you may use strings in the form of "keys":

Code:
local myTable = {}
local myString = "batbox_0"

myTable[myString] = peripheral.wrap(myString)

If you index the peripherals against their own names instead of against numbers, then it becomes very, very easy to check whether or not a given peripheral exists in your table, and to work out WHERE in the table it is... Because its location is simply its name. Given that for the purposes of a conditional, an existing variable counts as "true":

Code:
if myTable["batbox_0"] then print("I have that peripheral!") end

So, with all that in mind, let's say you turned your initial peripheral search into something like this:

Code:
for a,b in pairs(peripheral.getNames()) do
   if peripheral.getType(b) == "batbox" then
     mfsu[b] = peripheral.wrap(b)
     maxEUs = maxEUs + mfsu[b].getCapacity()
   end
end

Now let's say you wanted to know the sum total of EU stored in all MFSUs:

Code:
local function getCurrentEUs()  -- Note that functions are stored in variables. You must declare them BEFORE you try to call them - including before declarations of other functions that may want to call them!
  local result = 0
  for a,b in pairs(mfsu) do  -- "a" is the indexes ("batbox_0","batbox_1",etc), "b" is the content (the wrapped peripherals).
    result = result + b.getStored()
  end
  return result
end

Meaning that your main program loop can be structured somewhat like this:

Code:
-- Declare variables/functions first,
-- then build your initial table of MFSUs,
-- up here.

-- Note that there's no point in rebuilding the whole table over and over again - that sort of "initialisation" work shouldn't go in your main program loop.

local myTimer = os.startTimer(2)  -- Start a two-second timer, store its ID in "myTimer".

while true do
  myEvent = {os.pullEvent()}  -- Some functions return more then one result. This syntax allows you to stick all such results in a numerically-indexed table.
  -- Calling "os.pullEvent()" pauses the program (or rather, causes it to "yield") until an event actually occurs.

  if myEvent[1] == "timer" and myEvent[2] == myTimer then  -- The event thrown was our timer expiring.
    storedEUs = getCurrentEUs()  -- Call the function I demonstrated above to get the current amount of EU in the tank(s).

    -- Update the screen etc here.

    myTimer = os.startTimer(2)  -- Set a new timer.

  elseif myEvent[1] == "peripheral" and peripheral.getType(myEvent[2]) == "batbox" then  -- The event thrown was a new storage unit being added to the system.
    mfsu[myEvent[2]] = peripheral.wrap(myEvent[2])  -- Dump it in the table with all the others...
    maxEUs = maxEUs + mfsu[myEvent[2]].getCapacity()  -- ... and bump up our max capacity figure.

  elseif myEvent[1] == "peripheral_detach" and mfsu[myEvent[2]] then  -- The event is a peripheral in our table being removed from the system!
    maxEUs = maxEUs - mfsu[myEvent[2]].getCapacity()  -- Bump the max capacity figure down...
    mfsu[myEvent[2]] = nil  -- ... and wipe the device from our table.

  end
end
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
I know I'm not your parents, but be wary - MineCraft won't teach you much in the way of real-world skills, don't blow off important stuff for it! ;)

Anyway, best I can make out, "isAddedToEnergyNet()" returns true if the block is plugged into an electric cable leading to other blocks.

Regarding dynamic updating of your MFSU list, the way to go there is to listen for events - in particular, the ones that fire when adding or removing peripherals, and perhaps a timer event for good measure.

First off, another note about tables: You don't have to use numeric indexes. Instead, you may use strings in the form of "keys":

Code:
local myTable = {}
local myString = "batbox_0"

myTable[myString] = peripheral.wrap(myString)

If you index the peripherals against their own names instead of against numbers, then it becomes very, very easy to check whether or not a given peripheral exists in your table, and to work out WHERE in the table it is... Because its location is simply its name. Given that for the purposes of a conditional, an existing variable counts as "true":

Code:
if myTable["batbox_0"] then print("I have that peripheral!") end

So, with all that in mind, let's say you turned your initial peripheral search into something like this:

Code:
for a,b in pairs(peripheral.getNames()) do
   if peripheral.getType(b) == "batbox" then
     mfsu[b] = peripheral.wrap(b)
     maxEUs = maxEUs + mfsu[b].getCapacity()
   end
end

Now let's say you wanted to know the sum total of EU stored in all MFSUs:

Code:
local function getCurrentEUs()  -- Note that functions are stored in variables. You must declare them BEFORE you try to call them - including before declarations of other functions that may want to call them!
  local result = 0
  for a,b in pairs(mfsu) do  -- "a" is the indexes ("batbox_0","batbox_1",etc), "b" is the content (the wrapped peripherals).
    result = result + b.getStored()
  end
  return result
end

Meaning that your main program loop can be structured somewhat like this:

Code:
-- Declare variables/functions first,
-- then build your initial table of MFSUs,
-- up here.

-- Note that there's no point in rebuilding the whole table over and over again - that sort of "initialisation" work shouldn't go in your main program loop.

local myTimer = os.startTimer(2)  -- Start a two-second timer, store its ID in "myTimer".

while true do
  myEvent = {os.pullEvent()}  -- Some functions return more then one result. This syntax allows you to stick all such results in a numerically-indexed table.
  -- Calling "os.pullEvent()" pauses the program (or rather, causes it to "yield") until an event actually occurs.

  if myEvent[1] == "timer" and myEvent[2] == myTimer then  -- The event thrown was our timer expiring.
    storedEUs = getCurrentEUs()  -- Call the function I demonstrated above to get the current amount of EU in the tank(s).

    -- Update the screen etc here.

    myTimer = os.startTimer(2)  -- Set a new timer.

  elseif myEvent[1] == "peripheral" and peripheral.getType(myEvent[2]) == "batbox" then  -- The event thrown was a new storage unit being added to the system.
    mfsu[myEvent[2]] = peripheral.wrap(myEvent[2])  -- Dump it in the table with all the others...
    maxEUs = maxEUs + mfsu[myEvent[2]].getCapacity()  -- ... and bump up our max capacity figure.

  elseif myEvent[1] == "peripheral_detach" and mfsu[myEvent[2]] then  -- The event is a peripheral in our table being removed from the system!
    maxEUs = maxEUs - mfsu[myEvent[2]].getCapacity()  -- Bump the max capacity figure down...
    mfsu[myEvent[2]] = nil  -- ... and wipe the device from our table.

  end
end

Ah! Brain implosion! Haha! I get what it does and the basis on how it works, but I can't really pick up what you're saying, if you get what I mean. You've taught me about the pairs and a basic for loop, but I don't really understand this reading from the tables business. You've used different variables in different places from earlier and that's confused me slightly too. I think you've maybe made the basis of an awesome program for me, but you've skipped bits I'm still unsure about and it's making me lose track of where things are going and what they're doing.

I'm going to modify my MFSU room to contain the modems and cables, then I'm going to connect that to a computer. Then I'm going to implement my basic program temporarily, then I'll try and figure out what on earth I'm doing with this awesome program you've come up with.

Thanks for the help with this, guys!
 

Bomb Bloke

New Member
Jul 29, 2019
612
0
0
Don't worry about understanding it all in one go - experiment with making some smaller scripts until you've got a clear idea what each of the commands do, and don't be afraid to ask if you still don't know what's going on.

It strikes me that I did make a mistake in there - it wouldn't be possible to subtract the maximum capacity of a removed peripheral, as it's no longer there to ask what its capacity was. Well, if you work the rest out, I'm sure you'll work out how that should be handled. ;)
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
Don't worry about understanding it all in one go - experiment with making some smaller scripts until you've got a clear idea what each of the commands do, and don't be afraid to ask if you still don't know what's going on.

It strikes me that I did make a mistake in there - it wouldn't be possible to subtract the maximum capacity of a removed peripheral, as it's no longer there to ask what its capacity was. Well, if you work the rest out, I'm sure you'll work out how that should be handled. ;)

I'm on to the new FTB Monster pack and I've basically disregarded my MFSU storage program for now. I'll get back to that when I'm around to building something like that again. What I had worked awesome and was colour coded though. Thanks for the help with that!

Anyways, I'm currently trying to automate a Big Reactors reactor with a computer and modems like before. Now I'm not sure if it's me doing something wrong or that something has changed, but I cannot get a working program as whenever I call getMaxEnergyStored(), I get the following error: "lua:52: attempt to call nil". This is the same with getEnergyStored(). If I remove the modems and attach directly, I still get the same error.

Am I doing something wrong, or since Thermal Expansion has changed how everything works, is it now incompatible or something?

If so, what alternatives are there for automating reactors for TE?
 

casilleroatr

New Member
Jul 29, 2019
1,360
0
0
A lot of of Open Peripherals has changed including method names which is probably why you are getting the error. It does still work though so long as you use the new methods.
The website isn't documented with the updated information but you can use peripheral.getMethods in game on all of the peripherals the open peripherals adds and it gives you good info. Even better is there is a get advanced method data method of some sort (I forget the proper name but you can find out with getMethods which gives more detailed info about each method.

By the way if you are into big reactors there is a block which you may have noticed that you can put into your multiblock reactor and it can be used to as a peripheral allowing you to write a program to control the reactor.
http://wiki.technicpack.net/Reactor_Computer_Port
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
A lot of of Open Peripherals has changed including method names which is probably why you are getting the error. It does still work though so long as you use the new methods.
The website isn't documented with the updated information but you can use peripheral.getMethods in game on all of the peripherals the open peripherals adds and it gives you good info. Even better is there is a get advanced method data method of some sort (I forget the proper name but you can find out with getMethods which gives more detailed info about each method.

By the way if you are into big reactors there is a block which you may have noticed that you can put into your multiblock reactor and it can be used to as a peripheral allowing you to write a program to control the reactor.
http://wiki.technicpack.net/Reactor_Computer_Port


Thanks for the info! However, I seem to be incapable of reading from a table... Could you advise on how to do so as unless I never really understood that in the above code you've all given me.

I did see the reactor peripheral block too but I don't really want any complicated control for now. Basically, all I want for now is if the energy cell is <70%, switch on the reactor and then put it back off when it hits 90%.

And I'm not particularly into the Big Reactors mod (though it does seem a little awesomely OP.....) but since everything has changed, the way I always used to do things is not possible and so I'm trying out all the new things. This just seemed worth trying. I'd really love a way to turn RotaryCraft power into EUs, though. Shame that nothing is available to do that and that Reika won't implement it.

EDIT: I think I figured that part out... Next problem is that it lists only two functions. They are "listMethods()" and "getAdvancedMethodsData()"..... Any ideas?
 
Last edited:

Bomb Bloke

New Member
Jul 29, 2019
612
0
0
The version of OpenPeripheral you're using doesn't support the new energy cells, it seems. It sounds like you should be able to manually update it past whatever version your modpack is using.
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
The version of OpenPeripheral you're using doesn't support the new energy cells, it seems. It sounds like you should be able to manually update it past whatever version your modpack is using.

Well that's interesting... As far as I can see, the latest downloadable version is 0.2.0 whereas the version included with FTB Monster is showing as 0.2.1.... Whut....?
 
Last edited:

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
Well that version definitely shows up the two important methods when I use listMethods(), but when I try and run either of them, it tells me that I need to be passing one parameter. Which makes no sense to me as it should just be returning one parameter.


EDIT: Literally just adding anything in that gap (as a string) it works. What...!?
EDIT 2: In fact, you merely have to write the function like this: getEnergyStored(""). That suffices.
 

casilleroatr

New Member
Jul 29, 2019
1,360
0
0
Well that version definitely shows up the two important methods when I use listMethods(), but when I try and run either of them, it tells me that I need to be passing one parameter. Which makes no sense to me as it should just be returning one parameter.


EDIT: Literally just adding anything in that gap (as a string) it works. What...!?
EDIT 2: In fact, you merely have to write the function like this: getEnergyStored(""). That suffices.
I am only hypothesising here but I have a feeling that it is something to do with how open peripherals doesn't support each block individually but has a more generic approach to get as much support as possible which is good for us, even if it does mean we have to use these strange parameters.

Perhaps the REC isn't as strict about how open peripherals queries its capacitor but perhaps a dynamo (which can only export power out of the top face) is more strict. I don't know why you would want to monitor a dynamos internal capacitor but there is probably someone out there who will be in a situation where they need to put in a particular side (that isn't just "").
 

xBlizzDevious

New Member
Jul 29, 2019
110
0
0
I am only hypothesising here but I have a feeling that it is something to do with how open peripherals doesn't support each block individually but has a more generic approach to get as much support as possible which is good for us, even if it does mean we have to use these strange parameters.

Perhaps the REC isn't as strict about how open peripherals queries its capacitor but perhaps a dynamo (which can only export power out of the top face) is more strict. I don't know why you would want to monitor a dynamos internal capacitor but there is probably someone out there who will be in a situation where they need to put in a particular side (that isn't just "").

Fair enough. Well it works so I'm happy. Haha!
 

casilleroatr

New Member
Jul 29, 2019
1,360
0
0
Yeah I am glad it is working for you too - I meant to say that in my last post at the end, I guess I was too far up my professor derp hat:)
 

Bomb Bloke

New Member
Jul 29, 2019
612
0
0
To my understanding, you should be able to get more info on how each other method works using "getAdvancedMethodsData()".