tbf/TestBenchFramework/BenchControl/Network/Camera/CLP1611/Camera.cs
Milan Hanajik 38c199f6f9 Interfaces between Camera and Roi and sequences finalized, TODO: network communication, ver. 2.12.446
Sequences more robust for debugging, T and Pr-meters checked for null
2017-01-25 17:28:57 +01:00

322 lines
8.7 KiB
C#

///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
using log4net;
using Config.Entities;
namespace TBF.BenchControl.Network.Camera.CLP1611
{
public class Camera : ComponentBase, GenericDevices.ICamera, Generic.IDevice
{
private static readonly ILog log = LogManager.GetLogger(typeof(Camera));
public override string ToString()
{
return string.Format("{0}, Name={1}, HWAddress={2}, IPAddress={3}, Serial={4}, Image={5}",
this.GetType().Namespace.Substring(17),
CameraCfg.Name,
CameraCfg.HardwareAddress,
ipAddress == null ? "not detected" : ipAddress.ToString(),
string.IsNullOrEmpty(serial) ? "not detected" : serial,
string.IsNullOrEmpty(sdCardVer) ? "not detected" : sdCardVer);
}
public bool Running { get { return running; } }
bool running;
const string ClpUserName = "tbf";
const string ClpPassword = "C1ern4V0d4";
const string ClpPrompt = "$ ";
public readonly CameraCfg CameraCfg;
public readonly GenericDevices.INetworkAdapter NetAdapter;
public IPAddress IPAddress { get { return ipAddress; } }
IPAddress ipAddress;
string hardware;
public string Hardware { get { return hardware; } }
string revision;
public string Revision { get { return revision; } }
string serial;
public string Serial { get { return serial; } }
string sdCardVer;
public string SDCardVer { get { return sdCardVer; } }
IList<string> roiParams;
int[] result;
///
public void ClearRois() { roiParams.Clear(); }
public int RegisterRoi(string rParams)
{
this.roiParams.Add(rParams);
int newHandle = this.roiParams.Count;
result = new int[newHandle];
return newHandle;
}
///
public int GetResult(int roiHandle)
{
if (roiHandle > 0 && roiHandle <= roiParams.Count)
{
return 0;
}
else
{
return result[roiHandle - 1];
}
}
public Telnet.TelnetClient Telnet;
private TerminalDlg terminalDlg;
///
/// UDP Port number for 'MeasurementOp'
///
const int UdpPortRangeStart = 49152;
const int UdpPortRangeEnd = 65535;
static int nextUdpPortNr = UdpPortRangeStart;
public static int GetNextUdpPortNr() { return nextUdpPortNr++; }
///
readonly int measurementUdpPortNr;
UdpClient measurementListener;
public Camera() {}
public Camera(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
CameraCfg = cfg as CameraCfg;
NetAdapter = TbfComponents.FindComponent(cfg.ParentName, components) as GenericDevices.INetworkAdapter;
if (NetAdapter == null) throw new ArgumentNullException("no network adapter");
Telnet = null;
terminalDlg = null;
measurementUdpPortNr = GetNextUdpPortNr();
roiParams = new List<string>();
running = false;
log.Debug(this.ToString());
}
public void Initialize()
{
if (CameraCfg.DebugLevel == DebugMode.Simulate) return;
/// Detect a camera
bool cameraDetected = DetectCamera(CameraCfg.HardwareAddress, true,
out ipAddress, out hardware, out revision, out serial, out sdCardVer);
if (!cameraDetected) throw new Exception(string.Format("Camera {0} with address {1} not detected",
Name, CameraCfg.HardwareAddress));
/// Open telnet clint and start the log-in process
Telnet = new Telnet.TelnetClient(this, CameraCfg.Name, ClpUserName, ClpPassword, ClpPrompt);
if (CameraCfg.DisplayTerminal)
{
terminalDlg = new TerminalDlg(CameraCfg.Name, Telnet);
terminalDlg.Show();
}
Telnet.Enqueue(new Telnet.Command(Network.Telnet.CmdAction.CONNECT, ipAddress.ToString(), 10, 30));
measurementListener = new UdpClient(measurementUdpPortNr);
new Thread(new ThreadStart(MeasurementUdpListener)).Start();
running = true;
log.FatalFormat("Successfully initialized device {0}", ToString());
}
public void StopDevice()
{
if (Telnet != null)
{
Telnet.Dispose();
Telnet = null;
}
running = false;
}
public void RunDeviceBefore() {}
public void RunDeviceAfter() {}
public IOperation LiveStreamOp(bool hiRes)
{
return new LiveStreamOp(this, Telnet, hiRes ? "clp/hrlivestream.sh" : "clp/livestream.sh");
}
public IOperation MeasurementOp()
{
if (Telnet != null)
{
return new MeasurementOp(this, NetAdapter.IPAddress.ToString(), measurementUdpPortNr, roiParams);
}
else
{
return null;
}
}
public IOperation GrabImageOp()
{
return null;
}
/// <summary>
/// Detect the camera with specified hardware address (DIP switches)
/// </summary>
/// <param name="hwAddress">Hardware address (DIP switches)</param>
/// <param name="setDateTime">true = Broadcast 'SetDateTime' to all cameras</param>
/// <param name="ipAddress">Detected IP address</param>
/// <param name="hardware">Detected hardware</param>
/// <param name="revision">Detected HW revision</param>
/// <param name="serial">Detected serial number</param>
/// <param name="sdCardVer">Detected OS image</param>
/// <returns>true when camera detected successfully</returns>
bool DetectCamera(int hwAddress, bool setDateTime, out IPAddress ipAddress, out string hardware, out string revision, out string serial, out string sdCardVer)
{
for (int trials = 1; trials <= 3; trials++)
{
UdpClient udpClient = new UdpClient();
if (setDateTime)
{
SetDateTime(udpClient, DateTime.Now);
}
///
/// Send a request for camera information
///
DateTime detectionStart = DateTime.Now;
CameraInfoRequest(udpClient, hwAddress);
///
/// Receive a response or timeout
///
IAsyncResult asyncRslt = udpClient.BeginReceive(null, null);
if (asyncRslt.AsyncWaitHandle.WaitOne(500))
{
/// Response received within time limit
IPEndPoint cameraIPEndpoint = new IPEndPoint(IPAddress.Any, 1852);
byte[] inputBuffer = udpClient.EndReceive(asyncRslt, ref cameraIPEndpoint);
double duration_ms = (DateTime.Now - detectionStart).TotalMilliseconds;
ipAddress = cameraIPEndpoint.Address;
udpClient.Close();
string response = Encoding.ASCII.GetString(inputBuffer, 0, inputBuffer.Length);
string[] strArr = response.Split(new char[] { ' ', '=' });
if (strArr.Length == 10 && strArr[0] == "Address" && strArr[2] == "Hardware" &&
strArr[4] == "Revision" && strArr[6] == "Serial" && strArr[8] == "Image")
{
hardware = strArr[3];
revision = strArr[5];
serial = strArr[7];
sdCardVer = strArr[9];
}
else if (strArr.Length == 8 && strArr[0] == "Address" && strArr[2] == "Hardware" &&
strArr[4] == "Revision" && strArr[6] == "Serial")
{
hardware = strArr[3];
revision = strArr[5];
serial = strArr[7];
sdCardVer = string.Empty;
}
else
{
continue;
}
string msg = string.Format("Camera {0} detected in {1} ms: HWAddress={2} IPAddress={3} {4}",
CameraCfg.Name,
duration_ms,
CameraCfg.HardwareAddress,
ipAddress == null ? "not detected" : ipAddress.ToString(),
response);
log.Info(msg);
Console.WriteLine(msg);
return true; /// Camera detected
}
udpClient.Close();
}
ipAddress = null;
hardware = null;
revision = null;
serial = null;
sdCardVer = null;
return false; /// No camera detected
}
void CameraInfoRequest(UdpClient udpClient, int hardwareAddress)
{
string strToSend = string.Format("getinfo {0}", hardwareAddress);
byte[] dataToSend = Encoding.ASCII.GetBytes(strToSend);
udpClient.Send(dataToSend, dataToSend.Length, new IPEndPoint(NetAdapter.BroadcastAddress, 1852));
}
void SetDateTime(UdpClient udpClient, DateTime dateTime)
{
string strToSend = string.Format("setdatetime {0:yyMMddHHmmss}", dateTime);
byte[] dataToSend = Encoding.ASCII.GetBytes(strToSend);
udpClient.Send(dataToSend, dataToSend.Length, new IPEndPoint(NetAdapter.BroadcastAddress, 1852));
}
void MeasurementUdpListener()
{
try
{
while (true)
{
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, measurementUdpPortNr);
byte[] byteArray = measurementListener.Receive(ref ipEndPoint);
string receivedData = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length);
int from = receivedData.IndexOf('[');
int to = receivedData.IndexOf(']');
int locPulses;
if (from >= 0 && to >= 0 && to > from &&
int.TryParse(receivedData.Substring(from + 1, to - from - 1), out locPulses))
{
//wmPulses = locPulses;
}
}
}
catch
{
log.FatalFormat("Camera : MeasurementUdpListener() thread failed");
}
}
}
}