Add digiline interface to power monitor

The power monitor can now be queried for information about the network. They
are retrieved from the associated switching station.

Also export information about the attached batteries.
This commit is contained in:
Alexander Ried
2020-06-30 14:00:38 +02:00
committed by Buckaroo Banzai
parent facc8e783c
commit 47e75e456f
3 changed files with 69 additions and 4 deletions

View File

@ -6,6 +6,15 @@ local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png" local cable_entry = "^technic_cable_connection_overlay.png"
-- return the position of the associated switching station or nil
local function get_swpos(pos)
local network_hash = technic.cables[minetest.hash_node_position(pos)]
local network = network_hash and minetest.get_position_from_hash(network_hash)
local swpos = network and {x=network.x,y=network.y+1,z=network.z}
local is_powermonitor = swpos and minetest.get_node(swpos).name == "technic:switching_station"
return is_powermonitor and swpos or nil
end
minetest.register_craft({ minetest.register_craft({
output = "technic:power_monitor", output = "technic:power_monitor",
recipe = { recipe = {
@ -32,7 +41,54 @@ minetest.register_node("technic:power_monitor",{
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Power Monitor")) meta:set_string("infotext", S("Power Monitor"))
meta:set_string("channel", "power_monitor"..minetest.pos_to_string(pos))
meta:set_string("formspec", "field[channel;Channel;${channel}]")
end, end,
on_receive_fields = function(pos, formname, fields, sender)
if not fields.channel then
return
end
local plname = sender:get_player_name()
if minetest.is_protected(pos, plname) and not minetest.check_player_privs(sender, "protection_bypass") then
minetest.record_protection_violation(pos, plname)
return
end
local meta = minetest.get_meta(pos)
meta:set_string("channel", fields.channel)
end,
digiline = {
receptor = {
rules = technic.digilines.rules,
action = function() end
},
effector = {
rules = technic.digilines.rules,
action = function(pos, node, channel, msg)
if msg ~= "GET" and msg ~= "get" then
return
end
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then
return
end
local sw_pos = get_swpos(pos)
if not sw_pos then
return
end
local sw_meta = minetest.get_meta(sw_pos)
digilines.receptor_send(pos, technic.digilines.rules, channel, {
supply = sw_meta:get_int("supply"),
demand = sw_meta:get_int("demand"),
lag = sw_meta:get_int("lag"),
battery_count = sw_meta:get_int("battery_count"),
battery_charge = sw_meta:get_int("battery_charge"),
battery_charge_max = sw_meta:get_int("battery_charge_max"),
})
end
},
},
}) })
minetest.register_abm({ minetest.register_abm({
@ -42,14 +98,12 @@ minetest.register_abm({
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local network_hash = technic.cables[minetest.hash_node_position(pos)] local sw_pos = get_swpos(pos)
local network = network_hash and minetest.get_position_from_hash(network_hash)
local sw_pos = network and {x=network.x,y=network.y+1,z=network.z}
local timeout = 0 local timeout = 0
for tier in pairs(technic.machines) do for tier in pairs(technic.machines) do
timeout = math.max(meta:get_int(tier.."_EU_timeout"),timeout) timeout = math.max(meta:get_int(tier.."_EU_timeout"),timeout)
end end
if timeout > 0 and sw_pos and minetest.get_node(sw_pos).name == "technic:switching_station" then if timeout > 0 and sw_pos then
local sw_meta = minetest.get_meta(sw_pos) local sw_meta = minetest.get_meta(sw_pos)
local supply = sw_meta:get_int("supply") local supply = sw_meta:get_int("supply")
local demand = sw_meta:get_int("demand") local demand = sw_meta:get_int("demand")

View File

@ -240,6 +240,7 @@ function technic.register_battery_box(data)
meta:set_int(tier.."_EU_supply", meta:set_int(tier.."_EU_supply",
math.min(data.discharge_rate, current_charge)) math.min(data.discharge_rate, current_charge))
meta:set_int("internal_EU_charge", current_charge) meta:set_int("internal_EU_charge", current_charge)
meta:set_int("internal_EU_charge_max", max_charge)
-- Select node textures -- Select node textures
local charge_count = math.ceil((current_charge / max_charge) * 8) local charge_count = math.ceil((current_charge / max_charge) * 8)

View File

@ -306,9 +306,16 @@ technic.switching_station_run = function(pos)
local charge_total = 0 local charge_total = 0
local battery_count = 0 local battery_count = 0
local BA_charge = 0
local BA_charge_max = 0
for n, pos1 in pairs(BA_nodes) do for n, pos1 in pairs(BA_nodes) do
meta1 = minetest.get_meta(pos1) meta1 = minetest.get_meta(pos1)
local charge = meta1:get_int("internal_EU_charge") local charge = meta1:get_int("internal_EU_charge")
local charge_max = meta1:get_int("internal_EU_charge_max")
BA_charge = BA_charge + charge
BA_charge_max = BA_charge_max + charge_max
if (meta1:get_int(eu_demand_str) ~= 0) then if (meta1:get_int(eu_demand_str) ~= 0) then
charge_total = charge_total + charge charge_total = charge_total + charge
@ -378,6 +385,9 @@ technic.switching_station_run = function(pos)
-- Data that will be used by the power monitor -- Data that will be used by the power monitor
meta:set_int("supply",PR_eu_supply) meta:set_int("supply",PR_eu_supply)
meta:set_int("demand",RE_eu_demand) meta:set_int("demand",RE_eu_demand)
meta:set_int("battery_count",#BA_nodes)
meta:set_int("battery_charge",BA_charge)
meta:set_int("battery_charge_max",BA_charge_max)
-- If the PR supply is enough for the RE demand supply them all -- If the PR supply is enough for the RE demand supply them all
if PR_eu_supply >= RE_eu_demand then if PR_eu_supply >= RE_eu_demand then