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

Help with train station project

Started by pietro.devo, 30 September 2015 - 10:52 PM
pietro.devo #1
Posted 01 October 2015 - 12:52 AM
Hi
I'm glad to have found this minecraft mod, I am completely a noob in programming, I had zero knowledge, but little by little I made some steps and I am trying to learn.
I always play minecraft with my favorite mods like industrialcraft, buildcraft, forestry, railcraft and traincraft.
I really love Traincraft and I have build a quite important and long railroad system in my world, so I have decided to take a little challenge, to set up a computercraft-controlled railroad system.

What I'm trying to do is a system as more modular as possible, network-based and with multiple levels of functions, which can be easily adapted to various scenarios, so different kinds of stations, yards, conditions, purposes, and can be easily modified on-the-fly in one or more components.
I'm talking of multiple computers running highly specific tasks to make all system works.
This is what I thought would be the best solution, I'm working on this project, now I think I am in a really early stage, but I would like to share and discuss with all of you
and I'm here exactly to do this, you are far better than me and I would really appreciate any kind of suggestions and help from you.

Let's take a look at a train station, for example starting from the case of a terminal station

What I first made is the definition of the system in its modules, having basically two important levels, one of basic imputs, activators, detectors, peripherals etc etc and one of managers, basically where the "intelligence" of system resides.
All the system works with rednet messages that are commands, requests about states, updates, events etc etc

Here is what I have defined, I will translate and explain:

gestore_annunci
gestore_arrivi
gestore_display
gestore_partenze
gestore_scambi
gestore_segnali
gestore_stati
gestore_tragitti
gestore_transiti

gestore_annunci is "ads_manager", it is the component responsible for listening to all the messages in station network, which are so many, and just separate the ones important for the public from the service messages, commands etc etc and translate from system language to something formal and informative, basically listening to "medium level" and "low level" messages and converting to "high level" messages, that can then be later displayed on station monitors for public or just joining "low level" and "medium level" messages and redirecting to technical consoles .

gestore_arrivi is "arrivals_manager", it is the component responsible for managing all incoming trains and takes in consideration the possibility or not to enter in the station and other things, inquirying sensors and listening to them. It informs the network of all arrivals and its properties in "medium level" messages.

gestore_display is "display_manager", it is the component responsible for managing all different monitors on station, organizing ads and informations in a ordered and graphical way.

gestore_partenze is "departures_manager", it is the component responsible for managing all outgoing trains, analog behaviour as "arrivals_manager".

gestore_scambi is "switch_manager", it is the component which controls all switches, that are some sort of "slave" components. it listens to "medium level" commands and sends "low level" commands.

gestore_segnali is "signposting_manager", it is the component which controls all the "traffic lights" stuff and signs etc etc. Like switch_manager it listens to "medium level" commands from other managers (like for example "gestore_tragitti", really important) and sends "low level" commands to "slave" units which phisically control single lights and so on.

gestore_stati is "states_manager", it is a core component because It is where all states of components are stored (for example if a switch is on or off, if a binary is occupied or not, if a light or a crossing is enabled or disabled and so on). It costantly listen to "low level" or "medium level" (depends on situations, certain kinds of scenarios have a further level of state interpretatation and broadcasting, lower, that then get send in a "medium level" language to "states_manager", for example long binary with multiple detectors to determine if train is just passing or stops there) and keeps updates all variables to responds to all requests of states from other managers , that uses them to elaborate the procedures and send commands or just to determine if a light must be on or off and so on.
It also has a local display, just to have updated visualization of states.

gestore_tragitti is "route_manager", it is very important, the most complex and "intelligent" part beacause it is involved when a train has to arrive, leave or just pass, in fact this component has to collect informations (from states_manager or other detectors) and define the route train has to follow to complete its intent. If a train for example is arriving (and can enter the station) it has to determine at which binary the train can stops and then send instructiond to switch_manager, that sets up all switches in correct way following iys embedded functions, and to signposting_manager, that sets up signs.
It reads and sends "medium level" messages and commands.

gestore_transiti is "passing_manager" and it is intended for non-terminal stations or for yard and switches along railway, where a train doesn't stop but has to pass. It is like gestore_arrivi and gestore_partenze and interacts with gestore_tragitti.

Then there are all the "slave" stuffs, which I don't write, because are simple low-end controllers that manage a single physical component.

I have written different managers and they are working fine in testing stage, sending and receiveing messages and commands, storing values and printing all the stuff.

I need some help with the gestore_tragitti, here is part of my code, it has to be intended as a sample, it is not complete, I need to understand the best way to go on and to write correctly the bottom part.
I want the program to check the state of first binary (all with use of network and inquiryng that involve states_manager) and if it is empty it can execute the function (that I will lately define) that sends commands to switch_manager and sets all switches to make train go to first binary (then the stop and timing etc etc will be apart), else will check next binary, the second one, and do the same, sending train here if possible by setting switches or going on to third switch and so on.
Basically it chooses the first possible arrival/departure/passing mode and makes switch_master and signposting_master execute specific instruction set defined for that route and contained in these.

Spoiler

rednet.open("back")
rednet.host("tragitti","gestore_tragitti")
		
local monitor = peripheral.wrap("top")
		
function configura_tragitto_arrivo_X()
rednet.broadcast("configura_tragitto_arrivo_X")
end
function configura_tragitto_arrivo_Y()
rednet.broadcast("configura_tragitto_arrivo_Y")
end
function configura_tragitto_arrivo_Z()
rednet.broadcast("configura_tragitto_arrivo_Z")
end
function configura_tragitto_arrivo_001()
rednet.broadcast("configura_tragitto_arrivo_001")
end
function configura_tragitto_arrivo_002()
rednet.broadcast("configura_tragitto_arrivo_002")
end
function configura_tragitto_arrivo_003()
rednet.broadcast("configura_tragitto_arrivo_003")
end
function configura_tragitto_arrivo_004()
rednet.broadcast("configura_tragitto_arrivo_004")
end
function configura_tragitto_arrivo_005()
rednet.broadcast("configura_tragitto_arrivo_005")
end
function configura_tragitto_arrivo_006()
rednet.broadcast("configura_tragitto_arrivo_006")
end
function configura_tragitto_arrivo_007()
rednet.broadcast("configura_tragitto_arrivo_007")
end
function configura_tragitto_arrivo_008()
rednet.broadcast("configura_tragitto_arrivo_008")
end
function configura_tragitto_arrivo_009()
rednet.broadcast("configura_tragitto_arrivo_009")
end
function configura_tragitto_partenza_X()
rednet.broadcast("configura_tragitto_partenza_X")
end
function configura_tragitto_partenza_Y()
rednet.broadcast("configura_tragitto_partenza_Y")
end
function configura_tragitto_partenza_Z()
rednet.broadcast("configura_tragitto_partenza_Z")
end
function configura_tragitto_partenza_001()
rednet.broadcast("configura_tragitto_partenza_001")
end
function configura_tragitto_partenza_002()
rednet.broadcast("configura_tragitto_partenza_002")
end
function configura_tragitto_partenza_003()
rednet.broadcast("configura_tragitto_partenza_003")
end
function configura_tragitto_partenza_004()
rednet.broadcast("configura_tragitto_partenza_004")
end
function configura_tragitto_partenza_005()
rednet.broadcast("configura_tragitto_partenza_005")
end
function configura_tragitto_partenza_006()
rednet.broadcast("configura_tragitto_partenza_006")
end
function configura_tragitto_partenza_007()
rednet.broadcast("configura_tragitto_partenza_007")
end
function configura_tragitto_partenza_008()
rednet.broadcast("configura_tragitto_partenza_008")
end
function configura_tragitto_partenza_009()
rednet.broadcast("configura_tragitto_partenza_009")
end
function configura_tragitto_transito_X()
rednet.broadcast("configura_tragitto_transito_X")
end
function configura_tragitto_transito_Y()
rednet.broadcast("configura_tragitto_transito_Y")
end
function configura_tragitto_transito_Z()
rednet.broadcast("configura_tragitto_transito_Z")
end
function configura_tragitto_transito_001()
rednet.broadcast("configura_tragitto_transito_001")
end
function configura_tragitto_transito_002()
rednet.broadcast("configura_tragitto_transito_002")
end
function configura_tragitto_transito_003()
rednet.broadcast("configura_tragitto_transito_003")
end
function configura_tragitto_transito_004()
rednet.broadcast("configura_tragitto_transito_004")
end
function configura_tragitto_transito_005()
rednet.broadcast("configura_tragitto_transito_005")
end
function configura_tragitto_transito_006()
rednet.broadcast("configura_tragitto_transito_006")
end
function configura_tragitto_transito_007()
rednet.broadcast("configura_tragitto_transito_007")
end
function configura_tragitto_transito_008()
rednet.broadcast("configura_tragitto_transito_008")
end
function configura_tragitto_transito_009()
rednet.broadcast("configura_tragitto_transito_009")
end
function stato_binario_X()
rednet.broadcast("stato_binario_X")
end
function stato_binario_Y()
rednet.broadcast("stato_binario_Y")
end
function stato_binario_Z()
rednet.broadcast("stato_binario_Z")
end
function stato_binario_001()
rednet.broadcast("stato_binario_001")
end
function stato_binario_002()
rednet.broadcast("stato_binario_002")
end
function stato_binario_003()
rednet.broadcast("stato_binario_003")
end
function stato_binario_004()
rednet.broadcast("stato_binario_004")
end
function stato_binario_005()
rednet.broadcast("stato_binario_005")
end
function stato_binario_006()
rednet.broadcast("stato_binario_006")
end
function stato_binario_007()
rednet.broadcast("stato_binario_007")
end
function stato_binario_008()
rednet.broadcast("stato_binario_008")
end
function stato_binario_009()
rednet.broadcast("stato_binario_009")
end

while true do
event, id, message, distance, protocol = os.pullEvent("rednet_message")

if message == "aggiornamento_arrivo" then
stato_binario_001()
   if message == "binario_001_libero" then
   configura_tragitto_arrivo_001()
   else stato_binario_002()
	if message == "binario_002_libero" then
	 configura_tragitto_arrivo_002()
	 else stato_binario_003()
	  if message == "binario_003_libero" then
	  configura_tragitto_arrivo_003()
	  else stato_binario_004()
	   if message == "binario_004_libero" then
	   configura_tragitto_arrivo_004()
	   else stato_binario_005()
		if message == "binario_005_libero" then
		configura_tragitto_arrivo_005()
		else

  etc etc etc	

end

end

I probably have made things in a stupid way, I tryed my best, and there is a better way to get the same things with twenty times less lines.
I don't really think it is correct what I've written, beacuse I am not sure if every time system request for a binary state from rednet and the states_master responds this program is still listening and can continue operation
I would appreciate any kind of help.

Sorry for long thread and for my errors, I'm learning english as much as programming.
Edited on 15 February 2016 - 11:16 AM
valithor #2
Posted 01 October 2015 - 10:09 PM
Your assumption about it not listening is correct. LUA code runs from top to bottom, so it is only listening for the message the one time you call os.pullEvent(). With that in mind I am also going to help you shorten your code, while helping you fix this problem.

So… Your individual functions can be shortened to a single function, which accepts a argument.

Example of functions with arguments:

function say(argument) --# the argument name can be anything
  print(argument)
end

say("hi") --# will print hi
say("hello") --# will print hello

So applied to your code:

function configura_tragitto_arrivo(argument)
 rednet.broadcast("configura_tragitto_arrivo_"..argument)
end

function configura_tragitto_partenza(argument)
  rednet.broadcast("configura_tragitto_partenza_"..argument)
end

function configura_tragitto_transito(argument)
  rednet.broadcast("configura_tragitto_transito_"..argument)
end

function stato_binario(argument)
  rednet.broadcast("stato_binario_"..argument)
end

Now since we have changed the functions to accept an argument we can now use a for loop to loop through all of the possible messages.


for i = 1, 9 do --# will loop through the numbers 1-9, and assign the current loop number to i

  event, id, message, distance, protocol = os.pullEvent("rednet_message")

  if message == "binario_00"..i.."_ibero" then
    configura_tragitto_arrivo(i)
    break --# will exit the loop if run, so if the if statement runs
  else
    stato_binario(i)
  end

end

If you need me to explain anything that I posted, or if I missed something obvious, then feel free to ask.
Edited on 01 October 2015 - 08:12 PM
pietro.devo #3
Posted 02 October 2015 - 02:57 PM
Thank you very much! Everything clear.

Now I'm wrtitting again stuff in a better way.
I have removed all X, Y, Z thing to just use numbers, also all the zeros.

What I've re-worked is gestore_stati, the states manager, this was the first working version:

Spoiler

