extractProperties static method
- 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;
},
);
}