FLYNC Model

Hint

The main entry point for any FLYNC Model is this class.

Expand for Schematic
        classDiagram

    class OutputStrategy {
        <<Enumeration>>
        AUTO: int = 1
        FOLDER: int = 1
        SINGLE_FILE: int = 2
        OMMIT_ROOT: int = 4
        FIXED_ROOT: int = 8
    }

    class PDUForwarder {
        deployment_type: Literal['pdu_forwarder'] = 'pdu_forwarder'
        pdu_ref: str
        egresses: list[ForwarderEgress]
    }

    class SOMEIPServiceInterface {
        name: str
        description: str | None = ''
        id: int
        major_version: int = 0
        minor_version: int = 0
        fields: list[SOMEIPField] | None = []
        events: list[SOMEIPEvent] | None = []
        eventgroups: list[SOMEIPEventgroup] | None = []
        methods: list[SOMEIPFireAndForgetMethod | SOMEIPRequestResponseMethod] = []
        meta: SOMEIPServiceMetadata
    }

    class MulticastGroup {
        address: IPvAnyAddress | MacAddress
        ports: list[str]
    }

    class App {
        name: str
        service_consumer_refs: list[ServiceConsumerReference] | None = list
        service_provider_refs: list[ServiceProviderReference] | None = list
    }

    class FLYNCTopology {
        ethernet_topology: EthernetTopology | None = None
        can_bus_topology: list[CANBusTopology] = list
        lin_bus_topology: list[LINBusTopology] = list
    }

    class FLYNCCommunicationConfig {
        tcp_profiles: list[TCPOption] | None = []
        someip_config: SOMEIPConfig | None = None
        diagnostics_config: DiagnosticsConfig | None = None
        channels: FLYNCChannelConfig | None = None
        state_management: StateManagementConfig | None = StateManagementConfig
    }

    class DoIPDiscoveryDeployment {
        deployment_type: Literal['doip_discovery'] = 'doip_discovery'
        name: str | None = None
        vehicle_identification: bool = True
        vehicle_announcement: bool = True
        doip_timings_profile: str | None = None
    }

    class VirtualControllerInterface {
        name: str
        vlanid: int | None = None
        addresses: list[IPv6AddressEndpoint | IPv4AddressEndpoint]
        multicast: list[IPvAnyAddress | MacAddress] | None = []
    }

    class SystemMetadata {
        type: Literal['system'] = 'system'
        author: str
        compatible_flync_version: BaseVersion
        extensions: dict[str, str] | None = None
        oem: str | None = None
        platform: str | None = None
        variant: str | None = None
        release: BaseVersion
    }

    class SOMEIPServiceDeployment {
        deployment_type: Literal['someip', 'someip_provider', 'someip_consumer']
        service: int
        major_version: int = 0
        instance_id: int
        someip_sd_timings_profile: str
    }

    class ECUPort {
        name: str
        mdi_config: BASET1 | BASET1S | BASET = BASET1
        mii_config: MII | RMII | SGMII | RGMII | XFI | None = None
    }

    class FLYNCModel {
        apps: list[App] | None = None
        communication: FLYNCCommunicationConfig | None = None
        ecus: list[ECU]
        topology: FLYNCTopology = FLYNCTopology
        metadata: SystemMetadata
        instrumentation: Instrumentation | None = None
    }

    class MultiplexedPDU {
        name: str
        length: int
        pdu_usage: Literal['application', 'bap', 'diag_request', 'diag_response', 'diag_state', 'network_management', 'other', 'service', 'tpl', 'xcp_pre_configured', 'xcp_runtime_configured'] | None = None
        description: str | None = None
        type: Literal['multiplexed'] = 'multiplexed'
        selector_signal: SignalInstance
        static_group: list[PDUInstance] | None = None
        mux_groups: list[MuxGroup] = list
    }

    class DoIPServerDeployment {
        deployment_type: Literal['doip_server'] = 'doip_server'
        name: str
        logical_address: int
        uds_server: str
        doip_timings_profile: str | None = None
    }

    class NamingStrategy {
        <<Enumeration>>
        AUTO: int = 0
        FIELD_NAME: int = 0
        FIXED_PATH: int = 1
    }

    class StandardPDU {
        name: str
        length: int
        pdu_usage: Literal['application', 'bap', 'diag_request', 'diag_response', 'diag_state', 'network_management', 'other', 'service', 'tpl', 'xcp_pre_configured', 'xcp_runtime_configured'] | None = None
        description: str | None = None
        type: Literal['standard'] = 'standard'
        signals: list[SignalInstance] = list
        signal_groups: list[SignalGroupInstance] = list
    }

    class Category {
        <<Enumeration>>
        VALUE_RANGE: int = 1
        REQUIRED: int = 2
        CONSISTENCY: int = 3
        UNIQUENESS: int = 4
        REFERENCE: int = 5
        FORMAT: int = 6
        COMPATIBILITY: int = 7
        STRUCTURAL: int = 8
        LIFECYCLE: int = 9
    }

    class EthernetMultidropConnection {
        type: Literal['ethernet_multidrop'] = 'ethernet_multidrop'
        id: str
        plca: PLCACycle | None = None
        nodes: list[EthernetMultidropNode]
    }

    class SOMEIPServiceProvider {
        deployment_type: Literal['someip_provider'] = 'someip_provider'
        service: int
        major_version: int
        instance_id: int
        someip_sd_timings_profile: str
        minor_version: int = 0
        provided_eventgroups: list[str] | None = None
        multicast_config: list[SOMEIPEventgroupMulticastConfig] | None = None
    }

    class CANFrameForwarder {
        frame_ref: str
        egresses: list[ForwarderEgress]
    }

    class ECU {
        name: str
        ports: list[ECUPort] | None = list
        controllers: list[Controller]
        switches: list[Switch] | None = list
        topology: InternalTopology | None = None
        ecu_metadata: ECUMetadata
        mac_multicast_endpoints: MACMulticastEndpoints | None = None
        multicast_groups: list[MulticastGroupMembership] | None = list
        state_memberships: list[StateMembershipRef] | None = []
    }

    class FLYNCBaseModel {
    }

    class J1939Frame {
        name: str
        length: Literal[8] = 8
        frame_usage: Literal['application', 'bap', 'diag_request', 'diag_response', 'diag_state', 'network_management', 'other', 'service', 'tpl', 'xcp_pre_configured', 'xcp_runtime_configured'] | None = None
        description: str | None = None
        packed_pdus: list[PDUInstance] = list
        priority: int
        pdu_format: int
        pdu_specific: int
        data_page: int
        extended_data_page: int
        destination_type: Literal['global', 'specific']
        type: Literal['j1939'] = 'j1939'
        timing: FrameTransmissionTiming | None = None
    }

    class LINBusTopology {
        bus_name: str
        bus_type: Literal['lin'] = 'lin'
        attachments: list[BusAttachmentPoint] = list
    }

    class CANBusTopology {
        bus_name: str
        bus_type: Literal['can'] = 'can'
        attachments: list[BusAttachmentPoint] = list
    }

    class Instrumentation {
        measurement_points: list[CANBusMeasurementPoint | EthernetBusMeasurementPoint | EthernetPortsMeasurementPoint | LINBusMeasurementPoint] | None = None
    }

    class ContainerPDU {
        name: str
        length: int
        pdu_usage: Literal['application', 'bap', 'diag_request', 'diag_response', 'diag_state', 'network_management', 'other', 'service', 'tpl', 'xcp_pre_configured', 'xcp_runtime_configured'] | None = None
        description: str | None = None
        type: Literal['container'] = 'container'
        pdu_id: int
        header: ContainerPDUHeader
        contained_pdus: list[ContainedPDURef] = list
    }

    class VLANEntry {
        name: str
        id: int
        default_priority: int
        ports: list[str]
        multicast: list[MulticastGroup] | None = []
    }

    App ..> ServiceProviderReference
    App ..> ServiceConsumerReference
    FLYNCCommunicationConfig ..> StateManagementConfig
    FLYNCCommunicationConfig ..> FLYNCChannelConfig
    FLYNCCommunicationConfig ..> TCPOption
    FLYNCCommunicationConfig ..> DiagnosticsConfig
    FLYNCCommunicationConfig ..> SOMEIPConfig
    ECU ..> InternalTopology
    ECU ..> Switch
    ECU ..> ECUPort
    ECU ..> ECUMetadata
    ECU ..> MACMulticastEndpoints
    ECU ..> MulticastGroupMembership
    ECU ..> StateMembershipRef
    ECU ..> Controller
    ECUPort ..> RMII
    ECUPort ..> XFI
    ECUPort ..> MII
    ECUPort ..> BASET
    ECUPort ..> RGMII
    ECUPort ..> BASET1S
    ECUPort ..> SGMII
    ECUPort ..> BASET1
    MulticastGroup ..> IPvAnyAddress
    MulticastGroup ..> MacAddress
    VirtualControllerInterface ..> IPv6AddressEndpoint
    VirtualControllerInterface ..> IPvAnyAddress
    VirtualControllerInterface ..> IPv4AddressEndpoint
    VirtualControllerInterface ..> MacAddress
    VLANEntry ..> MulticastGroup
    Instrumentation ..> LINBusMeasurementPoint
    Instrumentation ..> CANBusMeasurementPoint
    Instrumentation ..> EthernetBusMeasurementPoint
    Instrumentation ..> EthernetPortsMeasurementPoint
    SystemMetadata ..> BaseVersion
    ContainerPDU ..> ContainerPDUHeader
    ContainerPDU ..> ContainedPDURef
    J1939Frame ..> FrameTransmissionTiming
    J1939Frame ..> PDUInstance
    MultiplexedPDU ..> MuxGroup
    MultiplexedPDU ..> SignalInstance
    MultiplexedPDU ..> PDUInstance
    StandardPDU ..> SignalInstance
    StandardPDU ..> SignalGroupInstance
    CANFrameForwarder ..> ForwarderEgress
    PDUForwarder ..> ForwarderEgress
    SOMEIPServiceInterface ..> SOMEIPRequestResponseMethod
    SOMEIPServiceInterface ..> SOMEIPEventgroup
    SOMEIPServiceInterface ..> SOMEIPServiceMetadata
    SOMEIPServiceInterface ..> SOMEIPEvent
    SOMEIPServiceInterface ..> SOMEIPField
    SOMEIPServiceInterface ..> SOMEIPFireAndForgetMethod
    SOMEIPServiceProvider ..> SOMEIPEventgroupMulticastConfig
    FLYNCTopology ..> LINBusTopology
    FLYNCTopology ..> EthernetTopology
    FLYNCTopology ..> CANBusTopology
    CANBusTopology ..> BusAttachmentPoint
    LINBusTopology ..> BusAttachmentPoint
    EthernetMultidropConnection ..> PLCACycle
    EthernetMultidropConnection ..> EthernetMultidropNode
    FLYNCModel ..> FLYNCTopology
    FLYNCModel ..> Instrumentation
    FLYNCModel ..> App
    FLYNCModel ..> FLYNCCommunicationConfig
    FLYNCModel ..> SystemMetadata
    FLYNCModel ..> ECU


    
