Get electric network information using API

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
Programmdude
Burner Inserter
Burner Inserter
Posts: 17
Joined: Fri May 02, 2014 2:46 pm
Contact:

Get electric network information using API

Post by Programmdude »

I'd like a way to get all the electric networks given a force or surface. Currently the only way is to access electric_network_statistics from an entity, and it seems overkill to search for all power poles in the surface, then get all electric_network_statistics from each pole (let alone the issue of just trying to get distinct statistics).

I'm thinking something similar to LuaCircuitNetwork, containing an electric_network_statistics, and a list of all entities (poles, generators, etc) connected to this network.

The end goal is to show an external graph (using rcon or file dump) for power usage over time, and it seems feasible for pollution/items/kills/etc, but power is one I'm struggling with.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get electric network information using API

Post by eradicator »

Can you grab the LuaFlowStatistics from on_built_entity with type power-pole and store them in global?
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Programmdude
Burner Inserter
Burner Inserter
Posts: 17
Joined: Fri May 02, 2014 2:46 pm
Contact:

Re: Get electric network information using API

Post by Programmdude »

I'm not sure, I'll give it a go. More cumbersome than the other statistics, and it might have issues when joining/separating networks though.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get electric network information using API

Post by eradicator »

Programmdude wrote:
Fri Apr 16, 2021 3:59 am
I'm not sure, I'll give it a go. More cumbersome than the other statistics, and it might have issues when joining/separating networks though.
Joining should simply invalidate one of the objects. Splitting is difficult due to lack of events for it.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

SilentStorm
Inserter
Inserter
Posts: 25
Joined: Sun Jul 09, 2017 9:19 am
Contact:

Re: Get electric network information using API

Post by SilentStorm »

I would also like to see the ability to get a list of electric networks, ideally similar to how you can get logistic networks, which then just group them by surface and have a list of them for each surface.
It would also have to allow accessing either the LuaFlowStatistics of it directly from the network, or have a list of its members to then grab a random pole out of that network to get the statistics of it.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Get electric network information using API

Post by boskid »

This is a really tricky topic if i would want to handle it right now.

Asking for electric networks of a given force is not really possible, an electric network does not belong to any specific force as it may span across electric poles of different forces, and may power entities of different forces at the same time. This is not going to happen, an electric network would have to keep track of all forces of entities with electric energy source and update that aggregate value on any entity force changes and a single network would pass on queries for electric networks of different forces.

Asking for electric networks on a given surface is also not really possible, an electric network does not know on which surface it is. Because of that it is possible to have a cross surface wires in which case a single electric network may power entities on multiple surfaces at the same time. From the point of view of electric network it only cares about knowing which electric energy sources should provide or consume energy. There were some bugs because an electric network was trying to bind to one of the surfaces but that was only used in 3 places and all of them were broken (solar panel production when solar panels were on multiple surfaces, lamp power consumption when lamps were on multiple surfaces and electric network drawing on chart would incorrectly filter some electric networks if they were declaring as being on wrong surface) which i fixed that allowed me to literally get rid of the electric network association with a surface. There are some ways i can query on which surfaces an electric network has electric poles but this is primarily a drawing cache so i do not want to depend on this in anything in game state.

Electric networks and electric sub networks are not targetable so i cannot simply make object like LuaElectricNetwork or LuaElectricSubNetwork object that would be binding to them directly. I could make them targetable which feels like the only really good option, but that would be quite non intuitive when those concepts could become invalid, how they change with various player interactions, why would an electric network become invalid when a power switch is turned on etc.

Here there is quite important difference between "electric network" and "electric sub network" (going by the internal names).

"Electric sub network" is one network connected directly with copper wires. It keeps track of all electric energy sources of entities that are in the supply area of electric poles. If an entity is in range of multiple electric poles that have no direct copper connection, such entity will be powered by multiple electric sub networks, one of which is a designated primary and others are additional electric sub networks. When you add a wire between 2 electric sub networks, they are merged. A power switch is not considered as a solid copper connection so in general it will have different electric sub networks on both sides unless there is external direct connection going from left to right power switch copper connector. You can think of "electric sub network" as an object which is just for keeping track of entities that need to be powered by given continuous section of copper wires

