kpoppel
2013-07-02 053fa59739f4b772174bf0a090969b3395ab3f98
commit | author | age
cfb5bd 1 -- The MV down converter will step down MV EUs to LV EUs
K 2 -- If we take the solar panel as calibration then the
3 -- 1 MVEU = 5 LVEU as we stack 5 LV arrays to get an MV array.
4 -- The downconverter does of course have a conversion loss.
5 -- This loses 30% of the power.
6 -- The converter does not store any energy by itself.
7 minetest.register_node(
8    "technic:down_converter_mv", {
9       description = "MV Down Converter",
10       tiles  = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png",
11         "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"},
12       groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
13       sounds = default.node_sound_wood_defaults(),
14       drawtype = "nodebox",
15       paramtype = "light",
16       is_ground_content = true,
17       node_box = {
18      type = "fixed",
19      fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
20       },
21       selection_box = {
22      type = "fixed",
23      fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
24       },
25       on_construct = function(pos)
26             local meta = minetest.env:get_meta(pos)
27             meta:set_float("technic_mv_power_machine", 1)
28             meta:set_float("technic_power_machine", 1)
29             meta:set_float("internal_EU_buffer",0)
30             meta:set_float("internal_EU_buffer_size",0)
31             meta:set_string("infotext", "MV Down Converter")
32               meta:set_float("active", false)
33                end,
34    })
35
36 minetest.register_craft({
37     output = 'technic:down_converter_mv 1',
38     recipe = {
39         {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'},
40         {'technic:mv_transformer',        'technic:mv_cable',             'technic:lv_transformer'},
41         {'technic:mv_cable',              'technic:rubber',               'technic:lv_cable'},
42     }
43 })
44
45 minetest.register_abm(
46     {nodenames = {"technic:down_converter_mv"},
47     interval   = 1,
48     chance     = 1,
49     action = function(pos, node, active_object_count, active_object_count_wider)
50             -- MV->LV conversion factor
51             local mv_lv_factor = 5
52             -- The maximun charge a single converter can handle. Let's set this to
53             -- what 5 MV solar arrays can produce - 30% loss (720*5*0.7)
54             local max_charge = 2520*mv_lv_factor
55
56             local meta             = minetest.env:get_meta(pos)
57             local meta1            = nil
58             local pos1             = {}
59             local available_charge = 0 -- counted in LV units
60             local used_charge      = 0 -- counted in LV units
61
62             -- Index all MV nodes connected to the network
63             -- MV cable comes in through the bottom
64             pos1.y = pos.y-1
65             pos1.x = pos.x
66             pos1.z = pos.z
67             meta1  = minetest.env:get_meta(pos1)
68             if meta1:get_float("mv_cablelike")~=1 then return end
69
70             local MV_nodes    = {} -- MV type
71             local MV_PR_nodes = {} -- MV type
72             local MV_BA_nodes = {} -- MV type
73
74             MV_nodes[1]         = {}
75             MV_nodes[1].x       = pos1.x
76             MV_nodes[1].y       = pos1.y
77             MV_nodes[1].z       = pos1.z
78
79             local table_index = 1
80             repeat
81                check_MV_node(MV_PR_nodes,nil,MV_BA_nodes,MV_nodes,table_index)
82                table_index = table_index + 1
83                if MV_nodes[table_index] == nil then break end
84             until false
85
86             --print("MV_nodes: PR="..table.getn(MV_PR_nodes).." BA="..table.getn(MV_BA_nodes))
87
88             -- Index all LV nodes connected to the network
89             -- LV cable comes out of the top
90             pos1.y = pos.y+1
91             pos1.x = pos.x
92             pos1.z = pos.z
93             meta1  = minetest.env:get_meta(pos1)
94             if meta1:get_float("cablelike")~=1 then return end
95
96             local LV_nodes    = {} -- LV type
97             local LV_RE_nodes = {} -- LV type
98             local LV_BA_nodes = {} -- LV type
99
100             LV_nodes[1]         = {}
101             LV_nodes[1].x       = pos1.x
102             LV_nodes[1].y       = pos1.y
103             LV_nodes[1].z       = pos1.z
104
105             table_index = 1
106             repeat
107                check_LV_node(nil,LV_RE_nodes,LV_BA_nodes,LV_nodes,table_index)
108                table_index = table_index + 1
109                if LV_nodes[table_index] == nil then break end
110             until false
111
112             --print("LV_nodes: RE="..table.getn(LV_RE_nodes).." BA="..table.getn(LV_BA_nodes))
113
114             -- First get available power from all the attached MV suppliers
115             -- Get the supplier internal EU buffer and read the EUs from it
116             -- No update yet!
117             local pos1
118 -- FIXME: Until further leave the producers out of it and just let the batteries be the hub
119 --            for _,pos1 in ipairs(MV_PR_nodes) do
120 --               meta1  = minetest.env:get_meta(pos1)
121 --               local internal_EU_buffer = meta1:get_float("internal_EU_buffer")
122 --               available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor
123 --               -- Limit conversion capacity
124 --               if available_charge > max_charge then
125 --              available_charge = max_charge
126 --              break
127 --               end
128 --            end
129 --            print("Available_charge PR:"..available_charge)
130
131             for _,pos1 in ipairs(MV_BA_nodes) do
132                meta1  = minetest.env:get_meta(pos1)
133                local internal_EU_buffer = meta1:get_float("internal_EU_buffer")
134                available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor
135                -- Limit conversion capacity
136                if available_charge > max_charge then
137               available_charge = max_charge
138               break
139                end
140             end
141             --print("Available_charge PR+BA:"..available_charge)
142
143             -- Calculate total number of receivers:
144             local LV_receivers = table.getn(LV_RE_nodes)+table.getn(LV_BA_nodes)
145
146             -- Next supply power to all connected LV machines
147             -- Get the power receiver internal EU buffer and give EUs to it
148             -- Note: for now leave out RE type machines until producers distribute power themselves even without a battery
149 --            for _,pos1 in ipairs(LV_RE_nodes) do
150 --               local meta1                   = minetest.env:get_meta(pos1)
151 --               local internal_EU_buffer      = meta1:get_float("internal_EU_buffer")
152 --               local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size")
153 --               local charge_to_give = math.min(1000, available_charge/LV_receivers) -- power rating limit on the LV wire
154 --               -- How much can this unit take?
155 --               if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then
156 --              charge_to_give=internal_EU_buffer_size-internal_EU_buffer
157 --               end
158 --               -- If we are emptying the supply take the remainder
159 --               if available_charge<used_charge+charge_to_give then charge_to_give=available_charge-used_charge end
160 --               -- Update the unit supplied to
161 --               internal_EU_buffer = internal_EU_buffer + charge_to_give
162 --               meta1:set_float("internal_EU_buffer",internal_EU_buffer)
163 --               -- Do the accounting
164 --               used_charge = used_charge + charge_to_give
165 --               if available_charge == used_charge then break end -- bail out if supply depleted
166 --            end
167             --print("used_charge RE:"..used_charge)
168
169             for _,pos1 in ipairs(LV_BA_nodes) do
170                local meta1 = minetest.env:get_meta(pos1)
171                local internal_EU_buffer      = meta1:get_float("internal_EU_buffer")
172                local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size")
173                --print("internal_EU_buffer:"..internal_EU_buffer)
174                --print("internal_EU_buffer_size:"..internal_EU_buffer_size)
175                local charge_to_give = math.min(math.floor(available_charge/LV_receivers), 1000) -- power rating limit on the LV wire
176                --print("charge_to_give:"..charge_to_give)
177                -- How much can this unit take?
178                if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then
179               charge_to_give=internal_EU_buffer_size-internal_EU_buffer
180                end
181                --print("charge_to_give2:"..charge_to_give)
182                -- If we are emptying the supply take the remainder
183                if available_charge<used_charge+charge_to_give then charge_to_give=available_charge-used_charge end
184                -- Update the unit supplied to
185                --print("charge_to_give3:"..charge_to_give)
186                internal_EU_buffer = internal_EU_buffer + charge_to_give
187                --print("internal_EU_buffer:"..internal_EU_buffer)
188                meta1:set_float("internal_EU_buffer",internal_EU_buffer)
189                -- Do the accounting
190                used_charge = used_charge + charge_to_give
191                --print("used_charge:"..used_charge)
192                if available_charge == used_charge then break end -- bail out if supply depleted
193             end
194             --print("used_charge RE+BA:"..used_charge)
195
196             -- Last update the MV suppliers with the actual demand.
197             -- Get the supplier internal EU buffer and update the EUs from it
198             -- Note: So far PR nodes left out and only BA nodes are updated
199             local MV_BA_size = table.getn(MV_BA_nodes)
200             for _,pos1 in ipairs(MV_BA_nodes) do
201                meta1  = minetest.env:get_meta(pos1)
202                local internal_EU_buffer = meta1:get_float("internal_EU_buffer")
203                local charge_to_take = math.floor(used_charge/MV_BA_size/mv_lv_factor) -- MV units
204                if internal_EU_buffer-charge_to_take <= 0 then
205               charge_to_take = internal_EU_buffer
206                end
207                if charge_to_take > 0 then
208               internal_EU_buffer = internal_EU_buffer-charge_to_take
209               meta1:set_float("internal_EU_buffer",internal_EU_buffer)
210                end
211             end
212
213             if used_charge>0 then
214                meta:set_string("infotext", "MV Down Converter is active (MV:"..available_charge.."/LV:"..used_charge..")");
215                meta:set_float("active",1) -- used for setting textures someday maybe
216             else
217                meta:set_string("infotext", "MV Down Converter is inactive (MV:"..available_charge.."/LV:"..used_charge..")");
218                meta:set_float("active",0) -- used for setting textures someday maybe
219                return
220             end
221     end,
222 })
223
224 -- This machine does not store energy it receives energy from the MV side and outputs it on the LV side
225 register_MV_machine ("technic:down_converter_mv","RE")
226 register_LV_machine ("technic:down_converter_mv","PR")