class FLYNCModel

Bases: FLYNCBaseModel

Represents the top-level FLYNC configuration model for a system.

This model aggregates all ECUs, system topology, metadata, and communication configuration settings for the entire system.

Parameters

appslist of App, optional

Applications of the system.

ecuslist of ECU

List of ECU definitions included in the system.

topologyFLYNCTopology

The system-wide topology including external ECU connections and optional multicast paths.

metadataSystemMetadata

System-level metadata including OEM, platform, and hardware/software information.

communicationFLYNCCommunicationConfig, optional

Optional communication configuration settings applicable system-wide.

instrumentationInstrumentation, optional

Optional measurement and logging overlay - the measurement points recording this system. Absent for a system that is not being measured, which is the ordinary case for a production configuration.

classmethod warn_experimental(data)

Experimental Classes

classmethod default_absent_topology(data)

Treat an absent topology/ folder as the default (empty) topology for a CAN/LIN-only workspace.

When no topology folder exists the workspace loader supplies None for topology; drop the key so the default_factory builds an empty FLYNCTopology (with no ethernet topology) instead of raising a misleading “input should be a valid dictionary” error.

classmethod skip_broken_ecus(data)

Remove None ECUs from the list before validation.

When an ECU file fails to load the workspace inserts None into the ecus list. JErrors are already reported at the ECU level, so the None entries are silently dropped here to prevent a cascade of FLYNCModel-level errors for the same root cause.