"Electric network" is set of multiple electric sub networks that are part of single electricity flow group. When a power switch has connection to 2 electric sub networks and power switch is turned on, it causes both electric sub networks to become part of the same electric network by merging electric networks. This creates some problems because statistics you want to get are inside of the "electric network" which is the most fragile of those structures. If a power switch opens, electric network may be split into 2 separate electric networks. You can think of "electric network" as a update unit, all sub networks that are part of the same electric network will transfer energy any way possible between sub networks.

For the purpose of deduplication, right now you can query LuaEntity::electric_network_id. This is however not ideal: contrary to the name, it gives you a unique identifier of an "electric sub network", and if there are power switches involved, multiple electric sub networks may be part of the same electric network causing them to share a statistics at a given point in time. The electric_network_id is defined for both entities with electric energy source and for electric poles. For the entities with electric energy source this returns only the primary electric sub network index. For electric poles this is the most reliable as an electric pole always belongs to exactly 1 electric sub network, but still that is a sub network, not the parent network which holds the statistics.

I do not want any temporary solutions where a lua object would be binding to an underlying electric pole because in 1.2 there will be at least 2 features which will no longer guarantee every electric sub network contains an electric pole so such electric sub networks would no longer be possible to be provided by such lua object with just an electric pole targeter.

As of right now, electric sub networks have an index which is exposed by LuaEntity::electric_network_id as already mentioned. electric network does not contain any indexes that would make them easily identifiable for the deduplication purposes. Just trying to expose all statistics reliably would mean following changes would be required:
- electric network would have to get a unique identifier.
- LuaEntity::electric_network_id would have to be renamed into electric_sub_network_id, that is a mod breaking change which i do not want to do.
- LuaEntity would have to expose all electric sub network indexes in case of an electric energy source supplied from multiple networks
- electric network and electric sub network would have to become targetable.
- LuaElectricNetwork would be binding directly to electric network allowing to read statistics, electric network index and get access to all electric sub networks it consists of at a given point in time
- LuaElectricSubNetwork would be binding directly to electric sub network allowing to read all entities that are part of this sub network, reading electric network sub index (not sure if particularily useful)
- LuaEntity would have to provide a way to query all LuaElectricSubNetworks and LuaElectricNetworks which that entity is related to, or at least sub networks because from this it would be possible to get the electric networks directly as every sub network belongs to exactly 1 electric network.
- More documentation would have to be made to describe all the internals, when statistics are merged or lost (when merging 2 electric networks, statistics are merged, when splitting an electric network into 2, the statistics are moved to the larger electric network where depending on how they are split, a larger network may be one that has more electric poles in the sub network that has wire removed or other metric in case of power switch turning off).

curiosity
Filter Inserter
Filter Inserter
Posts: 325
Joined: Wed Sep 11, 2019 4:13 pm
Contact:

Re: Get electric network information using API

Post by curiosity »

boskid wrote:
Tue Aug 08, 2023 10:08 am
When a power switch has connection to 2 electric sub networks and power switch is turned on, it causes both electric sub networks to become part of the same electric network by merging electric networks. This creates some problems because statistics you want to get are inside of the "electric network" which is the most fragile of those structures.
Why was it made like this, by the way? It seems to me like all problems with statistics could be solved by having statistics track sub networks instead of networks. Are there usually so many sub networks in a network that it costs too much to add up their statistics when necessary?
boskid wrote:
Tue Aug 08, 2023 10:08 am
Electric networks and electric sub networks are not targetable so i cannot simply make object like LuaElectricNetwork or LuaElectricSubNetwork object that would be binding to them directly. I could make them targetable which feels like the only really good option, but that would be quite non intuitive when those concepts could become invalid, how they change with various player interactions, why would an electric network become invalid when a power switch is turned on etc.
Isn't this already the case with the LuaFlowStatistics we get from LuaEntity.electric_network_statistics? It becomes invalid when the underlying network becomes invalid. So you don't need to worry about exposing anything new on this front.

Post Reply

Return to “Modding interface requests”