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

Active Cooled Big Reactor: Turbine PID-Controller with master control and monitoring.

Started by kla_sch, 30 December 2014 - 12:00 AM
kla_sch #1
Posted 30 December 2014 - 01:00 AM
Hello,

i have finished my program to control turbines of a big reactor (http://big-reactors.com/).

It implements a standard PID controller to change the turbine speed and display some status informations. A second program collect all status informations of any reachable turbine control program and displays a table to console and any attached monitor. This master controller is able to change speed of any turbine controller.

Version history:
  • v0.1, 2014-12-29: initial version
  • v0.2, 2015-01-02: some improvements (pocket computers) and bugfixes
  • v0.3, 2015-01-05: Support terminal glasses and bugfixes
1 The PID controller

The PID controller switch the turbine between three different states: OFF, 900 RPM and 1800 RPM. It displays some status informations to the console and any attached monitor. A master controller is able to collect any turbine information and it is able to change the turbine status.

1.1 Installation and setup

Attach a computer to the computer port (direct or with a wired modem). Label your computer with some unique name:

label set Turbine_01

Download the program ans save it as "startup":

pastebin get gTEBHv3D startup
old v0.1
pastebin get kfWVibVF startup

Start the control program with "startup". It shows the following screen:



Now, you can type in "m" or "f" to start up the turbine. You may also type in "o" to switch the turbine off. The program tries to reach the desired speed by changing the maximum steam float.

You can attach a monitor to any side of the control computer to show some operation stats. You may also attach a monitor with a wired modem. A 1x1-Monitor will do the work. It then shows the following:



In the first line it shows the operation state: off, 900 RPM or 1800 RPM. The third line shows the actual speed of the turbine. The fourth and fifth line informs about the maximum and actual steam flow.
The maximum steam flow is the configured value of the turbine. The actual steam flow is the real flow the turbine get by the connected reactor at this time. If the actual flow is less than the maximum flow and the turbine does not reach its target speed, the turbine needs more flow to operate.

A normal computer and monitor will work. If you use the advanced ones, the display uses colors. If you use bigger monitors, the program try to scales up the status display:



I you use a newer version of Big Reactor (>= v0.3.4A), the turbines have a disengage coils feature. The controller use this for faster startup. If the coild are disengaged the turbine does not produce energy anymore. If you want to disable this feature, have a look at line 46 of the code and change the variable "useDisengageCoils" to "false":

46: local useDisengageCoils = true

1.2 Networking

The turbine controller is able to send its status informations to a central master controller (see section 2). It also change the operating speed by network request.
By default, the remote information feature is enabled and the remote control is disabled.

1.2.1 Security issues

The networking feature not implemented any security feature at all. If you use this features in a multi player environment, you should trust the other users. By default configuration they can only use the information feature of the controller, if you attach a modem.

1.2.2 Disable remote information feature.

If you want to avoid that other users are able to collect the informations of your turbines, you can disable the sending of this informations. Edit the file "startup" at line 34 and set the variable "stateRequestChannel" to 0:

34: local stateRequestChannel = 0 -- Broadcast channel.

The controller would not send any status informations to attached modems anymore. You don't need to do this, if you don't attach any modem to the computer.

1.2.3 Enable remote control feature

If you want to control the turbine by the master control program (see section 2), you have to edit the file "startup" at line 40 and set the variable "remoteControl" to "true":

40: local remoteControl = true

1.2.4 Use the network

You can simply attach a wired or wireless modem at the controller computer. The controller will use any modem to collect information of control requests.

1.2.5 Use the network feature for your own programs

The network code using the modem API. I don't use the rednet API, because it always use only the first found modem to send messages.

To receive turbine informations, you have to send "BR_turbine_get_state" to the configured broadcast channel (stateRequestChannel = 32768, see line 34 of the code). Use your computerID as reply channel and open this channel to recieve the reply:


peripheral.call(modemSide, "open", os.getComputerID())
peripheral.call(modemSide, "transmit", 32768, os.getComputerID(), "BR_turbine_get_state")

The turbine controller send back the status informations to your reply channel.
You should decode and check the reply:


local rState = textutils.unserialize(tostring(recievedValue))
if rState ~= nil
   and type(rState) == "table"
   and rState.version ~= nil
   and rState.version == "Turbine V0.1"
then
	...
end

Have a look at line 590, to see what type of values you will recieve.

To change the turbine speed, you can simply send the new speed with the prefix "BR_turbine_set_speed:" to the controller:


local speed=900
peripheral.call(modemSide, "transmit", turbineComputerId, os.getComputerID(), "BR_turbine_set_speed:" .. speed)

The speed should be 0, 900 oder 1800 to set the turbine target speeds: off, 900 RPM and 1800 RPM. In the example it would send "BR_turbine_set_speed:900". The turbine controller just change the target speed and replies nothing.

1.4 Reconfigure your turbine.

The first time you use the control program, it measures the startup speed of your turbine and save this as a basic configuration into the file "turbine_crtl.save". If you change the setup of your turbine (make it bigger or change the coils), this values are no longer suitable to operate the controller.

Simply remove the file "turbine_crtl.save" after you change your turbine setup. The controller will measure the new startup speed again.

1.5 Customization (Monitor)

If you want to change the informations at the monitor, you can do that by changing the function "displayStateOnMonitor" beginning at line 326.

If you need a bigger screen to display your information, you can change the scale functionality at line 329:

local width, height = scaleMonitor(mon, 15, 16, 5, 5)

This line scales the monitor up and down. You find the documentation of this function beginning at the line 280 of the program.

2. The master controller

The master control program will collect informations of any reachable turbine controller. If the remote control feature of the turbine controller is enabled (see section 1.2.3), you are able to change the operation state of this turbine controller.

2.1 Installation and setup

Place a computer anywhere and set a unique label:

label set Turbine_Master_Control

Download the program and save it as "startup":

pastebin get RcBGNSgb startup
old v0.2
pastebin get rg1auFSE startup
old v0.1
pastebin get F5JPrFUU startup

Then attach a wired ore wireless modem to the master computer and any turbine controller. If you use wired modems, you should connect them by wires, of cause.

After starting the master control program with "startup", it sends broadcast requests to any attached modem. If a turbine controller received this broadcast message, it sends the status informations of the turbine back to the master controller. The master controller displays a table with the collected informations:



The columns:
  • Label: The label of the turbine computer. The +/- indicates the status of the turbine (active/deactive) for normal computers without colors
  • TRPM: The target speed. This is the operation status of the turbine controller: 900 RPM, 1800 RPM and OFF
  • ARPM: The actual speed of the turbine. If it is orange, the turbine does not reach the target speed. If it is red, the turbine is too fast (> 2000 RPM)
  • MFlow: The maximum steam flow, the turbine is configured with
  • AFlow: The actual steam flow of the turbine (explained in section 1.1)
  • kRF/t: Actual energy production of the turbine
  • Energy: Load of the internal energy cell
You can also attach monitors to any side of the computer. You may also connect monitors with wired modems. All attached monitors show the table of turbine controllers. The controller need at least two monitors in row to display the table. Better you use three monitors in a row, to see the complete table:



You may also use bigger monitors. The program tries to scale the output:



If you use smaller monitors, the program only shows a few of the columns:



By using an advanced monitor, you can cycle between the different informations by clicking the table header or the last line.

Since v0.2 you can also use a wireless pocket computer as a master controller:



You may also cycle between different informations by clicking the table header or the last line on advanced pocket computers. Or you can simply press the space key, with also works on normal pocket computers.

2.2 Change operating state of turbine controllers

To change the operating state of the displayed turbine controllers, the controllers need the remote control feature enabled (see section 1.2.3). You also need an advanced computer or monitor to change the control state.

To change the state of a turbine controller, simply click with the mouse at the displayed line (right click at monitors, right or left click at the console) and a change dialog box appears:



The last line of the box shows the different operation states of the turbine controller. The actual configured state is marked by a blue background color.
Simply click to any of this states. The box will disappear and the controller will change its control state. If you click outside, the box simply disappears without changing the operation state of the turbine controller.

2.3 OpenPeripheral Terminal Glasses

Since v0.3 the maser supports Terminal Glasses of OpenPeripheral. Simply attach a Terminal Glasses Bridge to your computer and register your terminal glasses by right click with it an the bridge. Then your HUD schould show this:



It also supports some chat commands to hide the HUD, change the speed of a turbine or show some detailed informations:
  • $$help: Shows a box with the chat commandy you can use
  • $$hide: Hide the HUD display
  • $$show: With no parameters, it shows the table again. If you use a label of a turbine as parameter it shows a detailed information screen for this turbine.
  • $$speed: Set the target speed of the turbine. First parameter ist the new speed (off, 900 or 1800). Second parameter is the label of the turbine computer.
Some exampels:

$$help
shows this:



$$show Tsmall 5x5
shows this:



Or simply change the target speed:
$$speed 900 Tsmall 5x5

I you want to place the HUD to another location, have a look at line 37 of the code. If you change the posX and posY values to move the HUD to anjother place. The Terminal Glasses don't give informations about the screen size, so i was not able to align the HUD to the bottom or right side of the screen.

2.4 Customization (Monitor)

If you want to change the output of the table, you can change the function "displayTableOnMonitor" beginning at line 294 of the program. As the turbine control program, it use the function "scaleMonitor" (see line 305) to scale the monitor output. If you want to use bigger or smaller tables, you should change the parameters. The description of "scaleMonitor" can be found at line 230 of the code.
If you change the table header height (two lines) or the position from top, you have to change the calculations in function "changeSpeed" (beginning at line 1203) also. To insert additional informations into the cycle for small monitors, you can change them in function "doCycleInformations" (beginning in line 1174).

The turbine controller send any known status information of the turbine to the controller. So, in most cases, you don't have to change the protocol. Have a look at line 590 of the turbine controller program, to see what type of informations are send. If you need any additional information, simply add it to the "rState" table at this location.


I hope, my poor english skills are not too annoying.

Have fun, kla_sch
Edited on 09 January 2015 - 11:18 AM
kla_sch #2
Posted 31 December 2014 - 01:49 PM
Hello,

do the pictures work? I have to use a mobile phone connection that use a picture proxy to create compressed pictures. First i have used the wrong URL. I have corrected it, but i am not sure, if they are working now.

So sorry, kla_sch
wieselkatze #3
Posted 02 January 2015 - 02:02 AM
Wow - this is some well documented code! Nice work. I've seen many posts about several programs so far, but this one definitely amazed me. +1
Yeah, the pictures work just fine. ( Dein Englisch stört auch nicht ;)/> )
I see you have localized your variables - doing that with your functions as well would not hurt :P/>
If I used BigReactors that much, I would give this one a shot - no doubt.