model_post_init(context)

Perform post-initialization processing after the model is created.

Following steps are performed:

  1. Populate the solicited-node RX multicast group memberships for each IPv6 address configured in any ECU.

  2. Populate the solicited-node TX multicast group memberships for each ECU based on the RX entries for the same multicast group and VLAN.

wire_multidrop_ports() → Self

Join the ports sharing a multidrop segment, so the passes below see a segment as the connection it is.

Sits here rather than with the rest of the topology derivation because everything that walks the graph runs before that: unconnected-port reporting next, multicast path analysis further down.

validate_no_unconnected_ecu_ports() → Self

Must not require an ethernet topology: a workspace that wires only CAN/LIN has no topology/ file, but its ports still deserve an unconnected report.

require_ethernet_topology_when_used() → Self

The ethernet topology (topology/ethernet_topology.flync.yaml) is optional, but system-wide features that rely on inter-ECU Ethernet connectivity (cross-ECU multicast, SOME/IP multicast) cannot be validated without it. Raise instead of silently skipping those checks.

validate_unique_ips() → Self

Validate all IPs are unique system wide

validate_no_someip_multicast_on_tcp() → Self

Validate that no SOME/IP eventgroup multicast is configured on a TCP socket.

TCP is a point-to-point transport, so it cannot carry the eventgroup multicast of a provided service - that deployment belongs on a UDP socket.

