private bool CommandHandler(Guid guid, int byteCount, byte[] buffer) { var data = Encoding.ASCII.GetString(buffer, 0, byteCount); TcpClient client = null; lock (lockObj) { client = clients[guid]; } LogHelp.localEndpoint = tcpListener.LocalEndpoint; LogHelp.remoteEndPoint = clients[guid].Client.RemoteEndPoint; // If FE only show in DEBUG mode. if (data.Contains("FE")) { LogHelp.LogRead(guid, data, LogHelp.LogLevel.debug); } else { LogHelp.LogRead(guid, data, LogHelp.LogLevel.info); } if (buffer[0].Equals(2)) // Byte0 = STX, start of Command { int pump = 0; try { pump = Convert.ToInt16(data.Substring(2, 2)); } catch { } switch (Convert.ToChar(buffer[1])) { /* STX B xx C ETX CD * B - Message identifier * xx- Pump No * C - Cancel identifier * Pump No = 1 * Sample command = STX B 01 C ETX CD * * STX B xx xxxxxxx ETX CD * Finalize Command Character=B * Pump #=XX (01 to 32) * xxxxxxxx = EHM$VPL * * • Pump 1 * * Sample Command = STX B 01 EHM$VPL ETX CD */ case 'B': //Pump Cancel or Finalize if (data.Substring(4, 1) == "C") // Cancel Pump { ThisStation.SetStatus(pump, PumpStatusEnum.Idle); } else if (data.Substring(4, 7) == "EHM$VPL") // Get Finalization { if (ThisStation.Pumps[pump].PumpStatus.Equals(PumpStatusEnum.DispenseCompleted)) { /* 01H2M1$0000000000V0000000000P002600L010000 * SendCMD(guid, $"07H2M0$0000002000V0000009217P002170L002000f"); * 07 H2 M0 $0000002000 V0000009217 P002170 L002000 * Pump=07 * Hose=2 * M=0 (flag?) * Amount:00000020.00 * Volume:0000009.217 * PPU:002.170 * Limit:0020.00 * Final sales data for pump 7, Hose=2, Amt=20.00, Vol=9.217, PPU=2.170 (L=20.00) */ Pump.Pump Fpump = ThisStation.Pumps[pump]; decimal vol = Fpump.Volume; vol = vol.Equals(0) ? 1 : vol; SendCMD(guid, $"{pump:00}" + // Pump $"H{Fpump.Hose:0}" + //Hose $"M{Fpump.Flag:0}" + //Flag $"${Fpump.Amount * 100:0000000000}" + //amount * 100 $"V{Fpump.Volume * 1000:0000000000}" + //volume liter * 1000 $"P{(Fpump.Amount / (vol)) * 1000:000000}" + // price per unit * 1000 $"L{Fpump.Limit * 100:000000}" + // original limith * 100 $""); ThisStation.SetStatus(pump, PumpStatusEnum.Idle); } } break; /* * STX A Pump# Hose# Flag $$$$.$$ vvv.vvv ETX CD * In the actual command, decimal points are implied only. * Authorize Command Character=A * Pump #=XX (01 to 32) * Hose #=X (0 to 8, with 0 authorizing any hose — also see Multi-grade Lock Authorization which follows) * Flag=X (Type of authorization — see Description) * Dollar Limit Amount=$$$$.$$ (0000.01 to 9999.99) * Volume Limit Amount=vvv.vvv (000.001 to 999.999) * * • Pump 1 * • Hose 1 * • $25.00 * * Sample Command = STX A 0101002500000000 ETX CD */ case 'A': // Authorize int hose = Convert.ToInt16(data.Substring(4, 1)); string flag = data.Substring(5, 1); decimal dollarLimit = Convert.ToDecimal(data.Substring(6, 6).Insert(4, ".")); decimal volumeLimit = Convert.ToDecimal(data.Substring(12, 6).Insert(3, ".")); if (ThisStation.Pumps[pump].PumpStatus.Equals(PumpStatusEnum.Reserved)) { Pump.Pump Npump = ThisStation.Pumps[pump]; Npump.Limit = dollarLimit; Npump.Volume = volumeLimit; Npump.Hose = hose; Npump.Flag = flag; if (ThisStation.Pumps.ContainsKey(pump)) { ThisStation.Pumps.Remove(pump); } ThisStation.Pumps.Add(pump, Npump); ThisStation.SetStatus(pump, PumpStatusEnum.Authorized); } break; /* * 1, Check current pump state which should be idle * 2. If match, sending reserve message to ISIS by sending pumpId and ZapOrderId. * * STX M xx ETX CD * * M Reserve identifier * xx Pump No * Pump No = 1 * * Sample command = STX M 01 ETX CD * Failure command = STX M 01 1 ETX CD */ case 'M': // Reserve if (ThisStation.Pumps[pump].PumpStatus.Equals(PumpStatusEnum.Idle)) { ThisStation.SetStatus(pump, PumpStatusEnum.Reserved); } else { SendCMD(guid, $"M{pump:00}{0x01}"); LogHelp.LogWrite(guid, $"Pump #{pump:00}: is already reserved", LogHelp.LogLevel.debug); } break; /* * Request Pump Status * Get Status Command Character=FE * * Sample Command = STX FE ETX CD * Response Command = STX 28000000000000000000000000000000000000000000000000000000000000000 ETX CD * (64 chars) */ case 'F': // Request Pump Status if (data.Substring(1, 1) != "E") { //Do Timer tick here //storyman.StoryHandler.TimerTick(); string PumpStatus = ""; foreach (KeyValuePair <int, Pump.Pump> item in ThisStation.Pumps) { if (!item.Key.Equals(0)) { PumpStatus += item.Value.Status; } } for (int i = ThisStation.Pumps.Count; i < 66; i++) { PumpStatus += 0x00; PumpStatus += 0x00; } PumpStatus = PumpStatus.Substring(0, 64); SendCMD(guid, $"28{PumpStatus}"); } break; case 'G': // Get Status on pump SendCMD(guid, $"G{pump:00}{ThisStation.Pumps[pump].Status}"); break; case 'S': // Change Status on pump string Status = data.Substring(4, 2); ThisStation.SetStatusText(pump, Status); break; case 'V': // Change Volume on pump decimal volume = Convert.ToDecimal(data.Substring(4, 6).Insert(3, ".")); ThisStation.SetVolume(pump, volume); break; case 'D': // Change Amount on pump decimal Amount = Convert.ToDecimal(data.Substring(4, 6).Insert(3, ".")); ThisStation.SetAmount(pump, Amount); break; case 'I': // Pump Info decimal vol1 = ThisStation.Pumps[pump].Volume; vol1 = vol1.Equals(0) ? 1 : vol1; SendCMD(guid, $"I{pump:00}" + // Pump $"S{ThisStation.Pumps[pump].Status}" + $"H{ThisStation.Pumps[pump].Hose:0}" + //Hose $"M{ThisStation.Pumps[pump].Flag:0}" + //Flag $"${ThisStation.Pumps[pump].Amount * 100:0000000000}" + //amount * 100 $"V{ThisStation.Pumps[pump].Volume * 1000:0000000000}" + //volume liter * 1000 $"P{(ThisStation.Pumps[pump].Amount / (vol1)) * 1000:000000}" + // price per unit * 1000 $"L{ThisStation.Pumps[pump].Limit * 100:000000}" + // original limith * 100 $""); break; default: SendCMD(guid, data); break; } return(true); } else { return(false); } }