~wieselkatze
Edited on 02 January 2015 - 01:02 AM
kla_sch #4
Posted 02 January 2015 - 08:41 PM
I have upgraded my code into v0.2.

Changes of the PID-Controller:
  • Disengage coils for faster speedup. This feature has been introduced in Big Reactors v0.3.4A. If your reactor version supports this feature, the controller use this for faster speedup the turbine. You can disable this feature by setting "useDisengageCoils" to "false". Have a look at the changed setup instructions.
  • Bugfix: If you don't set a computer label, the old version simply submit the ID-Number as number to the controller. The controller crashed, because it expects a string. Now, the controller sends a string with the prefix "ComputerID:".
  • I do also some code improvements. Mostly some more usage of the "local" keyword as suggested by wieselkatze.
Changes of the Master Controller:
  • The Version 0.2 supports wireless pocket computers as master controllers. To support this type of computer, a second table layout with only 25 characters per line has been implemented. You can cycle between the different informations (TRPM/ARPN, TFlow/AFlow, kRF/t and Energy).
  • The code also supports advanced monitors with less than 50 characters per line by cycle the informations. So, you only need two monitors in a row.
  • Default width of table has been reduced to 50 charaters per line. This is more suitable if you use five monitors in a row.
  • Bugfix: There was a small bug at the scale feature.
  • I do also some code improvements. Mostly some more usage of the "local" keyword as suggested by wieselkatze.