rednet.open("back")
rednet.host("stati","gestore_stati")
display = peripheral.wrap("top")
binario_X = " "
binario_Y = " "
binario_Z = " "
binario_001 = " "
binario_002 = " "
binario_003 = " "
binario_004 = " "
binario_005 = " "
binario_006 = " "
binario_007 = " "
binario_008 = " "
binario_009 = " "
scambio_X = " "
scambio_Y = " "
scambio_Z = " "
scambio_001 = " "
scambio_002 = " "
scambio_003 = " "
scambio_004 = " "
scambio_005 = " "
scambio_006 = " "
scambio_007 = " "
scambio_008 = " "
scambio_009 = " "
segnale_X = " "
segnale_Y = " "
segnale_Z = " "
segnale_001 = " "
segnale_002 = " "
segnale_003 = " "
segnale_004 = " "
segnale_005 = " "
segnale_006 = " "
segnale_007 = " "
segnale_008 = " "
segnale_009 = " "
function clear()
term.clear()
term.setCursorPos(1,1)
end
function monitor()
term.redirect(display)
print(" ")
print("BINARI")
print(" ")
print("1 - ",binario_001)
print("2 - ",binario_002)
print("3 - ",binario_003)
print("4 - ",binario_004)
print("5 - ",binario_005)
print("6 - ",binario_006)
print("7 - ",binario_007)
print("8 - ",binario_008)
print("9 - ",binario_009)
print("_________________")
print(" ")
print("SCAMBI")
print(" ")
print("1 - ",scambio_001)
print("2 - ",scambio_002)
print("3 - ",scambio_003)
print("4 - ",scambio_004)
print("5 - ",scambio_005)
print("6 - ",scambio_006)
print("7 - ",scambio_007)
print("8 - ",scambio_008)
print("9 - ",scambio_009)
print("_________________")
print(" ")
print("SEGNALI")
print(" ")
print("1 - ",segnale_001)
print("2 - ",segnale_002)
print("3 - ",segnale_003)
print("4 - ",segnale_004)
print("5 - ",segnale_005)
print("6 - ",segnale_006)
print("7 - ",segnale_007)
print("8 - ",segnale_008)
print("9 - ",segnale_009)
end
function stato_binari()
rednet.broadcast("binario_X_",binario_X)
rednet.broadcast("binario_Y_",binario_Y)
rednet.broadcast("binario_Z_",binario_Z)
rednet.broadcast("binario_001_",binario_001)
rednet.broadcast("binario_002_",binario_002)
rednet.broadcast("binario_003_",binario_003)
rednet.broadcast("binario_004_",binario_004)
rednet.broadcast("binario_005_",binario_005)
rednet.broadcast("binario_006_",binario_006)
rednet.broadcast("binario_007_",binario_007)
rednet.broadcast("binario_008_",binario_008)
rednet.broadcast("binario_009_",binario_009)
end
function stato_binario_X()
rednet.broadcast("binario_X_",binario_X)
end
function aggiornamento_binario_X_libero()
binario_X = "libero"
end
function aggiornamento_binario_X_occupato()
binario_X = "occupato"
end
function aggiornamento_binario_X_transito()
binario_X = "transito"
end
function stato_binario_Y()
rednet.broadcast("binario_Y_",binario_Y)
end
function aggiornamento_binario_Y_libero()
binario_Y = "libero"
end
function aggiornamento_binario_Y_occupato()
binario_Y = "occupato"
end
function aggiornamento_binario_Y_transito()
binario_Y = "transito"
end
function stato_binario_Z()
rednet.broadcast("binario_Z_",binario_Z)
end
function aggiornamento_binario_Z_libero()
binario_Z = "libero"
end
function aggiornamento_binario_Z_occupato()
binario_Z = "occupato"
end
function aggiornamento_binario_Z_transito()
binario_Z = "transito"
end
function stato_binario_001()
rednet.broadcast("binario_001_",binario_001)
end
function aggiornamento_binario_001_libero()
binario_001 = "libero"
end
function aggiornamento_binario_001_occupato()
binario_001 = "occupato"
end
function aggiornamento_binario_001_transito()
binario_001 = "transito"
end
function stato_binario_002()
rednet.broadcast("binario_002_",binario_002)
end
function aggiornamento_binario_002_libero()
binario_002 = "libero"
end
function aggiornamento_binario_002_occupato()
binario_002 = "occupato"
end
function aggiornamento_binario_002_transito()
binario_002 = "transito"
end
function stato_binario_003()
rednet.broadcast("binario_003_",binario_003)
end
function aggiornamento_binario_003_libero()
binario_003 = "libero"
end
function aggiornamento_binario_003_occupato()
binario_003 = "occupato"
end
function aggiornamento_binario_003_transito()
binario_003 = "transito"
end
function stato_binario_004()
rednet.broadcast("binario_004_",binario_004)
end
function aggiornamento_binario_004_libero()
binario_004 = "libero"
end
function aggiornamento_binario_004_occupato()
binario_004 = "occupato"
end
function aggiornamento_binario_004_transito()
binario_004 = "transito"
end
function stato_binario_005()
rednet.broadcast("binario_005_",binario_005)
end
function aggiornamento_binario_005_libero()
binario_005 = "libero"
end
function aggiornamento_binario_005_occupato()
binario_005 = "occupato"
end
function aggiornamento_binario_005_transito()
binario_005 = "transito"
end
function stato_binario_006()
rednet.broadcast("binario_006_",binario_006)
end
function aggiornamento_binario_006_libero()
binario_006 = "libero"
end
function aggiornamento_binario_006_occupato()
binario_006 = "occupato"
end
function aggiornamento_binario_006_transito()
binario_006 = "transito"
end
function stato_binario_007()
rednet.broadcast("binario_007_",binario_007)
end
function aggiornamento_binario_007_libero()
binario_007 = "libero"
end
function aggiornamento_binario_007_occupato()
binario_007 = "occupato"
end
function aggiornamento_binario_007_transito()
binario_007 = "transito"
end
function stato_binario_008()
rednet.broadcast("binario_008_",binario_008)
end
function aggiornamento_binario_008_libero()
binario_008 = "libero"
end
function aggiornamento_binario_008_occupato()
binario_008 = "occupato"
end
function aggiornamento_binario_008_transito()
binario_008 = "transito"
end
function stato_binario_009()
rednet.broadcast("binario_009_",binario_009)
end
function aggiornamento_binario_009_libero()
binario_009 = "libero"
end
function aggiornamento_binario_009_occupato()
binario_009 = "occupato"
end
function aggiornamento_binario_009_transito()
binario_009 = "transito"
end
function stato_scambi()
rednet.broadcast("scambio_X_",scambio_X)
rednet.broadcast("scambio_Y_",scambio_Y)
rednet.broadcast("scambio_Z_",binario_Z)
rednet.broadcast("scambio_001_",scambio_001)
rednet.broadcast("scambio_002_",scambio_002)
rednet.broadcast("scambio_003_",scambio_003)
rednet.broadcast("scambio_004_",scambio_004)
rednet.broadcast("scambio_005_",scambio_005)
rednet.broadcast("scambio_006_",scambio_006)
rednet.broadcast("scambio_007_",scambio_007)
rednet.broadcast("scambio_008_",scambio_008)
rednet.broadcast("scambio_009_",scambio_009)
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_scambio_X()
rednet.broadcast("scambio_X_",scambio_X)
end
function aggiornamento_scambio_X_attivo()
scambio_X = "attivo"
end
function aggiornamento_scambio_X_inattivo()
scambio_X = "inattivo"
end
function stato_segnali()
rednet.broadcast("segnale_X_",segnale_X)
rednet.broadcast("segnale_Y_",segnale_Y)
rednet.broadcast("segnale_Z_",segnale_Z)
rednet.broadcast("segnale_001_",segnale_001)
rednet.broadcast("segnale_002_",segnale_002)
rednet.broadcast("segnale_003_",segnale_003)
rednet.broadcast("segnale_004_",segnale_004)
rednet.broadcast("segnale_005_",segnale_005)
rednet.broadcast("segnale_006_",segnale_006)
rednet.broadcast("segnale_007_",segnale_007)
rednet.broadcast("segnale_008_",segnale_008)
rednet.broadcast("segnale_009_",segnale_009)
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
function stato_segnale_X()
rednet.broadcast("segnale_X_",segnale_X)
end
function aggiornamento_segnale_X_attivo()
segnale_X = "attivo"
end
function aggiornamento_segnale_X_inattivo()
segnale_X = "inattivo"
end
while true do
event, id, message, distance, protocol = os.pullEvent("rednet_message")

if message == "stato_binari" then
  stato_binari()
end
if message == "stato_binario_X" then
  stato_binario_X()
end
if message == "stato_binario_Y" then
  stato_binario_Y()
end
if message == "stato_binario_Z" then
  stato_binario_Z()
end
if message == "stato_binario_001" then
  stato_binario_001()
end
if message == "stato_binario_002" then
  stato_binario_002()
end
if message == "stato_binario_003" then
  stato_binario_003()
end
if message == "stato_binario_004" then
  stato_binario_004()
end
if message == "stato_binario_005" then
  stato_binario_005()
end
if message == "stato_binario_006" then
  stato_binario_006()
end
if message == "stato_binario_007" then
  stato_binario_007()
end
if message == "stato_binario_008" then
  stato_binario_008()
end
if message == "stato_binario_009" then
  stato_binario_009()
end
if message == "stato_scambi" then
  stato_scambi()
end
if message == "stato_scambio_X" then
  stato_scambio_X()
end
if message == "stato_scambio_Y" then
  stato_scambio_Y()
end
if message == "stato_scambio_Z" then
  stato_scambio_Z()
end
if message == "stato_scambio_001" then
  stato_scambio_001()
end
if message == "stato_scambio_002" then
  stato_scambio_002()
end
  if message == "stato_scambio_003" then
stato_scambio_003()
end
if message == "stato_scambio_004" then
  stato_scambio_004()
end
if message == "stato_scambio_005" then
  stato_scambio_005()
end
if message == "stato_scambio_006" then
  stato_scambio_006()
end
if message == "stato_scambio_007" then
  stato_scambio_007()
end
if message == "stato_scambio_008" then
  stato_scambio_008()
end
if message == "stato_scambio_009" then
  stato_scambio_009()
end
if message == "stato_segnali" then
  stato_segnali()
end
if message == "stato_segnale_X" then
  stato_segnale_X()
end
if message == "stato_segnale_Y" then
  stato_segnale_Y()
end
if message == "stato_segnale_Z" then
  stato_segnale_Z()
end
  if message == "stato_segnale_001" then
stato_segnale_001()
end
  if message == "stato_segnale_002" then
stato_segnale_002()
end
if message == "stato_segnale_003" then
  stato_segnale_003()
end
if message == "stato_segnale_004" then
  stato_segnale_004()
end
if message == "stato_segnale_005" then
  stato_segnale_005()
end
if message == "stato_segnale_006" then
  stato_segnale_006()
end
if message == "stato_segnale_007" then
  stato_segnale_007()
end
if message == "stato_segnale_008" then
  stato_segnale_008()
end
if message == "stato_segnale_009" then
  stato_segnale_009()
end
if message == "aggiornamento_binario_001_libero" then
  aggiornamento_binario_001_libero()
  clear()
  monitor()
end
if message == "aggiornamento_binario_001_occupato" then
  aggiornamento_binario_001_occupato()
  clear()
  monitor()
end
if message == "aggiornamento_binario_001_transito" then
  aggiornamento_binario_001_transito()
  clear()
  monitor()
end
if message == "aggiornamento_binario_002_libero" then
  aggiornamento_binario_002_libero()
  clear()
  monitor()
end
if message == "aggiornamento_binario_002_occupato" then
  aggiornamento_binario_002_occupato()
  clear()
  monitor()
end
if message == "aggiornamento_binario_002_transito" then
  aggiornamento_binario_002_transito()
  clear()
  monitor()
end
if message == "aggiornamento_binario_003_libero" then
  aggiornamento_binario_003_libero()
  clear()
  monitor()
end
if message == "aggiornamento_binario_003_occupato" then
  aggiornamento_binario_003_occupato()
  clear()
  monitor()
end
if message == "aggiornamento_binario_003_transito" then
  aggiornamento_binario_003_transito()
  clear()
  monitor()
end
if message == "aggiornamento_binario_004_libero" then
  aggiornamento_binario_004_libero()
  clear()
  monitor()
end
if message == "aggiornamento_binario_004_occupato" then
  aggiornamento_binario_004_occupato()
  clear()
  monitor()
end
if message == "aggiornamento_binario_004_transito" then
  aggiornamento_binario_004_transito()
  clear()
  monitor()
end
if message == "aggiornamento_binario_005_libero" then
  aggiornamento_binario_005_libero()
  clear()
  monitor()
end
if message == "aggiornamento_binario_005_occupato" then
  aggiornamento_binario_005_occupato()
  clear()
  monitor()
end
if message == "aggiornamento_binario_005_transito" then
  aggiornamento_binario_005_transito()
  clear()
  monitor()
end
end

And here we have the new one, actually there isn't the local printing function, I'll add later or, maybe, much better, I will work on a broadcasting system that let display and updates all values on a remote and dedicated system:

Spoiler

rednet.open("back")
rednet.host("stati","gestore_stati")
display = peripheral.wrap("top")
binario_0 = " "
binario_1 = " "
binario_2 = " "
binario_3 = " "
binario_4 = " "
binario_5 = " "
binario_6 = " "
binario_7 = " "
binario_8 = " "
binario_9 = " "
binario_10 = " "
binario_11 = " "
binario_12 = " "
binario_13 = " "
binario_14 = " "
binario_15 = " "
binario_16 = " "
binario_17 = " "
binario_18 = " "
binario_19 = " "
binario_20 = " "
binario_21 = " "
binario_22 = " "
binario_23 = " "
binario_24 = " "
binario_25 = " "
binario_26 = " "
binario_27 = " "
binario_28 = " "
binario_29 = " "
binario_30 = " "
binario_31 = " "
binario_32 = " "
binario_33 = " "
binario_34 = " "
binario_35 = " "
binario_36 = " "
binario_37 = " "
binario_38 = " "
binario_39 = " "
binario_40 = " "
binario_41 = " "
binario_42 = " "
binario_43 = " "
binario_44 = " "
binario_45 = " "
binario_46 = " "
binario_47 = " "
binario_48 = " "
binario_49 = " "
binario_50 = " "
scambio_0 = " "
scambio_1 = " "
scambio_2 = " "
scambio_3 = " "
scambio_4 = " "
scambio_5 = " "
scambio_6 = " "
scambio_7 = " "
scambio_8 = " "
scambio_9 = " "
scambio_10 = " "
scambio_11 = " "
scambio_12 = " "
scambio_13 = " "
scambio_14 = " "
scambio_15 = " "
scambio_16 = " "
scambio_17 = " "
scambio_18 = " "
scambio_19 = " "
scambio_20 = " "
scambio_21 = " "
scambio_22 = " "
scambio_23 = " "
scambio_24 = " "
scambio_25 = " "
scambio_26 = " "
scambio_27 = " "
scambio_28 = " "
scambio_29 = " "
scambio_30 = " "
scambio_31 = " "
scambio_32 = " "
scambio_33 = " "
scambio_34 = " "
scambio_35 = " "
scambio_36 = " "
scambio_37 = " "
scambio_38 = " "
scambio_39 = " "
scambio_40 = " "
scambio_41 = " "
scambio_42 = " "
scambio_43 = " "
scambio_44 = " "
scambio_45 = " "
scambio_46 = " "
scambio_47 = " "
scambio_48 = " "
scambio_49 = " "
scambio_50 = " "
segnale_0 = " "
segnale_1 = " "
segnale_2 = " "
segnale_3 = " "
segnale_4 = " "
segnale_5 = " "
segnale_6 = " "
segnale_7 = " "
segnale_8 = " "
segnale_9 = " "
segnale_10 = " "
segnale_11 = " "
segnale_12 = " "
segnale_13 = " "
segnale_14 = " "
segnale_15 = " "
segnale_16 = " "
segnale_17 = " "
segnale_18 = " "
segnale_19 = " "
segnale_20 = " "
segnale_21 = " "
segnale_22 = " "
segnale_23 = " "
segnale_24 = " "
segnale_25 = " "
segnale_26 = " "
segnale_27 = " "
segnale_28 = " "
segnale_29 = " "
segnale_30 = " "
segnale_31 = " "
segnale_32 = " "
segnale_33 = " "
segnale_34 = " "
segnale_35 = " "
segnale_36 = " "
segnale_37 = " "
segnale_38 = " "
segnale_39 = " "
segnale_40 = " "
segnale_41 = " "
segnale_42 = " "
segnale_43 = " "
segnale_44 = " "
segnale_45 = " "
segnale_46 = " "
segnale_47 = " "
segnale_48 = " "
segnale_49 = " "
segnale_50 = " "
function stato_binario(argument)
rednet.broadcast("binario_"..argument.."_",binario_(argument))
end
function aggiornamento_binario_libero(argument)
binario_(argument) = "libero"
end
function aggiornamento_binario_occupato(argument)
binario_(argument) = "occupato"
end
function aggiornamento_binario_transito(argument)
binario_(argument) = "transito"
end
function stato_scambio(argument)
rednet.broadcast("scambio_"..argument.."_",scambio_(argument))
end
function aggiornamento_scambio_attivo(argument)
scambio_(argument) = "attivo"
end
function aggiornamento_scambio_inattivo(argument)
scambio_(argument) = "inattivo"
end
function aggiornamento_scambio_temporizzato(argument)
scambio_(argument) = "temporizzato"
end
function stato_segnale(argument)
rednet.broadcast("segnale_"..argument.."_",segnale_(argument))
end
function aggiornamento_segnale_attivo(argument)
segnale_(argument) = "attivo"
end
function aggiornamento_segnale_inattivo(argument)
segnale_(argument) = "inattivo"
end
function aggiornamento_segnale_temporizzato(argument)
segnale_(argument) = "temporizzato"
end
for i = 0, 50 do
  event, id, message, distance, protocol = os.pullEvent("rednet_message")
 
  if message == "stato_binario_"..i.." then
    stato_binario(i)
    break --# will exit the loop if run, so if the if statement runs
  end
 
  if message == "aggiornamento_binario_"..i.."_libero" then
    aggiornamento_binario_libero(i)
  end
 
  if message == "aggiornamento_binario_"..i.."_occupato" then
    aggiornamento_binario_occupato(i)
  end
 
  if message == "aggiornamento_binario_"..i.."_transito" then
    aggiornamento_binario_transito(i)
  end
 
  if message == "stato_scambio_"..i.." then
    stato_scambio(i)
    break --# will exit the loop if run, so if the if statement runs
  end
 
  if message == "aggiornamento_scambio_"..i.."_attivo" then
    aggiornamento_scambio_attivo(i)
  end
 
  if message == "aggiornamento_scambio_"..i.."_inattivo" then
    aggiornamento_scambio_inattivo(i)
  end
 
  if message == "aggiornamento_scambio_"..i.."_temporizzato" then
    aggiornamento_scambio_temporizzato(i)
  end
 
  if message == "stato_segnale_"..i.." then
    stato_segnale(i)
    break --# will exit the loop if run, so if the if statement runs
  end
 
  if message == "aggiornamento_segnale_"..i.."_attivo" then
    aggiornamento_segnale_attivo(i)
  end
 
  if message == "aggiornamento_segnale_"..i.."_inattivo" then
    aggiornamento_segnale_inattivo(i)
  end
 
  if message == "aggiornamento_segnale_"..i.."_temporizzato" then
    aggiornamento_segnale_temporizzato(i)
  end
 
end

I will translate names for better understanding:

binario —- > binary
scambio —-> switch
segnale —-> light/signpost

stato —-> state
aggiornamento —-> update

libero —-> free
occupato —-> busy
transito —-> passing

attivo —-> on
inattivo —-> off
temporizzato —-> temporized

So, what this basically does is storing all core variables for the system, constantly listening to rednet for state request (stato_), to which respond broadcasting the actual stored value, and state update (aggiornamento_), to which react writing the new value of variables.

