///|
pub struct FactoryGraphBuilder {
graph : FactoryGraph
mut edge_counter : Int
} derive(Debug)
///|
pub fn FactoryGraphBuilder::new(
plant_name? : String = "Automated Smart Factory",
location? : String = "Industrial High-Tech Zone",
takt_time_target_sec? : Double = 45.0,
) -> FactoryGraphBuilder {
let cfg = @types.FactoryConfig::default()
let updated_cfg : @types.FactoryConfig = {
plant_name,
site_location: location,
version: "1.0.0",
takt_time_target_sec,
planned_shifts_per_day: cfg.planned_shifts_per_day,
shift_duration_hours: cfg.shift_duration_hours,
target_oee: cfg.target_oee,
default_currency: cfg.default_currency,
}
{ graph: FactoryGraph::new(config=updated_cfg), edge_counter: 0 }
}
///|
pub fn FactoryGraphBuilder::add_workstation(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "AssemblyLine",
subzone? : String = "",
cycle_time_sec? : Double = 40.0,
nominal_power_kw? : Double = 15.0,
mtbf_hours? : Double = 1200.0,
mttr_hours? : Double = 1.5,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Workstation,
zone~,
subzone~,
cycle_time_sec~,
nominal_power_kw~,
mtbf_hours~,
mttr_hours~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_machine(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "MachiningZone",
subzone? : String = "",
cycle_time_sec? : Double = 30.0,
nominal_power_kw? : Double = 25.0,
mtbf_hours? : Double = 800.0,
mttr_hours? : Double = 3.0,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Machine,
zone~,
subzone~,
cycle_time_sec~,
nominal_power_kw~,
mtbf_hours~,
mttr_hours~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_conveyor(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "LogisticsZone",
subzone? : String = "",
nominal_power_kw? : Double = 5.5,
capacity? : Double = 50.0,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Conveyor,
zone~,
subzone~,
nominal_power_kw~,
capacity~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_buffer(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "WIP_Storage",
subzone? : String = "",
capacity? : Double = 200.0,
initial_wip? : Double = 20.0,
safety_zone_id? : String = "SZ-0",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Buffer,
zone~,
subzone~,
capacity~,
initial_wip~,
max_wip=capacity,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_sensor(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "SensingZone",
subzone? : String = "",
nominal_power_kw? : Double = 0.05,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Sensor,
zone~,
subzone~,
nominal_power_kw~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_power_source(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "PowerSubstation",
subzone? : String = "",
capacity_kw? : Double = 500.0,
safety_zone_id? : String = "SZ-0",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::PowerSource,
zone~,
subzone~,
nominal_power_kw=capacity_kw,
capacity=capacity_kw,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_safety_gate(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "SafetyZone",
subzone? : String = "",
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::SafetyGate,
zone~,
subzone~,
nominal_power_kw=0.1,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_plc(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "ControlRoom",
subzone? : String = "",
safety_zone_id? : String = "SZ-0",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::PLCController,
zone~,
subzone~,
nominal_power_kw=0.5,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_robot(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "RoboticCell",
subzone? : String = "",
cycle_time_sec? : Double = 25.0,
nominal_power_kw? : Double = 12.0,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::RobotArm,
zone~,
subzone~,
cycle_time_sec~,
nominal_power_kw~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
pub fn FactoryGraphBuilder::add_inspection(
self : FactoryGraphBuilder,
id : String,
name : String,
zone? : String = "QualityZone",
subzone? : String = "",
cycle_time_sec? : Double = 20.0,
nominal_power_kw? : Double = 3.5,
safety_zone_id? : String = "SZ-1",
) -> FactoryGraphBuilder {
let n = Node::create(
id,
name,
@types.NodeType::Inspection,
zone~,
subzone~,
cycle_time_sec~,
nominal_power_kw~,
safety_zone_id~,
)
self.graph.add_node(n)
self
}
///|
fn FactoryGraphBuilder::next_edge_id(
self : FactoryGraphBuilder,
prefix : String,
) -> String {
self.edge_counter = self.edge_counter + 1
prefix + "-" + self.edge_counter.to_string()
}
///|
pub fn FactoryGraphBuilder::connect_material(
self : FactoryGraphBuilder,
src : String,
dst : String,
bandwidth? : Double = 1200.0,
delay? : Double = 2.0,
distance? : Double = 10.0,
medium? : @types.TransferMedium = @types.TransferMedium::BeltConveyor,
redundancy_priority? : Int = 1,
) -> FactoryGraphBuilder {
let eid = self.next_edge_id("MAT")
let e = Edge::create(
eid,
src,
dst,
@types.FlowType::MaterialFlow,
bandwidth_units_per_hour=bandwidth,
transport_delay_sec=delay,
distance_meters=distance,
medium~,
redundancy_priority~,
)
self.graph.add_edge(e)
self
}
///|
pub fn FactoryGraphBuilder::connect_control(
self : FactoryGraphBuilder,
plc_id : String,
target_id : String,
protocol? : @types.ControlProtocol = @types.ControlProtocol::Profinet,
latency_ms? : Double = 5.0,
) -> FactoryGraphBuilder {
let eid = self.next_edge_id("CTL")
let e = Edge::create(
eid,
plc_id,
target_id,
@types.FlowType::ControlFlow,
transport_delay_sec=latency_ms / 1000.0,
protocol~,
)
self.graph.add_edge(e)
self
}
///|
pub fn FactoryGraphBuilder::connect_energy(
self : FactoryGraphBuilder,
power_source_id : String,
target_id : String,
energy_type? : @types.EnergyType = @types.EnergyType::AC_380V_3Phase,
loss_kw? : Double = 0.2,
) -> FactoryGraphBuilder {
let eid = self.next_edge_id("PWR")
let e = Edge::create(
eid,
power_source_id,
target_id,
@types.FlowType::EnergyFlow,
energy_loss_kw=loss_kw,
energy_type~,
)
self.graph.add_edge(e)
self
}
///|
pub fn FactoryGraphBuilder::connect_safety(
self : FactoryGraphBuilder,
safety_source_id : String,
target_id : String,
level? : @types.SafetyLevel = @types.SafetyLevel::SIL3,
) -> FactoryGraphBuilder {
let eid = self.next_edge_id("SAF")
let e = Edge::create(
eid,
safety_source_id,
target_id,
@types.FlowType::SafetyInterlock,
safety_level=level,
)
self.graph.add_edge(e)
self
}
///|
pub fn FactoryGraphBuilder::connect_telemetry(
self : FactoryGraphBuilder,
sensor_id : String,
collector_id : String,
protocol? : @types.ControlProtocol = @types.ControlProtocol::MQTT,
) -> FactoryGraphBuilder {
let eid = self.next_edge_id("TEL")
let e = Edge::create(
eid,
sensor_id,
collector_id,
@types.FlowType::DataTelemetry,
protocol~,
)
self.graph.add_edge(e)
self
}
///|
pub fn FactoryGraphBuilder::connect_line(
self : FactoryGraphBuilder,
station_ids : Array[String],
bandwidth? : Double = 1200.0,
delay? : Double = 2.0,
) -> FactoryGraphBuilder {
for i = 0; i < station_ids.length() - 1; i = i + 1 {
let src = station_ids[i]
let dst = station_ids[i + 1]
let _ = self.connect_material(src, dst, bandwidth~, delay~)
}
self
}
///|
pub fn FactoryGraphBuilder::connect_power_bus(
self : FactoryGraphBuilder,
source_id : String,
target_ids : Array[String],
energy_type? : @types.EnergyType = @types.EnergyType::AC_380V_3Phase,
) -> FactoryGraphBuilder {
for target in target_ids {
let _ = self.connect_energy(source_id, target, energy_type~)
}
self
}
///|
pub fn FactoryGraphBuilder::connect_plc_network(
self : FactoryGraphBuilder,
plc_id : String,
target_ids : Array[String],
protocol? : @types.ControlProtocol = @types.ControlProtocol::Profinet,
) -> FactoryGraphBuilder {
for target in target_ids {
let _ = self.connect_control(plc_id, target, protocol~)
}
self
}
///|
pub fn FactoryGraphBuilder::connect_safety_domain(
self : FactoryGraphBuilder,
safety_gate_id : String,
target_ids : Array[String],
level? : @types.SafetyLevel = @types.SafetyLevel::SIL3,
) -> FactoryGraphBuilder {
for target in target_ids {
let _ = self.connect_safety(safety_gate_id, target, level~)
}
self
}
///|
pub fn FactoryGraphBuilder::build(self : FactoryGraphBuilder) -> FactoryGraph {
self.graph
}