Have fun, kla_sch
Edited on 03 January 2015 - 05:46 PM
cormoo #5
Posted 03 January 2015 - 02:10 PM
This is a great program! I implemented it last night on two of my turbines and it works flawlessly. Thank you so much for this excellent way of managing turbines!
kla_sch #6
Posted 05 January 2015 - 11:13 AM
I have upgraded my master controller code into v0.3.

Changes of the PID-Controller:
  • No changes: There is no v0.3 for this code.
Changes of the Master Controller:
  • The Version v0.3 supports Terminal Glasses of OpenPeripheral. It shows the turbine table on HUD. It can also show some detailed informations of the turbines and let you change the target speed by char command.
  • Bugfix: The number formatting was broken.
Have fun, kla_sch
Edited on 05 January 2015 - 10:23 AM
Ultanna #7
Posted 09 January 2015 - 07:21 AM
Hello !

i just tried it and it works really great ! i just need to find a way to hook it to the reactor to control it too ;)/>
kla_sch #8
Posted 09 January 2015 - 12:17 PM
Hello !

i just tried it and it works really great ! i just need to find a way to hook it to the reactor to control it too ;)/>

Yes, thats the "not so easy" part. The reactor has weak indicators to see, if it produce too much steam. The only way, i find out, is the internal steam tank. In older versions of BR the method to get the size of this tank is missing. Also there is only a tiny gap in which you can use the steam level to control the reactor (most time, the tank is full or empty) and it does not react directly to rod level changes.

