///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using log4net;
using TBF.BenchControl.Network.Telnet;
namespace TBF.BenchControl.Network.Camera.Roi
{
public class RoiDetectionOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(RoiDetectionOp));
public override string ToString() { return string.Format("RoiDetectionOp()"); }
readonly Roi roi;
readonly RoiCfg roiCfg;
readonly CLP1611.Camera camera;
readonly Telnet.TelnetClient telnet;
readonly string imgFileNamePrefix;
string command;
bool roiDetectionCommandSent;
bool transferringDetectedImage;
string response;
bool passed;
bool failed;
bool previousFailed;
Boxes.IntBox roiX;
Boxes.IntBox roiY;
Boxes.IntBox roiWid;
Boxes.IntBox roiHgh; /// Wid and Hgh are usefull when masking
///
/// Events: Event.None or Event.Error
///
/// CLP1611.Camera reference
public RoiDetectionOp(Roi roi, CLP1611.Camera camera, string imgFileNamePrefix,
Boxes.IntBox roiX, Boxes.IntBox roiY,
Boxes.IntBox roiWid, Boxes.IntBox roiHgh)
{
this.roi = roi;
this.roiCfg = roi.RoiCfg;
this.camera = camera;
this.telnet = camera.Telnet;
this.imgFileNamePrefix = imgFileNamePrefix;
this.roiX = roiX;
this.roiY = roiY;
this.roiWid = roiWid;
this.roiHgh = roiHgh;
roiDetectionCommandSent = false;
transferringDetectedImage = false;
telnet.promptReceivedHandler += delegate(object sndr, PromptReceivedEventArgs a)
{
OnPromptReceived(sndr, a);
};
}
void OnPromptReceived(object sndr, PromptReceivedEventArgs a)
{
response = a.Response;
}
public void Start()
{
roiDetectionCommandSent = false;
transferringDetectedImage = false;
}
public Event Run()
{
if (!roiDetectionCommandSent)
{
if (telnet.State == TelnetClient.TelnetState.Inactive)
{
//
// State variables
//
response = null;
passed = false;
failed = false;
previousFailed = false;
//
// Prepare command
//
string masks = string.Empty;
Roi previous = roi.PreviousRoi;
int maskLevel = 0;
while (previous != null && maskLevel++ < 3)
{
if (!previous.Detected)
{
previousFailed = true;
return Event.RoiDetectionPreviousFailed;
}
masks += string.Format(" -m {0} {1} {2} {3}", previous.RoiX.Val, previous.RoiY.Val,
previous.RoiWid.Val, previous.RoiHgh.Val);
previous = previous.PreviousRoi;
}
command = string.Format("clp/RoiDetection{0}{1}{2}{3}{4} {5}",
masks,
string.Format(roiCfg.LoadImages ? " -l {0}" : " -n {0}", roiCfg.DetectionImagesCount),
roiCfg.SaveImages ? " -s -jpg" : "",
string.Format(" -p1 {0}", roiCfg.DetectionPeriod1),
string.Format(" -p2 {0}", roiCfg.DetectionPeriod2),
roiCfg.RoiParams);
//
// Send (or enqueue) command
//
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.CLEAR_RESPONSE));
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, command));
roiDetectionCommandSent = true;
}
return Event.CameraBusy;
}
else if (passed)
{
if (transferringDetectedImage)
{
/// ROI detection passed and image transfer is in progress
return Event.RoiDetectionPassed;
}
else if (0 == camera.TransferFileViaScp("detected.jpg", imgFileNamePrefix + "detected.jpg"))
{
/// File transfer successfully started
transferringDetectedImage = true;
return Event.RoiDetectionPassed;
}
else
{
/// Wait until the previous image transfer completes
return Event.CameraBusy;
}
}
else if (failed)
{
/// ROI detection failed, there in no image to transfer
return Event.RoiDetectionFailed;
}
else if (previousFailed)
{
return Event.RoiDetectionPreviousFailed;
}
else if (response != null)
{
int from = response.IndexOf('[');
int to = response.IndexOf(']');
if (!response.Contains("RESULT=0\r\n") || from < 0 || to < 0 || to < from)
{
roi.ClearRoi();
failed = true;
return Event.RoiDetectionFailed;
}
else
{
string oroiStr = response.Substring(from + 1, to - from - 1);
string[] terms = oroiStr.Split(new char[] { ',' });
int x, y, w, h;
if (terms.Length != 5 || !int.TryParse(terms[0], out x) || !int.TryParse(terms[1], out y)
|| !int.TryParse(terms[2], out w) || !int.TryParse(terms[3], out h))
{
roi.ClearRoi();
failed = true;
return Event.RoiDetectionFailed;
}
else
{
roi.SetRoi(x, y, w, h);
passed = true;
///
/// Start the file transfer
///
if (0 == camera.TransferFileViaScp("detected.jpg", imgFileNamePrefix + "detected.jpg"))
{
/// File transfer successfully started
transferringDetectedImage = true;
return Event.RoiDetectionPassed;
}
else
{
return Event.CameraBusy; /// File transfer not started yet
}
}
}
}
else
{
return Event.CameraBusy;
}
}
public void Stop()
{
}
}
}