/** * registerChild adapter for rotatingMachine. Custom because: * - virtual + real pressure children share the upstream/downstream * position slots; real ones must be tracked for the preference order * - re-registration of the same child must dedup the emitter listener * - non-measurement softwareTypes are no-ops (Machine has no children * other than measurement nodes today) */ 'use strict'; function registerMeasurementChild(host, child, softwareType) { const swType = softwareType || child?.config?.functionality?.softwareType || 'measurement'; host.logger.debug(`Setting up child event for softwaretype ${swType}`); if (swType !== 'measurement') return; const position = String(child.config.functionality.positionVsParent || 'atEquipment').toLowerCase(); const measurementType = child.config.asset.type; const childId = child.config?.general?.id || `${measurementType}-${position}-unknown`; const isVirtual = Object.values(host.virtualPressureChildIds).includes(childId); if (measurementType === 'pressure' && !isVirtual) host.realPressureChildIds[position]?.add(childId); const eventName = `${measurementType}.measured.${position}`; const key = `${childId}:${eventName}`; const existing = host.childMeasurementListeners.get(key); if (existing) { if (typeof existing.emitter.off === 'function') existing.emitter.off(existing.eventName, existing.handler); else if (typeof existing.emitter.removeListener === 'function') existing.emitter.removeListener(existing.eventName, existing.handler); } const handler = (eventData) => { host.logger.debug(`🔄 ${position} ${measurementType} from ${eventData.childName}: ${eventData.value} ${eventData.unit}`); host._callMeasurementHandler(measurementType, eventData.value, position, eventData); }; child.measurements.emitter.on(eventName, handler); host.childMeasurementListeners.set(key, { emitter: child.measurements.emitter, eventName, handler }); } function detachAllListeners(host) { if (!host.childMeasurementListeners) return; for (const [, e] of host.childMeasurementListeners) { if (typeof e.emitter?.off === 'function') e.emitter.off(e.eventName, e.handler); else if (typeof e.emitter?.removeListener === 'function') e.emitter.removeListener(e.eventName, e.handler); } host.childMeasurementListeners.clear(); } module.exports = { registerMeasurementChild, detachAllListeners };