Fix water inlet bug, change logic block

This commit is contained in:
Joachim Stolberg 2021-02-27 18:29:52 +01:00
parent e12262172b
commit bc059bc234
11 changed files with 176 additions and 141 deletions

View File

@ -908,36 +908,33 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"\n", "\n",
"Den TA3 Logikblock kann man so programmieren\\, dass ein oder mehrere Eingangskommandos zu einem Ausgangskommando verknüpft und gesendet werden. Dieser Block kann daher diverse Logik-Elemente wie AND\\, OR\\, NOT\\, XOR usw. ersetzen.\n".. "Den TA3 Logikblock kann man so programmieren\\, dass ein oder mehrere Eingangskommandos zu einem Ausgangskommando verknüpft und gesendet werden. Dieser Block kann daher diverse Logik-Elemente wie AND\\, OR\\, NOT\\, XOR usw. ersetzen.\n"..
"Eingangkommandos für den Logikblock sind 'on'/'off' Kommandos. Ein 'on' ist ein logisches 'true'\\, ein 'off' entspricht dem 'false'.\n".. "Eingangkommandos für den Logikblock sind 'on'/'off' Kommandos.\n"..
"Eingangskommandos werden über die Nummer referenziert\\, also bspw. '1234' für das Kommando vom Sender mit der Nummer 1234.\n".. "Eingangskommandos werden über die Nummer referenziert\\, also bspw. '1234' für das Kommando vom Sender mit der Nummer 1234.\n"..
"Das gleiche gilt für Ausgangskommandos.\n".. "Das gleiche gilt für Ausgangskommandos.\n"..
"\n".. "\n"..
"Eine Regel ist wie folgt aufgebaut:\n".. "Eine Regel ist wie folgt aufgebaut:\n"..
"\n".. "\n"..
" <output> = true/false if <input-expression> is true\n".. " <output> = on/off if <input-expression> is true\n"..
"\n".. "\n"..
"'<output>' ist die Nummer des Blocks\\, zu dem das Kommando gesendet werden soll.\n".. "'<output>' ist die Nummer des Blocks\\, zu dem das Kommando gesendet werden soll.\n"..
"\n".. "\n"..
"'<input-expression>' ist ein boolescher Ausdruck\\, bei dem Eingabenummern ausgewertet werden. \n".. "'<input-expression>' ist ein boolescher Ausdruck\\, bei dem Eingabenummern ausgewertet werden. \n"..
"\n".. "\n"..
" - \n"..
" - \n"..
"\n"..
"*Beispiele für den Input Ausdruck*\n".. "*Beispiele für den Input Ausdruck*\n"..
"\n".. "\n"..
"Signal negieren (NOT):\n".. "Signal negieren (NOT):\n"..
"\n".. "\n"..
" 1234 == false\n".. " 1234 == off\n"..
"\n".. "\n"..
"Logisches UND (AND):\n".. "Logisches UND (AND):\n"..
"\n".. "\n"..
" 1234 == true and 2345 == true\n".. " 1234 == on and 2345 == on\n"..
"\n".. "\n"..
"Logisches ODER (OR):\n".. "Logisches ODER (OR):\n"..
"\n".. "\n"..
" 1234 == true or 2345 == true\n".. " 1234 == on or 2345 == on\n"..
"\n".. "\n"..
"Folgende Operatoren sind zulässig: 'and' 'or' 'true' 'false' '==' '~=' '(' ')'\n".. "Folgende Operatoren sind zulässig: 'and' 'or' 'on' 'off' 'me' '==' '~=' '(' ')'\n"..
"\n".. "\n"..
"Ist der Ausdruck wahr (true)\\, wird ein Kommando an den Block mit der '<output>' Nummer gesendet.\n".. "Ist der Ausdruck wahr (true)\\, wird ein Kommando an den Block mit der '<output>' Nummer gesendet.\n"..
"\n".. "\n"..
@ -945,6 +942,10 @@ techage.manual_DE.aText = {
"\n".. "\n"..
"Die interne Durchlaufzeit aller Kommandos beträgt 100 ms.\n".. "Die interne Durchlaufzeit aller Kommandos beträgt 100 ms.\n"..
"\n".. "\n"..
"Über das Schlüsselwort 'me' kann die eigene Knotennummer referenziert werden. Damit ist es möglich\\, dass sich der Block selbst ein Kommando sendet (Flip-Flop Funktion).\n"..
"\n"..
"Die Sperrzeit definiert eine Pause nach einem Kommando\\, in der der Logikblock kein weiteres Kommando von extern annimmt. Empfangene Kommandos in der Sperrzeit werden damit verworfen. Die Sperrzeit kann in Sekunden definiert werden.\n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"Der Wiederholer (repeater) sendet das empfangene Signal an alle konfigurierten Nummern weiter.\n".. "Der Wiederholer (repeater) sendet das empfangene Signal an alle konfigurierten Nummern weiter.\n"..
@ -1222,7 +1223,7 @@ techage.manual_DE.aText = {
"Im Prinzip arbeitet das das Wärmespeichersystem genau gleich wie die Akkus\\, nur mit viel mehr Speicherkapazität. \n".. "Im Prinzip arbeitet das das Wärmespeichersystem genau gleich wie die Akkus\\, nur mit viel mehr Speicherkapazität. \n"..
"Der Wärmespeicher kann 60 ku aufnehmen und abgeben.\n".. "Der Wärmespeicher kann 60 ku aufnehmen und abgeben.\n"..
"\n".. "\n"..
"Damit das Wärmespeichersystem funktioniert\\, müssen alle Blöcke (außer Betonhülle und Gravel) mit Hilfe eines Forceloadblockes geladen sein.\n".. "Damit das Wärmespeichersystem funktioniert\\, müssen alle Blöcke (auch Betonhülle und Gravel) mit Hilfe eines Forceloadblockes geladen sein.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",

View File

@ -897,41 +897,41 @@ techage.manual_EN.aText = {
"\n".. "\n"..
"\n", "\n",
"The TA3 logic block can be programmed in such a way that one or more input commands are linked to one output command and sent. This block can therefore replace various logic elements such as AND\\, OR\\, NOT\\, XOR etc. \n".. "The TA3 logic block can be programmed in such a way that one or more input commands are linked to one output command and sent. This block can therefore replace various logic elements such as AND\\, OR\\, NOT\\, XOR etc. \n"..
"Input commands for the logic block are 'on' /'off' commands. An 'on' is a logical 'true'\\, an 'off' corresponds to the'false'. \n".. "Input commands for the logic block are 'on' /'off' commands.\n"..
"Input commands are referenced via the number\\, e.g. '1234' for the command from the sender with the number 1234. \n".. "Input commands are referenced via the number\\, e.g. '1234' for the command from the sender with the number 1234. \n"..
"The same applies to output commands.\n".. "The same applies to output commands.\n"..
"\n".. "\n"..
"A rule is structured as follows: \n".. "A rule is structured as follows: \n"..
"\n".. "\n"..
" <output> = true/false if <input-expression> is true\n".. " <output> = on/off if <input-expression> is true\n"..
"\n".. "\n"..
"'<output>' is the block number to which the command should be sent.\n".. "'<output>' is the block number to which the command should be sent.\n"..
"\n"..
"'<input-expression>' is a boolean expression where input numbers are evaluated.\n".. "'<input-expression>' is a boolean expression where input numbers are evaluated.\n"..
"\n".. "\n"..
" - \n"..
" - \n"..
"\n"..
"*Examples for the input expression*\n".. "*Examples for the input expression*\n"..
"\n".. "\n"..
"Negate signal (NOT):\n".. "Negate signal (NOT):\n"..
"\n".. "\n"..
" 1234 == false\n".. " 1234 == off\n"..
"\n".. "\n"..
"Logical AND:\n".. "Logical AND:\n"..
"\n".. "\n"..
" 1234 == true and 2345 == true\n".. " 1234 == on and 2345 == on\n"..
"\n".. "\n"..
"Logical OR:\n".. "Logical OR:\n"..
"\n".. "\n"..
" 1234 == true or 2345 == true\n".. " 1234 == on or 2345 == on\n"..
"\n".. "\n"..
"The following operators are allowed: 'and' 'or' 'true' 'false' '==' '~=' '(' ')'\n".. "The following operators are allowed: 'and' 'or' 'on' 'off' 'me' '==' '~=' '(' ')'\n"..
"\n".. "\n"..
"If the expression is true\\, a command is sent to the block with the '<output>' number. \n".. "If the expression is true\\, a command is sent to the block with the '<output>' number. \n"..
"Up to four rules can be defined\\, whereby all rules are always checked when a command is received. \n".. "Up to four rules can be defined\\, whereby all rules are always checked when a command is received. \n"..
"The internal processing time for all commands is 100 ms. \n".. "The internal processing time for all commands is 100 ms. \n"..
"\n".. "\n"..
"Your own node number can be referenced using the keyword 'me'. This makes it possible for the block to send itself a command (flip-flop function). \n"..
"\n"..
"The blocking time defines a pause after a command\\, during which the logic block does not accept any further external commands. Commands received during the blocking period are thus discarded. The blocking time can be defined in seconds. \n"..
"\n"..
"\n".. "\n"..
"\n", "\n",
"The repeater sends the received signal to all configured numbers.\n".. "The repeater sends the received signal to all configured numbers.\n"..
@ -1199,7 +1199,7 @@ techage.manual_EN.aText = {
"In principle\\, the heat storage system works exactly the same as the batteries\\, only with much more storage capacity.\n".. "In principle\\, the heat storage system works exactly the same as the batteries\\, only with much more storage capacity.\n"..
"The heat accumulator can hold and deliver 60 ku.\n".. "The heat accumulator can hold and deliver 60 ku.\n"..
"\n".. "\n"..
"In order for the heat storage system to work\\, all blocks (except the concrete shell and gravel) must be loaded using a forceload block.\n".. "In order for the heat storage system to work\\, all blocks (also the concrete shell and gravel) must be loaded using a forceload block.\n"..
"\n".. "\n"..
"\n".. "\n"..
"\n", "\n",

View File

@ -39,7 +39,7 @@ end
local function srv_peek(pos) local function srv_peek(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
if is_ocean(pos) then if is_ocean(pos) then
nvm.liquid.name = "default:water_source" nvm.liquid.name = "techage:water"
nvm.liquid.amount = 1 nvm.liquid.amount = 1
else else
nvm.liquid.name = nil nvm.liquid.name = nil

View File

@ -172,7 +172,7 @@ minetest.register_node("techage:t4_waterpump", {
on_timer = node_timer, on_timer = node_timer,
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=2, crumbly=2, choppy=2}, groups = {cracky=2, crumbly=2, choppy=2, not_in_creative_inventory = 1},
on_rotate = screwdriver.disallow, on_rotate = screwdriver.disallow,
is_ground_content = false, is_ground_content = false,
}) })

View File

@ -251,7 +251,6 @@ Blocks are disappeared=Blöcke sind verschwunden
Click on all the blocks that are part of the door/gate=Klicke auf alle Blöcke, die Teil des Tores sind Click on all the blocks that are part of the door/gate=Klicke auf alle Blöcke, die Teil des Tores sind
Ctrl,Inv=Ctrl,Inv Ctrl,Inv=Ctrl,Inv
Done=Fertig Done=Fertig
Error: Inventory already in use=Fehler: Inventar wird bereits genutzt
Record=Aufzeichnen Record=Aufzeichnen
Recording...=Aufzeichnung... Recording...=Aufzeichnung...
Remove=Entfernen Remove=Entfernen
@ -542,6 +541,7 @@ no usable water=Kein brauchbares Wasser
### logic_block.lua ### ### logic_block.lua ###
'me' has to be used for the own block number.@n='me' wird für die eigene Blocknummer verwendet.@n
'~@=' means: not equal@n='~@=' bedeutet: ungleich@n '~@=' means: not equal@n='~@=' bedeutet: ungleich@n
@n<input-expression> is a boolean expression@nwhere input numbers are evaluated.@n=@n<input-expression> ist ein boolescher Ausdruck,@nbei dem Eingabenummern ausgewertet werden.@n @n<input-expression> is a boolean expression@nwhere input numbers are evaluated.@n=@n<input-expression> ist ein boolescher Ausdruck,@nbei dem Eingabenummern ausgewertet werden.@n
@ -550,16 +550,14 @@ no usable water=Kein brauchbares Wasser
@nAll rules are checked with each received@ncommand.=@nAlle Regeln werden mit jedem empfangenen@nBefehl überprüft. @nAll rules are checked with each received@ncommand.=@nAlle Regeln werden mit jedem empfangenen@nBefehl überprüft.
@nExamples:@n1234 @=@= true@n1234 @=@= false@n1234 @=@= true and 2345 @=@= false@n2345 ~@= 3456@n=@nBeispiele:@n1234 @=@= true@n1234 @=@= false@n1234 @=@= true and 2345 @=@= false@n2345 ~@= 3456@n @nExamples:@n1234 @=@= on@n1234 @=@= off@n1234 @=@= on and 2345 @=@= off@n2345 ~@= 3456@n=@nBeispiele:@n1234 @=@= on@n1234 @=@= off@n1234 @=@= on and 2345 @=@= off@n2345 ~@= 3456@n
@nRule:@n<output> @= true/false if <input-expression> is true@n=@nRegel:@n<output> @= true/false if <input-expression> is true@n
@nThe following applies to inputs/outputs:@ntrue is 'on' and false is 'off'@n=@nFür alle Eingänge/Ausgänge gilt:@ntrue ist 'on' und false ist 'off'@n
@nRule:@n<output> @= on/off if <input-expression> is true@n=@nRegel:@n<output> @= on/off if <input-expression> is true@n
@nThe internal processing time for all@ncommands is 100 ms.=@nDie interne Durchlaufzeit für alle@nKommandos beträgt 100 ms. @nThe internal processing time for all@ncommands is 100 ms.=@nDie interne Durchlaufzeit für alle@nKommandos beträgt 100 ms.
@nValid operators:@nand or true false @=@= ~@= ( )@n=@nGültige Operatoren:@nand or true false @=@= ~@= ( )@n @nValid operators:@nand or on off me @=@= ~@= ( )@n=@nGültige Operatoren:@nand or on off @=@= ~@= ( )@n
Blocking Time=Sperrzeit
Help=Hilfe Help=Hilfe
Inputs=Eingänge Inputs=Eingänge
Outputs=Ausgänge Outputs=Ausgänge
@ -1075,3 +1073,4 @@ is a suitable place for a wind turbine!=ist ein geeigneter Ort für eine Windkra
##### not used anymore ##### ##### not used anymore #####

View File

@ -251,7 +251,6 @@ Blocks are disappeared=
Click on all the blocks that are part of the door/gate= Click on all the blocks that are part of the door/gate=
Ctrl,Inv= Ctrl,Inv=
Done= Done=
Error: Inventory already in use=
Record= Record=
Recording...= Recording...=
Remove= Remove=
@ -542,6 +541,7 @@ no usable water=
### logic_block.lua ### ### logic_block.lua ###
'me' has to be used for the own block number.@n=
'~@=' means: not equal@n= '~@=' means: not equal@n=
@n<input-expression> is a boolean expression@nwhere input numbers are evaluated.@n= @n<input-expression> is a boolean expression@nwhere input numbers are evaluated.@n=
@ -550,16 +550,14 @@ no usable water=
@nAll rules are checked with each received@ncommand.= @nAll rules are checked with each received@ncommand.=
@nExamples:@n1234 @=@= true@n1234 @=@= false@n1234 @=@= true and 2345 @=@= false@n2345 ~@= 3456@n= @nExamples:@n1234 @=@= on@n1234 @=@= off@n1234 @=@= on and 2345 @=@= off@n2345 ~@= 3456@n=
@nRule:@n<output> @= true/false if <input-expression> is true@n=
@nThe following applies to inputs/outputs:@ntrue is 'on' and false is 'off'@n=
@nRule:@n<output> @= on/off if <input-expression> is true@n=
@nThe internal processing time for all@ncommands is 100 ms.= @nThe internal processing time for all@ncommands is 100 ms.=
@nValid operators:@nand or true false @=@= ~@= ( )@n= @nValid operators:@nand or on off me @=@= ~@= ( )@n=
Blocking Time=
Help= Help=
Inputs= Inputs=
Outputs= Outputs=

View File

@ -19,28 +19,22 @@ local logic = techage.logic
local NUM_RULES = 4 local NUM_RULES = 4
local HELP = S("Send an 'on'/'off' command if the\nexpression becomes true.\n") .. local HELP = S("Send an 'on'/'off' command if the\nexpression becomes true.\n") ..
S("\nRule:\n<output> = true/false if <input-expression> is true\n") .. S("\nRule:\n<output> = on/off if <input-expression> is true\n") ..
S("\n<output> is the block number to which the\ncommand should be sent.\n") .. S("\n<output> is the block number to which the\ncommand should be sent.\n") ..
S("\nThe following applies to inputs/outputs:\ntrue is 'on' and false is 'off'\n") ..
S("\n<input-expression> is a boolean expression\nwhere input numbers are evaluated.\n") .. S("\n<input-expression> is a boolean expression\nwhere input numbers are evaluated.\n") ..
S("\nExamples:\n1234 == true\n1234 == false\n1234 == true and 2345 == false\n2345 ~= 3456\n") .. S("\nExamples:\n1234 == on\n1234 == off\n1234 == on and 2345 == off\n2345 ~= 3456\n") ..
S("\nValid operators:\nand or true false == ~= ( )\n") .. S("\nValid operators:\nand or on off me == ~= ( )\n") ..
S("'~=' means: not equal\n") .. S("'~=' means: not equal\n") ..
S("'me' has to be used for the own block number.\n") ..
S("\nAll rules are checked with each received\ncommand.") .. S("\nAll rules are checked with each received\ncommand.") ..
S("\nThe internal processing time for all\ncommands is 100 ms.") S("\nThe internal processing time for all\ncommands is 100 ms.")
-- mem.io_tbl = {
-- i123 = true, -- "on" received
-- i124 = false, -- "off" received
-- o456 = false, -- last output val
-- }
local ValidSymbols = { local ValidSymbols = {
["me"] = true, ["me"] = true,
["and"] = true, ["and"] = true,
["or"] = true, ["or"] = true,
["true"] = true, ["on"] = true,
["false"] = true, ["off"] = true,
["=="] = true, ["=="] = true,
["~="] = true, ["~="] = true,
["("] = true, ["("] = true,
@ -49,11 +43,12 @@ local ValidSymbols = {
local Dropdown = { local Dropdown = {
[""] = 1, [""] = 1,
["true"] = 2, ["on"] = 2,
["false"] = 3 ["off"] = 3
} }
local function check_expr(expr) local function check_expr(pos, expr)
local nvm = techage.get_nvm(pos)
local origin = expr local origin = expr
-- Add blanks for the syntax check -- Add blanks for the syntax check
expr = expr:gsub("==", " == ") expr = expr:gsub("==", " == ")
@ -62,10 +57,19 @@ local function check_expr(expr)
expr = expr:gsub("%)", " ) ") expr = expr:gsub("%)", " ) ")
-- First syntax check -- First syntax check
local old_sym = "or" -- valid default value
for sym in expr:gmatch("[^%s]+") do for sym in expr:gmatch("[^%s]+") do
if not ValidSymbols[sym] and string.find(sym, '^[0-9]+$') == nil then if not ValidSymbols[sym] and string.find(sym, '^[0-9]+$') == nil then
return "Unexpected symbol '"..sym.."'" return "Unexpected symbol '"..sym.."'"
end end
if string.find(sym, '^[0-9]+$') and sym == nvm.own_num then
return "Invalid node number '"..sym.."'"
end
-- function call check
if sym == "(" and (old_sym ~= "and" and old_sym ~= "or") then
return "Syntax error at '" .. sym .. "'"
end
old_sym = sym
end end
-- Second syntax check -- Second syntax check
local code, _ = loadstring("return " .. expr) local code, _ = loadstring("return " .. expr)
@ -74,24 +78,44 @@ local function check_expr(expr)
end end
end end
local function check_num(num, player_name) local function check_num(pos, num, player_name)
if num ~= "me" and not techage.check_numbers(num, player_name) then local nvm = techage.get_nvm(pos)
if num ~= "me" and (num == nvm.own_num or
not techage.check_numbers(num, player_name)) then
return "Invalid node number '"..num.."'" return "Invalid node number '"..num.."'"
end end
end end
local function send(pos, num, val) local function send(pos, num, val)
print("send", num, val)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
if num == "me" then
nvm.outp_tbl = nvm.outp_tbl or {}
nvm.outp_tbl.me = val
-- set the input directly
nvm.inp_tbl = nvm.inp_tbl or {}
nvm.inp_tbl.me = val
else
nvm.outp_tbl = nvm.outp_tbl or {}
nvm.outp_tbl[num] = val
nvm.own_num = nvm.own_num or M(pos):get_string("node_number") nvm.own_num = nvm.own_num or M(pos):get_string("node_number")
nvm.io_tbl = nvm.io_tbl or {}
nvm.io_tbl["o" .. num] = val == "on" and true or false
techage.send_single(nvm.own_num, num, val) techage.send_single(nvm.own_num, num, val)
end end
end
local function check_syntax(line, owner, outp, expr) local function get_inputs(pos)
local err = check_num(outp, owner) local nvm = techage.get_nvm(pos)
-- old data is needed for formspec 'input' values
nvm.old_inp_tbl = table.copy(nvm.inp_tbl or {})
return nvm.old_inp_tbl
end
local function check_syntax(pos, line, owner, outp, expr)
local err = check_num(pos, outp, owner)
if not err then if not err then
err = check_expr(expr) err = check_expr(pos, expr)
if not err then if not err then
return true, "ok" return true, "ok"
end end
@ -111,14 +135,25 @@ local function compile(nvm, str)
end end
end end
local function data(nvm)
local inp = {}
local outp = {}
for num, val in pairs(nvm.old_inp_tbl or {}) do
if num == nvm.own_num then num = "me" end
inp[#inp+1] = num .. " = " .. tostring(val)
end
for num, val in pairs(nvm.outp_tbl or {}) do
if num == nvm.own_num then num = "me" end
outp[#outp+1] = num .. " = " .. tostring(val)
end
return table.concat(inp, ", "), table.concat(outp, ", ")
end
local function get_code(pos, nvm) local function get_code(pos, nvm)
local meta = M(pos) local meta = M(pos)
local mem = techage.get_mem(pos) local tbl = {"local inputs = get_inputs(pos) or {}"}
local tbl = {}
local owner = M(pos):get_string("owner") local owner = M(pos):get_string("owner")
nvm.own_num = nvm.own_num or M(pos):get_string("node_number") nvm.own_num = nvm.own_num or M(pos):get_string("node_number")
nvm.io_tbl.send = send
nvm.io_tbl.pos = pos
for i = 1,NUM_RULES do for i = 1,NUM_RULES do
local outp = meta:get_string("outp" .. i) local outp = meta:get_string("outp" .. i)
@ -126,59 +161,48 @@ local function get_code(pos, nvm)
local expr = meta:get_string("expr" .. i) local expr = meta:get_string("expr" .. i)
if outp ~= "" and val ~= "" and expr ~= "" then if outp ~= "" and val ~= "" and expr ~= "" then
local res, err = check_syntax(i, owner, outp, expr) local res, err = check_syntax(pos, i, owner, outp, expr)
if res then if res then
val = val == "true" and "on" or "off" expr = string.gsub(expr, '([0-9]+)', 'inputs["%1"]')
-- add prefix 'i' to all numbers expr = string.gsub(expr, 'me', 'inputs["me"]')
expr = string.gsub(expr, '([0-9]+)', "i%1") expr = string.gsub(expr, 'on', '"on"')
expr = string.gsub(expr, 'me', "i" .. nvm.own_num) expr = string.gsub(expr, 'off', '"off"')
outp = string.gsub(outp, 'me', nvm.own_num) tbl[#tbl + 1] = "if "..expr.." then send(pos, '"..outp.."', '"..val.."') end"
tbl[#tbl + 1] = "if "..expr.." then send(pos, "..outp..", '"..val.."') end"
else else
nvm.error = err nvm.error = err
mem.code = nil
return return
end end
end end
end end
local str = table.concat(tbl, "\n") local str = table.concat(tbl, "\n")
print(str)
local code = compile(nvm, str) local code = compile(nvm, str)
if code then
local env = {}
env.send = send
env.pos = pos
env.get_inputs = get_inputs
setfenv(code, env)
return code return code
end end
end
local function execute(pos) local function execute(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
local mem = techage.get_mem(pos) local mem = techage.get_mem(pos)
nvm.own_num = nvm.own_num or M(pos):get_string("node_number") print("execute1", dump(nvm.inp_tbl))
nvm.io_tbl["i" .. nvm.own_num] = nvm.from_myself or false
mem.code = mem.code or get_code(pos, nvm) mem.code = mem.code or get_code(pos, nvm)
if mem.code then if mem.code then
setfenv(mem.code, nvm.io_tbl)
local res, _ = pcall(mem.code) local res, _ = pcall(mem.code)
if not res then if not res then
nvm.error = "Unknown runtime error" nvm.error = "Unknown runtime error"
mem.code = nil
print("Unknown runtime error")
end end
end end
end print("execute2", dump(nvm.outp_tbl))
local function data(nvm)
local inp = {}
local outp = {}
for k,v in pairs(nvm.io_tbl) do
if k ~= "send" and k ~= "pos" then
if k:byte(1) == 105 then -- 'i'
local num = k:sub(2)
if num == nvm.own_num then num = "me" end
inp[#inp+1] = num .. " = " .. dump(v)
else
local num = k:sub(2)
if num == nvm.own_num then num = "me" end
outp[#outp+1] = num .. " = " .. dump(v)
end
end
end
return table.concat(inp, ", "), table.concat(outp, ", ")
end end
local function rules(meta) local function rules(meta)
@ -186,7 +210,7 @@ local function rules(meta)
tbl[#tbl + 1] = "label[-0.2,0;<outp>]" tbl[#tbl + 1] = "label[-0.2,0;<outp>]"
tbl[#tbl + 1] = "label[1.4,0;=]" tbl[#tbl + 1] = "label[1.4,0;=]"
tbl[#tbl + 1] = "label[1.8,0;<bool>]" tbl[#tbl + 1] = "label[1.8,0;<cmnd>]"
tbl[#tbl + 1] = "label[3.5,0;if]" tbl[#tbl + 1] = "label[3.5,0;if]"
tbl[#tbl + 1] = "label[4.2,0;<inp expression> is true]" tbl[#tbl + 1] = "label[4.2,0;<inp expression> is true]"
@ -202,7 +226,7 @@ local function rules(meta)
tbl[#tbl + 1] = "field[0," .. y1 .. ";1.6,1;outp" .. i ..";;" .. outp .. "]" tbl[#tbl + 1] = "field[0," .. y1 .. ";1.6,1;outp" .. i ..";;" .. outp .. "]"
tbl[#tbl + 1] = "label[1.4," .. y2 .. ";=]" tbl[#tbl + 1] = "label[1.4," .. y2 .. ";=]"
tbl[#tbl + 1] = "dropdown[1.8," .. y3 .. ";1.6,1;val" .. i ..";,true,false;" .. val .. "]" tbl[#tbl + 1] = "dropdown[1.8," .. y3 .. ";1.6,1;val" .. i ..";,on,off;" .. val .. "]"
tbl[#tbl + 1] = "label[3.5," .. y2 .. ";if]" tbl[#tbl + 1] = "label[3.5," .. y2 .. ";if]"
tbl[#tbl + 1] = "field[4.2," .. y1 .. ";5.6,1;expr" .. i ..";;" .. expr .. "]" tbl[#tbl + 1] = "field[4.2," .. y1 .. ";5.6,1;expr" .. i ..";;" .. expr .. "]"
end end
@ -215,25 +239,31 @@ local function formspec(pos, meta)
err = minetest.formspec_escape(err) err = minetest.formspec_escape(err)
nvm.io_tbl = nvm.io_tbl or {} nvm.io_tbl = nvm.io_tbl or {}
local inputs, outputs = data(nvm) local inputs, outputs = data(nvm)
return "size[10,7.7]" .. local bt = nvm.blocking_time or 1
return "size[10,8.2]" ..
"tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";1;;true]" .. "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";1;;true]" ..
"container[0.4,0.1]" .. "container[0.4,0.1]" ..
rules(meta) .. rules(meta) ..
"container_end[]" .. "container_end[]" ..
"label[0,4.5;" .. S("Inputs") .. ":]" ..
"label[2,4.5;" .. inputs .."]" .. "label[0.2,4.4;" .. S("Blocking Time") .. "]"..
"label[0,5.1;" .. S("Outputs") .. ":]" .. "field[4.6,4.5;2,1;bt;;" .. bt .. "]"..
"label[2,5.1;" .. outputs .."]" .. "label[6.3,4.4;s]"..
"label[0,5.7;" .. S("Syntax") .. ":]" ..
"label[2,5.7;" .. err .. "]" .. "label[0,5.3;" .. S("Inputs") .. ":]" ..
"button[1.5,7.0;3,1;update;" .. S("Update") .. "]" .. "label[2,5.3;" .. inputs .."]" ..
"button[5.6,7.0;3,1;store;" .. S("Store") .. "]" "label[0,5.9;" .. S("Outputs") .. ":]" ..
"label[2,5.9;" .. outputs .."]" ..
"label[0,6.5;" .. S("Syntax") .. ":]" ..
"label[2,6.5;" .. err .. "]" ..
"button[1.5,7.5;3,1;update;" .. S("Update") .. "]" ..
"button[5.6,7.5;3,1;store;" .. S("Store") .. "]"
end end
local function formspec_help() local function formspec_help()
return "size[10,7.7]" .. return "size[10,8.2]" ..
"tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";2;;true]" .. "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";2;;true]" ..
"textarea[0.3,0.3;9.9,8;;;"..minetest.formspec_escape(HELP).."]" "textarea[0.3,0.3;9.9,8.5;;;"..minetest.formspec_escape(HELP).."]"
end end
minetest.register_node("techage:ta3_logic2", { minetest.register_node("techage:ta3_logic2", {
@ -248,7 +278,6 @@ minetest.register_node("techage:ta3_logic2", {
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
local meta = M(pos) local meta = M(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
nvm.io_tbl = {}
logic.after_place_node(pos, placer, "techage:ta3_logic2", S("TA3 Logic Block")) logic.after_place_node(pos, placer, "techage:ta3_logic2", S("TA3 Logic Block"))
logic.infotext(meta, S("TA3 Logic Block")) logic.infotext(meta, S("TA3 Logic Block"))
meta:set_string("formspec", formspec(pos, meta)) meta:set_string("formspec", formspec(pos, meta))
@ -269,8 +298,9 @@ minetest.register_node("techage:ta3_logic2", {
meta:set_string("expr" .. i, fields["expr" .. i] or "") meta:set_string("expr" .. i, fields["expr" .. i] or "")
end end
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
nvm.own_num = nvm.own_num or M(pos):get_string("node_number") nvm.blocking_time = tonumber(fields.bt) or 0.1
nvm.io_tbl = {["i" .. nvm.own_num] = false} nvm.inp_tbl = {me = "off"}
nvm.outp_tbl = {}
end end
if fields.tab == "2" then if fields.tab == "2" then
@ -294,7 +324,6 @@ minetest.register_node("techage:ta3_logic2", {
local meta = M(pos) local meta = M(pos)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
get_code(pos, nvm)
meta:set_string("formspec", formspec(pos, meta)) meta:set_string("formspec", formspec(pos, meta))
end, end,
@ -322,20 +351,22 @@ minetest.register_craft({
techage.register_node({"techage:ta3_logic2"}, { techage.register_node({"techage:ta3_logic2"}, {
on_recv_message = function(pos, src, topic, payload) on_recv_message = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos) local nvm = techage.get_nvm(pos)
local mem = techage.get_mem(pos)
nvm.own_num = nvm.own_num or M(pos):get_string("node_number") nvm.own_num = nvm.own_num or M(pos):get_string("node_number")
nvm.io_tbl = nvm.io_tbl or {} nvm.blocking_time = nvm.blocking_time or M(pos):get_float("blocking_time")
nvm.inp_tbl = nvm.inp_tbl or {}
if src ~= nvm.own_num then -- from other node if src ~= nvm.own_num and techage.SystemTime > (mem.ttl or 0) then
if topic == "on" then if topic == "on" then
nvm.io_tbl["i" .. src] = true nvm.inp_tbl[src] = "on"
elseif topic == "off" then elseif topic == "off" then
nvm.io_tbl["i" .. src] = false nvm.inp_tbl[src] = "off"
else else
return "unsupported" return "unsupported"
end end
mem.ttl = techage.SystemTime + (nvm.blocking_time or 0)
minetest.get_node_timer(pos):start(0.1) minetest.get_node_timer(pos):start(0.1)
else
nvm.from_myself = (topic == "on") and true or false
end end
end, end,
}) })

View File

@ -523,19 +523,18 @@ Hinweis: Mit dem Programmer können Blocknummern sehr einfach eingesammelt und k
### TA3 Logikblock / Logic Block ### TA3 Logikblock / Logic Block
Den TA3 Logikblock kann man so programmieren, dass ein oder mehrere Eingangskommandos zu einem Ausgangskommando verknüpft und gesendet werden. Dieser Block kann daher diverse Logik-Elemente wie AND, OR, NOT, XOR usw. ersetzen. Den TA3 Logikblock kann man so programmieren, dass ein oder mehrere Eingangskommandos zu einem Ausgangskommando verknüpft und gesendet werden. Dieser Block kann daher diverse Logik-Elemente wie AND, OR, NOT, XOR usw. ersetzen.
Eingangkommandos für den Logikblock sind `on`/`off` Kommandos. Ein `on` ist ein logisches `true`, ein `off` entspricht dem `false`. Eingangkommandos für den Logikblock sind `on`/`off` Kommandos.
Eingangskommandos werden über die Nummer referenziert, also bspw. `1234` für das Kommando vom Sender mit der Nummer 1234. Eingangskommandos werden über die Nummer referenziert, also bspw. `1234` für das Kommando vom Sender mit der Nummer 1234.
Das gleiche gilt für Ausgangskommandos. Das gleiche gilt für Ausgangskommandos.
Eine Regel ist wie folgt aufgebaut: Eine Regel ist wie folgt aufgebaut:
``` ```
<output> = true/false if <input-expression> is true <output> = on/off if <input-expression> is true
``` ```
- `<output>` ist die Nummer des Blocks, zu dem das Kommando gesendet werden soll. `<output>` ist die Nummer des Blocks, zu dem das Kommando gesendet werden soll.
`<input-expression>` ist ein boolescher Ausdruck, bei dem Eingabenummern ausgewertet werden.
- `<input-expression>` ist ein boolescher Ausdruck, bei dem Eingabenummern ausgewertet werden.
@ -543,17 +542,17 @@ Eine Regel ist wie folgt aufgebaut:
Signal negieren (NOT): Signal negieren (NOT):
1234 == false 1234 == off
Logisches UND (AND): Logisches UND (AND):
1234 == true and 2345 == true 1234 == on and 2345 == on
Logisches ODER (OR): Logisches ODER (OR):
1234 == true or 2345 == true 1234 == on or 2345 == on
Folgende Operatoren sind zulässig: `and` `or` `true` `false` `==` `~=` `(` `)` Folgende Operatoren sind zulässig: `and` `or` `on` `off` `me` `==` `~=` `(` `)`
Ist der Ausdruck wahr (true), wird ein Kommando an den Block mit der `<output>` Nummer gesendet. Ist der Ausdruck wahr (true), wird ein Kommando an den Block mit der `<output>` Nummer gesendet.
@ -561,6 +560,10 @@ Es können bis zu vier Regeln definiert werden, wobei immer alle Regeln geprüft
Die interne Durchlaufzeit aller Kommandos beträgt 100 ms. Die interne Durchlaufzeit aller Kommandos beträgt 100 ms.
Über das Schlüsselwort `me` kann die eigene Knotennummer referenziert werden. Damit ist es möglich, dass sich der Block selbst ein Kommando sendet (Flip-Flop Funktion).
Die Sperrzeit definiert eine Pause nach einem Kommando, in der der Logikblock kein weiteres Kommando von extern annimmt. Empfangene Kommandos in der Sperrzeit werden damit verworfen. Die Sperrzeit kann in Sekunden definiert werden.
[ta3_logic|image] [ta3_logic|image]

View File

@ -510,19 +510,18 @@ Note: With the programmer, block numbers can be easily collected and configured.
### TA3 Logic Block ### TA3 Logic Block
The TA3 logic block can be programmed in such a way that one or more input commands are linked to one output command and sent. This block can therefore replace various logic elements such as AND, OR, NOT, XOR etc. The TA3 logic block can be programmed in such a way that one or more input commands are linked to one output command and sent. This block can therefore replace various logic elements such as AND, OR, NOT, XOR etc.
Input commands for the logic block are `on` /` off` commands. An `on` is a logical ` true`, an `off` corresponds to the` false`. Input commands for the logic block are `on` /` off` commands.
Input commands are referenced via the number, e.g. `1234` for the command from the sender with the number 1234. Input commands are referenced via the number, e.g. `1234` for the command from the sender with the number 1234.
The same applies to output commands. The same applies to output commands.
A rule is structured as follows: A rule is structured as follows:
``` ```
<output> = true/false if <input-expression> is true <output> = on/off if <input-expression> is true
``` ```
- `<output>` is the block number to which the command should be sent. `<output>` is the block number to which the command should be sent.
`<input-expression>` is a boolean expression where input numbers are evaluated.
- `<input-expression>` is a boolean expression where input numbers are evaluated.
@ -530,22 +529,26 @@ A rule is structured as follows:
Negate signal (NOT): Negate signal (NOT):
1234 == false 1234 == off
Logical AND: Logical AND:
1234 == true and 2345 == true 1234 == on and 2345 == on
Logical OR: Logical OR:
1234 == true or 2345 == true 1234 == on or 2345 == on
The following operators are allowed: `and` `or` `true` `false` `==` `~=` `(` `)` The following operators are allowed: `and` `or` `on` `off` `me` `==` `~=` `(` `)`
If the expression is true, a command is sent to the block with the `<output>` number. If the expression is true, a command is sent to the block with the `<output>` number.
Up to four rules can be defined, whereby all rules are always checked when a command is received. Up to four rules can be defined, whereby all rules are always checked when a command is received.
The internal processing time for all commands is 100 ms. The internal processing time for all commands is 100 ms.
Your own node number can be referenced using the keyword `me`. This makes it possible for the block to send itself a command (flip-flop function).
The blocking time defines a pause after a command, during which the logic block does not accept any further external commands. Commands received during the blocking period are thus discarded. The blocking time can be defined in seconds.
[ta3_logic|image] [ta3_logic|image]

View File

@ -143,7 +143,7 @@ Sowohl der Generator als auch der Wärmetauscher haben einen Stromanschluss und
Im Prinzip arbeitet das das Wärmespeichersystem genau gleich wie die Akkus, nur mit viel mehr Speicherkapazität. Im Prinzip arbeitet das das Wärmespeichersystem genau gleich wie die Akkus, nur mit viel mehr Speicherkapazität.
Der Wärmespeicher kann 60 ku aufnehmen und abgeben. Der Wärmespeicher kann 60 ku aufnehmen und abgeben.
Damit das Wärmespeichersystem funktioniert, müssen alle Blöcke (außer Betonhülle und Gravel) mit Hilfe eines Forceloadblockes geladen sein. Damit das Wärmespeichersystem funktioniert, müssen alle Blöcke (auch Betonhülle und Gravel) mit Hilfe eines Forceloadblockes geladen sein.
[ta4_storagesystem|plan] [ta4_storagesystem|plan]

View File

@ -143,7 +143,7 @@ Both the generator and the heat exchanger have a power connection and must be co
In principle, the heat storage system works exactly the same as the batteries, only with much more storage capacity. In principle, the heat storage system works exactly the same as the batteries, only with much more storage capacity.
The heat accumulator can hold and deliver 60 ku. The heat accumulator can hold and deliver 60 ku.
In order for the heat storage system to work, all blocks (except the concrete shell and gravel) must be loaded using a forceload block. In order for the heat storage system to work, all blocks (also the concrete shell and gravel) must be loaded using a forceload block.
[ta4_storagesystem|plan] [ta4_storagesystem|plan]