extractProperties static method

Map<String, dynamic> extractProperties(
  1. ElectricalNode node
)

Extract ALL properties from ElectricalNode for presentation layer display Transforms domain data -> presentation data (clean architecture)

Implementation

static Map<String, dynamic> extractProperties(ElectricalNode node) {
  // Base properties: name + electrical state (only available fields)
  final Map<String, dynamic> props = {
    'name': node.name,
    'voltage': node.state.voltageVolts.toStringAsFixed(1),
    'current': node.state.currentAmps.toStringAsFixed(2),
    'amps': node.state.currentAmps.toStringAsFixed(1), // Alias
    'active_power_kw':
        (node.state.activePowerWatts / 1000).toStringAsFixed(2),
    'reactive_power_kvar':
        (node.state.reactivePowerVars / 1000).toStringAsFixed(2),
  };

  // Calculate apparent power (S = sqrt(P² + Q²))
  final s = sqrt(node.state.activePowerWatts * node.state.activePowerWatts +
      node.state.reactivePowerVars * node.state.reactivePowerVars);
  props['apparent_power_kva'] = (s / 1000).toStringAsFixed(2);

  // Calculate power factor (cos φ = P/S)
  if (s > 0) {
    props['power_factor'] =
        (node.state.activePowerWatts / s).toStringAsFixed(2);
  } else {
    props['power_factor'] = '1.00';
  }

  // Calculation results (if available)
  if (node.result != null) {
    props['design_current'] = node.result!.designCurrent.toStringAsFixed(2);
    props['voltage_at_node'] = node.result!.voltageAtNode.toStringAsFixed(1);
    props['drop_percent'] = node.result!.voltageDrop.toStringAsFixed(2);
    props['drop_volts'] = node.result!.voltageDropVolts.toStringAsFixed(2);
    props['admissible_current'] =
        node.result!.admissibleCurrent.toStringAsFixed(1);
    props['is_compliant'] = node.result!.isCompliant;

    // Short circuit currents
    props['max_short_circuit_current'] =
        node.result!.maxShortCircuitCurrent.toStringAsFixed(0);
    props['min_short_circuit_current'] =
        node.result!.minShortCircuitCurrent.toStringAsFixed(0);

    // Loop impedance
    props['loop_impedance'] = node.result!.loopImpedance.toStringAsFixed(3);
  } else {
    props['drop_percent'] = node.state.voltageDropPercent.toStringAsFixed(2);
  }

  // Node-specific properties
  return node.map(
    source: (n) {
      props['type'] = 'source';
      props['nominal_voltage'] = n.nominalVoltage.toStringAsFixed(0);
      props['short_circuit_capacity'] =
          (n.shortCircuitCapacity / 1000).toStringAsFixed(1);
      return props;
    },
    panel: (n) {
      props['type'] = 'panel';
      if (n.inputCable != null) {
        props['section_mm2'] = n.inputCable!.sectionMm2.toStringAsFixed(1);
        props['length'] = n.inputCable!.lengthMeters.toStringAsFixed(0);
        props['material'] =
            n.inputCable!.material == ConductorMaterial.copper ? 'Cu' : 'Al';
      }
      return props;
    },
    protection: (n) {
      props['type'] = 'protection';
      props['rating'] = n.ratingAmps.toStringAsFixed(0);
      props['curve'] = n.curve;
      props['poles'] = n.poles.toString();
      props['protection_type'] = n.protectionType.toString().split('.').last;
      if (n.pdc != null) {
        props['breaking_capacity'] = n.pdc!.toStringAsFixed(1);
      }
      if (n.protectionType == ProtectionType.differential) {
        props['sensitivity'] = n.sensitivity.toStringAsFixed(0);
      }
      // No inputCable for protection
      return props;
    },
    load: (n) {
      props['type'] = 'load';
      props['power'] = (n.powerWatts / 1000).toStringAsFixed(2);
      props['power_watts'] = n.powerWatts.toStringAsFixed(0);
      props['cos_phi'] = n.cosPhi.toStringAsFixed(2);
      props['load_type'] = n.type.name;
      props['is_three_phase'] = n.isThreePhase.toString();

      if (n.inputCable != null) {
        props['section_mm2'] = n.inputCable!.sectionMm2.toStringAsFixed(1);
        props['length'] = n.inputCable!.lengthMeters.toStringAsFixed(0);
        props['material'] =
            n.inputCable!.material == ConductorMaterial.copper ? 'Cu' : 'Al';
      }
      return props;
    },
  );
}