using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Threading; //using System.Diagnostics; using Wayne.Lib; #if _SINP using Wayne.ForecourtControl.Nfs; #endif using Wayne.ForecourtControl.OptBridge; using Wayne.ForecourtControl.OptBridge.Fusion; using Wayne.ForecourtControl.Vir.Fusion; using Wayne.FDCPOSLibrary; namespace Wayne.ForecourtControl.Fusion { internal class FUSIONAsyncMangager : Wayne.Lib.AsyncManager.AsyncManager { // Fields private ushort nextSequenceNumber; private object nextSequenceNumberLock; // Methods public FUSIONAsyncMangager(int id, IIdentifiableEntity parentEntity) : base(id, parentEntity) { this.nextSequenceNumber = 1; this.nextSequenceNumberLock = new object(); } protected override ushort CreateNextOperationId() { lock (this.nextSequenceNumberLock) { ushort num2; this.nextSequenceNumber = (ushort)((num2 = this.nextSequenceNumber) + 1); return num2; } } // Properties public override string EntitySubType { get { return "FUSIONForecourtControl"; } } } public abstract class FUSIONAsyncOperation { // Fields private DateTime creationDateTime; private object data; private TOperationId id; private object owner; private object userToken; // Events internal event EventHandler OnOperationCompleted; // Methods protected internal FUSIONAsyncOperation(object owner, TOperationId id, object userToken, object data) { this.creationDateTime = DateTime.Now; this.owner = owner; this.id = id; this.userToken = userToken; this.data = data; } public void Cancel() { this.Complete(); } protected internal void Complete() { if (this.OnOperationCompleted != null) { this.OnOperationCompleted(this, EventArgs.Empty); } } // Properties internal DateTime CreationDateTime { get { return this.creationDateTime; } set { this.creationDateTime = value; } } public object Data { get { return this.data; } } public TOperationId Id { get { return this.id; } } public object Owner { get { return this.owner; } } public object UserToken { get { return this.userToken; } } } public class FUSIONAsyncOperation : FUSIONAsyncOperation where TResultEventArgs : EventArgs { // Fields private EventHandler resultDelegate; // Methods internal FUSIONAsyncOperation(object owner, TOperationId id, object userToken, object data, EventHandler resultDelegate) : base(owner, id, userToken, data) { this.resultDelegate = resultDelegate; } public void Complete(TResultEventArgs resultEventArgs) { base.Complete(); if (this.resultDelegate != null) { this.resultDelegate.Invoke(base.Owner, resultEventArgs); } } public override string ToString() { return this.ToString("", CultureInfo.InvariantCulture); } public virtual string ToString(IFormatProvider provider) { return this.ToString("", provider); } public virtual string ToString(string format) { return this.ToString(format, CultureInfo.InvariantCulture); } public virtual string ToString(string format, IFormatProvider provider) { string str; IIdentifiableEntity owner = base.Owner as IIdentifiableEntity; if (owner != null) { str = IdentifiableEntity.ToString(owner); } else { str = base.Owner.ToString(); } return string.Format(CultureInfo.InvariantCulture, "FUSIONAsyncOperation Owner={2},Id={3},", new object[] { typeof(TOperationId).FullName, typeof(TResultEventArgs).FullName, str, base.Id }); } } internal class FUSIONInitializationStatus { // Fields private bool clientPropertySet; private bool configurationDataRead; private BitArray pumpStatusRead; private bool readingConfigurationData; private bool siteModeRead; // Methods public FUSIONInitializationStatus() { this.PumpStatusRead = new BitArray(0x20, false); } public void Reset() { this.ReadingConfigurationData = false; //this.ConfigurationDataRead = false; this.ClientPropertySet = false; this.SiteModeRead = false; this.PumpStatusRead.SetAll(false); } // Properties public bool ClientPropertySet { get { return this.clientPropertySet; } set { this.clientPropertySet = value; } } public bool ConfigurationDataRead { get { return this.configurationDataRead; } set { this.configurationDataRead = value; } } public BitArray PumpStatusRead { get { return this.pumpStatusRead; } set { this.pumpStatusRead = value; } } public bool ReadingConfigurationData { get { return this.readingConfigurationData; } set { this.readingConfigurationData = value; } } public bool SiteModeRead { get { return this.siteModeRead; } set { this.siteModeRead = value; } } } public class FUSIONManager : IIdentifiableEntity, IDisposable { // Fields public IFSFManager ifsfManager; private ConfigurationReader configurationReader; //private Dictionary connectionStringParamDict; //private DebugLogger debugLogger; private bool disposed; public FUSIONForecourtControl forecourtControl; private FUSIONInitializationStatus initializationStatus = new FUSIONInitializationStatus(); //private DataSet latestPricesDataSet = new DataSet(); //private ForecourtEntityTypes managedEntityTypes; private List managedPumpIds; //private ParameterFormatInfo parserFormatInfo = new ParameterFormatInfo(); //private NfsManagerState state; 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; private bool shouldSetConnected = false; // a flag to indicate if need to set connection state to be connected // Methods public FUSIONManager(FUSIONForecourtControl forecourtControl, ForecourtEntityTypes managedEntityTypes, int[] managedPumpIds) { try { //Logger.SetConfigFile(@".\LogConfig.xml"); //Logger.RefreshConfig(); Trace.Add(this); } catch (Exception ex) { Trace.WriteLine("FusionManager Exception - " + ex.Message); } this.configurationReader = new ConfigurationReader(this); //this.state = NfsManagerState.Uninitialized; this.forecourtControl = forecourtControl; Trace.WriteLine("starting ...Id = " + this.Id); //this.managedEntityTypes = managedEntityTypes; //this.asyncManager = new FUSIONAsyncMangager(this.Id, this); //this.debugLogger = new DebugLogger(this, true); this.ifsfManager = new IFSFManager(forecourtControl.Id, forecourtControl.ConfigParam); //this.clientSocket.ParserDomain = ParserDomain.FillingServer; //this.clientSocket.OnRpcRead += new EventHandler(this, (IntPtr)this.clientSocket_OnRpcRead); this.ifsfManager.clientSocket.OnConnectionStateChange += new EventHandler(clientSocket_OnConnectionStateChange); //new EventHandler(this, (IntPtr)this.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.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.OnLockFuelSaleTrx += new EventHandler(manager_OnLockFuelSaleTrx); this.ifsfManager.OnUnlockFuelSaleTrx += new EventHandler(manager_OnUnlockFuelSaleTrx); this.ifsfManager.OnClearFuelSaleTrx += new EventHandler(manager_OnClearFuelSaleTrx); this.ifsfManager.OnGetAvailableFuelSaleTrx += new EventHandler(manager_OnGetAvailableFuelSaleTrx); this.ifsfManager.OnGetFuelSaleTrxDetails += new EventHandler(manager_OnGetFuelSaleTrxDetails); this.ifsfManager.OnGetConfiguration += new EventHandler(manager_OnGetConfiguration); this.ifsfManager.OnConfigurationChange += new EventHandler(manager_OnConfigurationChange); this.ifsfManager.OnGetProductTable += new EventHandler(manager_OnGetProductTable); this.ifsfManager.OnTankData += new EventHandler(manager_OnTankData); this.ifsfManager.OnTwinMasterReady += new EventHandler(manager_OnTwinMasterReady); this.ifsfManager.OnOptRead += new EventHandler(manager_OnOptRead); this.versionInfoWakeUpEvent = new AutoResetEvent(false); } private int convertDeviceType(string deviceType) { if (deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint || deviceType == Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser) return (int)(ForecourtEntityTypes.Pump); //3; // is that Wayne.ForecourtControl.Nfs.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 //case xxx: // return 1; // warning default: return 1; // Error } } private int convertAlarmCode(int error) { return error; //int AlarmId = 0; //if (error == 6) // volume or amount decreased //{ // AlarmId = 219; //} //else if (error == 7 || error == 8) // pulser error //{ // AlarmId = 220; //} //else if (error == 9) // zero fuelling - antispandimento //{ // AlarmId = 212; //} //else if (error == 11) // price error //{ // AlarmId = 211; //} //else if (error == 12) // volume or amount garbage //{ // AlarmId = 219; //} //else if (error == 13) // display error //{ // AlarmId = 215; //} //else if (error == 14) // checksum error //{ // AlarmId = 219; //} //return AlarmId; } private void clientSocket_OnConnectionStateChange(object sender, ConnectionChangedEventArgs e) { Trace.WriteLine("manager clientSocket_OnConnectionStateChange ConnectionState=" + e.ConnectionState); try { if (e.ConnectionState == DeviceConnectionState.Connected) { this.initializationStatus.Reset(); shouldSetConnected = true; // when socket connection is active, start getting configuration this.InitializeOrhcestrator(); // JDL, AUG-10-10, site is open when FDC connection established. this.forecourtControl.WritableSiteOpened = true; } else if (e.ConnectionState != DeviceConnectionState.Connected) { if (e.ConnectionState == DeviceConnectionState.Disconnected) { //WJU - do not make reconnection read ConfigurationData again. It should read only first time connection initializationStatus.ReadingConfigurationData = false; // JDL, AUG-10-10, set site to closed this.forecourtControl.WritableSiteOpened = false; //this.DestroyObjects(); ifsfManager.Disconnect(); if (FUSIONOptFactory.getOptBridge() != null) { foreach (IOpt opt in ((FUSIONOptBridge)(FUSIONOptFactory.getOptBridge())).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) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } 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); Trace.WriteLine(string.Format("pump={0}, State={1}, pump.State={2}, nozzleUp={3}", pump.realId, state, pump.State, e.nozzleUp)); if (pump.State != state) pump.WritableState = state; try { pump.WritableReservedBy = (e.lockingAS != null && e.lockingAS != "") ? Convert.ToInt32(e.lockingAS) : -1; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception! cannot convert e.lockingAS='{0}' to Int32", e.lockingAS)); } foreach (FUSIONNozzle nozzle in pump.Nozzles) { Trace.WriteLine(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; Trace.WriteLine(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 (e.state == LogicalDeviceState.FDC_READY) tank.WritableConnectionState = DeviceConnectionState.Connected; else tank.WritableConnectionState = DeviceConnectionState.Disconnected; } } 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 Trace.WriteLine(string.Format("manager_OnVirStateChange>: vir={0} State={1} NOT managed !", vir.Id, e.state)); } else Trace.WriteLine(string.Format("manager_OnVirStateChange: vir={0} NOT FOUND !", e.deviceId)); } 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; Trace.WriteLine(string.Format("pump={0}, mode={1}", pump.realId, mode)); 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) { if (e.volume > 0 && e.volume != pump.CurrentFuelling.Quantity && pump.RunningFuellingUpdates) { // TODO setting pump current fuelling attributes FUSIONFuelling currentFuelling = null; currentFuelling = (FUSIONFuelling)(pump.CurrentFuelling); currentFuelling.WritablePrice = e.price; currentFuelling.WritableAmount = e.amount; currentFuelling.WritableQuantity = e.volume; if (pump.Nozzles.Count > e.nozzleId - 1 && e.nozzleId > 0) { currentFuelling.WritableNozzle = pump.Nozzles[e.nozzleId - 1]; currentFuelling.WritableFuelGrade = pump.Nozzles[e.nozzleId - 1].FuelGrade; } else Trace.WriteLine(String.Format("INVALID Nozzle: '{0}'", e.nozzleId)); pump.FireFuellingDataChange(pump.CurrentFuelling, pump.CurrentFuelling.Amount, pump.CurrentFuelling.Quantity); } } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } } 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); this.ifsfManager.clientSocket.ifsfMessages.asyncResponseManager.SendResponse(e.requestId, e.overallResult, pumpAccumulatorReading); } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } } 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) { //if (e.volume != pump.CurrentFuelling.Quantity) Trace.WriteLine(string.Format("pump={0}, pump.Nozzles.Count={1}, e.nozzleId={2}", pump.realId, pump.Nozzles.Count, e.nozzleId)); Trace.WriteLine(String.Format("Transaction state={0}", ((Wayne.FDCPOSLibrary.FuellingState)(e.transactionStatus)).ToString())); 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; #if !_USE_OLD_FCONTROL_ else if (e.transactionStatus == Wayne.FDCPOSLibrary.FuellingState.Paid) fuellingState = FuellingState.Paid; #endif if (fuelling == null) { if (pump.Nozzles.Count > e.nozzleId - 1)//&& e.nozzleId > 0) { // TODO possible transaction status to be defined currentFuelling.WritableCompletionReason = currentFuelling.convertStatus(e.completionReason); // overwrite the value set when authorising fuelling currentFuelling.WritableFuellingSequenceNumber = e.transactionId; currentFuelling.WritableCompletionDateTime = e.trxEndDateTime; // TODO is fuel mode useful ? //e.fuelMode currentFuelling.WritableFuelGrade = (e.nozzleId > 0) ? pump.Nozzles[e.nozzleId - 1].FuelGrade : 0; currentFuelling.WritableState = fuellingState; currentFuelling.WritablePrice = e.price; currentFuelling.WritableAmount = e.amount; 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; try { currentFuelling.WritableReservedBy = (e.lockingAS != null && e.lockingAS != "") ? Convert.ToInt32(e.lockingAS) : 0; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception! cannot convert e.lockingAS='{0}' to Int32", e.lockingAS)); } try { currentFuelling.WritableAuthorizedBy = (e.authAS != null && e.authAS != "") ? Convert.ToInt32(e.authAS) : 0; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception! cannot convert e.authAS='{0}' to Int32", e.authAS)); } //currentFuelling.WritableSignedReceiptLines = (e.DSPFields == null) ? "" : e.DSPFields; currentFuelling.WritableSignedReceiptLines = (e.MIDLinesNarrow == null) ? "" : e.MIDLinesNarrow; Trace.WriteLine(string.Format("SignedReceiptLines='{0}'", currentFuelling.SignedReceiptLines)); currentFuelling.WritableSignedReceiptLinesWide = (e.MIDLinesWide == null) ? "" : e.MIDLinesWide; Trace.WriteLine(string.Format("SignedReceiptLinesWide='{0}'", currentFuelling.SignedReceiptLinesWide)); currentFuelling.WritableAuthorizationId = e.releaseToken; currentFuelling.WritableReservingDeviceId = e.reservingDeviceId; currentFuelling.WritableType = e.fuellingType; // add a fuelling to the pump fuellings list fuelling = new FUSIONFuelling(this, pump); pump.WritableFuellingList.Add(fuelling); fuelling.WritableFuellingSequenceNumber = currentFuelling.WritableFuellingSequenceNumber; fuelling.WritableCompletionReason = currentFuelling.convertStatus(e.completionReason); fuelling.WritableCompletionDateTime = e.trxEndDateTime; // TODO is fuel mode useful ? //e.fuelMode fuelling.WritablePresetType = currentFuelling.PresetType; fuelling.WritablePresetValue = currentFuelling.PresetValue; fuelling.WritableFuelGrade = (e.nozzleId > 0) ? pump.Nozzles[e.nozzleId - 1].FuelGrade : 0; 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; #if !_USE_OLD_FCONTROL_ Trace.WriteLine(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)); #else Trace.WriteLine(String.Format("Firing FuellingStateChange: CurrentFuellingID={0}, pump={1}, state={2}, quantity={3}, amount={4}, lockAS={5}", pump.CurrentFuelling.FuellingSequenceNumber, pump.realId, ((Wayne.FDCPOSLibrary.FuellingState)(pump.CurrentFuelling.State)).ToString(), pump.CurrentFuelling.Quantity, pump.CurrentFuelling.Amount, pump.CurrentFuelling.ReservedBy)); #endif pump.FireFuellingDataChange(pump.CurrentFuelling, pump.CurrentFuelling.Amount, pump.CurrentFuelling.Quantity); pump.FireFuellingStateChange(fuelling, fuellingState); } else Trace.WriteLine(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; try { fuelling.WritableReservedBy = (e.lockingAS != null && e.lockingAS != "") ? Convert.ToInt32(e.lockingAS) : 0; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception! cannot convert e.lockingAS='{0}' to Int32", e.lockingAS)); } if (e.transactionId == currentFuelling.FuellingSequenceNumber) { currentFuelling.WritableState = fuellingState; try { currentFuelling.WritableReservedBy = (e.lockingAS != null && e.lockingAS != "") ? Convert.ToInt32(e.lockingAS) : 0; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception! cannot convert e.lockingAS='{0}' to Int32", e.lockingAS)); } } Trace.WriteLine(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)); pump.FireFuellingStateChange(fuelling, fuellingState); #if !_USE_OLD_FCONTROL_ if (fuellingState == FuellingState.Paid) { pump.WritableFuellingList.Remove(fuelling); currentFuelling.WritableType = FuellingType.Unknown; } #endif } } } } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } } } private void manager_OnDeviceAlarm(object sender, DeviceAlarmEventArgs e) { //if (e.deviceType == DeviceType.DT_FuelDispenser || e.deviceType == DeviceType.DT_FuellingPoint) //{ // FUSIONPump pump = this.GetPumpById(e.deviceId); // if (pump != null && pump.CurrentFuelling != null) // { // pump...FireFuellingDataChange(pump.CurrentFuelling, pump.CurrentFuelling.Amount, pump.CurrentFuelling.Quantity); // } //} int alarmCategory = getAlarmCategory(e.alarmId); int deviceType = convertDeviceType(e.deviceType); int deviceId = e.deviceId; int alarmCode = convertAlarmCode(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); Trace.WriteLine(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; //this.forecourtControl.FireAlarmEvent(args); } else if (alarmCode == NOALARMCODE && pump.TankLevelSwitchStatus == TankLevelSwitchStatus.Low) { pump.WritableTankLevelSwitchStatus = TankLevelSwitchStatus.Ok; this.forecourtControl.FireAlarmEvent(args); } } } 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 (fuelPrice == null) return; try { FUSIONFuelPriceAddPricePerPriceGroup pgd = null; if (fuelPrice != null) pgd = (FUSIONFuelPriceAddPricePerPriceGroup)(fuelPrice.PriceGroupDelta); if (pgd != null) { Monitor.Enter(fuelPrice.locker); pgd.setChanged(e.mode, false); bool resetchange = true; //for (int mode = pgd.PriceGroupNumbersMin; mode <= pgd.PriceGroupNumbersMax; mode++) for (int mode = FUSIONFuelPrice.PriceGroupNumbersMin; mode <= FUSIONFuelPrice.PriceGroupNumbersMax; mode++) { if (pgd.getChanged(mode)) { resetchange = false; break; } } if (resetchange) fuelPrice.Changed = false; } } catch (Exception ex) { Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace); } finally { Monitor.Exit(fuelPrice.locker); } } private void manager_OnLockFuelSaleTrx(object sender, FuelSaleTrxEventArgs e) { //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)); // if (fuelling != null) // { // fuelling.WritableReservedBy = this.Id; // } // } //} } private void manager_OnUnlockFuelSaleTrx(object sender, FuelSaleTrxEventArgs e) { //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)); // if (fuelling != null) // { // // TODO what value shoul be set ? at the moment set to '0' // fuelling.WritableReservedBy = 0; // } // } //} } 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_OnGetFuelSaleTrxDetails(object sender, FuelSaleTrxEventArgs e) { // do nothing because GetFuelSaleTrxDetails response is managed by OnFuelSaleTrx event } private void manager_OnGetProductTable(object sender, GetProductTableEventArgs e) { Trace.WriteLine("init"); ConfigurationReader.GetProductTableParam param = new ConfigurationReader.GetProductTableParam(e.sr, this); configurationReader.ReadProductTable(param); Trace.WriteLine("end"); } private void manager_OnTankData(object sender, TankDataEventArgs e) { Trace.WriteLine("init"); Trace.WriteLine("end"); } private void manager_OnGetConfiguration(object sender, GetConfigurationEventArgs e) { Trace.WriteLine("manager_OnGetConfiguration init"); ConfigurationReader.GetConfigurationParam param = new ConfigurationReader.GetConfigurationParam(e.sr, this); if (configurationReader.ReadConfiguration(param)) this.ifsfManager.isConfigRead = true; Trace.WriteLine("manager_OnGetConfiguration End"); } private void manager_OnConfigurationChange(object sender, EventArgs e) { Trace.WriteLine("manager_OnConfigurationChange - init"); //this.Disconnect(); this.DestroyObjects(false); this.forecourtControl.WritableConnectionState = DeviceConnectionState.Connecting; this.initializationStatus.ConfigurationDataRead = false; this.initializationStatus.ReadingConfigurationData = false; try { if (FUSIONConfigFactory.getConfigurator() != null) FUSIONConfigFactory.getConfigurator().FireOnConfigurationChanged(); } catch (Exception ex) { } shouldSetConnected = false; this.InitializeOrhcestrator(); Trace.WriteLine("End manager_OnConfigurationChange"); } private void manager_OnTwinMasterReady(object sender, EventArgs e) { Trace.WriteLine("init manager_OnTwinMasterReady"); try { if (FUSIONTwinFactory.getTwin() != null) ((FUSIONTwin)(FUSIONTwinFactory.getTwin())).FireOnTwinMasterReady(); else Trace.WriteLine("manager_OnTwinMasterReady - twin NOT created"); } catch (Exception ex) { } Trace.WriteLine("End manager_OnTwinMasterReady"); } private void manager_OnOptRead(object sender, OptReadEventArgs e) { Trace.WriteLine("init"); OptReadEventArgs args = new OptReadEventArgs(e.deviceType, e.deviceId, e.message); if (FUSIONOptFactory.getOptBridge() != null) ((FUSIONOptBridge)(FUSIONOptFactory.getOptBridge())).FireOnDataRead(e.deviceId, e.message); Trace.WriteLine("End"); } protected bool CheckConfiguration(ServiceResponseGetConfiguration sr) { Trace.WriteLine("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 (true && forecourtControl.ConfigParam.IsEMSGVersion) break; 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 bool bPumpFound = false; foreach (FUSIONPump pump in forecourtControl.WritablePumpList) { 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) { Trace.WriteLine(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; } } Trace.WriteLine("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 != null) ? 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.FuelGrade != Convert.ToInt32(productNo)) { Trace.WriteLine(string.Format("pump {0}, nozzle {1}, new product {2}, old product = {3} ", pump.realId, FPNozzle.FPNozzleNo, FPNozzle.FPProductId, nozzle.FuelGrade)); 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.FuelGrade)); this.manager_OnDeviceAlarm(this, arg); bResult = false; } break; } } if (!bNozzleFound) { Trace.WriteLine(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) { Trace.WriteLine(string.Format("pump {0}, nozzle {1}, product {2} not found in new configuration", pump.realId, nozzle.Id, nozzle.FuelGrade)); 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.FuelGrade)); this.manager_OnDeviceAlarm(this, arg); bResult = false; break; } } break; } } if (!bFPFound) { bResult = false; Trace.WriteLine(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); } Trace.WriteLine("end - true"); return bResult; } internal bool Connect(string connectionString) { //if (this.debugLogger.IsActive()) //{ // this.debugLogger.Add("Connect, connectionString=" + connectionString); //} //this.connectionStringParamDict = Strings.ParseConnectionString(connectionString); return this.ifsfManager.clientSocket.Connect(connectionString); //this.forecourtControl.WritableClientId = this.clientSocket.ClientId; //this.forecourtControl.WritableClientName = this.clientSocket.ClientName; } 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(); //this.DestroyObjects(); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.disposed) { this.disposed = true; if (disposing) { if (this.configurationReader != null) this.configurationReader.Dispose(); if (Trace.debugLogger != null) Trace.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 /*oppure tank.realId ?*/ == 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 /*oppure tank.realId ?*/ == iTankId) return tank; } } return null; } private void InitializeOrhcestrator() { Trace.WriteLine("InitializeOrhcestrator init"); if (!this.disposed) //&& (this.clientSocket.ConnectionState == DeviceConnectionState.Connected)) { if (!this.initializationStatus.ConfigurationDataRead) { if (!this.initializationStatus.ReadingConfigurationData) { Trace.WriteLine("calling ReadConfigurationDataAsync"); shouldSetConnected = false; this.initializationStatus.ReadingConfigurationData = true; ifsfManager.isConfigRead = false; this.configurationReader.ForceStart = true; this.configurationReader.ReadConfigurationDataAsync(); } else Trace.WriteLine("ReadingConfigurationData"); } } if (shouldSetConnected) { Trace.WriteLine("ConfigurationDataRead"); this.forecourtControl.WritableConnectionState = DeviceConnectionState.Connected; } } 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 implementing classes /// public string FullEntityName { get; set; } public int Id { get { return this.forecourtControl.Id; } } public IIdentifiableEntity ParentEntity { get { return null; } } // Nested Types private class ConfigurationReader : IDisposable { // Fields private bool cancelled; private FUSIONManager nfsManager; private AutoResetEvent readingDoneEvent = new AutoResetEvent(false); private bool running; // Methods public ConfigurationReader(FUSIONManager nfsManager) { this.nfsManager = nfsManager; } public void Cancel() { if (this.running) { this.cancelled = true; } } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(bool disposing) { this.Cancel(); if (disposing) { this.readingDoneEvent.Close(); this.readingDoneEvent = null; } } public bool Running { get { return running; } } public bool ForceStart { get; set; } ~ConfigurationReader() { this.Dispose(false); } private void ReadConfigurationData(object o) { Trace.WriteLine("ReadConfigurationData - init"); try { FUSIONManager parentEntity = o as FUSIONManager; //TLG parentEntity.ifsfManager.GetConfiguration(null, null, null); parentEntity.ifsfManager.GetProductTable(null, null, null); } finally { } Trace.WriteLine("ReadConfigurationData - end"); } public void ReadConfigurationDataAsync() { Trace.WriteLine(string.Format("ReadConfigurationDataAsync - Running={0}, ForceStart={1}", running, ForceStart)); if (ForceStart || (!this.running)) { Trace.WriteLine("ReadConfigurationDataAsync - Start ReadConfigurationData"); ForceStart = false; this.cancelled = false; this.readingDoneEvent.Reset(); this.running = true; Trace.WriteLine("ThreadPool.QueueUserWorkItem(new WaitCallback(this.ReadConfigurationData), this.nfsManager);"); ThreadPool.QueueUserWorkItem(new WaitCallback(this.ReadConfigurationData), this.nfsManager); } else { Trace.WriteLine("ReadConfigurationDataAsync() was called already!"); } } public void ReadProductTable(object o) { if (o == null) return; GetProductTableParam param = (GetProductTableParam)o; ServiceResponseGetProductTable sr = param.sr; FUSIONManager parentEntity = param.nfsManager; 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) { Trace.WriteLine(string.Format("errore in ServiceResponseGetProductTable")); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, "Error in GetProductTable"); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); parentEntity.forecourtControl.WritableConnectionState = DeviceConnectionState.Connected; this.running = false; this.readingDoneEvent.Set(); return; } try { try { if (parentEntity.forecourtControl.WritableFuelPriceList.Count > 0) { bool bAlarm = false; Trace.WriteLine(string.Format("forecourtControl.WritableFuelPriceList.Count = {0}, verify prices", parentEntity.forecourtControl.WritableFuelPriceList.Count)); //verify product numberl if (parentEntity.forecourtControl.WritableFuelPriceList.Count != sr.FDCdata[0].FuelProducts[0].Product.Length) { Trace.WriteLine(string.Format("forecourtControl.WritableFuelPriceList.Count = {0}, sr.FDCData[0].FuelProducts.Lenght = {1}", parentEntity.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, parentEntity.forecourtControl.WritableFuelPriceList.Count)); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); bAlarm = true; } foreach (FUSIONFuelPrice fuelprice in parentEntity.forecourtControl.WritableFuelPriceList) { bool bFound = false; foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { if (Convert.ToInt32(product.ProductNo) == fuelprice.FuelGrade) { 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.FuelGrade)); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); bAlarm = true; break; } } foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { bool bFound = false; foreach (FUSIONFuelPrice fuelprice in parentEntity.forecourtControl.WritableFuelPriceList) { if (Convert.ToInt32(product.ProductNo) == fuelprice.FuelGrade) { 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)); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); bAlarm = true; break; } } return; } foreach (ServiceResponseProductGetProductTable product in sr.FDCdata[0].FuelProducts[0].Product) { FUSIONFuelPrice fuelprice = new FUSIONFuelPrice(Convert.ToInt32(product.ProductNo)); parentEntity.forecourtControl.WritableFuelPriceList.Add(fuelprice); } } catch (Exception exception) { //managed in readConfiguration //initializationStatus.ReadingConfigurationData = false; } } finally { } //if (!nfsManager.forecourtControl.ConfigParam.IsEMSGVersion) { parentEntity.ifsfManager.GetDSPConfiguration(null, null, null); } //else //{ // parentEntity.ifsfManager.GetConfiguration(null, null, null); //} Trace.WriteLine("end"); } public bool ReadConfiguration(object o) { Trace.WriteLine("init ReadConfiguration"); if (o == null) return false; GetConfigurationParam param = (GetConfigurationParam)o; ServiceResponseGetConfiguration sr = param.sr; FUSIONManager parentEntity = param.nfsManager; bool end = true; 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))) { Trace.WriteLine(string.Format("end ReadConfiguration - errore in ServiceResponseGetConfiguration")); DeviceAlarmEventArgs arg = new DeviceAlarmEventArgs(Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint, 0, (int)Wayne.FDCPOSLibrary.ErrorCode.ERRCD_BADCONF, string.Format("error in Getconfiguration")); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); parentEntity.forecourtControl.WritableConnectionState = DeviceConnectionState.Connected; return false; } try { if (parentEntity.forecourtControl.WritablePumpList.Count > 0 && (sr.RequestType == "GetConfiguration" || sr.RequestType == "GetDSPConfiguration")) { Trace.WriteLine(string.Format("end ReadConfiguration - forecourtControl.WritablePumpList.Count = {0}, call CheckConfiguration", parentEntity.forecourtControl.WritablePumpList.Count)); if (!parentEntity.CheckConfiguration(sr)) { Trace.WriteLine(string.Format("Configurazione Fusion != Configurazione interna, send Alarm")); //TODO SendAlarm } return false; } else if (parentEntity.forecourtControl.WritableTankGroupList.Count > 0 && sr.RequestType == "GetTLGConfiguration") { Trace.WriteLine(string.Format("forecourtControl.WritablePumpList.Count = {0}, call CheckConfiguration", parentEntity.forecourtControl.WritablePumpList.Count)); if (!parentEntity.CheckConfiguration(sr)) { Trace.WriteLine(string.Format("Configurazione Fusion != Configurazione interna, send Alarm")); //TODO SendAlarm return false; } } if (sr.FDCdata[0].DeviceClass != null) { foreach (ServiceDeviceClassConfiguration deviceClass in sr.FDCdata[0].DeviceClass) { switch (deviceClass.Type) { case Wayne.FDCPOSLibrary.DeviceType.DT_FuelDispenser: { //if (nfsManager.forecourtControl.ConfigParam.IsEMSGVersion) //{ // break; //} ReadPumpConfiguration(parentEntity, deviceClass.DeviceClass[0]); } break; case Wayne.FDCPOSLibrary.DeviceType.DT_FuellingPoint: { ReadPumpConfiguration(parentEntity, deviceClass); } break; case Wayne.FDCPOSLibrary.DeviceType.DT_TankLevelGauge: //DT_TankProbe: { Trace.WriteLine(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 = parentEntity.getTankGroupByIndex(Convert.ToInt32(nestedDevice.TPProductNo)); if (tankgroup == null) { tankgroup = new FUSIONTankGroup(parentEntity, Convert.ToInt32(nestedDevice.TPProductNo), Convert.ToInt32(nestedDevice.TPProductNo)); parentEntity.forecourtControl.WritableTankGroupList.Add(tankgroup); } FUSIONTank tank = new FUSIONTank(parentEntity, Convert.ToInt32(nestedDevice.TPTankNo), tankgroup); tankgroup.WritableTankList.Add(tank); Trace.WriteLine(string.Format("WritableTankList.Add tank={0}", tank.realId)); // TODO assign tank properties // ... } } break; } } } if (this.cancelled) { Trace.WriteLine("end ReadConfiguration - this.cancelled"); return false; } if (sr.RequestType == "GetDSPConfiguration") { //parentEntity.ifsfManager.GetTLGConfiguration(null, null, null); end = false; //return false; } //parentEntity.initializationStatus.ConfigurationDataRead = true; } catch (Exception exception) { parentEntity.initializationStatus.ReadingConfigurationData = false; Trace.WriteLine(string.Format("Exception! : {0}", exception.Message)); //Logger.AddEntry(new ExceptionLogEntry(parentEntity, ErrorLogSeverity.RecoverableDataLoss, "Exception in ReadConfigurationData ", exception)); } finally { if (end) { Trace.WriteLine("ReadConfiguration finally"); this.running = false; this.readingDoneEvent.Set(); } } //FG, MAR-15-2011, bug fix #28041; trigger to GetConfiguration again if there's no pump on FM. if (parentEntity.forecourtControl.WritablePumpList.Count == 0) { return false; } parentEntity.shouldSetConnected = false; parentEntity.InitializeOrhcestrator(); // TODO codice temporaneo if (this.OnConnectionStateChange != null) parentEntity.initializationStatus.ConfigurationDataRead = true; Trace.WriteLine("WritableConnectionState = DeviceConnectionState.Connected"); parentEntity.forecourtControl.WritableConnectionState = DeviceConnectionState.Connected; } finally { if (end) { Trace.WriteLine("ReadConfiguration finally"); this.running = false; this.readingDoneEvent.Set(); } } Trace.WriteLine("ReadConfiguration - end"); return true; } internal void ReadPumpConfiguration(FUSIONManager parentEntity, ServiceDeviceClassConfiguration deviceClass) { FUSIONPump pump = new FUSIONPump(parentEntity); pump.WritableParentDevice = parentEntity.forecourtControl; pump.WritableCapFuelGradeSelected = false; pump.WritableCapNozzleDetection = false; pump.WritableCapSetLight = false; pump.WritableCapSuspendFuelling = false; pump.WritablePumpId = Convert.ToInt32(deviceClass.FPPumpNo); pump.WritableDeviceName = "Pump " + deviceClass.FPPumpNo; foreach (ServiceNozzleFPDeviceClassConfiguration FPnozzle in deviceClass.FPNozzle) { string productNo = (FPnozzle.FPProductId[0].PIFPProductNo != null) ? FPnozzle.FPProductId[0].PIFPProductNo : FPnozzle.FPProductId[0].PIFPProductNo1; FUSIONNozzle nozzle = new FUSIONNozzle(Convert.ToInt32(FPnozzle.FPNozzleNo), pump); nozzle.FuelGrade = Convert.ToInt32(productNo); bool bFound = false; foreach (FUSIONFuelPrice fuelprice in parentEntity.forecourtControl.WritableFuelPriceList) { if (fuelprice.FuelGrade == 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)); parentEntity.manager_OnDeviceAlarm(parentEntity, arg); } pump.WritableNozzleList.Add(nozzle); } parentEntity.forecourtControl.WritablePumpList.Add(pump); Trace.WriteLine(string.Format("WritablePumpList.Add pump={0}", pump.realId)); } public class GetProductTableParam { public FUSIONManager nfsManager; public ServiceResponseGetProductTable sr; public GetProductTableParam(ServiceResponseGetProductTable _sr, FUSIONManager _nfsManager) { sr = _sr; nfsManager = _nfsManager; } } public class GetConfigurationParam { public FUSIONManager nfsManager; public ServiceResponseGetConfiguration sr; public GetConfigurationParam(ServiceResponseGetConfiguration _sr, FUSIONManager _nfsManager) { sr = _sr; nfsManager = _nfsManager; } } } } }