is it written correctly and is there any further optimization to reduce lenght off all the stuff? (I would like to combine all "aggiornamento_" messages of every component, without splitting into "_libero/_occupato/_transito" or "_attivo/_inattivo/_temporizzato" but I am honestly not sure how to do this.

Thanks again valithor for your kind reply
valithor #4
Posted 02 October 2015 - 06:49 PM
You can shorten all of the variable declarations using tables. Tables are a extremely powerful part of LUA, but they are slightly difficult to understand at first. Essentially they are a variable, which contains a large number of other variables inside of it. Each variable inside of the table is assigned to a "key" or reference value, which makes it to where you can loop through similar to how we did the functions.


tbl = {} --# creating the table
tbl[1] = "hi"
tbl[2] = "hello"

print(tbl[1]) --# prints hi
print(tbl[2]) --# prints hello

Applied to your code:

binario = {}
scambio = {}
segnale = {}

for i = 0, 50 do
  binario[i] = " "
  scambio[i] = " "
  segnale[i] = " "
end

To reference the values in the table you would do tablename[keyname], so for example you could do binario[1] to reference the variable assigned to the "1" key.

A few things you might want to change, but I am not completely sure:

- putting the for loop inside a while loop, so the program is constantly running

while true do
  for i = 1, 50 do
	--# I removed everything from here to make the post take less space
  end
end

- You will need to restructure your code in order for it to work how you want. The way the for loop is setup up currently it is expecting a rednet message before it does the loop each time, so you can only put functions in the loop that are requesting a new rednet message to be sent to the computer.

Applied:

binario = {}
scambio = {}
segnale = {}

for i = 0, 50 do
  binario[i] = " "
  scambio[i] = " "
  segnale[i] = " "
end

function stato_binario(argument)
  rednet.broadcast("binario_"..argument.."_",binario_(argument))
end
function aggiornamento_binario_libero(argument)
  binario[argument] = "libero"
end
function aggiornamento_binario_occupato(argument)
  binario[argument] = "occupato"
end
function aggiornamento_binario_transito(argument)
  binario[argument] = "transito"
end
function stato_scambio(argument)
  rednet.broadcast("scambio_"..argument.."_",scambio_(argument))
end
function aggiornamento_scambio_attivo(argument)
  scambio[argument] = "attivo"
end
function aggiornamento_scambio_inattivo(argument)
  scambio[argument] = "inattivo"
end
function aggiornamento_scambio_temporizzato(argument)
  scambio[argument] = "temporizzato"
end
function stato_segnale(argument)
  rednet.broadcast("segnale_"..argument.."_",segnale_(argument))
end
function aggiornamento_segnale_attivo(argument)
  segnale[argument] = "attivo"
end
function aggiornamento_segnale_inattivo(argument)
  segnale[argument] = "inattivo"
end
function aggiornamento_segnale_temporizzato(argument)
  segnale[argument] = "temporizzato"
end

while true do
  event, id, message, distance, protocol = os.pullEvent("rednet_message")
  local boolean = false --# used to keep track of whether or not the message has been found

  for i = 0, 50 do --# checking the ones that do not require os.pullEvent first

	if message == "aggiornamento_binario_"..i.."_libero" then
	  aggiornamento_binario_libero(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_binario_"..i.."_occupato" then
	  aggiornamento_binario_occupato(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_binario_"..i.."_transito" then
	  aggiornamento_binario_transito(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_scambio_"..i.."_attivo" then
	  aggiornamento_scambio_attivo(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_scambio_"..i.."_inattivo" then
	  aggiornamento_scambio_inattivo(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_scambio_"..i.."_temporizzato" then
	  aggiornamento_scambio_temporizzato(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_segnale_"..i.."_attivo" then
	  aggiornamento_segnale_attivo(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_segnale_"..i.."_inattivo" then
	  aggiornamento_segnale_inattivo(i)
	  boolean = true
	  break
	end

	if message == "aggiornamento_segnale_"..i.."_temporizzato" then
	  boolean = true
	  aggiornamento_segnale_temporizzato(i)
	  break
	end
  end
  if boolean == false then
	for i = 0, 50 do
	  if message == "stato_scambio_"..i.." then
		stato_scambio(i)
		break --# will exit the loop if run, so if the if statement runs
	  end

	  if message == "stato_segnale_"..i.." then
		stato_segnale(i)
		break --# will exit the loop if run, so if the if statement runs
	  end

	  if message == "stato_binario_"..i.." then
		stato_binario(i)
		break --# will exit the loop if run, so if the if statement runs
	  end
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	end
  end
end

If you need me to explain anything feel free to ask. I am in class right now, and ran out of time before I could explain everything.
Edited on 02 October 2015 - 04:53 PM
pietro.devo #5
Posted 05 October 2015 - 08:28 AM
Thanks again for your reply.

I am learning the use of tables, and trying to follow your nice suggestion.
First of all I tried to use your code, I have set up a tester that frequently requests for states and then a displayer of rednet messages to see if the states manager is working correctly.
Program works without errors but doesn't seem to respond to states requests.

What then I did to investigate is putting a local print function just after and update execution and it just doesn't work.
I can't understand if is it actually storing values but not responding or not storing and updating values too.
There is something wrong, but I can't understant what, maybe I'll return to the simpler things
Edited on 26 October 2015 - 09:01 AM
pietro.devo #6
Posted 26 October 2015 - 10:01 AM
Any idea on what's wrong?
Bomb Bloke #7
Posted 28 October 2015 - 12:50 AM
First of all I tried to use your code, I have set up a tester that frequently requests for states and then a displayer of rednet messages to see if the states manager is working correctly.
Program works without errors but doesn't seem to respond to states requests.

Checking valithor's suggested code, I'd be surprised if you don't get errors - the mis-matching quotes down the bottom should cause it to crash. The script you posted has the same problem; a line like:

if message == "stato_scambio_"..i.." then

… should be:

if message == "stato_scambio_"..i then

… or else you'll be checking if "message" is equal to lots of lines of code!

Assuming you fixed that, and corrected the commas in the rednet.broadcast() calls to something more like rednet.broadcast("binario_"..argument.."_"..binario[argument]), it looks like the extra os.pullEvent() call down the bottom would stop it from reliably responding to anything. It may also have trouble if you're using leading zeros in front of the numbers in your strings (eg, "aggiornamento_scambio_050_inattivo").

You really need to stop using functions for every little thing. A good function can be used from multiple areas of your script. If you don't want to use it more than once, then you probably shouldn't be writing it as a function.

Your code can be reduced dramatically by making better use of tables. Here's another re-write of the same stuff:

rednet.open("back")
rednet.host("stati","gestore_stati")
local display = peripheral.wrap("top")

-- Build structures of tables:
local aggiornamento = { binario = {}, scambio = {}, segnale = {} }
for i = 0, 50 do
	aggiornamento["binario"][i] = " "
	aggiornamento["scambio"][i] = " "
	aggiornamento["segnale"][i] = " "
end

-- So now we can access eg scambio_2 as aggiornamento["scambio"][2]

while true do  -- Run a loop that repeats indefinitely.
	local senderID, message = rednet.receive()
	
	-- Split the message into "words" (using pattern matching), put them into a new table:
	local words = {}
	for word in string.gmatch(message, "%w+") do words[#words + 1] = word end
	
	-- Eg, if the message is "aggiornamento_scambio_050_inattivo",
	-- then words[1] will be "aggiornamento", words[2] will be "scambio", words[3] will be "050", etc...
	
	-- It would be a lot easier to just rednet.send() tables of words in the first place, instead of combining them altogether into single strings!!!
	
	if words[1] == "stato" then
		rednet.broadcast(words[2].."_"..words[3].."_"..aggiornamento[ words[2] ][ tonumber(words[3]) ])
		
		-- So if we got the message "stato_binario_010",
		-- words[2] would be "binario", words[3] would be "010",
		-- so we would send back:
		
		-- "binario" .. "_" .. "010" .. "_" .. aggiornamento[ "binario" ][ 10 ]
	
	elseif words[1] == "aggiornamento" then
		aggiornamento[ words[2] ][ tonumber(words[3]) ] = words[4]
		
		-- So if we got the message "aggiornamento_scambio_050_inattivo",
		-- we would end up doing:
		
		-- aggiornamento[ "scambio" ][ 50 ] = "inattivo"
		
	end
end
pietro.devo #8
Posted 28 October 2015 - 03:47 PM
Thank you very much for your response.
You are right, I'm using a long and basic code for my program, I could not write down as you did by myself.
Now I will try to use the form you wrote, I just did prefer to use "stato" instead of "aggiornamento" because of the concept, so this is what I have now, hope is right (Had to add and "end" beacuse got execution error):

Spoiler

rednet.open("back")
rednet.host("stati","gestore_stati")
local display = peripheral.wrap("top")
local aggiornamento = { binario = {}, scambio = {}, segnale = {} }
for i = 0, 50 do
	    stato["binario"][i] = " "
	    stato["scambio"][i] = " "
	    stato["segnale"][i] = " "
end
while true do
	    local senderID, message = rednet.receive()
	   
	    local words = {}
	    for word in string.gmatch(message, "%w+") do words[#words + 1] = word end
					
	    if words[1] == "stato" then
			    rednet.broadcast(words[2].."_"..words[3].."_"..stato[ words[2] ][ tonumber(words[3]) ])
					 
	    else if words[1] == "aggiornamento" then
			    stato[ words[2] ][ tonumber(words[3]) ] = words[4]
							   
	    end
end 
end


Now i get "gestore_stati:9 attempt to index ?" and I can't find out what is wrong.
I'm going on writing the rest of things trying to reduce code as well and planning then to share (translated in english) for everything interested
KingofGamesYami #9
Posted 28 October 2015 - 03:54 PM
You haven't defined 'stato' as a table, so you cannot treat it as one.

This line:

local aggiornamento = { binario = {}, scambio = {}, segnale = {} }

…should be changed to this:

local stato = { binario = {}, scambio = {}, segnale = {} }
pietro.devo #10
Posted 28 October 2015 - 03:57 PM
Oh, that a really noob error, thank you very much
Bomb Bloke #11
Posted 29 October 2015 - 12:05 AM
(Had to add and "end" beacuse got execution error):

That's because you added a space here:

else if words[1] == "aggiornamento" then

It should work the way you've done it, but it'd be somewhat more tidy to just use "elseif".
Edited on 28 October 2015 - 11:06 PM
pietro.devo #12
Posted 12 November 2015 - 10:00 PM
Hi there.
I took again some time to continue my work, with my stupid knowledge.
Now I am trying to write some generic code for switches, then the same should be done for rail sensors (basically activator rails) and signals.
I have already archieved the thing to work writing ad-hoc code for a single switch, but I'd like to have just a code ready to use to put in every switch and just change a variable number, that identify that specific switch or sensor on the network and all the work is done.

Now, I am not absolutely sure if this is correct, but that's what I have written:

Spoiler

function rete(argument)
rednet.open("bottom")
rednet.host("scambi","scambio_"..i)

function avvio(argument)
print("avvio_scambio_"..i)
rednet.broadcast("avvio_scambio_"..i)
end

function scambio_attivo(argument)
redstone.setOutput("top", true)
rednet.broadcast("aggiornamento_scambio_"..i.."_attivo")
end

function scambio_inattivo(argument)
redstone.setOutput("top", false)
rednet.broadcast("aggiornamento_scambio_"..i.."_inattivo")
end

function scambio_temporizzato(argument)
redstone.setOutput("top", true)
rednet.broadcast("aggiornamento_scambio_"..i.."_temporizzato")
sleep(10)
redstone.setOutput("top", false)
rednet.broadcast("aggiornamento_scambio_"..i.."_inattivo")
end

i = 1

rete(i)
avvio(i)

while true do
local senderID, message = rednet.receive()

if message == "comando_scambio_"..i.."_attivo" then
scambio_attivo(i)
end
if message == "comando_scambio_"..i.."_inattivo" then
scambio_inattivo(i)
end
if message == "comando_scambio_"..i.."_temporizzato" then
scambio_temporizzato(i)
end

end

Then I am thinking on writing some sort of code that can make all devices boot with their code, a sort of central core that sends power_on or power_off function on the network, would be possible in a easy way for me?
Edited on 12 November 2015 - 10:01 PM
Bomb Bloke #13
Posted 13 November 2015 - 12:12 AM
I would just rely on all computers being on all the time. If the server shuts down or their chunks unload, they should boot back up when the chunks are next loaded, automatically.

But, if you really want to turn them on / off manually, and the devices are connected together using wired modems, then you can use peripheral.find() and the computer's peripheral functions to do this pretty easily:

local compList = {peripheral.find("computer")}  -- Hunt down all connected computers, wrap them as peripherals, stick them in a table.

for i = 1, #compList do compList[i].turnOn() end   -- Iterate through the table and turn each computer on.

Without a wired system, it's not so simple. You could probably do something with eg Wireless Redstone (WR-CBE) and an Autonomous Activator to start them, and a simple rednet message to trigger shut downs.
Edited on 13 November 2015 - 03:42 AM
pietro.devo #14
Posted 13 November 2015 - 06:58 AM
Your point is right, I think it's far better to just have computers always execute code. I will just have some core components that need to be always loaded, like the ones that have the control of train schedules, but he rest is fine.

For the switch code I know it is wrong, I am not so sure in the use of arguments
Bomb Bloke #15
Posted 13 November 2015 - 12:33 PM
Ah, yes, looking at your code I can see there's an issue or two. You've set "i" to 1 and then you never change it. If strings are incoming with different numbers in the middle of them, then you'd be better off using something like the technique I showed you earlier to break the strings up into separate words so you can inspect them individually.

Scratch that, you'd be better off sending the commands as tables in the first place instead of clumping multiple, separate bits of information together into single strings.

It'd be a lot easier to comment if you also provided the script which is sending the "comando"s, but I'm thinking that all the "numbers with the commands" business could be done away with if you just put that "senderID" data to good use.
pietro.devo #16
Posted 13 November 2015 - 01:56 PM
Yes, would be better to archieve that with tables, but for a switch I prefer to do this more friendly to me.
Sorry, I didn't explain well, I would like to install on place my switches, near the rails, then just set the "i" value at the moment, for each of them editing the generic code, on the base on what number I decide to assign to them.
Basically I have then a computer that sends all commands to the correct switches on the base of the route is needed to be set up.

EDIT:

I have solved problem writing the code this way:


i=""

print("inizializzazione")
sleep(1)
print("connessione")
rednet.open("bottom")
rednet.host("scambi","scambio_"..i)
rednet.broadcast("avvio_scambio_"..i)
sleep(1)
print("funzionamento")

while true do
event, id, message, distance, protocol = os.pullEvent("rednet_message")

if message == "comando_scambio_"..i.."_attivo" then
redstone.setOutput("back", true)
rednet.broadcast("aggiornamento_scambio_"..i.."_attivo")
end
if message == "comando_scambio_"..i.."_inattivo" then
redstone.setOutput("back", false)
rednet.broadcast("aggiornamento_scambio_"..i.."_inattivo")
end
if message == "comando_scambio_"..i.."_temporizzato" then
redstone.setOutput("back", true)
rednet.bradcast("aggironamento_scambio_"..i.."_temporizzato")
sleep(10)
redstone.setOutput("back", false)
rednet.broadcast("aggiornamento_scambio_"..i.."_inattivo")
end
end
Edited on 13 November 2015 - 10:10 PM
pietro.devo #17
Posted 24 November 2015 - 11:31 PM
Hi there.

Here I have written my detector's code.
Basically I am using railcraft detectors under rails, in a future I can use some traincraft possible rail detectors (if there will be), and this is the reason of redstone input from top or back of computer.
Because I have no permanent storage of information on the states manager (so at every server restart all variables need to be defined again) I have simply made every sensor check and send a network update at boot.


i=""

sleep(1)
print("< "..i.." >")
sleep(1)
print("rilevatore")
sleep(1)
print("assegnazione")
sleep(1)
print("inizializzazione")
sleep(1)
print("connessione")
rednet.open("bottom")
rednet.host("rilevatori","rilevatore_"..i)
rednet.broadcast("avvio_rilevatore_"..i)
sleep(1)
print("funzionamento")
sleep(1)
if redstone.getInput("top",true) then
rednet.broadcast("aggiornamento_rilevatore_"..i.."_attivo")
else if redstone.getInput("back",true) then
rednet.broadcast("aggiornamento_rilevatore_"..i.."_attivo")
else
rednet.broadcast("aggiornamento_rilevatore_"..i.."_inattivo")
end
end
while true do
os.pullEvent("redstone")
if redstone.getInput("top",true) then
rednet.broadcast("aggiornamento_rilevatore_"..i.."_attivo")
else if redstone.getInput("back",true) then
  rednet.broadcast("aggiornamento_rilevatore_"..i.."_attivo")
  else
  rednet.broadcast("aggiornamento_rilevatore_"..i.."_inattivo")
  end
end

end

The code is similiar to the switch one and signal one, I just download code from pastebin or from floppy on the fly when setting the computer and change its number at the beginning with a fast edit.

Now, my states manager listen on the network to update its variables, the problem I have found is in the rednet.host function of every single computer on the net.
I am using it to have every controller named in a precise way, and also is useful because if I accidentaly set up a certain controller with a number already in use it just has and error that says me that hostname is already used.
The problem is that with this rednet.host every computer sends a table message over the network and this break my states master, that just stops working because it expects strings.
Do I have to remove the rednet.host function from computers or can I do something on the code of states manager to avoid the issue?


print("< gestore >")
sleep(1)
print("stati")
sleep(1)
print("assegnazione")
sleep(1)
print("inizializzazione")
sleep(1)
print("connessione")
rednet.open("top")
rednet.host("sistemi","gestore_stati")
rednet.broadcast("avvio_gestore_stati")
sleep(1)
print("funzionamento")
local display = peripheral.wrap("top")
local stato = { binario = {}, scambio = {}, segnale = {}, rilevatore = {} }
for i = 0, 50 do
stato["binario"][i] = " "
stato["scambio"][i] = " "
stato["segnale"][i] = " "
stato["rilevatore"][i] = " "
end
while true do
local senderID, message = rednet.receive()
local words = {}

for word in string.gmatch(message, "%w+") do words[#words + 1] = word end
if words[1] == "stato" then
rednet.broadcast(words[2].."_"..words[3].."_"..stato[ words[2] ][ tonumber(words[3]) ])
end

if words[1] == "aggiornamento" then
stato[ words[2] ][ tonumber(words[3]) ] = words[4]
end
end
Bomb Bloke #18
Posted 24 November 2015 - 11:45 PM
rednet.host()/lookup()-related messages use a protocol of "dns". By using your own protocol for your own messages, you can ignore the "dns" ones.

rednet.broadcast("avvio_gestore_stati", "trainStation")   -- Broadcast using "trainStation" protocol.

local senderID, message = rednet.receive("trainStation")  -- Receive only messages sent using the "trainStation" protocol.
Edited on 24 November 2015 - 10:45 PM
pietro.devo #19
Posted 22 December 2015 - 04:07 PM
Thank you very much Bomb Bloke, I was planning to keep the DNS for some sort of useful thing in complex stations with many computers for technical monitoring, but It causes more troubles than help for me, so yes, better remove that.
I am very busy and working on this in the little time I get, now I am trying to learn the use of tables, that as you all pointed out, are the better and more polite way of going.
I'd like to drastically reduce code size for the switch master program, simply having some tables defined at the beginning of the code, edited when placing the controller on every station with the correct switch on and off combination for the different routes that station can offers, depending on the number of rails and platforms.

This is what I wrote now:


print("< switches >")
sleep(1)
print("master")
sleep(1)
print("assigning")
sleep(1)
print("initializing")
sleep(1)
print("connecting")
rednet.open("top")
rednet.broadcast("startup_switch_master")
sleep(1)
print("running")

route_0 = {""}
route_1 = {""}
route_2 = {""}
route_3 = {""}
route_4 = {""}
route_5 = {""}
....
route_50_switches_numbers = {"0","1","2","3","4","5"}
route_50_switches_states =  {"on","off","on","on","on","on"}


for i = 0, 50 do
event, id, message, distance, protocol = os.pullEvent("rednet_message")
	  
if message == "configure_route"..i then
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[1].."_"..route_[i]_switches_states[1])
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[2].."_"..route_[i]_switches_states[2])
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[3].."_"..route_[i]_switches_states[3])
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[4].."_"..route_[i]_switches_states[4])
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[5].."_"..route_[i]_switches_states[5])
rednet.broadcast("command_switch_"..route_[i]_switches_numbers[6].."_"..route_[i]_switches_states[6])
end

end

Basically, for every possible route number (numbers can be passengers functions, service ones, cargo skipping station etc etc) there is a table with the numbers of switches that are involved in that route and a table with the states that need to have every switch in the same order.
The switch master, when a superior input is broadcasted in the message form "configure_route_<number> (a specific train is approaching and need to be send somewhere or has to pass and the computer managing trains wants to have everything set up) just sends messages for every involved switch with its number and the state needed, in the form "command_switch_<number>_<state>", and that switches then set theit outputs.
Probably would be better also to merge everything in a unique string, but for me it's already hard this challenge, so, for now I prefer this way.
As it is the program doesn't work, can't figure out how to write correctly, and I also have some doubts about how to manage the fact that I won't have the same number of switches to set in every route, some of them can have a single switch, others over ten of them and so on, I would necessarily to read the number of variables in the table, so number of switches, and broadcast that number of messages sequentially, reading first variable of switch numbers table and first variable of switch states table and broadcasting the commands until the last variable number.
The written form as now is stupid, just with multiple lines with changed numbers, and I don't want to keep as it is, it's just for testing.
Edited on 22 December 2015 - 03:11 PM
Bomb Bloke #20
Posted 24 December 2015 - 12:24 AM
You can't do this sort of thing:

route_50_switches_numbers = {"0","1","2","3","4","5"}
route_50_switches_states =  {"on","off","on","on","on","on"}

.
.
.

rednet.broadcast("whatever" .. route_[i]_switches_numbers[1] .. "whatever")

The correct format is "tableName[index]". You can't try and split it like "tableName[index]moreTableName". What you're wanting is to build some proper sub-tables; tables put within tables:

route = {}  -- Make a table.

route["switches"] = {}  -- Make another table, in the route table.

route["switches"]["numbers"] = {}  -- Make yet another table, in the route["switches"] table.

route["switches"]["states"] = {}  -- And so on.

-- Now we can do:

route["switches"]["numbers"][50] = {"0","1","2","3","4","5"}
route["switches"]["states"][50] = {"on","off","on","on","on","on"}

-- And later:

rednet.broadcast("whatever"..route["switches"]["numbers"][i][1].."_"..route["switches"]["states"][i][1]).."whatever")

You could alternatively build your table using a single command, though you'd likely still want to spread it out over multiple lines:

route = {
	["switches"] = {
		["numbers"] = {
			[1] = {"0","1","2","3","4","5"},  -- Commas go between entries in the same sub-table.
			[2] = {"0","1","2","3","4","5"},
			.
			.
			.
			[50] = {"0","1","2","3","4","5"}
		},
		
		["states"] = {
			[1] = {"on","off","on","on","on","on"},
			[2] = {"on","off","on","on","on","on"},
			.
			.
			.
			[50] = {"on","off","on","on","on","on"}
		}
	}
}

If a table key is a string (eg "numbers"), then you can use dot notation to refer to it. For example,

route["switches"]["numbers"][i]

… is the same as:

route.switches.numbers[i]

And that for loop you've got there… argh. Fifty times it gets a message, and each time it does, "i" goes up by one. That makes it pretty random as to whether the current message will ever indicate "i"'s value, yeah? If it doesn't match, you're just throwing that message away and getting a new one, by which time "i" has changed again, etc… Ditch that sort of loop!

Probably would be better also to merge everything in a unique string, but for me it's already hard this challenge, so, for now I prefer this way.

Seriously, you'd be FAR BETTER OFF dropping the idea of transmitting individual strings AT ALL, and just sending tables. Putting strings together and then later trying to pull them apart is far more trouble than it's worth.

For example:

local command = {"configure", "route", 4}  -- command[1] = "configure", command[2] = "route", command[3] = 4

rednet.broadcast(command)

Now at the other end, you might do:

-- Define great big route.switch.whatever table up here

while true do
  local command = rednet.receive()

  if command[1] == "configure" then
    if command[2] == "route" then
      rednet.broadcast( { "command", "switch", route.switches.numbers[ command[3] ], route.switches.states[ command[3] ] } )

    elseif command[2] == "some other word" then
      -- do something else
    end
  end
end

Note the lack of a need to run a loop checking a ton of values of "i" - you just pluck the correct number straight out of the command's table (command[3], which was 4), no muss, no fuss. The info's right there.

Also note that we don't need to go through and send each of the six entries in the route.switches.numbers[ command[3] ] / route.switches.states[ command[3] ] tables individually. We simply send off the entire sub-tables and their whole contents go at once.

And then at the other end you might do:

while true do
  local command = rednet.receive()

  if command[1] == "command" then
    if command[2] == "switch" then
      -- command[3] must be the whole table route.switches.numbers[i] pointed to.
      for i = 1, #command[3] do  -- For each entry in that table, do...
        -- Set number command[3][i] to whatever state is indicated by command[4][i].
      end

    elseif command[2] == "something else" then
      -- do something else
    end

  elseif command[1] == "something else" then
    -- do something else

  elseif etc
  end
end
Edited on 23 December 2015 - 11:27 PM
pietro.devo #21
Posted 24 December 2015 - 11:03 AM
Seriously, you'd be FAR BETTER OFF dropping the idea of transmitting individual strings AT ALL, and just sending tables. Putting strings together and then later trying to pull them apart is far more trouble than it's worth.

You are really patient Bomb Bloke, and ok, I got the point and I will go straight to the use of tables, learning how to use them.
The only main reason I was using strings is that they where user-readable commands on the net, but they are really a limit.
I'd better migrate all the other now working components to that use (switches, signs, sensors).

Now I have:


print("< switches >")
sleep(1)
print("master")
sleep(1)
print("assigning")
sleep(1)
print("initializing")
sleep(1)
print("connecting")
local present = false
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
present = true
rednet.open(side)
rednet.broadcast("startup_switch_master")
end
end
sleep(1)
print("running")

route = {
		["switches"] = {
				["numbers"] = {
						[1] = {"0","1","2","3","4","5"},
						[2] = {"0","1","2","3","4","5","6"},											  
						[50] = {"0","1","2","3"}
				},
			  
				["states"] = {
						[1] = {"on","off","on","on","on","on"},
						[2] = {"on","off","on","on","on","on","on"},					  
						[50] = {"on","off","on","off"}
				}
		}
}

while true do
  local command = rednet.receive()

  if command[1] == "configure" then
	if command[2] == "route" then
	  rednet.broadcast( { "command", "switch", route.switches.numbers[ command[3] ], route.switches.states[ command[3] ] } )

	elseif command[2] == "to define later" then
	  -- do
	end
  end
end

This is the actual code, added also a way to find the modem side.

On the upper level I made this tester (now just a redstone lever):


rednet.open("bottom")

local command1 = {"configure", "route", 1}
local command2 = {"configure", "route", 2}

while true do
os.pullEvent("redstone")

if redstone.getInput("back",true) then
  print("configure_route_1")
  rednet.broadcast(command1)
else
  print("configure_route_2")
  rednet.broadcast(command2)
end
end

And I'm getting "attempt to index ? (a number value)" at line 40 of switch master code, the if command part.
Edited on 24 December 2015 - 10:07 AM
Blue #22
Posted 24 December 2015 - 12:09 PM
And I'm getting "attempt to index ? (a number value)" at line 40 of switch master code, the if command part.
That's probably because rednet.receive doesn't return a table. You need to use textutils.unserialize,

local command = texutils.unserialize(rednet.receive())
pietro.devo #23
Posted 24 December 2015 - 12:16 PM
Giving a try just returns an error at line 39 with an attempt to index a nil value
KingofGamesYami #24
Posted 24 December 2015 - 01:49 PM
rednet.receive returns id, message. You'll need to catch message and unserialize it - treating a number as a table doesn't work, and unserializing a number simply returns nil.
Bomb Bloke #25
Posted 24 December 2015 - 02:13 PM
That is to say, change:

local command = rednet.receive()

… to:

local id, command = rednet.receive()

True, I forgot the "id" in my psuedo-code. But unless you're using an antiquated build of ComputerCraft (as in, pre-1.53), there's no need to serialise/unserialise anything.
pietro.devo #26
Posted 24 December 2015 - 10:50 PM
Yes sir, that worked!

While I am finding how to change the actual structure of code, to let the railway works in meanwhile I have found a not so complicated way to archieve the point keeping the string form at all, so not needing to modify al switches and stuff codes:


route = {}
route["switches"] = {}
route["switches"]["numbers"] = {}
route["switches"]["states"] = {}

route["switches"]["numbers"][1] = {"0","1","3","4","5","6"}
route["switches"]["states"][1] = {"on","off","on","off","on","off"}
route["switches"]["numbers"][2] = {"0","7","8","9","10"}
route["switches"]["states"][2] = {"off","on","on","on","off"}

print("< switches >")
sleep(1)
print("manager")
sleep(1)
print("assigning")
sleep(1)
print("initializing")
sleep(1)
print("connecting")
local present = false
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
present = true
rednet.open(side)
rednet.broadcast("startup_switches_manager")
end
end
sleep(1)
print("running")

while true do
local senderID, message = rednet.receive()
local words = {}
local i = " "

for word in string.gmatch(message, "%w+") do words[#words + 1] = word end
if words[1] == "configure" then
  if words[2] == "route" then  
   local n = tonumber(words[3])
   local l = #route["switches"]["numbers"][n]  

   for i = 1, l do
   rednet.broadcast("command_switch_"..route["switches"]["numbers"][n][i].."_"..route["switches"]["states][n][i])
   end

  end
 end
end

It works good at all with no problems.
But yes, I'll need tables because I see more complicated things to do next, for examble transmitting train status, estimated arrival time, platform, destinations etc etc to monitors and the way al that stuff need to be printed graphically.

Is there a way to uniquely identify a entity or object near a computer, in this case I have trains, or eventually just get its type?
Edited on 24 December 2015 - 09:53 PM
Bomb Bloke #27
Posted 25 December 2015 - 11:01 AM
That's looking a bit more workable - you seem to be getting the hang of things at least. :)/>

Consider working in a command to make your remote systems download a fresh copy of their scripts, and then reboot themselves! This'll make it significantly easier to implement sweeping changes later, as need be.

Is there a way to uniquely identify a entity or object near a computer, in this case I have trains, or eventually just get its type?

How much info do you need?

The "simple" way is to slap down a detector rail and have your computer wait for the redstone pulse. That on its own won't give you "unique" identification, though; it'll merely pick up "stuff on the rails".

But you could tie that to a check with a "sensor", like the one from OpenCCSensors, or the one from OpenPeripheral. ComputerCraft on its own doesn't offer one, short of some rather obscure commands you can run through a command computer (available only to OPs)..
pietro.devo #28
Posted 25 December 2015 - 11:34 AM
Yes, you all really helped me a lot learning things guys.

The update command is really a great idea!, that would be very useful.
For the managers and core components, that are not so many, I can still update by myself, but for all switches, sensors, lights, monitors it would be fantastic, it would just has to keep the old parameters set on installation between versions of program, so the number of unit and the side of redstone input for sensors, or side of redstone output for switches, but yes, really good idea.

As it is I am just having a "stuff on the rails" sensor, that is good, but I can't manage complex scenarios where I have different trains, cargo and passengers one, and not every of them for sure has to be considered the same way.
A passenger train can stop at a station, but maybe can skip another one, have different level of priority, a cargo train surely has another kind of stops and procedures.
Even better: If have a route branch, two routes that maybe share one piece of railway but then need to separate to different directions, how can I do? I need for sure to identify trains, so yes, openCCsensors would do the job, identifying uniquely a train or at least catching the type of locomotive or of one of the wagons maybe, so then just using different types of carts or locomotives specifically for every kind of route or service that make the system classify that train in a certain way.

Last but not least… Merry Christmas to all guys :)/>
Edited on 25 December 2015 - 10:36 AM
Dragon53535 #29
Posted 25 December 2015 - 11:39 AM
That's looking a bit more workable - you seem to be getting the hang of things at least. :)/>

Consider working in a command to make your remote systems download a fresh copy of their scripts, and then reboot themselves! This'll make it significantly easier to implement sweeping changes later, as need be.

I would have it if everything was connected with wired modems (Probably not, but I can hope) just having it save to a central disk drive, and just read on startup the file holding all your data. Then if you need to edit it, you go into the file, change the stuff. Then tell the master controller to tell the rest to reboot and they'll get a new one.

IF you're on wireless, the approach I would do is have the stuff on the master computer, on startup for the others, have them get what they need and then save that to a local file. At the same time, have the master computer send over a version number that also gets saved to a different file. When restarting with the master computer, they check their version number, and send it over to the master computer as well. If the version is out of date, well then get new data, and resave it into the file, get the new number, and save that as well. The version number is of course saved on the master computer, so you can have it saved to a file there, and increment it when you tell all the other computers to reboot. Bam, your version number goes up when you want it to.

As for how you're sending data, I would personally use the modem api instead of the rednet api. Create a constant for the master's value, or somehow send it with rednet.broadcast after rednet receiving a correct message, blah blah. And this will be the channel that the master controller listens to. Then every slave computer sends a hello world message to that at first start, and the master computer sends the correct data. I would also have it so that the master computer keeps track of used modem channels for the track, and assigns a new one for each of the slaves at the first time they connect. That way, you can talk to the computer that contacted you ONLY, and at the same time, issue specific commands to specific computers.
pietro.devo #30
Posted 25 December 2015 - 12:38 PM
Yes, all the system is completely wired, and It's intended to be a railway "intranet", so every communication to the "extranet", for example when I need to connect two different and distant stations or just want to control things from a place not in the railway system, would be filtered and I will have later to work on a computer that puts my stations and local system in communication to a upper level, a mask that maybe uses an authentication and so on, with special commands etc etc (keeping in mind that every station o switch point has the numbers of signals, sensors etc etc that begins from 0/1, and the more the system will grow, the more will be impossible just to have numbers for whole world, it is also difficult to manage future number change or additions, having locally some high numbers and so on, better a local subnet with prefix I thought).
Edited on 25 December 2015 - 11:39 AM
Dragon53535 #31
Posted 25 December 2015 - 01:43 PM
If everything is wired, you can easily setup the changing of rail stuff. Setup a disk drive that is connected to the network, put a disk in that drive. Edit a certain file that every computer knows of, and make it have the values you want in it.


--#Let's say the file's name is Station
local function getTableFromFile(fileName)
  local drive = ""--#Blank name of drive.
  for a,v in pairs(peripheral.getNames()) do --#Loop through all connected peripherals and find a connected drive
    if peripheral.getType(v) == "drive" and disk.hasData(v) then --#Drive found and has a disk
	  drive = v --#Get it's name
	  break --#Leave the loop
    end
  end
  if drive == "" then --#If no drive, then return nil.
    return nil
  end
  local path = disk.getMountPath(drive) --#This returns the mount path of the drive, which is needed to properly and without fail reference the drive's files.
  local file = fs.open(path.."/"..fileName,"r")
  local tbl = textutils.unserialize(file.readAll())
  file.close()
  return tbl
end

local stationData = getTableFromFile("station")
pietro.devo #32
Posted 25 December 2015 - 03:58 PM
That is really interesting, and saves lot of time! I am going to implement this idea
The best way would be probably have a file locally stored on every computer with defined things that will never be changed, they are just defined one time, like the kind of code it will execute (the function, so a switch, sensor and so on), the number that identify it and the side used for interactions (for redstone and so on).
The code then updates itself on the base of the kind of machine running and sets variables at boot.

What would be for you the better way to have communication between system over the chunk loading area and, generally, over really far distances?
Train schedules probably are set one time and they would not change after all, this doesn't break anything of local system, they simply know how to behave, but if I have to instruct my system about a "una tantum", one-time exta-ordinary route of a train that needs to transport some goods from one point to another and need to stop or not in certain position and son on the problem of distance would be concrete.
Edited on 25 December 2015 - 03:00 PM
Dragon53535 #33
Posted 25 December 2015 - 04:12 PM
As my post a couple above said, I'd use the modem api, and since you're going to use different stations, I would setup each individual station to have it's own id/channel. Wireless modems can still use the modem api, and it's distance is still limited to the distance of the wireless config option.
As for personal touches and how the system may be setup anyways, I have no idea.

I would work on the setup for a singular station first, then implement ideas for multiple stations towards the end. What you can do however, is while you're making the singular station's code, add in useful arguments or variables that allow you to change what a function does should you need it to do so from a different station.
pietro.devo #34
Posted 04 January 2016 - 03:16 PM
Hi there guys.
Now I have my written and full working code for my route manager, and here is it:

Spoiler

-- limit
l = 5000

-- passengers binaries
p = 4
-- cargo binaries
m = 3
-- services binaries
s = 2

-- stop binaries
f = 0
-- transit binaries
t = 0

-- block binaries
ke = 1000
ks = 2000
ko = 3000
kn = 4000

-- cardinality versors
ve = 1
vs = 2
vo = 3
vn = 4
-- category routes coding
xp = 100
zp = 200
xm = 300
zm = 400
xs = 500
zs = 600

-- function routes coding
xf = 0
zf = 0
xt = 0
zt = 0
-- cardinality coding
ce = 1000
cs = 2000
co = 3000
cn = 4000
-- category binaries operators
yp = xp+p
wp = zp+p
ym = xm+m
wm = zm+m
ys = xs+s
ws = zs+s
-- function binaries operators
yf = xf+f
wf = zf+f
yt = xt+t
wt = zt+t

print("< routes >")
sleep(1)
print("manager")
sleep(1)
print("assigning")
sleep(1)
print("initializing")
sleep(1)
print("connecting")
local present = false
for _, side in pairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
present = true
rednet.open(side)
rednet.broadcast("startup_manager_routes")
end
end
sleep(1)
print("running")

function configure_route(argument)
rednet.broadcast("configure_route_"..argument)
end

function state_track(argument)
rednet.broadcast("state_track_"..argument)
end

while true do
local senderID, message = rednet.receive()
local words = {}
local i = " "
for word in string.gmatch(message, "%w+") do words[#words + 1] = word end

if words[1] == "prepare" then

  if words[2] == "arrival" then

   if tonumber(words[3]) == ve or tonumber(words[3]) == vs or tonumber(words[3]) == vo or tonumber(words[3]) == vn then
   v = tonumber(words[3])

	if v == ve then
	w = ce
	end
	if v == vs then
	w = cs
	end
	if v == vo then
	w = co
	end
	if v == vn then
	w = cn
	end

	if words[4] == "passengers" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_arrival_"..v.."_passengers_undefined")
	 elseif p == 0 then
	 rednet.broadcast("prepare_arrival_function_passengers_inexistent")
	 else  
	  if words[5] == "processes" then
	   for i = xp+1 , yp do
		if v == ve or v == vs then
		a = i
		b = 0
		u = yp
		end
		if v == vo or v == vn then
		a = xp+yp+1
		b = i
		u = xp+1
		end
	   local r = i-xp
	   local j = a-b
	   state_track(j)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..j.."_free" then
		local h = i+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_passengers_"..r.."_processed")
		break
		end
		if message == "track_"..u.."_undefined" then
		rednet.broadcast("prepare_arrival_"..v.."_passengers_impossible")
		end
		if message == "track_"..u.."_occupied" then
		rednet.broadcast("prepare_arrival_"..v.."_passengers_impossible")
		end
		if message == "track_"..u.."_transit" then
		rednet.broadcast("prepare_arrival_"..v.."_passengers_impossible")
		end
	   end
	  else
	  local r = tonumber(words[5])
	  local c = tonumber(words[5])+xp
	   if c > yp then
	   rednet.broadcast("prepare_arrival_"..v.."_passengers_"..r.."_inexistent")
	   else  
	   state_track(c)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..c.."_free" then
		local h = c+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_passengers_"..r.."_completed")
		else
		rednet.broadcast("prepare_arrival_"..v.."_passengers_"..r.."_impossible")
		end
	   end
	  end
	 end
	end

	if words[4] == "cargo" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_arrival_"..v.."_cargo_undefined")
	 elseif m == 0 then
	 rednet.broadcast("prepare_arrival_function_cargo_inexistent")
	 else
	  if words[5] == "processes" then
	   for i = xm+1 , ym do
		if v == ve or v == vs then
		a = i
		b = 0
		u = ym
		end
		if v == vo or v == vn then
		a = xm+ym+1
		b = i
		u = xm+1
		end
	   local r = i-xm
	   local j = a-b
	   state_track(j)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..j.."_free" then
		local h = i+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_cargo_"..r.."_processed")
		break
		end
		if message == "track_"..u.."_undefined" then
		rednet.broadcast("prepare_arrival_"..v.."_cargo_impossible")
		end
		if message == "track_"..u.."_occupied" then
		rednet.broadcast("prepare_arrival_"..v.."_cargo_impossible")
		end
		if message == "track_"..u.."_transit" then
		rednet.broadcast("prepare_arrival_"..v.."_cargo_impossible")
		end
	   end
	  else
	  local r = tonumber(words[5])
	  local c = tonumber(words[5])+xm
	   if c > ym then
	   rednet.broadcast("prepare_arrival_"..v.."_cargo_"..r.."_inexistent")
	   else  
	   state_track(c)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..c.."_free" then
		local h = c+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_cargo_"..r.."_completed")
		else
		rednet.broadcast("prepare_arrival_"..v.."_cargo_"..r.."_impossible")
		end
	   end
	  end
	 end
	end

	if words[4] == "services" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_arrival_"..v.."_services_undefined")
	 elseif s == 0 then
	 rednet.broadcast("prepare_arrival_function_services_inexistent")
	 else
	  if words[5] == "processes" then
	   for i = xs+1 , ys do
		if v == ve or v == vs then
		a = i
		b = 0
		u = ys
		end
		if v == vo or v == vn then
		a = xs+ys+1
		b = i
		u = xs+1
	 end
	   local r = i-xs
	   local j = a-b
	   state_track(j)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..j.."_free" then
		local h = i+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_services_"..r.."_processed")
		break
		end
		if message == "track_"..u.."_undefined" then
		rednet.broadcast("prepare_arrival_"..v.."_services_impossible")
		end
		if message == "track_"..u.."_occupied" then
		rednet.broadcast("prepare_arrival_"..v.."_services_impossible")
		end
		if message == "track_"..u.."_transit" then
		rednet.broadcast("prepare_arrival_"..v.."_services_impossible")
		end
	   end
	  else
	  local r = tonumber(words[5])
	  local c = tonumber(words[5])+xs
	   if c > ys then
	   rednet.broadcast("prepare_arrival_"..v.."_services_"..r.."_inexistent")
	   else  
	   state_track(c)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..c.."_free" then
		local h = c+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_services_"..r.."_completed")
		else
		rednet.broadcast("prepare_arrival_"..v.."_services_"..r.."_impossible")
		end
	   end
	  end
	 end
	end

	if words[4] == "exceptional" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_arrival_"..v.."_exceptional_undefined")
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])
	  if c > l then
	  rednet.broadcast("prepare_arrival_"..v.."_exceptional_"..r.."_inexistent")
	  else
	   if xp < c and c < yp or xm < c and c < ym or xs < c and c < ys then
	   state_track(c)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..c.."_free" then
		local h = c+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_arrival_"..v.."_exceptional_"..r.."_completed")
		else
		rednet.broadcast("prepare_arrival_"..v.."_exceptional_"..r.."_impossible")
		end
	   else
	   rednet.broadcast("prepare_arrival_"..v.."_exceptional_"..r.."_inexistent")
	   end
	  end
	 end
	end

   else
   rednet.broadcast("prepare_arrival_"..tonumber(words[3]).."_cardinality_inexistent")
   end

  end

  if words[2] == "departure" then

   if tonumber(words[3]) == ve or tonumber(words[3]) == vs or tonumber(words[3]) == vo or tonumber(words[3]) == vn then
   v = tonumber(words[3])

	if v == ve then
	w = ce
	k = ke
	end
	if v == vs then
	w = cs
	k = ks
	end
	if v == vo then
	w = co
	k = ko
	end
	if v == vn then
	w = cn
	k = kn
	end

	if words[4] == "passengers" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_departure_"..v.."_passengers_undefined")
	 elseif p == 0 then
	 rednet.broadcast("prepare_departure_function_passengers_inexistent")
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])+zp
	  if c > wp then
	  rednet.broadcast("prepare_departure_"..v.."_passengers_"..r.."_inexistent")
	  end  
	  if c < wp then
	  state_track(k)
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	   if message == "track_"..k.."_free" then
	   local h = c+w
	   configure_route(h)
	   sleep(1)
	   rednet.broadcast("prepare_departure_"..v.."_passengers_"..r.."_completed")
	   else
	   rednet.broadcast("prepare_departure_"..v.."_passengers_"..r.."_impossible")
	   end
	  end
	 end
	end

	if words[4] == "cargo" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_departure_"..v.."_cargo_undefined")
	 elseif m == 0 then
	 rednet.broadcast("prepare_departure_function_cargo_inexistent")
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])+zm
	  if c > wm then
	  rednet.broadcast("prepare_departure_"..v.."_cargo_"..r.."_inexistent")
	  end
	  if c < wm then
	  state_track(k)
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	   if message == "track_"..k.."_free" then
	   local h = c+w
	   configure_route(h)
	   sleep(1)
	   rednet.broadcast("prepare_departure_"..v.."_cargo_"..r.."_completed")
	   else
	   rednet.broadcast("prepare_departure_"..v.."_cargo_"..r.."_impossible")
	   end
	  end
	 end
	end

	if words[4] == "services" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_departure_"..v.."_services_undefined")
	 elseif s == 0 then
	 rednet.broadcast("prepare_departure_function_services_inexistent")
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])+zs
	  if c > ws then
	  rednet.broadcast("prepare_departure_"..v.."_services_"..r.."_inexistent")
	  end
	  if c < ws then
	  state_track(k)
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	   if message == "track_"..k.."_free" then
	   local h = c+w
	   configure_route(h)
	   sleep(1)
	   rednet.broadcast("prepare_departure_"..v.."_services_"..r.."_completed")
	   else
	   rednet.broadcast("prepare_departure_"..v.."_services_"..r.."_impossible")
	   end
	  end
	 end
	end

	if words[4] == "exceptional" then
	 if words[5] == nil then
	 rednet.broadcast("prepare_departure_"..v.."_exceptional_undefined")
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])
	  if c > l then
	  rednet.broadcast("prepare_departure_"..v.."_exceptional_"..r.."_inexistent")
	  else
	   if zp < c and c < wp or zm < c and c < wm or zs < c and c < ws then
	   state_track(k)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..k.."_free" then
		local h = c+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_departure_"..v.."_exceptional_"..r.."_completed")
		else
		rednet.broadcast("prepare_departure_"..v.."_exceptional_"..r.."_impossible")
		end
	   else
	   rednet.broadcast("prepare_departure_"..v.."_exceptional_"..r.."_inexistent")
	   end
	  end
	 end
	end

   else
   rednet.broadcast("prepare_departure_"..tonumber(words[3]).."_cardinality_inexistent")
   end

  end

  if words[2] == "stop" then
   if tonumber(words[3]) == ve or tonumber(words[3]) == vs or tonumber(words[3]) == vo or tonumber(words[3]) == vn then
   v = tonumber(words[3])

	if v == ve then
	w = ce
	end
	if v == vs then
	w = cs
	end
	if v == vo then
	w = co
	end
	if v == vn then
	w = cn
	end
	if words[4] == "linear" then
	 if f == 0 then
	 rednet.broadcast("prepare_stop_function_inexistent")
	 else
	 local j = yf+w
	 state_track(j)
	 event, id, message, distance, protocol = os.pullEvent("rednet_message")
	  if message == "track_"..j.."_free" then
	  configure_route(j)
	  sleep(1)
	  rednet.broadcast("prepare_stop_"..v.."_linear_completed")
	  end
	  if message == "track_"..j.."_undefined" then
	  rednet.broadcast("prepare_stop_"..v.."_linear_impossible")
	  end
	  if message == "track_"..j.."_occupied" then
	  rednet.broadcast("prepare_stop_"..v.."_linear_impossible")
	  end
	  if message == "track_"..j.."_transit" then
	  rednet.broadcast("prepare_stop_"..v.."_linear_impossible")
	  end
	 end
	end
   else
   rednet.broadcast("prepare_stop_"..tonumber(words[3]).."_cardinality_inexistent")
   end
  end

  if words[2] == "transit" then
   if tonumber(words[3]) == ve or tonumber(words[3]) == vs or tonumber(words[3]) == vo or tonumber(words[3]) == vn then
   v = tonumber(words[3])

	if v == ve then
	w = ce
	end
	if v == vs then
	w = cs
	end
	if v == vo then
	w = co
	end
	if v == vn then
	w = cn
	end

	if words[4] == "embedded" then
	 if words[5] == "processes" then
	  if t == 0 then
	  rednet.broadcast("prepare_transit_function_inexistent")
	  else
	   for i = xt+1 , yt do
		if v == ve or v == vs then
		a = i
		b = 0
		u = yt
		end
		if v == vo or v == vn then
		a = xt+yt+1
		b = i
		u = xt+1
		end
	   local r = i-xt
	   local j = a-b
	   state_track(j)
	   event, id, message, distance, protocol = os.pullEvent("rednet_message")
		if message == "track_"..j.."_free" then
		local h = i+w
		configure_route(h)
		sleep(1)
		rednet.broadcast("prepare_transit_"..v.."_embedded_"..r.."_processed")
		break
		end
		if message == "track_"..u.."_undefined" then
		rednet.broadcast("prepare_transit_"..v.."_embedded_impossible")
		end
		if message == "track_"..u.."_occupied" then
		rednet.broadcast("prepare_transit_"..v.."_embedded_impossible")
		end
		if message == "track_"..u.."_transit" then
		rednet.broadcast("prepare_transit_"..v.."_embedded_impossible")
		end
	   end
   end
	 else
	 local r = tonumber(words[5])
	 local c = tonumber(words[5])+xt
	  if c > yt then
	  rednet.broadcast("prepare_transit_"..v.."_embedded_"..r.."_inexistent")
	  else  
	  state_track(c)
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	   if message == "track_"..c.."_free" then
	   local h = c+w
	   configure_route(h)
	   sleep(1)
	   rednet.broadcast("prepare_transit_"..v.."_embedded_"..r.."_completed")
	   else
	   rednet.broadcast("prepare_transit_"..v.."_embedded_"..r.."_impossible")
	   end
	  end
	 end
	end
	if words[4] == "exceptional" then
	local r = tonumber(words[5])
	local c = tonumber(words[5])
	 if c > l then
	 rednet.broadcast("prepare_transit_"..v.."_exceptional_"..r.."_inexistent")
	 else  
	  if xp < c and c < yp or xm < c and c < ym or xs < c and c < ys or xt < c and c < yt then
	  state_track(c)
	  event, id, message, distance, protocol = os.pullEvent("rednet_message")
	   if message == "track_"..c.."_free" then
	   local h = c+w
	   configure_route(h)
	   sleep(1)
	   rednet.broadcast("prepare_transit_"..v.."_exceptional_"..r.."_completed")
	   else
	   rednet.broadcast("prepare_transit_"..v.."_exceptional_"..r.."_impossible")
	   end
	  else
	  rednet.broadcast("prepare_transit_"..v.."_exceptional_"..r.."_inexistent")
	  end
	 end
	end

   else
   rednet.broadcast("prepare_transit_"..tonumber(words[3]).."_cardinality_inexistent")
   end

  end