validate_unique_macs() → Self

Validate all MACs are unique system wide

validate_bus_interface_frame_refs() → Self

Workspace-level bus interface pass: every CAN / LIN interface names a declared bus of its own kind and resolves its frame refs.

validate_forwarders() → Self

Workspace-level forwarder/deployment pass: ref resolution, same-controller locality + direction safety, and cycle detection.

validate_j1939_pdu_consistency()

A PDU packed by a CAN (non-J1939) frame must never carry SPN (FLYNC-GEN-MAJ-CONS-251).

validate_j1939_application_buses_only_j1939_frames()

A bus attached through a J1939-capable CAN interface may only carry J1939Frame frames, never CAN ones.

validate_j1939_frames_on_j1939_application_buses()

J1939Frame frames may only be deployed on a bus attached through a J1939-capable CAN interface.

validate_j1939_sa_uniqueness()

Two J1939 nodes on the same CAN bus must not claim the same source address (SA).

A controller (one CAN interface) is a single J1939 node, so an ECU exposes multiple nodes by declaring several J1939-capable CAN interfaces (possibly on different controllers). Each node must hold a distinct SA on the bus it attaches to, or address claiming would collide at runtime.

validate_j1939_bus_nodes_are_j1939()

Every node on a J1939 bus (one carrying J1939Frame frames) must declare j1939_name.

A bus is identified as a J1939 bus by carrying J1939Frame frames. Any CAN interface attached to it – whether or not it declares sender/receiver frames – must then provide a j1939_name: the NAME is what identifies a node in the J1939 address-claiming scheme. source_address remains optional and is claimed at runtime.

validate_j1939_pgn_uniqueness()

Two J1939Frame frames on the same CAN bus must not share a Parameter Group Number (PGN).