I have made a working prototype of a PID controller for this, but it is far away from completion. I have to test and optimize a little bit more. It needs a GUI and it should also communicate with the master controller. Much work to do and i have only a limited amount of time to do that.
Just8Will #9
Posted 15 January 2015 - 09:02 PM
Hello kla_sch,

I've looked around at a few turbine and reactor control programs and this is by far the best. You mentioned that you were having trouble with reading the steam levels. Have you considered requiring an external steam tank (perhaps one from open blocks or something similar) and wrapping this as a peripheral. Then you can read the levels and how they change over time to understand the steam level the reactor is producing.

I'm going to try combining using your code with using the power management system I found here.
Together they should give me great system control.
If you have made any more progress on the reactor control program that'd be great to here about
kla_sch #10
Posted 16 January 2015 - 01:22 PM
Hallo Just8Will.

[…] You mentioned that you were having trouble with reading the steam levels. Have you considered requiring an external steam tank (perhaps one from open blocks or something similar) and wrapping this as a peripheral. Then you can read the levels and how they change over time to understand the steam level the reactor is producing.

As i mentioned, i have created a working prototype, which mostly works well. The problem i see is, that i have to read the stream level every single tick (1 tick = 1/20s = 50ms). I am not sure if it really brothers.

To support external tanks, is one option to avoid cpu/lag problems. But then, the program depends on another mod which has to be installed.
Also, it throws up new questions like "how to handle two reactors which fill one single big tank?", "can the tanks be connected by wireless modem?", "how to support two tanks with two sensors" and many more. If i make a solution for a fixed scenario, any question has a simple answer. If i try to create a common solution for different scenarios, it rapidly turns complex.

So, i prefer to avoid a solution with external tanks, because it should be plug&play.

It will take some time to create a solution for active cooled reactors. It's time consuming to make tests with different reactors and turbines to find a always working solution. Also, i have to rewrite the monitor tool, to support reactor informations too. I have not that much time to do all this work in weeks and, of cause, i want to play a little bit minecraft next time too :D/>.

Have fun, kla_sch
makeme #11
Posted 16 January 2015 - 02:49 PM
Wasn't Direwolf20 able to read steam levels in his Big Reactor program? You could have a look at that.

And remember if someone is using this on a server ticks most likely won't be 20tps
kla_sch #12
Posted 16 January 2015 - 04:17 PM
Wasn't Direwolf20 able to read steam levels in his Big Reactor program? You could have a look at that.

