BaseSerialPort:
- Flush buffer (DiscardInBuffer) removed as some bytes are missing from time to time. The IrDA sniffer showed these on the communication line, but they are incompletely received. Assuming the DiscardInBuffer may be delayed, so the incoming data will be scrapped. IrdaTransmitProtocol: - WakeUpMessage marked and debug output
This commit is contained in:
@@ -155,7 +155,7 @@
|
|||||||
</site>
|
</site>
|
||||||
<site name="MeterProcessState" id="2">
|
<site name="MeterProcessState" id="2">
|
||||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||||
<virtualDirectory path="/" physicalPath="C:\ProgrammeSensus\Repo\Lab\La_Operations\laa_production\Common\Service\MeterProcessState" />
|
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\laa_production\Common\Service\MeterProcessState" />
|
||||||
</application>
|
</application>
|
||||||
<bindings>
|
<bindings>
|
||||||
<binding protocol="http" bindingInformation="*:56011:localhost" />
|
<binding protocol="http" bindingInformation="*:56011:localhost" />
|
||||||
|
|||||||
@@ -409,6 +409,11 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
|
|||||||
/// <remarks date="2019-Dec-14" author="T.Wiedebusch">
|
/// <remarks date="2019-Dec-14" author="T.Wiedebusch">
|
||||||
/// - Flush buffer if received length is 0.
|
/// - Flush buffer if received length is 0.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
/// <remarks date="2022-Jul-15" author="T.Wiedebusch">
|
||||||
|
/// - Flush buffer (DiscardInBuffer) removed as some bytes are missing from time to time.
|
||||||
|
/// The IrDA sniffer showed these on the communication line, but they are incompletely received.
|
||||||
|
/// Assuming the DiscardInBuffer may be delayed, so the incoming data will be scrapped.
|
||||||
|
/// </remarks>
|
||||||
private void ReadingThreadLoop()
|
private void ReadingThreadLoop()
|
||||||
{
|
{
|
||||||
//put the receive thread to JoinWaitSleep to avoid reading and logger output for timeout on
|
//put the receive thread to JoinWaitSleep to avoid reading and logger output for timeout on
|
||||||
@@ -464,7 +469,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
|
|||||||
rxByte = (Byte)_serialPort.ReadByte();
|
rxByte = (Byte)_serialPort.ReadByte();
|
||||||
//record raw data stream for output on missing sync-byte to investigate this issue
|
//record raw data stream for output on missing sync-byte to investigate this issue
|
||||||
rxRawRecord.Add(rxByte);
|
rxRawRecord.Add(rxByte);
|
||||||
} while ((_serialPort.BytesToRead > 0) && (PortSettingsForTransmitProtocol.ProtSyncByte != rxByte));
|
} while (_serialPort.BytesToRead > 0 && PortSettingsForTransmitProtocol.ProtSyncByte != rxByte);
|
||||||
|
|
||||||
// if syncByte has not been detected skip read loop and wait for next incoming record
|
// if syncByte has not been detected skip read loop and wait for next incoming record
|
||||||
if (PortSettingsForTransmitProtocol.ProtSyncByte == rxByte)
|
if (PortSettingsForTransmitProtocol.ProtSyncByte == rxByte)
|
||||||
@@ -545,10 +550,10 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
|
|||||||
catch (TimeoutException)
|
catch (TimeoutException)
|
||||||
{
|
{
|
||||||
//flush receive buffer at timeout to force task to enter JoinWaitSleep state in finally
|
//flush receive buffer at timeout to force task to enter JoinWaitSleep state in finally
|
||||||
if (_serialPort.IsOpen)
|
//if (_serialPort.IsOpen)
|
||||||
{
|
//{
|
||||||
_serialPort.DiscardInBuffer();
|
// _serialPort.DiscardInBuffer();
|
||||||
}
|
//}
|
||||||
|
|
||||||
_byteDataLogger.Trace($"{Ident} Read timeout({InterByteReadDelayMs}ms)");
|
_byteDataLogger.Trace($"{Ident} Read timeout({InterByteReadDelayMs}ms)");
|
||||||
//_byteDataLogger.Trace($"{Ident} Read timeout({PortSettingsForTransmitProtocol.ResponseTimeoutMs}ms)");
|
//_byteDataLogger.Trace($"{Ident} Read timeout({PortSettingsForTransmitProtocol.ResponseTimeoutMs}ms)");
|
||||||
@@ -655,6 +660,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts
|
|||||||
|
|
||||||
_serialPort.Write(txByteList.ToArray(), 0, txByteList.Count);
|
_serialPort.Write(txByteList.ToArray(), 0, txByteList.Count);
|
||||||
|
|
||||||
|
//TODO THW flush before sending NOT after
|
||||||
// flush the buffer for MOXA, to avoid two subsequent communications assembled to one communication!
|
// flush the buffer for MOXA, to avoid two subsequent communications assembled to one communication!
|
||||||
_serialPort.BaseStream.Flush();
|
_serialPort.BaseStream.Flush();
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
// Format of IrDA transmit protocol:
|
// Format of IrDA transmit protocol:
|
||||||
// IrdaSyncByte|IrdaSend/ReceiveHeader|IrdaPayLoadLength|IrdaCommand/Message|
|
// IrdaSyncByte|IrdaSend/ReceiveHeader|IrdaPayLoadLength|IrdaCommand/Message|
|
||||||
// IrdaPayLoad|IrdaCrc LSB|IrdaCrc MSB
|
// IrdaPayLoad|IrdaCrc LSB|IrdaCrc MSB
|
||||||
|
|
||||||
private const Byte IrdaSyncByte = 0x9B;
|
private const Byte IrdaSyncByte = 0x9B;
|
||||||
|
|
||||||
// Encoding of IrdaSendHeader (LAT: listen after talk, LAT 10b: 500ms)
|
// Encoding of IrdaSendHeader (LAT: listen after talk, LAT 10b: 500ms)
|
||||||
@@ -25,6 +24,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
// Bits: 0| 1| 10| 0| 001
|
// Bits: 0| 1| 10| 0| 001
|
||||||
// standard frame|register to adapter|LAT|reserved|optical message
|
// standard frame|register to adapter|LAT|reserved|optical message
|
||||||
private const Byte IrdaReceiveHeader = 0x61;
|
private const Byte IrdaReceiveHeader = 0x61;
|
||||||
|
|
||||||
// Mask out the LAT and the reserved bit for the IrdaReceiveHeader
|
// Mask out the LAT and the reserved bit for the IrdaReceiveHeader
|
||||||
private const Byte IrdaReceiveHeaderMask = 0xC7;
|
private const Byte IrdaReceiveHeaderMask = 0xC7;
|
||||||
|
|
||||||
@@ -34,6 +34,10 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
// data from register (water meter) to adapter (software) referred as optical message
|
// data from register (water meter) to adapter (software) referred as optical message
|
||||||
private const Byte IrdaMessage = 0x03;
|
private const Byte IrdaMessage = 0x03;
|
||||||
|
|
||||||
|
// wakeup from register (water meter) to adapter (software) wakeup message length of IrDA
|
||||||
|
private static readonly Byte[] IrdaWakeupMessage =
|
||||||
|
{IrdaSyncByte, 0x41, 0x03, 0x04, 0x00, 0xFF, 0xFF, 0xED, 0x6E };
|
||||||
|
|
||||||
// IrdaSyncByte|IrdaReceiveHeader|IrdaPayLoadLength|IrdaMessage|CRC LSB|CRC MSB
|
// IrdaSyncByte|IrdaReceiveHeader|IrdaPayLoadLength|IrdaMessage|CRC LSB|CRC MSB
|
||||||
private const Int32 IrdaProtocolFrameLength = 6;
|
private const Int32 IrdaProtocolFrameLength = 6;
|
||||||
|
|
||||||
@@ -49,7 +53,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
//private const Int32 DefaultResponseTimeoutMs = 50;
|
//private const Int32 DefaultResponseTimeoutMs = 50;
|
||||||
private const Int32 DefaultResponseTimeoutMs = 150;
|
private const Int32 DefaultResponseTimeoutMs = 150;
|
||||||
private Int32 _responseTimeoutMs = DefaultResponseTimeoutMs;
|
private Int32 _responseTimeoutMs = DefaultResponseTimeoutMs;
|
||||||
|
|
||||||
private const UInt32 BaudRate = 115200;
|
private const UInt32 BaudRate = 115200;
|
||||||
|
|
||||||
private readonly UInt32? _receiveBufferFlushThreshold = 1;
|
private readonly UInt32? _receiveBufferFlushThreshold = 1;
|
||||||
@@ -65,7 +69,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
_responseTimeoutMs = DefaultResponseTimeoutMs;
|
_responseTimeoutMs = DefaultResponseTimeoutMs;
|
||||||
}
|
}
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IrdaTransmitProtocol(String portName) : base (portName)
|
public IrdaTransmitProtocol(String portName) : base(portName)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -84,6 +88,9 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
/// <remarks date="2020-Dec-19" author="T.Wiedebusch">
|
/// <remarks date="2020-Dec-19" author="T.Wiedebusch">
|
||||||
/// - Removed IrdaMessage identifier check as it was observed receiving a 0x03 or a 0x04 in this field.
|
/// - Removed IrdaMessage identifier check as it was observed receiving a 0x03 or a 0x04 in this field.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
/// <remarks date="2022-Jul-15" author="T.Wiedebusch">
|
||||||
|
/// - Wakeup message detection reported to log-file.
|
||||||
|
/// </remarks>
|
||||||
public override List<Byte> DecodeDataForLogicLayer(List<Byte> irdaRecord)
|
public override List<Byte> DecodeDataForLogicLayer(List<Byte> irdaRecord)
|
||||||
{
|
{
|
||||||
Logger.Info($"DecodeDataForPhysicalLayer Cordonel->PC({BitConverter.ToString(irdaRecord.ToArray())})");
|
Logger.Info($"DecodeDataForPhysicalLayer Cordonel->PC({BitConverter.ToString(irdaRecord.ToArray())})");
|
||||||
@@ -92,11 +99,27 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol
|
|||||||
if (irdaRecord.Count < IrdaProtocolFrameLength + irdaRecord[IrdaPayLoadLengthIndex]
|
if (irdaRecord.Count < IrdaProtocolFrameLength + irdaRecord[IrdaPayLoadLengthIndex]
|
||||||
|| irdaRecord[IrdaSyncByteIndex] != IrdaSyncByte
|
|| irdaRecord[IrdaSyncByteIndex] != IrdaSyncByte
|
||||||
|| (irdaRecord[IrdaHeaderIndex] & IrdaReceiveHeaderMask) != (IrdaReceiveHeader & IrdaReceiveHeaderMask)
|
|| (irdaRecord[IrdaHeaderIndex] & IrdaReceiveHeaderMask) != (IrdaReceiveHeader & IrdaReceiveHeaderMask)
|
||||||
|| irdaRecord[IrdaMessageIndex] != IrdaMessage )
|
|| irdaRecord[IrdaMessageIndex] != IrdaMessage)
|
||||||
{
|
{
|
||||||
var error = new ApplicationException("Reply format from IrDA is invalid. Decoding of transmit layer failed.");
|
var wakeUp = true;
|
||||||
|
for (var i = 0; i < IrdaWakeupMessage.Length; i++)
|
||||||
|
{
|
||||||
|
if (irdaRecord[i] != IrdaWakeupMessage[i])
|
||||||
|
wakeUp = false;
|
||||||
|
}
|
||||||
|
if (wakeUp)
|
||||||
|
{
|
||||||
|
var error = new ApplicationException(
|
||||||
|
"Wakeup message from IrDA received. Retry of last message required.");
|
||||||
|
Logger.Error(error.Message, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var error = new ApplicationException(
|
||||||
|
"Reply format from IrDA is invalid. Decoding of transmit layer failed.");
|
||||||
|
Logger.Error(error.Message, error);
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Error(error.Message, error);
|
|
||||||
return new List<Byte>();
|
return new List<Byte>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2158,7 +2158,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
|||||||
|
|
||||||
while (retryLeft > 0 && !done)
|
while (retryLeft > 0 && !done)
|
||||||
{
|
{
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(50);
|
||||||
var result = WriteRegister(a.Key.GetIdent(), 1);
|
var result = WriteRegister(a.Key.GetIdent(), 1);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -2173,7 +2173,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for storing
|
// Wait for storing
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(400);
|
||||||
if (a.Key.AppName == "SENSUSRADIO")
|
if (a.Key.AppName == "SENSUSRADIO")
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
|
|||||||
@@ -330,6 +330,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
|||||||
/// <remarks date="2019-Jan-22" author="T.Wiedebusch">
|
/// <remarks date="2019-Jan-22" author="T.Wiedebusch">
|
||||||
/// - Avoid activation of wakeup retry if record is meanwhile acknowledged.
|
/// - Avoid activation of wakeup retry if record is meanwhile acknowledged.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
/// <remarks date="2022-Jul-15" author="T.Wiedebusch">
|
||||||
|
/// - Additional delay before retry.
|
||||||
|
/// </remarks>
|
||||||
public override void DecodeRecord(IPortDataEventArgs data)
|
public override void DecodeRecord(IPortDataEventArgs data)
|
||||||
{
|
{
|
||||||
//the request response record covers the entire request protocol
|
//the request response record covers the entire request protocol
|
||||||
@@ -348,6 +351,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol
|
|||||||
_logger.Debug($"{_ident} WakeupMessageRetry(1)");
|
_logger.Debug($"{_ident} WakeupMessageRetry(1)");
|
||||||
_recordInProcess.WakeupMessageRetryCtr = 1;
|
_recordInProcess.WakeupMessageRetryCtr = 1;
|
||||||
_recordInProcess.RetryCtr--;
|
_recordInProcess.RetryCtr--;
|
||||||
|
Thread.Sleep(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
46bd00889699f5a20a4981a22f62b66368323855
|
1a3d4919c9c702245832d925951f2b7cb72fc333
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
a50e8e35fe346dde3daa1dd9af1217ba2785aa48
|
f64d563def603c89cafafa61a3219ba97e1e344c
|
||||||
|
|||||||
Reference in New Issue
Block a user