using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using Wayne.FDCPOSLibrary; using Wayne.ForecourtControl.Fusion.ReadDeviceStatus; using Wayne.ForecourtControl.OptBridge; using Wayne.ForecourtControl.OptBridge.Fusion; using Wayne.ForecourtControl.Vir.Fusion; using Wayne.Lib; using Wayne.Lib.Log; namespace Wayne.ForecourtControl.Fusion { public class FUSIONManager : IIdentifiableEntity, IDisposable { // Fields public IFSFManager ifsfManager; private ConfigurationReader configurationReader; private bool disposed; public FUSIONForecourtControl forecourtControl; private List managedPumpIds; public AutoResetEvent versionInfoWakeUpEvent; public string version; public string release; public string hotfix; public string getFwRelease() { return version + "." + release + "." + hotfix; } public int IdShift = 0; public int IdPumpShift = 0; public int IdNozzleShift = 0; public int IdTankShift = 0; public int FuelGradeShift = 0; internal readonly IPumpAuthorizationIdGenerator PumpAuthIdSequence; private readonly ReadDeviceStatusController _readDeviceStatusController; private readonly DebugLogger debugLogger; private ConfigurationSet CurrentConfiguration { get; set; } public DebugLogger DebugLogger { get { return debugLogger; } } // Methods internal FUSIONManager(FUSIONForecourtControl forecourtControl, ForecourtEntityTypes managedEntityTypes, int[] managedPumpIds, IPumpAuthorizationIdGenerator pumpAuthorizaitonIdGenerator, ReadDeviceStatusController readDeviceStatusController) { debugLogger = new DebugLogger(this, true); FuelPriceReadings = new List(); this.configurationReader = new ConfigurationReader(this); this.forecourtControl = forecourtControl; DebugLog("starting ..."); this.PumpAuthIdSequence = pumpAuthorizaitonIdGenerator; this._readDeviceStatusController = readDeviceStatusController; this.ifsfManager = new IFSFManager(this, forecourtControl.Id); this.ifsfManager.clientSocket.OnConnectionStateChange += new EventHandler(clientSocket_OnConnectionStateChange); this.ifsfManager.OnDeviceStateChange += new EventHandler(manager_OnDeviceStateChange); this.ifsfManager.OnVirStateChange += new EventHandler(manager_OnVirStateChange); this.ifsfManager.OnFuelModeChange += new EventHandler(manager_OnFuelModeChange); this.ifsfManager.OnOperationModeChange += manager_OnOperationModeChange; this.ifsfManager.OnCurrentFuellingStatus += new EventHandler(manager_OnCurrentFuellingStatus); this.ifsfManager.OnFuelPointTotals += new EventHandler(manager_OnFuelPointTotals); this.ifsfManager.OnFuelSaleTrx += new EventHandler(manager_OnFuelSaleTrx); this.ifsfManager.OnDeviceAlarm += new EventHandler(manager_OnDeviceAlarm); this.ifsfManager.OnVersionInfo += new EventHandler(manager_OnVersionInfo); this.ifsfManager.OnChangeFuelPrice += new EventHandler(manager_OnChangeFuelPrice); this.ifsfManager.OnClearFuelSaleTrx += new EventHandler(manager_OnClearFuelSaleTrx); this.ifsfManager.OnGetAvailableFuelSaleTrx += new EventHandler(manager_OnGetAvailableFuelSaleTrx); this.ifsfManager.OnConfigurationChange += new EventHandler(manager_OnConfigurationChange); this.ifsfManager.OnTwinMasterReady += new EventHandler(manager_OnTwinMasterReady); this.ifsfManager.OnOptRead += new EventHandler(manager_OnOptRead); this.versionInfoWakeUpEvent = new AutoResetEvent(false); } private void DebugLog(string s) { if (debugLogger.IsActive()) debugLogger.Add(s); } private int convertDeviceType(string deviceType) { if (deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint || deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser) return (int)(ForecourtEntityTypes.Pump); else if (deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_PricePole || deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_PricePolePoint) return (int)(ForecourtEntityTypes.PricePole); else if (deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_TankLevelGauge || deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_TankProbe) return (int)(ForecourtEntityTypes.Tank); return 0; } private int getAlarmCategory(int alarmId) { switch (alarmId) { case 1003: return 0; // Information default: return 1; // Error } } private void clientSocket_OnConnectionStateChange(object sender, ConnectionChangedEventArgs e) { DebugLog("manager clientSocket_OnConnectionStateChange ConnectionState=" + e.ConnectionState); try { if (e.ConnectionState == DeviceConnectionState.Connected) { // when socket connection is active, start getting configuration this._readDeviceStatusController.GetConfiguration(this.ConfigurationSetComplete); } else if (e.ConnectionState != DeviceConnectionState.Connected) { if (e.ConnectionState == DeviceConnectionState.Disconnected) { ifsfManager.Disconnect(); var optBridge = (FUSIONOptBridge)(FUSIONOptFactory.getOptBridge()); if (optBridge != null) { foreach (IOpt opt in optBridge.Opts) { if (((FUSIONOpt)opt).managedBy == OPTManagedBy.SINP) ((FUSIONOpt)opt).optTCP.Disconnect(); } } foreach (FUSIONPump pump in this.forecourtControl.Pumps) { pump.WritableState = PumpState.Inoperative; } } this.forecourtControl.WritableConnectionState = e.ConnectionState; } } catch (Exception ex) { DebugLog("Exception! " + ex.ToString()); } } private void manager_OnDeviceStateChange(object sender, DeviceStateChangedEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null) { PumpState state = pump.convertPumpState(e.state, e.substate); DebugLog(string.Format("pump={0}, State={1}, pump.State={2}, nozzleUp={3}", pump.realId, state, pump.State, e.nozzleUp)); if (pump.State != state) { // keep previous "open" state var pumpWasOpen = pump.Open; // update current state pump.WritableState = state; // Get fuel mode from pump when pump becames open if (pump.Open && !pumpWasOpen) this.ifsfManager.GetFuelMode(e.deviceId, null, null, null); } int reservedBy; if (string.IsNullOrEmpty(e.lockingAS)) reservedBy = 0; else if (!int.TryParse(e.lockingAS, out reservedBy)) reservedBy = -1; // An external device id. pump.WritableReservedBy = reservedBy; foreach (FUSIONNozzle nozzle in pump.Nozzles) { DebugLog(string.Format("pump={0}, nozzle={1}, nozzle.State={2}", pump.realId, nozzle.Id, nozzle.State)); if (nozzle.State == NozzleState.Out && e.nozzleUp != nozzle.Id) nozzle.State = NozzleState.In; else if (nozzle.State == NozzleState.In && e.nozzleUp == nozzle.Id) nozzle.State = NozzleState.Out; } } } else if (e.deviceType == DeviceType.DT_OutdoorPaymentTerminal) { if (FUSIONOptFactory.getOptBridge() == null) return; FUSIONOpt opt = ((FUSIONOptBridge)(FUSIONOptFactory.getOptBridge())).GetOptFromId(e.deviceId); if (opt != null) { DeviceConnectionState state; if (e.state == LogicalDeviceState.FDC_READY) state = DeviceConnectionState.Connected; else state = DeviceConnectionState.Disconnected; DebugLog(string.Format("opt={0}, State={1}", opt.Id, state)); if (opt.ConnectionState != state) opt.WritableConnectionState = state; } } else if (e.deviceType == DeviceType.DT_TankProbe) { FUSIONTank tank = this.getTankByIndex(e.deviceId); if (tank != null) { if (e.state == LogicalDeviceState.FDC_READY) tank.WritableConnectionState = DeviceConnectionState.Connected; else tank.WritableConnectionState = DeviceConnectionState.Disconnected; } else DebugLog(string.Format("manager_OnDeviceStateChange: tank={0} NOT FOUND !", e.deviceId)); } } private void manager_OnVirStateChange(object sender, VIRStateChangedEventArgs e) { FUSIONVir vir = (FUSIONVir)(FUSIONVirFactory.getVir(e.deviceId)); if (vir != null) { if (e.state == DeviceConnectionState.Connected) vir.Connected(e.virId); else if (e.state == DeviceConnectionState.Disconnected) vir.Disconnected(e.virId); else DebugLog(string.Format("manager_OnVirStateChange>: vir={0} State={1} NOT managed !", vir.Id, e.state)); } else DebugLog(string.Format("manager_OnVirStateChange: vir={0} NOT FOUND !", e.deviceId)); } private void manager_OnOperationModeChange(object sender, OperationModeChangedEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null) { var mode = e.mode; DebugLog(string.Format("pump={0}, Op mode={1}", pump.realId, mode)); pump.WritableOperationMode = mode; pump.FireOperationModeChange(mode); } } } private void manager_OnFuelModeChange(object sender, FuelModeChangedEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null) { int mode = e.mode; pump.WritableFuelMode = mode; if (pump.CurrentFuelling != null) { lock (pump.CurrentFuelling) { var currentFuelling = (FUSIONFuelling)(pump.CurrentFuelling); currentFuelling.WritableType = forecourtControl.ForecourtConfiguration.GetFuellingType(mode, currentFuelling.WritablePriceGroup); } } pump.FireFuelModeChange(mode); } } } private void manager_OnCurrentFuellingStatus(object sender, CurrentFuellingStatusEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { try { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null && pump.CurrentFuelling != null) { var previousFuellingState = pump.CurrentFuelling.State; var previousFuellingVolume = pump.CurrentFuelling.Quantity; lock (pump.CurrentFuelling) { FUSIONFuelling currentFuelling = null; currentFuelling = (FUSIONFuelling)(pump.CurrentFuelling); currentFuelling.WritablePrice = e.price; currentFuelling.WritableAmount = e.amount; currentFuelling.WritableQuantity = e.volume; currentFuelling.WritableState = FuellingState.CurrentPumpData; currentFuelling.WritableAuthorizationId = e.ReleaseId; currentFuelling.WritableTransactionId = e.TransactionId; currentFuelling.WritableCompletionReason = 0; //Ok currentFuelling.WritableCompletionDateTime = DateTime.Now; currentFuelling.WritableFuelPeriodId = e.FuelPeriodSequenceNo; if (pump.Nozzles.Count > e.nozzleId - 1 && e.nozzleId > 0) { currentFuelling.WritableNozzle = pump.Nozzles[e.nozzleId - 1]; currentFuelling.WritableFuelGrade = ((FUSIONNozzle)pump.WritableNozzleList[e.nozzleId - 1]).WritableFuelGrade; } else DebugLog(String.Format("INVALID Nozzle: '{0}'", e.nozzleId)); } if (pump.State == PumpState.Fuelling && previousFuellingState != FuellingState.CurrentPumpData) { // On first current pump data event from pump, fire fuelling state change pump.FireFuellingStateChange(pump.CurrentFuelling, FuellingState.Fuelling); } if (e.volume > 0 && e.volume != previousFuellingVolume && pump.RunningFuellingUpdates) { pump.FireFuellingDataChange(pump.CurrentFuelling, pump.CurrentFuelling.Amount, pump.CurrentFuelling.Quantity); } } } catch (Exception ex) { DebugLog("Exception! " + ex.ToString()); } } } private void manager_OnFuelPointTotals(object sender, FuelPointTotalsEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { try { FUSIONPump pump = this.GetPumpById(e.deviceId); FUSIONNozzle nozzle = (FUSIONNozzle)(pump.Nozzles[e.nozzleId - 1]); if (pump != null && nozzle != null) { PumpAccumulatorReading pumpAccumulatorReading = new PumpAccumulatorReading(pump, nozzle, 0, PumpAccumulatorReadingType.RequestedReading, e.volume, e.amount, e.originalTransactionData); this.ifsfManager.clientSocket.ifsfMessages.asyncResponseManager.SendResponse(e.requestId, e.overallResult, pumpAccumulatorReading); } } catch (Exception ex) { DebugLog("Exception! " + ex.ToString()); } } } private void manager_OnFuelSaleTrx(object sender, FuelSaleTrxEventArgs e) { if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { try { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null && pump.CurrentFuelling != null) { lock (pump.CurrentFuelling) { DebugLog(string.Format("pump={0}, pump.Nozzles.Count={1}, e.nozzleId={2}, Transaction state={3}", pump.realId, pump.Nozzles.Count, e.nozzleId, e.transactionStatus)); FUSIONFuelling fuelling = (FUSIONFuelling)(pump.getFuellingByTransactionId(e.transactionId, e.releaseToken)); FUSIONFuelling currentFuelling = (FUSIONFuelling)(pump.CurrentFuelling); FuellingState fuellingState = FuellingState.Unknown; if (e.transactionStatus == Wayne.FDCPOSLibrary.FuellingState.Locked) fuellingState = FuellingState.Locked; else if (e.transactionStatus == Wayne.FDCPOSLibrary.FuellingState.Payable) fuellingState = FuellingState.PayableTransaction; else if (e.transactionStatus == Wayne.FDCPOSLibrary.FuellingState.Paid) fuellingState = FuellingState.Paid; if (fuelling == null) { if (pump.Nozzles.Count > e.nozzleId - 1) { currentFuelling.WritableCompletionReason = currentFuelling.convertStatus(e.completionReason); // overwrite the value set when authorising fuelling currentFuelling.WritableTransactionId = e.transactionId; currentFuelling.WritableFuellingSequenceNumber = e.fuellingSeqNo; currentFuelling.WritableCompletionDateTime = e.trxEndDateTime; currentFuelling.WritablePriceGroup = forecourtControl.ForecourtConfiguration.GetPriceGroup(e.fuelMode, e.fuellingType); currentFuelling.WritableFuelGrade = (e.nozzleId > 0) ? ((FUSIONNozzle)pump.WritableNozzleList[e.nozzleId - 1]).WritableFuelGrade : 1; currentFuelling.WritableState = fuellingState; currentFuelling.WritablePrice = e.price; currentFuelling.WritableAmount = e.amount; currentFuelling.WritableFuelPeriodId = e.FuelPeriodSequenceNo; if (pump.CurrentFuelling.PresetValue == 0) { currentFuelling.WritablePresetType = PresetType.Amount; currentFuelling.WritablePresetValue = e.amount; } currentFuelling.WritableQuantity = e.volume; currentFuelling.WritableNozzle = (e.nozzleId > 0) ? pump.Nozzles[e.nozzleId - 1] : null; int reservedBy; if (string.IsNullOrEmpty(e.lockingAS)) reservedBy = 0; else if (!int.TryParse(e.lockingAS, out reservedBy)) reservedBy = -1; // An external device id. currentFuelling.WritableReservedBy = reservedBy; int authorizedBy; if (string.IsNullOrEmpty(e.authAS)) authorizedBy = 0; else if (!int.TryParse(e.authAS, out authorizedBy)) authorizedBy = -1; // An external device id. currentFuelling.WritableAuthorizedBy = authorizedBy; currentFuelling.WritableSignedReceiptLines = e.MIDLinesNarrow ?? ""; currentFuelling.WritableSignedReceiptLinesWide = e.MIDLinesWide ?? ""; currentFuelling.WritableAuthorizationId = e.releaseToken; currentFuelling.WritableReservingDeviceId = e.reservingDeviceId; currentFuelling.WritableType = e.fuellingType; currentFuelling.origMessageXml = e.origMessageXml; // add a fuelling to the pump fuellings list fuelling = new FUSIONFuelling(this, pump); pump.WritableFuellingList.Add(fuelling); fuelling.WritableTransactionId = currentFuelling.WritableTransactionId; fuelling.WritableFuellingSequenceNumber = currentFuelling.WritableFuellingSequenceNumber; fuelling.WritableCompletionReason = currentFuelling.convertStatus(e.completionReason); fuelling.WritableCompletionDateTime = e.trxEndDateTime; fuelling.WritablePriceGroup = forecourtControl.ForecourtConfiguration.GetPriceGroup(e.fuelMode, e.fuellingType); fuelling.WritablePresetType = currentFuelling.PresetType; fuelling.WritablePresetValue = currentFuelling.PresetValue; fuelling.WritableFuelGrade = (e.nozzleId > 0) ? ((FUSIONNozzle)pump.WritableNozzleList[e.nozzleId - 1]).WritableFuelGrade : 1; fuelling.WritableState = fuellingState; fuelling.WritablePrice = e.price; fuelling.WritableAmount = e.amount; fuelling.WritableQuantity = e.volume; fuelling.WritableNozzle = (e.nozzleId > 0) ? pump.Nozzles[e.nozzleId - 1] : null; fuelling.WritableCRC = 0; fuelling.WritableReservedBy = currentFuelling.WritableReservedBy; fuelling.WritableAuthorizedBy = currentFuelling.WritableAuthorizedBy; fuelling.WritableSignedReceiptLines = currentFuelling.WritableSignedReceiptLines; fuelling.WritableSignedReceiptLinesWide = currentFuelling.WritableSignedReceiptLinesWide; fuelling.WritableAuthorizationId = e.releaseToken; fuelling.WritableReservingDeviceId = e.reservingDeviceId; fuelling.WritableType = currentFuelling.WritableType; fuelling.WritableFuelPeriodId = currentFuelling.WritableFuelPeriodId; fuelling.origMessageXml = e.origMessageXml; DebugLog(String.Format("Firing FuellingStateChange: CurrentFuellingID={0}, pump={1}, state={2}, quantity={3}, amount={4}, authAS={5}, lockAS={6}, reservingDeviceId={7}", pump.CurrentFuelling.FuellingSequenceNumber, pump.realId, ((Wayne.FDCPOSLibrary.FuellingState)(pump.CurrentFuelling.State)).ToString(), pump.CurrentFuelling.Quantity, pump.CurrentFuelling.Amount, pump.CurrentFuelling.AuthorizedBy, pump.CurrentFuelling.ReservedBy, pump.CurrentFuelling.ReservingDeviceId)); if (fuellingState == FuellingState.Paid) pump.WritableFuellingList.Remove(fuelling); pump.FireFuellingDataChange(pump.CurrentFuelling, pump.CurrentFuelling.Amount, pump.CurrentFuelling.Quantity); pump.FireFuellingStateChange(fuelling, fuellingState); } else DebugLog(String.Format("INVALID Nozzle: '{0}'", e.nozzleId)); } else { // if fuelling exist the only item that can change is the status //if (fuellingState != fuelling.State) { fuelling.WritableState = fuellingState; int reservedBy; if (string.IsNullOrEmpty(e.lockingAS)) reservedBy = 0; else if (!int.TryParse(e.lockingAS, out reservedBy)) reservedBy = -1; // An external device id. fuelling.WritableReservedBy = reservedBy; if (e.transactionId == currentFuelling.TransactionId) { currentFuelling.WritableState = fuellingState; currentFuelling.WritableReservedBy = reservedBy; } DebugLog(String.Format("Firing FuellingStateChange: fuellingID={0}, pump={1}, state={2}, quantity={3}, amount={4}, authAS={5}, lockAS={6}", fuelling.FuellingSequenceNumber, ((FUSIONPump)(fuelling.Pump)).realId, ((Wayne.FDCPOSLibrary.FuellingState)(fuelling.State)).ToString(), fuelling.Quantity, fuelling.Amount, fuelling.AuthorizedBy, fuelling.ReservedBy)); if (fuellingState == FuellingState.Paid) pump.WritableFuellingList.Remove(fuelling); pump.FireFuellingStateChange(fuelling, fuellingState); } } } } } catch (Exception ex) { DebugLog("Exception! " + ex.ToString()); } } } public void manager_OnDeviceAlarm(object sender, DeviceAlarmEventArgs e) { int alarmCategory = getAlarmCategory(e.alarmId); int deviceType = convertDeviceType(e.deviceType); int deviceId = e.deviceId; int alarmCode = e.alarmId; string debugText = e.alarmDescr; AlarmEventArgs args = new AlarmEventArgs(deviceId, deviceType, alarmCode, alarmCategory, debugText); // low level alarm code: 4 const int LOWLEVELALARMCODE = 0x1F; //15; const int NOALARMCODE = 0; if ((e.deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint || e.deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser) && (alarmCode == 0 || alarmCode == LOWLEVELALARMCODE)) { FUSIONPump pump = this.GetPumpById(deviceId); DebugLog(string.Format("pump={0}, deviceType={1}, alarmCode={2}, TankLevelSwitchStatus={3}", deviceId, deviceType, alarmCode, (pump != null) ? pump.TankLevelSwitchStatus.ToString() : "invalid")); if (pump != null) { if (alarmCode == LOWLEVELALARMCODE && pump.TankLevelSwitchStatus != TankLevelSwitchStatus.Low) { pump.WritableTankLevelSwitchStatus = TankLevelSwitchStatus.Low; } else if (alarmCode == NOALARMCODE && pump.TankLevelSwitchStatus == TankLevelSwitchStatus.Low) { pump.WritableTankLevelSwitchStatus = TankLevelSwitchStatus.Ok; } } } else this.forecourtControl.FireAlarmEvent(args); } private void manager_OnVersionInfo(object sender, VersionInfoEventArgs e) { this.release = e.release; this.version = e.version; this.hotfix = e.hotfix; versionInfoWakeUpEvent.Set(); } private void manager_OnChangeFuelPrice(object sender, ChangeFuelPriceEventArgs e) { FUSIONFuelPrice fuelPrice = (FUSIONFuelPrice)this.forecourtControl.getFuelPriceByProductId(e.productId); if (forecourtControl.ForecourtConfiguration.WriteFuelPrice(e.productId, e.mode, e.newPrice)) DebugLog(string.Format("FuelPriceChanged Product={0}, Mode={1}, NewPrice={2}, OldPrice={3}", e.productId, e.mode, e.newPrice, e.oldPrice)); if (fuelPrice == null) return; try { FUSIONFuelPriceAddPricePerPriceGroup pgd = (FUSIONFuelPriceAddPricePerPriceGroup)(fuelPrice.PriceGroupDelta); if (pgd != null) { Monitor.Enter(fuelPrice.locker); pgd.setChanged(forecourtControl.ForecourtConfiguration.GetPriceGroups(e.mode), false); bool resetchange = true; for (int pg = PriceGroup.MinValue; pg <= PriceGroup.MaxValue; pg++) { if (pgd.getChanged(pg)) { resetchange = false; break; } } if (resetchange) fuelPrice.Changed = false; } } catch (Exception ex) { DebugLog("Exception! " + ex.ToString()); } finally { Monitor.Exit(fuelPrice.locker); } } private void manager_OnClearFuelSaleTrx(object sender, FuelSaleTrxEventArgs e) { // when the transaction is paid it is removed from the pump transaction list if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) { FUSIONPump pump = this.GetPumpById(e.deviceId); if (pump != null) { FUSIONFuelling fuelling = (FUSIONFuelling)(pump.getFuellingByTransactionId(e.transactionId, e.releaseToken)); if (fuelling != null) { fuelling.Dispose(); } } } } private void manager_OnGetAvailableFuelSaleTrx(object sender, FuelSaleTrxEventArgs e) { this.forecourtControl.manager.ifsfManager.GetFuelSaleTrxDetails(e.deviceId, e.transactionId, e.releaseToken, null, null, null); } private void manager_OnConfigurationChange(object sender, EventArgs e) { DebugLog("init manager_OnConfigurationChange"); _readDeviceStatusController.GetConfiguration(ReReadConfigurationComplete); DebugLog("End manager_OnConfigurationChange"); } private void ReReadConfigurationComplete(object sender, AsyncCompletedEventArgs e) { if (!e.Success) { DebugLog("ERROR: FAiled to re-read configuration after configuration change event - give up and continue running as if nothing happened."); return; } if (BreakingChange(e.Result, CurrentConfiguration)) { DebugLog("Configuration change - and after reading configuration found there were breaking changes - applying configuration and changing connection state"); forecourtControl.ReadStatusBeforeSetConnectionState(DeviceConnectionState.Connecting); DestroyObjects(false); ApplyConfigurationSet(e.Result); this.forecourtControl.ReadStatusBeforeSetConnectionState(DeviceConnectionState.Connected); } else { DebugLog("Configuration change - after reading configuration found there were NO breaking changes continue operating without change"); } if (FUSIONConfigFactory.getConfigurator() != null) { DebugLog("Configuration change event fired"); FUSIONConfigFactory.getConfigurator().FireOnConfigurationChanged(); } } /// /// Method that determines if a configuration change from FDC /// is a breaking change so that we should toggle the connection state. /// This is done by comparing the current configuration set with a newly read set. /// /// /// /// private bool BreakingChange(ConfigurationSet newConfigurationSet, ConfigurationSet currentConfiguration) { //Added pump, removed pump var newPumpIds = newConfigurationSet.PumpNumbers(); var oldPumpIds = currentConfiguration.PumpNumbers(); if (!newPumpIds.SequenceEqual(oldPumpIds)) { DebugLog("Breaking change : Pump Ids does not match"); return true; } //Added nozzle, removed nozzle, changed product, Tank association for nozzle var newNozzleSetup = newConfigurationSet.NozzleSetup(); var currentNozzleSetup = currentConfiguration.NozzleSetup(); if (!newNozzleSetup.SequenceEqual(currentNozzleSetup)) { DebugLog("Breaking change : Nozzle setup does not match"); return true; } //Added / Removed product var newProductNumbers = newConfigurationSet.ProductNumbers(); var currentProductNumbers = currentConfiguration.ProductNumbers(); if (!newProductNumbers.SequenceEqual(currentProductNumbers)) { DebugLog("Breaking change: Changed product setup"); return true; } return false; } private void manager_OnTwinMasterReady(object sender, EventArgs e) { DebugLog("init manager_OnTwinMasterReady"); try { if (FUSIONTwinFactory.getTwin() != null) ((FUSIONTwin)(FUSIONTwinFactory.getTwin())).FireOnTwinMasterReady(); else DebugLog("manager_OnTwinMasterReady - twin NOT created"); } catch (Exception ex) { } DebugLog("End manager_OnTwinMasterReady"); } private void manager_OnOptRead(object sender, OptReadEventArgs e) { DebugLog("init"); OptReadEventArgs args = new OptReadEventArgs(e.deviceType, e.deviceId, e.message); if (FUSIONOptFactory.getOptBridge() != null) ((FUSIONOptBridge)(FUSIONOptFactory.getOptBridge())).FireOnDataRead(e.deviceId, e.message); DebugLog("End"); } public bool CheckConfiguration(ServiceResponseGetConfiguration sr) { DebugLog("init CheckConfiguration"); bool bResult = true; foreach (ServiceDeviceClassConfiguration deviceClass in sr.FDCdata[0].DeviceClass) { switch (deviceClass.Type) { case Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser: { //look for FuellingPoint in actual configuration if (!ConfigPump(deviceClass.DeviceClass[0])) bResult = false; } break; case Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint: { //look for FuellingPoint in actual configuration if (!ConfigPump(deviceClass)) bResult = false; } break; case Wayne.FDCPOSLibrary.DeviceType.DT_TankLevelGauge: case Wayne.FDCPOSLibrary.DeviceType.DT_TankProbe: case Wayne.FDCPOSLibrary.DeviceType.DT_PricePole: break; } } //look for actual pump in new configuration foreach (FUSIONPump pump in forecourtControl.WritablePumpList) { var bPumpFound = false; foreach (ServiceDeviceClassConfiguration deviceClass in sr.FDCdata[0].DeviceClass) { if (deviceClass.Type != Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint && deviceClass.Type != Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser) continue; if (Convert.ToInt32(deviceClass.FPPumpNo) == pump.realId) { bPumpFound = true; break; } } if (!bPumpFound) { DebugLog(string.Format("pump {0} not found in new configuration", pump.realId)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.realId, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0} not found in new configuration", pump.Id)); this.manager_OnDeviceAlarm(this, arg); bResult = false; } } DebugLog("end CheckConfiguration"); return bResult; } internal bool ConfigPump(ServiceDeviceClassConfiguration deviceClass) { bool bResult = true; bool bFPFound = false; foreach (FUSIONPump pump in this.forecourtControl.WritablePumpList) { if (pump.realId == Convert.ToInt32(deviceClass.FPPumpNo)) { bFPFound = true; bool bNozzleFound = false; foreach (ServiceNozzleFPDeviceClassConfiguration FPNozzle in deviceClass.FPNozzle) { string productNo = FPNozzle.FPProductId[0].PIFPProductNo ?? FPNozzle.FPProductId[0].PIFPProductNo1; bNozzleFound = false; foreach (FUSIONNozzle nozzle in pump.Nozzles) { if (nozzle.realId == Convert.ToInt32(FPNozzle.FPNozzleNo)) { bNozzleFound = true; if (nozzle.WritableFuelGrade != Convert.ToInt32(productNo)) { DebugLog(string.Format("pump {0}, nozzle {1}, new product {2}, old product = {3} ", pump.realId, FPNozzle.FPNozzleNo, FPNozzle.FPProductId, nozzle.WritableFuelGrade)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.realId, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0}: nozzle {1} new productNo {2} configured productNo {3}", pump.Id, FPNozzle.FPNozzleNo, productNo, nozzle.WritableFuelGrade)); this.manager_OnDeviceAlarm(this, arg); bResult = false; } break; } } if (!bNozzleFound) { DebugLog(string.Format("pump {0}, nozzle {1}, product {2} not found in actual configuration", pump.realId, FPNozzle.FPNozzleNo, FPNozzle.FPProductId)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.realId, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0}: new nozzle {1} productNo {2} not configured", pump.Id, FPNozzle.FPNozzleNo, productNo)); this.manager_OnDeviceAlarm(this, arg); bResult = false; } } foreach (FUSIONNozzle nozzle in pump.Nozzles) { bNozzleFound = false; foreach (ServiceNozzleFPDeviceClassConfiguration FPNozzle in deviceClass.FPNozzle) { if (nozzle.realId == Convert.ToInt32(FPNozzle.FPNozzleNo)) { bNozzleFound = true; break; } } if (!bNozzleFound) { DebugLog(string.Format("pump {0}, nozzle {1}, product {2} not found in new configuration", pump.realId, nozzle.Id, nozzle.WritableFuelGrade)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.realId, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0}: nozzle {1} productNo {2} not found in new configuration", pump.Id, nozzle.Id, nozzle.WritableFuelGrade)); this.manager_OnDeviceAlarm(this, arg); bResult = false; break; } } break; } } if (!bFPFound) { bResult = false; DebugLog(string.Format("pump {0} not found in old configuration", deviceClass.FPPumpNo)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, Convert.ToInt32(deviceClass.FPPumpNo), (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0} not found in previous configuration", deviceClass.FPPumpNo)); this.manager_OnDeviceAlarm(this, arg); } return bResult; } internal bool Connect(string connectionString) { return this.ifsfManager.clientSocket.Connect(connectionString); } private void DestroyObjects(bool bDisconnect) { foreach (FUSIONPump pump in this.forecourtControl.WritablePumpList) { pump.Dispose(); } this.forecourtControl.WritablePumpList.Clear(); this.forecourtControl.WritableTankGroupList.Clear(); this.forecourtControl.WritablePricePoleList.Clear(); this.forecourtControl.WritableFuelPriceList.Clear(); if (bDisconnect) ifsfManager.Disconnect(); } internal void Disconnect() { if (FUSIONOptFactory.getOptBridge() != null) { foreach (IOpt opt in ((FUSIONOptBridge)(FUSIONOptFactory.getOptBridge())).Opts) { if (((FUSIONOpt)opt).managedBy == OPTManagedBy.SINP) ((FUSIONOpt)opt).optTCP.Disconnect(); else this.ifsfManager.OptRemove(opt.Id, null, null, null); } } this.ifsfManager.LogOff(); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.disposed) { this.disposed = true; if (disposing) { this.ifsfManager.clientSocket.OnConnectionStateChange -= clientSocket_OnConnectionStateChange; this.DestroyObjects(true); ifsfManager.Dispose(); debugLogger.Dispose(); } } } ~FUSIONManager() { this.Dispose(false); } public FUSIONPump GetPumpById(int pumpNumber) { foreach (FUSIONPump pump in this.forecourtControl.Pumps) { if (pump.realId == pumpNumber) { return pump; } } return null; } public FUSIONTankGroup getTankGroupByIndex(int iTankGroupId) { foreach (FUSIONTankGroup tankgroup in this.forecourtControl.TankGroups) { if (tankgroup.Id == iTankGroupId) { return tankgroup; } } return null; } public FUSIONTank getTankByIndex(int iTankGroupId, int iTankId) { foreach (FUSIONTankGroup tankgroup in this.forecourtControl.TankGroups) { if (tankgroup.Id == iTankGroupId) { foreach (FUSIONTank tank in tankgroup.Tanks) { if (tank.Id == iTankId) return tank; } } } return null; } public FUSIONTank getTankByIndex(int iTankId) { foreach (FUSIONTankGroup tankgroup in this.forecourtControl.TankGroups) { foreach (FUSIONTank tank in tankgroup.Tanks) { if (tank.Id == iTankId) return tank; } } return null; } private void ConfigurationSetComplete(object sender, AsyncCompletedEventArgs e) { if (!e.Success) { DebugLog("Failed to read configuration, retrying!"); Disconnect(); return; } ApplyConfigurationSet(e.Result); this.forecourtControl.ReadStatusBeforeSetConnectionState(DeviceConnectionState.Connected); } private void ApplyConfigurationSet(ConfigurationSet configurationSet) { CurrentConfiguration = configurationSet; configurationReader.ReadProductTable(CurrentConfiguration.ProductTable); configurationReader.ReadFuelProducts(CurrentConfiguration.ProductTable); configurationReader.ReadConfiguration(CurrentConfiguration.DspConfiguration); configurationReader.ReadConfiguration(CurrentConfiguration.TlgConfiguration); configurationReader.ReadSomePriceGroupInformation(CurrentConfiguration.DspConfiguration); } internal void RequestFillingData(int pumpNumber, bool onlyCurrentFuelling) { this.ifsfManager.GetCurrentFuellingStatus(pumpNumber, null, null, null); } // Properties public string EntitySubType { get { return ""; } } public string EntityType { get { return "FUSIONManager"; } } /// /// This is used by the logger and should never be set by inheriting classes /// public string FullEntityName { get; set; } public int Id { get { return this.forecourtControl.Id; } } public IIdentifiableEntity ParentEntity { get { return null; } } public List FuelPriceReadings { get; private set; } } // Nested Types internal class ConfigurationReader { // Fields private readonly FUSIONManager fusionManager; private readonly DebugLogger debugLogger; // Methods public ConfigurationReader(FUSIONManager fusionManager) { this.fusionManager = fusionManager; debugLogger = fusionManager.DebugLogger; } private void DebugLog(string s) { if (debugLogger.IsActive()) debugLogger.Add(s); } public void ReadProductTable(ServiceResponseGetProductTable sr) { if (sr == null || (sr.OverallResult != FDCPOSLibrary.OverallResult.Success.ToString() && sr.OverallResult != "") || sr.FDCdata == null || sr.FDCdata.Length == 0 || sr.FDCdata[0].FuelProducts == null || sr.FDCdata[0].FuelProducts.Length == 0 || sr.FDCdata[0].FuelProducts[0].Product == null || sr.FDCdata[0].FuelProducts[0].Product.Length == 0) { DebugLog("error in ServiceResponseGetProductTable"); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, "Error in GetProductTable"); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); return; } try { if (fusionManager.forecourtControl.WritableFuelPriceList.Count > 0) { DebugLog(string.Format("forecourtControl.WritableFuelPriceList.Count = {0}, verify prices", fusionManager.forecourtControl.WritableFuelPriceList.Count)); //verify product numberl if (fusionManager.forecourtControl.WritableFuelPriceList.Count != sr.FDCdata[0].FuelProducts[0].Product.Length) { DebugLog(string.Format("forecourtControl.WritableFuelPriceList.Count = {0}, sr.FDCData[0].FuelProducts.Lenght = {1}", fusionManager.forecourtControl.WritableFuelPriceList.Count, sr.FDCdata[0].FuelProducts.Length)); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("GetProductTable: product number received ({0}) differs from product number cofigured ({1})", sr.FDCdata[0].FuelProducts[0].Product.Length, fusionManager.forecourtControl.WritableFuelPriceList.Count)); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); } foreach (FUSIONFuelPrice fuelprice in fusionManager.forecourtControl.WritableFuelPriceList) { bool bFound = false; foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { if (Convert.ToInt32(product.ProductNo) == fuelprice.WritableFuelGrade) { bFound = true; break; } } if (!bFound) { DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("GetProductTable: product {0} not present in new configuration", fuelprice.WritableFuelGrade)); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); break; } } foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { bool bFound = false; foreach (FUSIONFuelPrice fuelprice in fusionManager.forecourtControl.WritableFuelPriceList) { if (Convert.ToInt32(product.ProductNo) == fuelprice.WritableFuelGrade) { bFound = true; break; } } if (!bFound) { DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("GetProductTable: product {0} not present in previous configuration", product.ProductNo)); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); break; } } } else { foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { FUSIONFuelPrice fuelprice = new FUSIONFuelPrice(Convert.ToInt32(product.ProductNo), fusionManager); fusionManager.forecourtControl.WritableFuelPriceList.Add(fuelprice); } } } catch (Exception exception) { } DebugLog("end"); } public void ReadConfiguration(ServiceResponseGetConfiguration sr) { DebugLog("init ReadConfiguration"); try { if (sr == null || ((sr.RequestType == "GetDSPConfiguration" || sr.RequestType == "GetConfiguration") && sr.OverallResult != FDCPOSLibrary.OverallResult.Success.ToString()) || (sr.RequestType == "GetTLGConfiguration" && sr.OverallResult != FDCPOSLibrary.OverallResult.Success.ToString() && sr.OverallResult != FDCPOSLibrary.OverallResult.NoData.ToString() && sr.OverallResult != FDCPOSLibrary.OverallResult.WrongConfiguration.ToString()) || sr.FDCdata == null || sr.FDCdata.Length == 0 || ((sr.RequestType == "GetDSPConfiguration" || sr.RequestType == "GetConfiguration") && (sr.FDCdata[0].DeviceClass == null || sr.FDCdata[0].DeviceClass.Length == 0))) { DebugLog("end ReadConfiguration - error in ServiceResponseGetConfiguration"); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("error in Getconfiguration")); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); return; } try { if (fusionManager.forecourtControl.WritablePumpList.Count > 0 && (sr.RequestType == "GetConfiguration" || sr.RequestType == "GetDSPConfiguration")) { DebugLog( string.Format( "end ReadConfiguration - forecourtControl.WritablePumpList.Count = {0}, call CheckConfiguration", fusionManager.forecourtControl.WritablePumpList.Count)); if (!fusionManager.CheckConfiguration(sr)) { DebugLog("Configurazione Fusion != Configurazione interna, send Alarm"); } return; } else if (fusionManager.forecourtControl.WritableTankGroupList.Count > 0 && sr.RequestType == "GetTLGConfiguration") { DebugLog( string.Format( "end ReadConfiguration - forecourtControl.WritableTankGroupList.Count = {0}, call CheckConfiguration", fusionManager.forecourtControl.WritableTankGroupList.Count)); if (!fusionManager.CheckConfiguration(sr)) { DebugLog("Configurazione Fusion != Configurazione interna, send Alarm"); } return; } if (sr.FDCdata[0].DeviceClass != null) { foreach (ServiceDeviceClassConfiguration deviceClass in sr.FDCdata[0].DeviceClass) { switch (deviceClass.Type) { case Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser: { ReadPriceConfiguration(deviceClass); } //read FP configuration foreach (var dc in deviceClass.DeviceClass) { if (dc.Type == Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint) ReadPumpConfiguration(dc); } break; case Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint: { ReadPumpConfiguration(deviceClass); } break; case Wayne.FDCPOSLibrary.DeviceType.DT_TankLevelGauge: { DebugLog(string.Format("DT_TankLevelGauge.Add id={0}", deviceClass.DeviceID)); foreach ( ServiceDeviceClassConfiguration nestedDevice in deviceClass.DeviceClass) { // only 1 tankgroup per product will be created FUSIONTankGroup tankgroup = fusionManager.getTankGroupByIndex( Convert.ToInt32(nestedDevice.TPProductNo)); if (tankgroup == null) { tankgroup = new FUSIONTankGroup(fusionManager, Convert.ToInt32( nestedDevice.TPProductNo), Convert.ToInt32( nestedDevice.TPProductNo)); fusionManager.forecourtControl.WritableTankGroupList.Add(tankgroup); } FUSIONTank tank = new FUSIONTank(fusionManager, Convert.ToInt32(nestedDevice.TPTankNo), tankgroup); tankgroup.WritableTankList.Add(tank); DebugLog(string.Format("WritableTankList.Add tank={0}", tank.realId)); } } break; } } } } catch (Exception exception) { DebugLog(string.Format("Exception! : {0}", exception.ToString())); } } finally { DebugLog("ReadConfiguration finally"); fusionManager.forecourtControl.FireConfigurationChangeEvent(new ConfigurationChangeEventArgs()); } DebugLog("end ReadConfiguration"); } private void ReadPumpConfiguration(ServiceDeviceClassConfiguration deviceClass) { FUSIONPump pump = new FUSIONPump(fusionManager); pump.WritableParentDevice = fusionManager.forecourtControl; pump.WritableCapFuelGradeSelected = false; pump.WritableCapNozzleDetection = true; pump.WritableCapSetLight = false; pump.WritableCapSuspendFuelling = true; pump.WritablePumpId = Convert.ToInt32(deviceClass.FPPumpNo); pump.WritableDeviceName = "Pump " + deviceClass.FPPumpNo; foreach (ServiceNozzleFPDeviceClassConfiguration FPnozzle in deviceClass.FPNozzle) { string productNo = FPnozzle.FPProductId[0].PIFPProductNo ?? FPnozzle.FPProductId[0].PIFPProductNo1; FUSIONNozzle nozzle = new FUSIONNozzle(Convert.ToInt32(FPnozzle.FPNozzleNo), fusionManager, pump); nozzle.WritableFuelGrade = Convert.ToInt32(productNo); nozzle.PrimaryTankNo = (FPnozzle.FPProductId[0].PIFPProductNo != null) ? Convert.ToInt32(FPnozzle.FPProductId[0].PIFPTankNo1) : 0; ; nozzle.SecondaryTankNo = (FPnozzle.FPProductId[0].PIFPProductNo != null) ? Convert.ToInt32(FPnozzle.FPProductId[0].PIFPTankNo2) : 0; bool bFound = false; foreach (FUSIONFuelPrice fuelprice in fusionManager.forecourtControl.WritableFuelPriceList) { if (fuelprice.WritableFuelGrade == Convert.ToInt32(productNo)) { bFound = true; break; } } if (!bFound) { DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, pump.realId, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("Pump {0} nozzle {1}: product {2} is not a valid productNo", pump.Id, nozzle.Id, FPnozzle.FPProductId[0].PIFPProductNo)); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); } pump.WritableNozzleList.Add(nozzle); } fusionManager.forecourtControl.WritablePumpList.Add(pump); DebugLog(string.Format("WritablePumpList.Add pump={0}", pump.realId)); } protected void ReadPriceConfiguration(ServiceDeviceClassConfiguration deviceClass) { foreach (var product in deviceClass.DSPProduct) { FUSIONFuelPrice foundPrice = null; foreach (FUSIONFuelPrice fuelprice in fusionManager.forecourtControl.WritableFuelPriceList) { if (Convert.ToInt32(product.DSPProductNo) == fuelprice.WritableFuelGrade) { foundPrice = fuelprice; break; } } if (foundPrice == null) { DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("ReadPriceConfiguration: product {0} not present in new configuration", product.DSPProductNo)); fusionManager.manager_OnDeviceAlarm(fusionManager, arg); break; } else { foundPrice.WritableReserved = true; } } } /// /// Price group information - this code was moved here from Ifsf manager. /// should probably be moved together with rest of Pump initialization on the /// next refactor. /// /// public void ReadSomePriceGroupInformation(ServiceResponseGetDSPConfiguration sr) { if (sr.FDCdata[0] != null && sr.FDCdata[0].DeviceClass != null) { foreach (var deviceClass in sr.FDCdata[0].DeviceClass) { if (deviceClass.DSPProduct == null) continue; foreach (var product in deviceClass.DSPProduct) { if (product == null) continue; foreach (var dspFuelPrice in product.DSPFuelPrice) { var foundNew = true; var priceGroup = fusionManager.forecourtControl.ForecourtConfiguration.GetPriceGroup(Convert.ToInt32(dspFuelPrice.FPDSPModeNo), FuellingType.OptCardPaid); foreach (var reading in fusionManager.FuelPriceReadings) { if (reading.Fuelgrade == Convert.ToInt32(product.DSPProductNo) && reading.PriceGroup == priceGroup) foundNew = false; } if (foundNew) { var fuelPriceReading = new FuelPriceReading(Convert.ToInt32(product.DSPProductNo), priceGroup, FDCConvert.ToDecimal(dspFuelPrice.FPDSPPrice), null); fusionManager.FuelPriceReadings.Add(fuelPriceReading); } } } } } } /// /// Populate the forecourtControl.FuelProducts array /// /// public void ReadFuelProducts(ServiceResponseGetProductTable sr) { fusionManager.forecourtControl.WritableFuelProducts.Clear(); foreach (var product in sr.FDCdata[0].FuelProducts[0].Product) { var fuelProduct = new FuelProduct(Convert.ToInt32(product.ProductNo), product.ProductName); fusionManager.forecourtControl.WritableFuelProducts.Add(fuelProduct); } } } }