It's not the problem to read the steam levels. But the internal tank is not much bigger than the steam which the reactor produce each tick.
Example: I have created a really big one. It produce 40 buckets per tick. The hot fluid tank of this reactor holds only 50 buckets. With a PID-Controller, i try to hold the level of the steam at 1/2 of the maximum level (25 buckets in this case). The controller get the actual steam level as input and calculate the rod level according the different (the error) between actual steam level and target steam level (25 buckets). If you measure the steam level it looks like this:


tick 1: steam=0 B, error = -25 B
tick 2: steam=0 B, error = -25 B
tick 3: steam=15 B, error = -10 B
tick 4: steam=50 B, error = 25 B
tick 5: steam=50 B, error = 25 B

It is difficult to hold the steam buffer level at 25 B, if you don't measure the level each game tick. The controller program has to react fast, to stabilize the steam production. That means, that i have to recalculate the level 20 times in a second and i don't know, if it hurts anyone.

The only other thing, what i can do is to accept the fluctuation around the target value. But then some turbines get not enough steam to hold the target speed. They also begin to fluctuate, which has also a retroactive effect to the reactor (the steam consumption change). So, thats not the best choice.

The last choice is to use a much bigger external tank to control the reactor steam. Then, the controller has more time to recalculate the rod levels.

And remember if someone is using this on a server ticks most likely won't be 20tps

That could be the next problem.

Have fun, kla_sch
Ultanna #13
Posted 17 January 2015 - 09:14 PM
Wasn't Direwolf20 able to read steam levels in his Big Reactor program? You could have a look at that.

And remember if someone is using this on a server ticks most likely won't be 20tps

i just watched his code spotlight for his reactor control program and Direwolf his only refering to the steam level to calculate the aproximative level he should insert control rods in the reactor. Basically to control the reactor he's using a capacitor bank. When the capacitor bank get at a certain low level, he start the reactor and engage coils on the turbine. When the capacitor bank gets filled, he disengage the coils on the turbine and stops the reactor. he also have a loop checking for the turbine RPM to get it over 1840 when coils are disabled. this ensure the turbine will be at the optimal speed when he will need some power.

it seems to be a really nice way to control both turbine and reactor as the turbine is always ready to output a lot of RF and the reactor can save some fuel when the capacitor bank is full. The only problem i can see is the way it is programmed at the moment, you can only have 1 turbine controled and his monitor is not as awsome as Kla_sch ;)/>

Pastebin of Direwolf20's program : A7v2sKyW
bluntzultimat3 #14
Posted 06 May 2015 - 11:11 PM
I am having some trouble with the code. When i try to turn one turbine off, it turns them all off. The same for turning on

Also the terminal glasses dont show anything on screen. I have no idea what is going on there. Any help would be amazing :)/>
Edited on 06 May 2015 - 10:00 PM
biohazard457 #15
Posted 13 May 2015 - 10:24 PM
Is there a way to make this to just monitor the Turbines and not adjust the speeds or flow rates? I was wanting to use Direwolf20's control program but I really like the monitor display of your Master Controller program better.
tethlah #16
Posted 30 May 2015 - 06:46 AM
I love this, it's amazing, great job. My only beef with it is it seems that terminal glasses wont work with it for some reason.
tethlah #17
Posted 21 June 2015 - 05:48 PM
So terminal glasses don't work because you don't use .sync()

The new version is using .sync() on your glasses object, any plans to add that to this so terminal glasses work with the current version of peripherals?
kla_sch #18
Posted 06 July 2015 - 05:22 PM
Sorry, i missed the notification options. I hope, it will work now.

Is there a way to make this to just monitor the Turbines and not adjust the speeds or flow rates? I was wanting to use Direwolf20's control program but I really like the monitor display of your Master Controller program better.

It's not that difficult to do that. You have to change a few lines of the turbine controller:

1. Change line 442 from

if restoreControllerState() == false then
to

if false then

2. Change line 353 from

if tSpeed ~= 0 then
to

if false then

3. Remove line 489:

   saveControllerState()

4. Change line 494 from

	  if evt == "char" then
to

	  if false then


So terminal glasses don't work because you don't use .sync()

The new version is using .sync() on your glasses object, any plans to add that to this so terminal glasses work with the current version of peripherals?