In J1939 the PGN (built from the frame’s data page / extended data page / PDU Format / PDU Specific) identifies a message on the bus independently of priority and source address, so two frames declaring the same PGN on the same bus are indistinguishable. The CAN can_id uniqueness check skips J1939 frames on purpose, so this pass is the J1939 equivalent.

validate_service_refs_in_apps()

Validate that applications are referencing existing services.

validate_app_refs_in_controller_bindings() → Self

Validate that app_bindings of ecu controllers and their compute nodes are referencing existing apps.

validate_app_bindings_consume_deployed_services() → Self

Every app bound to a controller must have its service_consumer_refs matched by a someip_consumer deployment on that same controller.

validate_state_management_groups() → Self

Workspace-level state management pass: group refs, derived member sets, NM PDU binding, and reachability.

build_and_validate_bus_topologies() → Self

Derive the system-wide CAN, LIN and Ethernet multidrop topology from bus definitions and ECU interfaces, then validate it.

bind_instrumentation() → Self

Workspace-level measurement pass: resolve measurement points against the loaded model.

get_can_bus_topology(bus_name: str) → CANBusTopology | None

Return the derived CAN bus topology for bus_name, or None if unknown.

get_lin_bus_topology(bus_name: str) → LINBusTopology | None

Return the derived LIN bus topology for bus_name, or None if unknown.

property multidrop_connections: List[EthernetMultidropConnection]

Every multidrop connection in the system topology.

get_multidrop_connection(connection_id: str) → EthernetMultidropConnection | None

Return the multidrop connection with connection_id, or None if unknown.

get_all_ecus()

Return a list of all ECU names.

get_ecu_by_name(ecu_name: str)

Retrieve an ECU by name.

get_all_controllers()

Return a list of all controllers in all ECUs.

get_all_ecu_ports() → List[ECUPort]

Return a list of all ECU ports

get_all_interfaces()

Return the config of every Ethernet interface, compute node interfaces included.

iter_app_binding_owners()

Yield everything that can declare app_bindings — every controller and every compute node beneath it.

A compute node binds its own applications to its own sockets, so it is a binding owner in its own right rather than being folded into its host controller.

get_all_interfaces_names()

Return all the controller interface names

get_interfaces_for_ecu(ecu_name: str)

Return a list of all interfaces for a given ECU.

get_ethernet_topology_info()

Return ethernet topology details, or None if no ethernet topology is defined.

validate_unique_doip_logical_addresses() → Self

Raise err_major if two DoIPServerDeployments anywhere in the system declare the same logical_address - DoIP logical addresses must be unique across the vehicle, not just per socket.

validate_multicast_someip() → Self

Validate multicast configuration for SOME/IP consumers and providers

For provider: check if the parent socket has a multicast_tx entry

Defined after resolve_someip_deployments(): the message identifies the offending service through _service_ref, which only exists once the deployments have been bound.

get_all_someip_services() → List[SOMEIPServiceInterface]

Return all SOME/IP service interfaces declared in the system-wide someip_config.

get_someip_services_by_identity() → Dict[Tuple[int, int], SOMEIPServiceInterface]

Return the system-wide SOME/IP service interfaces keyed by (service_id, major_version).

get_all_pdu_forwarders() → List[PDUForwarder]

Return every PDUForwarder declared on any socket across all ECUs.

get_all_can_frame_forwarders() → List[CANFrameForwarder]

Return every CANFrameForwarder declared on any CAN interface across all ECUs.

model_config = {'extra': 'forbid', 'validate_assignment': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Multicasting

See also

Multicast Group Memberships are dynamically collected per-ECU. Go to ECU Multicast Group Memberships to understand how they are populated.

On system-level these Multicast Groups are then validated:

  1. For a multicast group, at least one TX node is expected.

  2. A tx node must reach all rx nodes of the group.

Hint

After successful validation of the Multicast Groups, the switch config is automatically updated with the relevant group entries in the respective VLANEntry.