end
if words[1] == "systems" then
  if words[2] == "manager" then
   if words[3] == "routes" then
	if words[4] == "poweroff" then
	rednet.broadcast("poweroff_manager_routes"")
	os.shutdown()
	end
	if words[4] == "reboot" then
	rednet.broadcast("reboot_manager_routes")
	os.reboot()
	end
   end
  end
end
end

Yes, I have written it in a not so good way, still no tables here, but I did it on my own and I am happy it is woking with no problem.
I like to improve and learn so here I ask you opinions on how can be written better and more efficently, maybe using functions and so on.

Here is the more important thing:
Now I need to write down a simple scheduler that help me manage my station platforms.
I need it to just receive from rednet some strings or tables that contain for example a platform number, a name for the train and, most important, its departure time, storing them, putting them for example in a table, and managing timers so that when the world's time coincides with one of the times it is storing it just has to send a rednet message that says "that train at that platform has to leave".
The rest, so the imput to this manager and the procedure of departing is apart from it.
What would be the best way to go?
Edited on 04 January 2016 - 08:15 PM
Bomb Bloke #35
Posted 06 January 2016 - 03:45 AM
Once you've put all your scheduled train actions into your table and sorted them, figure out the time it'll take until the firstmost one is due to be performed, and use os.startTimer() to wait for it.

Every time and action occurs, increment a counter variable, and use that to get the index of the current action you should be setting your next timer for. If the counter exceeds the number of elements in your table, just reset it back to 1 to start from the beginning.
pietro.devo #36
Posted 06 January 2016 - 09:28 AM
Yes, that was an idea.
The fact to manage is I have different trains that can arrive, and they can delay, can come after another train that was intended not to be before or also can not pass.
So I tought of a code for every train, that identify it, that comes from combination of OpenPeripheral and Railcraft, that is transmitted every time a train in arriving out of the station.
A computer has inside the table of daily trains, so it takes this code and with a loop it compare it with all the codes it has in his table.
At this point can happen three things:
The code is finded, it reads then the arrival time, departure time, preferred platform, destinations etc etc from sub tables and finds out that train is on time.
The code is finded, it reads then the arrival time, departure time, preferred platform, destinations etc etc from sub tables and finds out that train is delaying.
The code is not finded, so the train isn't expected to be arrived or is a special train and is not processed.

In the first two situations my idea was:
Computer asks the route master for the correct route, if there was a preferred platform it asks for that destination else it asks to calculate the first free platform, and if the returning message says the route is configured correctly (so there is a free platform to approach) it then sends the start to the train (that basically is an input to a powered rail or somemithing like that) and waits until there is a message that says the platform is now occupied.
At this point comes the idea for the scheduler, the computer sends to a scheduler the time of departure for the train it has just managed, adding for example 1 minute to the arrival time, (later having this useful for station displays that shows trains informations and delays) so it is possible to manage also the delays.
At this point the computer is free from the scheduling procedure and can manage another arrival or transit while the scheduler has just timers to wait and then sends the departure signal, without even knowing what trains and destinations etc etc are at platforms.
Edited on 06 January 2016 - 08:42 AM
pietro.devo #37
Posted 13 February 2016 - 03:18 PM
Hi there,

I made a complete re-write of the code posted now a month ago, with the use of functions to drastically reduce code that with the addiction of lots of improvements (like while cycles to prevents an undesireed message to break the configuring routine, verifications for the effective setup of routes and complete debugging messages that point out what problems occured, different binary order calculations and coding on the base of the cardinality of trains, possibility to enable or disable and customize functions etc etc) reached something like more than 2k lines. I am pretty happy with this.

Spoiler

-- system limit

ls = 10000

-- binaries for passengers

bp = 10

-- binaries for cargo

bm = 10

-- binaries for services

bs = 10

-- binaries for transit

bt = 10

-- functions of stop

fp = "admitted"
fl = "admitted"

-- functions of  transit


td = "admitted"
te = "admitted"

-- transit for categories

tp = "admitted"
tm = "admitted"
ts = "admitted"

-- codify binaries for categories

xp = 100
xm = 200
xs = 300

-- codify functional binaries

xf = 500
xt = 600

-- operators for category binarie

yp = xp+bp
ym = xm+bm
ys = xs+bs

-- operators for functional binaries

yf = xf+bf
yt = xt+bt

-- versors for cardinality

ve = 1
vs = 2
vw = 3
vn = 4

-- versors for directions

we = 3
ws = 4
ww = 1
wn = 2

-- functions of versors

ge = "unmanaged"
gs = "unmanaged"
gw = "unmanaged"
gn = "unmanaged"

-- codify versors

cv = 1000
cw = 100

-- binaries for directors

cx = 1
cy = 2
cz = 3

-- functions for director

de = "unmanaged"

-- initializing peripherals

modem = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "modem" then
  modem = side
  break
  end
end

monitor = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "monitor" then
  monitor = side
  break
  end
end

-- boot code

sleep(1)
print("< routes >")
sleep(1)
print("manager")
sleep(1)
print("assigning")
sleep(1)
print("initiliazing")
sleep(1)
print("connecting")
rednet.open(modem)
rednet.broadcast("startup_manager_routes")
sleep(1)
print("running")

-- functions code

function configure_versors(v,ve,vs,vw,vn)

q = nil
g = nil
w = nil
if v == ve then
q = "existing"
g = ge
w = we
end
if v == vs then
q = "existing"
g = gs
w = ws
end
if v == vw then
q = "existing"
g = gw
w = ww
end
if v == vn then
q = "existing"
g = gn
w = wn
end	
  
end

function configure_directors(de,cx,cy,cz)

xd = nil
yd = nil
if de == "unmanaged" then
xd = cx
yd = cy
end
if de ~= "unmanaged" then
xd = cz
yd = cz
end

end

function configure_blocks(q,e,v,cv,cd)

k = nil
d = nil
if q == "existing" and g == "unmanaged" then
d = cd
k = v*cv+d
end

end

function configure_stop(v,ve,vs,vw,vn)

p = nil
l = nil
if v == ve then
p = xf+1
l = v*cv+c
end
if v == vs then
p = xf+1
l = v*cv+c
end
if v == nw then
p = xf+2
l = v*cv+c
end
if v == vn then
p = xf+2
l = v*cv+c
end

end

function route_configure(v,d,c)

cnfg = nil
cnf1 = nil
cnf2 = nil
rednet.broadcast("configure_route_"..v.."_"..d.."_"..c)
while true do
event, id, message, distance, protocol = os.pullEvent("rednet_message")
  if message == "route_"..v.."_"..d.."_"..c.."_switches_configured" then
  cnf1 = true
  end
  if message == "route_"..v.."_"..d.."_"..c.."_signals_configured" then
  cnf2 = true
  end
  if message == "route_"..v.."_"..d.."_"..c.."_switches_undefined" then
  cnf1 = false
  end
  if message == "route_"..v.."_"..d.."_"..c.."_signals_undefined" then
  cnf2 = false
  end
  if message == "route_"..v.."_"..d.."_"..c.."_switches_error" then
  cnf1 = false
  end
  if message == "route_"..v.."_"..d.."_"..c.."_signals_error" then
  cnf2 = false
  end
  if cnf1 == true and cnf2 == true then
  cnfg = true
  break
  end
  if cnf1 == false or cnf2 == false then
  cnfg = false
  break
  end
end

end

function route_transit(v1,v2,d1,d2,c,k)

route_configure(v1,d1,c)
if cnfg == true then
cnc1 = true
end
if cnfg == false then
cnc1 = false
end
route_configure(v2,d2,k)
if cnfg == true then
cnc2 = true
end
if cnfg == false then
cnc2 = false
end
if cnc1 == true and cnc2 == true then
cnct = true
end
if cnc1 == false or cnc2 == false then
cnct = false
end
end

function route_binary(c)

erro = nil
rednet.broadcast("state_binary_"..c)
event, id, message, distance, protocol = os.pullEvent("rednet_message")
if message == "binary_"..c.."_free" then
erro = false
end
if message == "binary_"..c.."_undefined" then
erro = true
end
if message == "binary_"..c.."_occupied" then
erro = true
end
if message == "binary_"..c.."_transit" then
erro = true
end

end

function route_process(v,ve,vs,vw,vn,b,x,y)

erro = nil
for i = 1 , b do
  if v == ve then
  j = i
  u = y
  end
  if v == vs then
  j = i
  u = y
  end
  if v == vw then
  j = b-i
  u = x
  end
  if v == vn then
  j = b-i
  u = x
  end
r = i
c = j+x
rednet.broadcast("state_binary_"..c)
event, id, message, distance, protocol = os.pullEvent("rednet_message")
  if message == "binary_"..c.."_free" then
  erro = false
  break
  end
  if message == "binary_"..u.."_undefined" then
  erro = true
  end
  if message == "binary_"..u.."_occupied" then
  erro = true
  end
  if message == "binary_"..u.."_transit" then
  erro = true
  end
end

end

function route_prepare(t,v,d,n,s,r,c,erro)

if erro == false then
route_configure(v,d,c)
  if cnfg == true then
  rednet.broadcast(t.."_"..v.."_"..n.."_"..r.."_prepared")
  end
  if cnfg == false then
  rednet.broadcast(t.."_"..v.."_"..n.."_"..s.."_exception")
  end
end
if erro == true then
rednet.broadcast(t.."_"..v.."_"..n.."_"..s.."_impossible")
end

end

function transit_binary(c,k)

ste1 = nil
ste2 = nil
route_binary(c)
ste1 = erro
route_binary(k)
ste2 = erro

end

function transit_process(v,ve,vs,vw,vn,d,b,x,y,k)

ste1 = nil
ste2 = nil
route_process(v,ve,vs,vw,vn,d,b,x,y)
ste1 = erro
route_binary(k)
ste2 = erro

end

function transit_prepare(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)

step = nil
if ste1 == false and ste2 == false then
step = false
end
if ste1 == true or ste2 == true then
step = true
end
if step == false then
route_transit(v1,v2,d1,d2,c,k)
  if cnct == true then
  rednet.broadcast("transit_".."_"..v1.."_"..v2.."_"..n.."_"..r.."_prepared")
  end
  if cnct == false then
   if cnc1 == false then
   rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_incident_binary")
   end
   if cnc2 == false then
   rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_incident_line")
   end  
  rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_exception")
  end
end
if step == true then
  if ste1 == true then
  rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_block_binary")
  end
  if ste2 == true then
  rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_block_line")
  end  
rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_"..s.."_impossible")
end

end

function transit_verify(v,ve,vs,vw,vn,d,n,f,b,x,y)

if f == "admitted" then
rednet.broadcast("transit_exceptional_"..n.."_"..f)
sleep(1)
route_process(v,ve,vs,vw,vn,b,x,y)
er = r
ec = c
  if erro == true then
  rednet.broadcast("transit_exceptional_"..n.."_impossible")  
  vrfy = nil
  end  
  if erro == false then
  rednet.broadcast("transit_exceptional_"..n.."_possible")
  vrfy = n
  end  
end
if f == "denyed" then
rednet.broadcast("transit_exceptional_"..n.."_"..f)
end
r = nil
c = nil

end

function transit_dedicated(v1,v2,ve,vs,vw,vn,d1,d2,n,b,s,r,c,k,x,y)

if b == 0 then
rednet.broadcast("transit_function_"..n.."_unexisting")
end
if b ~= 0 then
  if s == nil then
  rednet.broadcast("transit_"..v.."_"..n.."_undefined")
  end	  
  if s == "process" then  
  transit_process(v1,ve,vs,vw,vn,d1,b,x,y,k)
  transit_prepare(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
  t = nil
  end
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast("transit_"..v1.."_"..v2.."_"..n.."_binary_unexisting")
   end
   if c < y then
   transit_binary(c,k)
   transit_prepare(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
   end
  end
end

end

function transit_exceptional(v1,v2,ve,vs,vw,vn,d1,d2,n,f,s,r,c,k,xp,xm,xs,yp,ym,ys,ls)

if f == "denyed" then
rednet.broadcast("transit_"..v.."_function_"..n.."_"..f)
end
if f == "admitted" then
  if s == nil then
  rednet.broadcast("transit_"..v.."_exceptional_binary_undefined")
  end
  if s == "process" then	
  vrfy = nil	
   if vrfy == nil then
   n = "passengers"
   transit_verify(v,ve,vs,vw,vn,d,n,tp,bp,xp,yp)
   ste1 = erro
   end
   if vrfy == nil then
   n = "cargo"
   transit_verify(v,ve,vs,vw,vn,d,n,tm,bm,xm,ym)
   ste1 = erro
   end
   if vrfy == nil then
   n = "services"		
   transit_verify(v,ve,vs,vw,vn,d,n,ts,bs,xs,ys)
   ste1 = erro
   end
  route_binary(k)
  ste2 = erro
  transit_prepare(v1,v2,d1,d2,n,s,er,ec,k,ste1,ste2)
  end
  if r ~= nil then
  c = r
   if r > ls then
   rednet.broadcast("transit_"..v.."_exceptional_"..r.."_limite_sistemi")
   end
   if r < ls then
   transit_binary(c,k)
   transit_prepare(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
   end
  end
end

end

function prepare_arrival(v,ve,vs,vw,vn,d,n,b,s,r,k,x,y)

if b == 0 then
rednet.broadcast("arrival_function_"..n.."_unexisting")
end
if b ~= 0 then
  if s == nil then
  rednet.broadcast("arrival_"..v.."_"..n.."_binary_undefined")
  end  
  if s == "process" then
  route_process(v,ve,vs,vw,vn,b,x,y)
  route_prepare("arrival",v,d,n,s,r,c,erro)
  r = nil
  end
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast("arrival_"..v.."_"..n.."_binary_unexisting")
   end
   if c < y then
   route_binary(c)
   route_prepare("arrival",v,d,n,s,r,c,erro)
   end  
  end
end  

end

function prepare_departure(v,d,n,b,s,r,k,x,y)

if b == 0 then
rednet.broadcast("departure_function_"..n.."_unexisting")
end
if b ~= 0 then
  if s == nil then	
  rednet.broadcast("departure_"..v.."_"..n.."_binary_undefined")
  end	  
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast("departure_"..v.."_"..n.."_binary_unexisting")
   end	
   if c < y then
   route_binary(k)
   route_prepare("departure",v,d,n,s,r,c,erro)
   end
  end
end

end

function prepare_exceptional(t,v,d,b,s,r,c,k,ls)
	
if s == nil then
rednet.broadcast(t.."_"..v.."_exceptional_binary_undefined")
end
if s ~= nil then
c = r
  if r > ls then
  rednet.broadcast(t.."_"..v.."_exceptional_limite_sistemi")
  end
  if r < ls then
   if xp < r and r < yp or xm < r and r < ym or xs < r and r < ys then
   route_binary(k)
   route_prepare(t,v,d,n,s,r,c,erro)
   else
   rednet.broadcast(t.."_"..v.."_exceptional_binary_unexisting")
   end
  end
end

end

function prepare_stop(v,w,xd,yd,n,f,s,r,c,k)

if f == "denyed" then
rednet.broadcast("stop_function_"..n.."_"..f)
end
if f == "admitted" then
  if r == "arrival" then	  
  route_binary(c)	  
  route_prepare("stop",v,xd,n,s,r,c,erro)
  end  
  if r == "departure" then	  
  route_binary(k)	  
  route_prepare("stop",w,yd,n,s,r,c,erro)
  end
end

end
	
-- system code

while true do
local senderID, message = rednet.receive()
local words = {}
local i = " "

for word in string.gmatch(message, "%w+") do words[#words + 1] = word end

if words[1] == "prepare" then

  if words[2] == "arrival" then

  t = words[2]
  v = tonumber(words[3])
  n = words[4]
  s = words[5]
  r = tonumber(words[5])

  configure_versors(v,ve,vs,vw,vn)
  configure_directors(de,cx,cy,cz)
  configure_blocks(q,e,v,cv,xd)
  
   if q == "existing" and g == "managed" then
  
	if n == "passengers" then
	prepare_arrival(v,ve,vs,vw,vn,d,n,bp,s,r,k,xp,yp)
	end
	if n == "cargo" then
	prepare_arrival(v,ve,vs,vw,vn,d,n,bm,s,r,k,xm,ym)
	end
	if n == "services" then
	prepare_arrival(v,ve,vs,vw,vn,d,n,bs,s,r,k,xs,ys)
	end
	if n == "exceptional" then
	prepare_exceptional(t,v,ve,vs,vw,vn,d,n,s,r,c,k)
	end

   end
  
   if q == "existing" and g == "unmanaged" then
   rednet.broadcast("arrival_"..v.."_cardinality_"..g)
   end
   if q == "unexisting" then
   rednet.broadcast("arrival_"..v.."_cardinality_"..q)
   end
   if v == nil then
   rednet.broadcast("arrival_cardinality_undefined")
   end

  end

  if words[2] == "departure" then  

  t = words[2]
  v = tonumber(words[3])
  n = words[4]
  s = words[5]
  r = tonumber(words[5])

  configure_versors(v,ve,vs,vw,vn)
  configure_directors(de,cx,cy,cz)
  configure_blocks(q,e,v,cv,yd)
	
   if q == "existing" and g == "managed" then
  
	if n == "passengers" then
	prepare_departure(v,d,n,bp,s,r,k,xp,yp)
	end
	if n == "cargo" then
	prepare_departure(v,d,n,bm,s,r,k,xm,ym)
	end
	if n == "services" then
	prepare_departure(v,d,n,bs,s,r,k,xs,ys)
	end
	if n == "exceptional" then
	prepare_exceptional(t,v,d,n,s,r,c,k)
	end

   end
  
   if q == "existing" and g == "unmanaged" then
   rednet.broadcast("departure_"..v.."_cardinality_"..g)
   end
   if q == "unexisting" then
   rednet.broadcast("departure_"..v.."_cardinality_"..q)
   end
   if v == nil then
   rednet.broadcast("departure_cardinality_indefinita")
   end

  end

  if words[2] == "stop" then

  t = words[2]
  v = tonumber(words[3])
  n = words[4]
  s = words[5]
  r = words[5]

  configure_versors(v,ve,vs,vw,vn)
  configure_stop(v,ve,vs,vw,vn)
  configure_directors(de,cx,cy,cz)
  configure_blocks(q,e,v,cv,yd)

   if q == "existing" and g == "managed" then

	if n == "parallel" then
	prepare_stop(v,w,xd,yd,n,fp,s,r,p,k)
	end
	if n == "linear" then
	prepare_stop(v,w,xd,yd,n,fl,s,r,p,k)
	end
	
   end
	
   if q == "existing" and g == "unmanaged" then
   rednet.broadcast("stop_"..v.."_cardinality_"..g)
   end
   if q == "unexisting" then
   rednet.broadcast("stop_"..v.."_cardinality_"..q)
   end
   if v == nil then
   rednet.broadcast("stop_cardinality_indefinita")
   end

  end

  if words[2] == "transit" then

  t = words[2]
  v1 = tonumber(words[3])
  v2 = tonumber(words[4])  
  q1 = nil
  q2 = nil
  g1 = nil
  g2 = nil
  n = words[5]
  s = words[6]
  r = tonumber(words[6])

  configure_versors(v1,ve,vs,vw,vn)
  q1 = q
  g1 = g
  configure_versors(v2,ve,vs,vw,vn)
  q2 = q
  g2 = g  
  configure_directors(de,cx,cy,cz)
  d1 = xd
  d2 = yd
  configure_blocks(q,e,v,cv,yd)

   if q1 == "existing" and q2 == "existing" then
   q = "existing"
   end
   if q1 == "unexisting" or q2 == "unexisting" then
   q = "unexisting"
   end  
   if g1 == "unmanaged" and g2 == "unmanaged" then
   g = "unmanaged"
   end
   if g1 == "unmanaged" or g2 == "unmanaged" then
   g = "unmanaged"
   end
  
   if q == "existing" and g == "managed" then
  
	if n == "dedicated" then
	transit_dedicated(v1,v2,ve,vs,vw,vn,d1,d2,n,bt,s,r,c,k,xt,yt)
	end	
	if n == "exceptional" then	
	transit_exceptional(v1,v2,ve,vs,vw,vn,d1,d2,n,te,s,r,c,k,xp,xm,xs,yp,ym,ys,ls)
	end
	
   end  

   if q == "existing" and g == "unmanaged" then
   rednet.broadcast("transit_"..v.."_cardinality_"..g)
   end
   if q == "unexisting" then
   rednet.broadcast("transit_"..v.."_cardinality_"..q)
   end  
   if v == nil then
   rednet.broadcast("transit_cardinality_indefinita")
   end

  end

end

if words[1] == "systems" then

  if words[2] == "manager" then

   if words[3] == "routes" then

	if words[5] == "shutdown" then
	rednet.broadcast("shutdown_manager_routes")
	os.shutdown()
	end
	
	if words[5] == "reboot" then
	rednet.broadcast("reboot_manager_routes")
	os.reboot()
	end

   end

  end

end

end

Meanwhile I set up all my components to be immune from game start and stop having them asking for the last state they are actually supposed to assume to the states manager, having a simple and intelligent gerarchy wait function that prevent to make every component rednet request at the same time and having the net completely filled and making impossibile for the manager to respond to all without making a mess, but makes every component ask for it a fraction of second after each other in the order based on their assigned number.

I played with the use of files and had to make a lot of tries before starting to understand well things.
A the beginning I was thinking about a system that just save the states table on a file when the system shutdown but yes, If the game is simply closed this would result in a mess at the restart, with trains going crazy and everything broke down, so I succesfully wrote this code for states manager that basically keeps constantly updated a file with the current data of states table.
Because I worried from the beginning about delay of saving to file that can result in situations of two or more contemporary state updates not being saved all, that was the reason of just having the save to file function on system shutdown, I made managers that set switches or other components in batch having a delay between every command, to let states manager save the command confirmation from component to the file.

Anyway, here is the code:

Spoiler

-- archive configuration

a = "states"

-- initialize peripherals

modem = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "modem" then
  modem = side
  break
  end
end

monitor = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "monitor" then
  monitor = side
  break
  end
end  

-- boot code

sleep(1)
print("< states >")
sleep(1)
print("manager")
sleep(1)
print("assigning")
sleep(1)
print("initializing")
sleep(1)
print("connecting")
rednet.open(modem)
rednet.broadcast("startup_manager_states")
sleep(1)
print("running")

-- functions code

function generate_table()

state = {}
state["binary"] = {}
state["switch"] = {}
state["signal"] = {}
state["display"] = {}
state["relevator"] = {}
state["activator"] = {}
state["stopper"] = {}
state["starter"] = {}
state["type"] = {}
state["train"] = {}

end

function save_table(table,name)

local file = fs.open(name,"w")
local text = textutils.serialize(table)
file.write(text)
file.close()

end

function load_table(table,name)

local file = fs.open(name,"r")
local text = file.readAll()
local data = textutils.unserialize(text)
table = data
file.close()

end

-- archive code

local archive = fs.exists(a)

if archive == true then
load_table(state,a)
end

if archive == false then
generate_table()
end

-- system code

while true do
local senderID, message = rednet.receive()
local words = {}
local i = " "

for word in string.gmatch(message, "%w+") do words[#words + 1] = word end

if words[1] == "state" then

local c = words[2]
local n = tonumber(words[3])
local s = state[c][n]

  if s ~= nil then
  rednet.broadcast(c.."_"..n.."_"..s)
  end

  if s == nil then
  rednet.broadcast(c.."_"..n.."_undefined")
  end

end

if words[1] == "update" then

local c = words[2]
local n = tonumber(words[3])
local s = words[4]
state[c][n] = s
save_table(state,a)

end

if words[1] == "systems" then

  if words[2] == "manager" then

   if words[3] == "states" then

	if words[4] == "shutdown" then
	rednet.broadcast("shutdown_manager_states")
	os.shutdown()
	end
	
	if words[4] == "reboot" then
	rednet.broadcast("reboot_manager_states")
	os.reboot()
	end
	
	if words[4] == "reset" then
	rednet.broadcast("reset_manager_states")
	fs.delete(a)
	os.reboot()
	end	

   end

  end

end

end

This is giving me some problems.
At first boot of clean computer, state manager just works and I put some states to it.
When I shutdown the computer and open the archive file I find my table have the first entry of the first sub-table filled with value does not have the key, while all the other entries then have their keys and values.
This causes at the next reboot an error when the programs is asked to report the state value for a certain component.
What is wrong?

Last thing:
I am thinking about the auto-update funtion we were talking about with Dragon53535, and I tought about simply making a Railway API with all my functions and also programs functions, then just a script on every computer with the local informations and a "purpose field" and API update function with then then running program called from the api on the base of what kind of purpose is set
Edited on 13 February 2016 - 02:23 PM
Bomb Bloke #38
Posted 14 February 2016 - 11:55 PM
When I shutdown the computer and open the archive file I find my table have the first entry of the first sub-table filled with value does not have the key, while all the other entries then have their keys and values.
This causes at the next reboot an error when the programs is asked to report the state value for a certain component.
What is wrong?

Can you provide examples as to what the file should and does look like?
pietro.devo #39
Posted 15 February 2016 - 07:52 AM
Sure!


{
  switch = {
	[ 5 ] = "active",
	[ 14 ] = "active",
	[ 11 ] = "active",
  },
  binary = {
	"free",
	[ 104 ] = "occupied",
	[ 108 ] = "transit",
	[ 107 ] = "occupied",
  },
  signal = {},
  stopper = {},
  relevator = {},
  display = {},
  starter = {},
  train = {},
  type = {},
  activator = {},
}

In this case the first update I pushed was of binary 101, saying it was free, but I get just the value without its key, I don't have [ 101 ] = "free", then I pushed some others states for binaries and they are just fine and correctly saved.
At this point I push another kind of information, the switch one, to see I the first entry gets the same problm, but it doesn't and all the states I pushed are again correctly stored
Edited on 15 February 2016 - 06:53 AM
Dragon53535 #40
Posted 15 February 2016 - 09:04 AM
Are you sure that the value was 101? Real quick see if when you're saving this that printing the binary[101] value is actually correct.


print(state.binary[101])
print(state.binary[1])
pietro.devo #41
Posted 15 February 2016 - 11:42 AM
101 was the key for sub-table, value was "free".
Now I tryed using a different name for file, just using the name "file".
This seems to solve the problem but actually what is wrong is the table: First boot I always let computer gets some states updated to fill the table, then I reboot it and next time I ask for a state or I try to add another update it stops executing code beacuse of attempt to call a nil value, so seems like not only the previously saved table is not loaded correctly with old values (deduction from the state request command), but simply It can't push again values in it and fill table, meaning it doesn't exists and is considered nil (deduction from the state update command)
Edited on 15 February 2016 - 11:11 AM
pietro.devo #42
Posted 04 March 2016 - 03:56 PM
I have started changing all my rednet stuff to tables, from now no more strings and such things.
I really understand the power and simplicity of using tables. What I am at same time doing is remove completely the need of configuring tons of computers on the base of each different station making a cntralized config computer that just instructs every other at each boot, so when I need to change something, add a schedule, change a platform and so on, I simply change the config in it and it is all done.

Next step will be also putting away functions from local systems and having them called too.

Here is the code, while still working on it I am keeping in my language, sorry for this, at the end will be translated:

Spoiler

-- INIZIALIZZAZIONE

N = {}
C = {}
B = {}
F = {}
T = {}
D = {}
S = {}

-- NORME

-- codice direttrice
N.cd = 1000

-- versore est
N.ve = 1
-- versore sud
N.vs = 2
-- versore ovest
N.vw = 3
-- versore nord
N.vn = 4

-- inversore est
N.we = 3
-- inversore sud
N.ws = 4
-- inversore ovest
N.ww = 1
-- inversore nord
N.wn = 2

-- circolazione positiva
N.cx = 1
-- circolazione negativa
N.cy = 2
-- circolazione neutra
N.cz = 3

-- binari passeggeri
N.bp = 100
-- binari merci
N.bm = 200
-- binari servizi
N.bs = 300
-- binari fermata
N.bf = 500
-- binari transito
N.bt = 600

-- CONFIGURAZIONI

-- limite sistemi
C.ls = 10000

-- circolazione binata
C.cb = "gestita"

-- binari passeggeri
C.bp = 10
-- binari merci
C.bm = 10
-- binari servizi
C.bs = 10
-- binari fermata
C.bf = 10
-- binari transito
C.bt = 10

-- direttrice est
C.de = "gestita"
-- direttrice sud
C.ds = "gestita"
-- direttrice ovest
C.dw = "gestita"
-- direttrice nord
C.dn = "gestita"

-- BINARI

-- iniziale passeggeri
B.xp = N.bp+1
-- iniziale merci
B.xm = N.bm+1
-- iniziale servizi
B.xs = N.bs+1
-- iniziale fermata
B.xf = N.bf+1
-- iniziale transito
B.xt = N.bt+1

-- finale passeggeri
B.yp = N.bp+C.bp
-- finale merci
B.ym = N.bm+C.bm
-- finale servizi
B.ys = N.bs+C.bs
-- finale fermata
B.yf = N.bf+C.bf
-- finale transito
B.yt = N.bt+C.bt

-- FUNZIONI

-- fermata parallela
F.fp = "amcodiceo"
-- fermata lineare
F.fl = "amcodiceo"

-- transito dedicato
F.td = "amcodiceo"
-- transito eccezionale
F.te = "amcodiceo"

-- transito passeggeri
F.tp = "amcodiceo"
-- transito merci
F.tm = "amcodiceo"
-- transito servizi
F.ts = "amcodiceo"

-- TRENI

T[000] = {}

-- DEVIATOI

D[000] = {}

-- SEGNALI

S[000] = {}

-- ISTRUZIONI

I = {N,C,B,F,T,D,S}

-- INIZIALIZAZZIONE PERIFERICHE

modem = nil
 for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "modem" then
  modem = side
  break
  end
 end
 
monitor = nil
 for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "monitor" then
  monitor = side
  break
  end
 end

-- CODICE AVVIO
 
sleep(1)
print("< configurazioni >")
sleep(1)
print("gestore")
sleep(1)
print("assegnazione")
sleep(1)
print("inizializzazione")
sleep(1)
print("connessione")
rednet.open(modem)
rednet.host("SCGIRC","gestore_configurazioni")
rednet.broadcast({"avvio","gestore","configurazioni"})
sleep(1)
print("funzionamento")

-- CODICE SISTEMA

while true do
local id, codice = rednet.receive()

 if codice[1] == "istruisci" then
 r = codice[2]
 local codice = I[r]
 rednet.broadcast(r)
 end
 
end

So basically here I set up all the stuff in specific tables, then I just call the table with instructions I really need for every manager computer, for example the scheduling one won't need to know informations about switches and lights and won't ask for these tables and so on.

Here the routes manager posted before, without local configs and with use of tables for every command:

Spoiler

-- inizializzazione periferiche

modem = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "modem" then
  modem = side
  break
  end
end

monitor = nil
for _, side in pairs(rs.getSides()) do
  if peripheral.getType(side) == "monitor" then
  monitor = side
  break
  end
end

-- codice avvio

sleep(1)
print("< tragitti >")
sleep(1)
print("gestore")
sleep(1)
print("assegnazione")
sleep(1)
print("inizializzazione")
sleep(1)
print("connessione")
rednet.open(modem)
rednet.host("SCGIRC","gestore_tragitti")
rednet.broadcast({"avvio","gestore","tragitti"})
sleep(1)
print("funzionamento")

-- codice funzioni

function configura_versori(v)

q = nil
g = nil
w = nil
xd = nil
yd = nil
if v == ve then
q = "esistente"
g = C.de
w = N.we
end
if v == vs then
q = "esistente"
g = C.ds
w = N.ws
end
if v == vw then
q = "esistente"
g = C.dw
w = N.ww
end
if v == vn then
q = "esistente"
g = C.dn
w = N.wn
end

end

function configura_blocchi(q,g,v,d)

k = nil
xd = nil
yd = nil
if q == "esistente" and g == "gestita" then
k = v*N.cd+d
end
if C.cb == "gestita" then
xd = N.cx
yd = N.cy
end
if C.cb == "ingestita" then
xd = N.cz
yd = N.cz
end

end

function configura_fermata(v)

p = nil
l = nil
if v == N.ve then
p = N.bf+1
l = v*N.cd+c
end
if v == N.vs then
p = N.bf+1
l = v*N.cd+c
end
if v == N.vw then
p = N.bf+2
l = v*N.cd+c
end
if v == N.vn then
p = N.bf+2
l = v*N.cd+c
end

end

function tragitto_configura(v,d,c)

cnfg = nil
cnf1 = nil
cnf2 = nil
rednet.broadcast({"configura","tragitto",v,d,c})
while true do
local id, codice = rednet.receive()
  if codice == {"tragitto",v,d,c,"deviatoi","configurato"} then
  cnf1 = true
  end
  if codice == {"tragitto",v,d,c,"segnali","configurato"} then
  cnf2 = true
  end
  if codice == {"tragitto",v,d,c,"deviatoi","indefinito"} then
  cnf1 = false
  end
  if codice == {"tragitto",v,d,c,"segnali","indefinito"} then
  cnf2 = false
  end
  if codice == {"tragitto",v,d,c,"deviatoi","errore"} then
  cnf1 = false
  end
  if codice == {"tragitto",v,d,c,"segnali","errore"} then
  cnf2 = false
  end
  if cnf1 == true and cnf2 == true then
  cnfg = true
  break
  end
  if cnf1 == false or cnf2 == false then
  cnfg = false
  break
  end
end

end

function tragitto_transito(v1,v2,d1,d2,c,k)

tragitto_configura(v1,d1,c)
if cnfg == true then
cnc1 = true
end
if cnfg == false then
cnc1 = false
end
tragitto_configura(v2,d2,k)
if cnfg == true then
cnc2 = true
end
if cnfg == false then
cnc2 = false
end
if cnc1 == true and cnc2 == true then
cnct = true
end
if cnc1 == false or cnc2 == false then
cnct = false
end
end

function tragitto_binario(c)

erro = nil
rednet.broadcast({"stato","binario",c})
local id, codice = rednet.receive()
if codice == {"binario",c,"libero"} then
erro = false
end
if codice == {"binario",c,"indefinito"} then
erro = true
end
if codice == {"binario",c,"occupato"} then
erro = true
end
if codice == {"binario",c,"transito"} then
erro = true
end

end

function tragitto_elabora(v,b,x,y)

erro = nil
for i = 1 , b do
  if v == N.ve then
  j = i
  u = y
  end
  if v == N.vs then
  j = i
  u = y
  end
  if v == N.vw then
  j = b-i
  u = x
  end
  if v == N.vn then
  j = b-i
  u = x
  end
r = i
c = j+x
rednet.broadcast({"stato","binario",c})
local id, codice = rednet.receive()
  if codice == {"binario",c,"libero"} then
  erro = false
  break
  end
  if codice == {"binario",c,"indefinito"} then
  erro = true
  end
  if codice == {"binario",c,"occupato"} then
  erro = true
  end
  if codice == {"binario",c,"transito"} then
  erro = true
  end
end

end

function tragitto_prepara(t,v,d,n,s,r,c,erro)

if erro == false then
tragitto_configura(v,d,c)
  if cnfg == true then
  rednet.broadcast({t,v,n,r,"preparato"})
  end
  if cnfg == false then
  rednet.broadcast({t,v,n,s,"eccezione"})
  end
end
if erro == true then
rednet.broadcast({t,v,n,s,"impossibile"})
end

end

function transito_binario(c,k)

ste1 = nil
ste2 = nil
tragitto_binario(c)
ste1 = erro
tragitto_binario(k)
ste2 = erro

end

function transito_elabora(v,d,b,x,y,k)

ste1 = nil
ste2 = nil
tragitto_elabora(v,ve,vs,vw,vn,d,b,x,y)
ste1 = erro
tragitto_binario(k)
ste2 = erro

end

function transito_prepara(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)

step = nil
if ste1 == false and ste2 == false then
step = false
end
if ste1 == true or ste2 == true then
step = true
end
if step == false then
tragitto_transito(v1,v2,d1,d2,c,k)
  if cnct == true then
  rednet.broadcast({"transito",v1,v2,n,r,"preparato"})
  end
  if cnct == false then
   if cnc1 == false then
   rednet.broadcast({"transito",v1,v2,n,s,"imprevisto","binario"})
   end
   if cnc2 == false then
   rednet.broadcast({"transito",v1,v2,n,s,"imprevisto","linea"})
   end  
  rednet.broadcast({"transito",v1,v2,n,s,"eccezione"})
  end
end
if step == true then
  if ste1 == true then
  rednet.broadcast({"transito",v1,v2,n,s,"blocco_binario"})
  end
  if ste2 == true then
  rednet.broadcast({"transito",v1,v2,n,s,"blocco_linea"})
  end  
rednet.broadcast({"transito",v1,v2,n,s,"impossibile"})
end

end

function transito_verifica(v,d,n,f,b,x,y)

if f == "ammesso" then
rednet.broadcast({"transito","eccezionale",n,f})
sleep(1)
tragitto_elabora(v,b,x,y)
er = r
ec = c
  if erro == true then
  rednet.broadcast({"transito","eccezionale",n,"impossibile"})  
  vrfy = nil
  end  
  if erro == false then
  rednet.broadcast({"transito","eccezionale",n,"possibile"})
  vrfy = n
  end  
end
if f == "vietato" then
rednet.broadcast({"transito","eccezionale",n,f})
end
r = nil
c = nil

end

function transito_dedicato(v1,v2,d1,d2,n,b,s,r,c,k,x,y)

if b == 0 then
rednet.broadcast({"transito","funzione",n,"inesistente"})
end
if b ~= 0 then
  if s == nil then
  rednet.broadcast({"transito",v1,v2,n,"indefinito"})
  end	  
  if s == "elabora" then  
  transito_elabora(v1,d1,b,x,y,k)
  transito_prepara(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
  t = nil
  end
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast({"transito",v1,v2,n,"binario","inesistente"})
   end
   if c < y then
   transito_binario(c,k)
   transito_prepara(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
   end
  end
end

end

function transito_eccezionale(v1,v2,d1,d2,n,f,s,r,c,k)

if f == "vietato" then
rednet.broadcast({"transito","funzione",n,f})
end
if f == "ammesso" then
  if s == nil then
  rednet.broadcast({"transito",v1,v2,"eccezionale","binario","indefinito"})
  end
  if s == "elabora" then	
  vrfy = nil	
   if vrfy == nil then
   n = "passeggeri"
   transito_verifica(v,d,n,F.tp,C.bp,N.xp,N.yp)
   ste1 = erro
   end
   if vrfy == nil then
   n = "merci"
   transito_verifica(v,d,n,F.tm,C.bm,N.xm,N.ym)
   ste1 = erro
   end
   if vrfy == nil then
   n = "servizi"		
   transito_verifica(v,d,n,F.ts,B.bs,N.xs,N.ys)
   ste1 = erro
   end
  tragitto_binario(k)
  ste2 = erro
  transito_prepara(v1,v2,d1,d2,n,s,er,ec,k,ste1,ste2)
  end
  if r ~= nil then
  c = r
   if r > C.ls then
   rednet.broadcast({"transito",v1,v2,"eccezionale",r,"limite","sistemi"})
   end
   if r < C.ls then
   transito_binario(c,k)
   transito_prepara(v1,v2,d1,d2,n,s,r,c,k,ste1,ste2)
   end
  end
end

end

function prepara_arrivo(v,d,n,b,s,r,k,x,y)

if b == 0 then
rednet.broadcast({"arrivo","funzione",n,"inesistente"})
end
if b ~= 0 then
  if s == nil then
  rednet.broadcast({"arrivo",v,n,"binario","indefinito"})
  end  
  if s == "elabora" then
  tragitto_elabora(v,b,x,y)
  tragitto_prepara("arrivo",v,d,n,s,r,c,erro)
  r = nil
  end
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast({"arrivo",v,n,"binario","inesistente"})
   end
   if c < y then
   tragitto_binario(c)
   tragitto_prepara("arrivo",v,d,n,s,r,c,erro)
   end  
  end
end  

end

function prepara_partenza(v,d,n,b,s,r,k,x,y)

if b == 0 then
rednet.broadcast({"partenza","funzione",n,"inesistente"})
end
if b ~= 0 then
  if s == nil then	
  rednet.broadcast({"partenza",v,n,"binario","indefinito"})
  end	  
  if r ~= nil then
  c = r+x
   if c > y then
   rednet.broadcast({"partenza",v,n,"binario","inesistente"})
   end	
   if c < y then
   tragitto_binario(k)
   tragitto_prepara("partenza",v,d,n,s,r,c,erro)
   end
  end
end

end

function prepara_eccezionale(t,v,d,b,s,r,c,k)
	
if s == nil then
rednet.broadcast({t,v,"eccezionale","binario","indefinito"})
end
if s ~= nil then
c = r
  if r > C.ls then
  rednet.broadcast({t,v,"eccezionale","limite","sistemi"})
  end
  if r < C.ls then
   if B.xp < r and r < B.yp or B.xm < r and r < B.ym or B.xs < r and r < B.ys then
   tragitto_binario(k)
   tragitto_prepara(t,v,d,n,s,r,c,erro)
   else
   rednet.broadcast({t,v,"eccezionale","binario","inesistente"})
   end
  end
end

end

function prepara_fermata(v,w,xd,yd,n,f,s,r,c,k)

if f == "vietato" then
rednet.broadcast({"fermata","funzione",n,f})
end
if f == "ammesso" then
  if r == "arrivo" then	  
  tragitto_binario(c)	  
  tragitto_prepara("fermata",v,xd,n,s,r,c,erro)
  end
  if r == "partenza" then	  
  tragitto_binario(k)	  
  tragitto_prepara("fermata",w,yd,n,s,r,c,erro)
  end
end

end

-- codice sistema

rednet.broadcast({"istruisci","N"})
id, N =  rednet.receive()
rednet.broadcast({"istruisci","C"})
id, C =  rednet.receive()
rednet.broadcast({"istruisci","B"})
id, B =  rednet.receive()

while true do
local id, codice = rednet.receive()

if codice[1] == "prepara" then

  if codice[2] == "arrivo" then

  t = codice[2]
  v = tonumber(codice[3])
  n = codice[4]
  s = codice[5]
  r = tonumber(codice[5])

  configura_versori(v)
  configura_blocchi(q,g,v,xd)
  
   if q == "esistente" and g == "gestita" then
	if n == "passeggeri" then
	prepara_arrivo(v,xd,n,C.bp,s,r,k,B.xp,B.yp)
	end
	if n == "merci" then
	prepara_arrivo(v,xd,n,C.bm,s,r,k,B.xm,B.ym)
	end
	if n == "servizi" then
	prepara_arrivo(v,xd,n,C.bs,s,r,k,B.xs,B.ys)
	end
	if n == "eccezionale" then
	prepara_eccezionale(t,v,xd,n,s,r,c,k)
	end
   end
  
   if q == "esistente" and g == "ingestita"  then
   rednet.broadcast({"arrivo",v,"cardinalita'",g})
   end
   if q == "inesistente" then
   rednet.broadcast({"arrivo",v,"cardinalita'",q})
   end
   if v == nil then
   rednet.broadcast({"arrivo","cardinalita'","indefinita"})
   end

  end

  if codice[2] == "partenza" then  

  t = codice[2]
  v = tonumber(codice[3])
  n = codice[4]
  s = codice[5]
  r = tonumber(codice[5])

  configura_versori(v)
  configura_blocchi(q,g,v,yd)
	
   if q == "esistente" and g == "gestita" then
	if n == "passeggeri" then
	prepara_partenza(v,yd,n,C.bp,s,r,k,B.xp,B.yp)
	end
	if n == "merci" then
	prepara_partenza(v,yd,n,C.bm,s,r,k,B.xm,B.ym)
	end
	if n == "servizi" then
	prepara_partenza(v,yd,n,C.bs,s,r,k,B.xs,B.ys)
	end
	if n == "eccezionale" then
	prepara_eccezionale(t,v,yd,n,s,r,c,k)
	end
   end
  
   if q == "esistente" and g == "ingestita" then
   rednet.broadcast({"partenza",v,"cardinalita'",g})
   end
   if q == "inesistente" then
   rednet.broadcast({"partenza",v,"cardinalita'",q})
   end
   if v == nil then
   rednet.broadcast({"partenza","cardinalita'","indefinita"})
   end

  end

  if codice[2] == "fermata" then

  t = codice[2]
  v = tonumber(codice[3])
  n = codice[4]
  s = codice[5]
  r = codice[5]

  configura_versori(v)
  configura_fermata(v)
  configura_blocchi(q,g,v,yd)

   if q == "esistente" and g == "gestita" then
	if n == "parallela" then
	prepara_fermata(v,w,xd,yd,n,F.fp,s,r,p,k)
	end
	if n == "lineare" then
	prepara_fermata(v,w,xd,yd,n,F.fl,s,r,p,k)
	end
   end
	
   if q == "esistente" and g == "ingestita" then
   rednet.broadcast({"fermata",v,"cardinalita'",g})
   end
   if q == "inesistente" then
   rednet.broadcast({"fermata",v,"cardinalita'",q})
   end
   if v == nil then
   rednet.broadcast({"fermata","cardinalita'","indefinita"})
   end

  end

  if codice[2] == "transito" then

  t = codice[2]
  v1 = tonumber(codice[3])
  v2 = tonumber(codice[4])  
  q1 = nil
  q2 = nil
  g1 = nil
  g2 = nil
  n = codice[5]
  s = codice[6]
  r = tonumber(codice[6])

  configura_versori(v1)
  q1 = q
  g1 = g
  configura_versori(v2)
  q2 = q
  g2 = g
  configura_blocchi(q,g,v,yd)
  d1 = xd
  d2 = yd

   if q1 == "esistente" and q2 == "esistente" then
   q = "esistente"
   end
   if q1 == "inesistente" or q2 == "inesistente" then
   q = "inesistente"
   end  
   if g1 == "gestita" and g2 == "gestita" then
   g = "gestita"
   end
   if g1 == "ingestita" or g2 == "ingestita" then
   g = "ingestita"
   end
  
   if q == "esistente" and g == "gestita" then
	if n == "dedicato" then
	transito_dedicato(v1,v2,d1,d2,n,C.bt,s,r,c,k,B.xt,B.yt)
	end	
	if n == "eccezionale" then	
	transito_eccezionale(v1,v2,d1,d2,n,F.te,s,r,c,k)
	end
   end  

   if q == "esistente" and g == "ingestita" then
   rednet.broadcast({"transito",v1,v2,"cardinalita'",g})
   end
   if q == "inesistente" then
   rednet.broadcast({"transito",v1,v2,"cardinalita'",q})
   end  
   if v == nil then
   rednet.broadcast({"transito","cardinalita'","indefinita"})
   end

  end

end

if codice == {"sistemi","gestore","tragitti","spegnimento"} then
rednet.broadcast({"spegnimento","gestore","tragitti"})
os.shutdown()
end
if codice == {"sistemi","gestore","tragitti","riavvio"} then
rednet.broadcast({"riavvio","gestore","tragitti"})
os.reboot()
end

end

I have rednet displayer that show me when this route manager boot up asks correctly for instruction tables and the config manager gives them to it, so at this point no problems, what is not working is that whatever command I try to send the programs doesn't seem to respond, what is wrong?
Edited on 04 March 2016 - 03:01 PM
Bomb Bloke #43
Posted 05 March 2016 - 08:41 AM
I have rednet displayer that show me when this route manager boot up asks correctly for instruction tables and the config manager gives them to it, so at this point no problems, what is not working is that whatever command I try to send the programs doesn't seem to respond, what is wrong?

Urgh…

I see two great long sheets of code with rednet calls in them. Could you please pastebin them and clearly indicate which one isn't working as expected, and the line numbers which should be doing whatever isn't being done?
pietro.devo #44
Posted 05 March 2016 - 11:55 AM
Let's say I just try the shutdown command on gestore_tragitti.
I execute this translated:

rednet.broadcast({"systems","routes","manager","shutdown"})

On the other end, routes manager should shutdown itself beacuse of this:


[...]

while true do
local id, code = rednet.receive()

[...]

if code == {"systems","routes","manager","shutdown"} then
rednet.broadcast({"shutdown","routes","manager"})
os.shutdown()
end

[..]

end

I imagine there is something very stupid I am doing here, but can't figure out
Edited on 05 March 2016 - 10:58 AM
KingofGamesYami #45
Posted 05 March 2016 - 01:15 PM
You can't compare tables like that.

print( {} == {} ) --#output: false
Edited on 05 March 2016 - 12:15 PM
pietro.devo #46
Posted 05 March 2016 - 04:36 PM
Ok, so eventually I can also create a loop to verify the matching of every entry of table, correct?
Edited on 05 March 2016 - 04:42 PM
KingofGamesYami #47
Posted 05 March 2016 - 07:19 PM
Yes. It'd be something like this:

local function comparetables( a, b )
  if #a ~= #b then
    return false
  end
  for k, v in pairs( a ) do
    if b[ k ] ~= v then
      return false
    end
  end
  return true
end