The problem with OpenPeripherals is, that a written documentation is missing. I have not much time to experiment things out and google for example codes. In next main release, i plan to drop the glasses support, because it consumes to much time to support this mod.

But i try to have a look at this problem this week. I will fix it, if i find a solution, that also works with older releases of the mod.
rexthecapt #19
Posted 19 September 2015 - 08:35 PM
The glasses dont work for me. I did place that terminal glasses bridge on the controller and right clicked the bridge with the glasses and nothing happened
Spoog #20
Posted 20 September 2015 - 05:29 AM
Hey I've been looking around for programs to monitor my big reactors and so far I love your program. But with that there are a few suggestions that I could make

Firstly when pressing "o" to turn off the setup, instead of turning off both the reactor and the turbine it would be more beneficial to turn off the reactor and disengage the coils on the turbine.
HadesDurin #21
Posted 21 September 2015 - 07:15 PM
i lately start to use your program and some of my advanced computers attached to the turbines crash randomly
here is a picture on the crash massage i get

http://www.pichost.de/image/JAi
Bomb Bloke #22
Posted 23 September 2015 - 05:53 AM
Always the same error, with that same line number?

Have you modified the script file in any way? If so, what's the changed version look like?
HadesDurin #23
Posted 23 September 2015 - 08:17 AM
the line number ist mostly around 124-125
the only change i made to the pastbin code is
1.2.3 Enable remote control feature
in line 40
all other i left untouched
the computer (attached to turbine) crashes are randomly thru all 6 (i use 6 turbines) of them
and sometimes only 1 crashes and sometimes even more
the only thing thats identical is that yielding thing error
EDIT: latest computercrash http://prntscr.com/8jmdj5
Edited on 23 September 2015 - 03:04 PM
HadesDurin #24
Posted 24 September 2015 - 12:38 AM
here are 2 new errors i lately got

http://prntscr.com/8jrwpv

http://prntscr.com/8jrx82

Edit: newest error, after the next time i try to start it works
http://prntscr.com/8jvwuf
Edited on 24 September 2015 - 08:48 AM
aadje93 #25
Posted 27 October 2015 - 05:38 PM
Hello, your script looks awsome! Can't wait to implement it in my power station (20 turbines to come)

But i'm very new in the "new" CC, never knew about the advanced monitors and modems etc, they look awsome to, mouse control on the monitor :D/>

But now to the real question;

do i need to connect a computer to the turbine, or can i just put a modem on the port? I dont like the looks of a computer on every turbine, but a modem looks good, i can put the "computers" somewhere else if thats nessecary (backroom of control room?)

I'm looking forward to your response :)/>
Caleb Ragnarok #26
Posted 02 November 2015 - 06:26 PM
You can do either, a computer, a turtle or a wired modem. I'm using a combination of all three.
ultratutu9 #27
Posted 25 January 2016 - 07:30 PM
How can i do for change the speed limit to disengange the coils again? Like, if the speed drops down to 1500 RPM, disengange the coils to speed up faster.
El_Loko_ #28
Posted 08 October 2016 - 09:53 PM
Guys,

have written a small add-on for this nice script. Thanks kla_sch I love it.

This script controls the reactor to save fuel.

The profiler will create a profile of your reactor how many steam will be created if running with rod level x
Run this script before you start the control script.
It will take some time to create the profile. Best way is to add 4 turbines set them to max speed and run the script.

http://pastebin.com/rKKiEmxm


--
-- Control an active cooled reactor from Big reactors (http://big-reactors.com/).
-- Profiler
-- run this script before running the reactor control script
-- run this script every time you change your reactor layout
--
-- Author: El_Loko_
--
-- Save as "startup"
--
--
--
-- Constant values (configuration)
-- ===============================
local rodLevel = 100
local reactor
reactor = peripheral.wrap("bottom")
local hold = 20 -- as higher the hold value that more accurate are the values
local profile = fs.open("profile.txt", "w")
reactor.setActive(true)
rod = 100
repeat
reactor.setAllControlRodLevels(rod)
sleep(hold)
print("R: " .. rod .. " Heat: " .. reactor.getFuelTemperature() .. " Steam: " .. reactor.getEnergyProducedLastTick())
profile.writeLine(rod .. ";" .. reactor.getFuelTemperature() .. ";" .. reactor.getEnergyProducedLastTick())
rod = rod - 1
if(reactor.getEnergyProducedLastTick() > 8000) then
  rod = 0
end
until rod == 0
reactor.setActive(false)
profile.close()

This is the controller. Save it as startup after creating the profile

http://pastebin.com/7aCWb3MC


--
-- Control an active cooled reactor from Big reactors (http://big-reactors.com/).
-- this is an Addon Script for kla_sch turbine script (http://www.computercraft.info/forums2/index.php?/topic/21430-active-cooled-big-reactor-turbine-pid-controller-with-master-control-and-monitoring/)
--
-- This script controls a activ cooled reactor to save fuel. It set the rod level automaticly
-- Run the profiler script before running this script
--
-- Author: El_Loko_
--
-- Save as "startup"
--
--
--
-- Constant values (configuration)
-- ===============================
-- set the Broadcast channel (make sure it is the same as the turbines)
local stateRequestChannel = 32768 -- Broadcast channel.
local loopT = 1
local rodLevel = 100
-- set the positon where your computer is conected to the reactor
-- top, bottom, left, right, back  
local reactor
local reactor = peripheral.wrap("bottom")
-- the file with the reactor profile
local profile = "profile.txt"
local reactorProfil = {}
-- Author: kla_sch
local function sendBroadcastRequest()
   local pList = peripheral.getNames()
   local i, name
   for i, name in pairs(pList) do
	  if peripheral.getType(name) == "modem" then
		 peripheral.call(name, "open", os.getComputerID())
		 peripheral.call(name, "transmit", stateRequestChannel, os.getComputerID(), "BR_turbine_get_state")
		
	  end
   end
end

-- Author: unknown
function split(pString, pPattern)
   local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
		  if s ~= 1 or cap ~= "" then
		 table.insert(Table,cap)
		  end
		  last_end = e+1
		  s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
		  cap = pString:sub(last_end)
		  table.insert(Table, cap)
   end
   return Table
end

-- check if the profile is available
function file_exists(file)
  local f = io.open(file, "rb")
  if f then f:close() end
  return f ~= nil
end
-- get all lines from a file, returns an empty
-- list/table if the file does not exist
function lines_from(file)
  if not file_exists(file) then return {} end
  lines = {}
  for line in io.lines(file) do
	lines[#lines + 1] = line
  end
  return lines
end
-- tests the functions above
local lines = lines_from(profile)
-- load profile
for k,v in pairs(lines) do
   line = v
   table.insert(reactorProfil, split(line, ";"))
end

-- set rod to 100
reactor.setAllControlRodLevels(rodLevel)
reactor.setActive(true)
-- parts of this codes are from kla_sch
-- some is from me
while(true) do
  
	term.clear()
	sendBroadcastRequest()
	local steamNeeded = 0
	local tID = os.startTimer(loopT)
	repeat
	  
	turbineTable = {}
local evt, p1, p2, p3, p4, p5 = os.pullEvent()
if evt == "modem_message"
  and p2 == os.getComputerID()
  and p3 == stateRequestChannel
then
  local rState = textutils.unserialize(tostring(p4))
  if rState ~= nil
   and type(rState) == "table"
   and rState.version ~= nil
   and rState.version == "Turbine V0.1"
  then
   -- seems to be a suitable data structure
   turbineTable[rState.label] = rState
   steamNeeded = rState.fluidFlowRateMax + steamNeeded
   end
end
	
-- search the table reactorProfile for the first value wich is above
-- the needed steam value and set the rods to this level
-- very ineficent but working
for k,v in pairs(reactorProfil) do
  --print(v[3])
  if (tonumber(v[3]) > steamNeeded) then
   reactor.setAllControlRodLevels(tonumber(v[1]))
   break
  end
end
term.clear()
print("Rod Level:		" .. reactor.getControlRodLevel(0))
print("Energy Produced:  " .. reactor.getEnergyProducedLastTick())
print("Energy Requested: " .. steamNeeded)
	until evt == "timer" and p1 == tID
end

Cheers, El_Loko_