diff --git a/TBF/Rig/GenericDevices/ICamera.cs b/TBF/Rig/GenericDevices/ICamera.cs
index 509c0cd7d..0d2891af9 100644
--- a/TBF/Rig/GenericDevices/ICamera.cs
+++ b/TBF/Rig/GenericDevices/ICamera.cs
@@ -1,5 +1,5 @@
///
-/// Copyright (c) 2017 Sensus Slovensko a.s.
+/// Copyright (c) 2017-2022 Sensus Slovensko a.s.
///
using Common;
@@ -13,6 +13,10 @@ namespace TBF.Rig.GenericDevices
int GetResult(int roiHandle, out long timeMs); /// returns result for a registered ROI and camera time in ms
+ bool ShowOverlayRect { set; }
+ System.Drawing.Rectangle OverlayRect { set; }
+ int OverlayThickness { set; }
+
///
/// Display live image.
///
diff --git a/TBF/Rig/Network/Camera/CLP1611/Camera.cs b/TBF/Rig/Network/Camera/CLP1611/Camera.cs
index c31c7d610..1527e36c7 100644
--- a/TBF/Rig/Network/Camera/CLP1611/Camera.cs
+++ b/TBF/Rig/Network/Camera/CLP1611/Camera.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
@@ -69,6 +70,15 @@ namespace TBF.Rig.Network.Camera.CLP1611
public bool Running { get { return running; } }
bool running;
+ public bool ShowOverlayRect { set { showOverlayRect = value; } }
+ bool showOverlayRect = false;
+
+ public Rectangle OverlayRect { set { overlayRect = value; } }
+ Rectangle overlayRect;
+
+ public int OverlayThickness { set { overlayThickness = value; } }
+ int overlayThickness;
+
public int CameraIdx { get { return cameraIdx; } }
int cameraIdx;
///
@@ -210,12 +220,12 @@ namespace TBF.Rig.Network.Camera.CLP1611
Telnet.Enqueue(new Telnet.Command(Network.Telnet.CmdAction.CLEAR_RESPONSE));
Telnet.Enqueue(new Telnet.Command(Network.Telnet.CmdAction.SEND_COMMAND, "sha1sum clp/*"));
- log.FatalFormat("'{0}' with address {1} detected, IP = {2}, SD = {3}", Name, CameraCfg.HardwareAddress, ipAddress, sdCardVer);
+ log.FatalFormat("'{0}' detected: Id={1} addr={2} IP={3} SD={4}", Name, CameraIdx, CameraCfg.HardwareAddress, ipAddress, sdCardVer);
}
else
{
UiBridge.Bridge.OnCameraInfo(this.cameraIdx, string.Format("{0} s/n {1} was not detected", Name, CameraCfg.HardwareAddress));
- log.FatalFormat("'{0}' with address {1} not detected", Name, CameraCfg.HardwareAddress);
+ log.FatalFormat("'{0}' NOT detected: Id={1} addr={2}", Name, CameraIdx, CameraCfg.HardwareAddress);
}
}
@@ -464,37 +474,37 @@ namespace TBF.Rig.Network.Camera.CLP1611
FileInfo[] fileInfos = dirInfo.GetFiles();
foreach (FileInfo fi in fileInfos)
{
- lock (fileUploadLock)
- {
- FileStream fs = fi.Open(FileMode.Open);
- fs.Position = 0;
- byte[] sha1 = sha1calculator.ComputeHash(fs);
- fs.Close();
+ //lock (fileUploadLock)
+ //{
+ // FileStream fs = fi.Open(FileMode.Open);
+ // fs.Position = 0;
+ // byte[] sha1 = sha1calculator.ComputeHash(fs);
+ // fs.Close();
- sha1str.Clear();
- foreach (var b in sha1) sha1str.Append(b.ToString("x2"));
+ // sha1str.Clear();
+ // foreach (var b in sha1) sha1str.Append(b.ToString("x2"));
- if (!sha1sumResponse.Contains(string.Format("{0} clp/{1}", sha1str, fi.Name)))
- {
- /// Copy a file to the camera if SHA1 sum is different of the file is missing
- log.InfoFormat("{0}, IP={1}, Uploading file {2}", Name, IPAddress, fi.Name);
- scpClient.Upload(fi, string.Format("~/clp/{0}", fi.Name));
- }
- }
+ // if (!sha1sumResponse.Contains(string.Format("{0} clp/{1}", sha1str, fi.Name)))
+ // {
+ // /// Copy a file to the camera if SHA1 sum is different of the file is missing
+ // log.InfoFormat("{0}, IP={1}, Uploading file {2}", Name, IPAddress, fi.Name);
+ // scpClient.Upload(fi, string.Format("~/clp/{0}", fi.Name));
+ // }
+ //}
- if (!sha1sumResponse.Contains(fi.Name))
- {
- /// Change file properties if it was a new file
- string command = string.Format("chmod 755 ~/clp/{0}", fi.Name);
- log.InfoFormat("{0}, IP={1}, Executing command '{2}'", Name, IPAddress, command);
- sshClient.CreateCommand(command).Execute();
+ //if (!sha1sumResponse.Contains(fi.Name))
+ //{
+ // /// Change file properties if it was a new file
+ // string command = string.Format("chmod 755 ~/clp/{0}", fi.Name);
+ // log.InfoFormat("{0}, IP={1}, Executing command '{2}'", Name, IPAddress, command);
+ // sshClient.CreateCommand(command).Execute();
- //if (fi.Name.Equals("runmeonce"))
- //{
- // log.InfoFormat("{0}, IP={1}, Executing command 'sudo clp/runmeonce'", Name, IPAddress);
- // sshClient.CreateCommand("sudo clp/runmeonce").Execute();
- //}
- }
+ // //if (fi.Name.Equals("runmeonce"))
+ // //{
+ // // log.InfoFormat("{0}, IP={1}, Executing command 'sudo clp/runmeonce'", Name, IPAddress);
+ // // sshClient.CreateCommand("sudo clp/runmeonce").Execute();
+ // //}
+ //}
}
}
}
@@ -588,6 +598,8 @@ namespace TBF.Rig.Network.Camera.CLP1611
{
JpegFrame jpegFrame = new JpegFrame();
bool synced = false;
+ int penWidth = 1;
+ Pen pen = new Pen(Color.Green, penWidth);
while (!stopRtpListenerFlag)
{
@@ -606,7 +618,20 @@ namespace TBF.Rig.Network.Camera.CLP1611
switch (jpegFrame.AddPacket(newPacket))
{
case RtpFrame.STATE.Complete:
- UiBridge.Bridge.OnImage(this.cameraIdx, jpegFrame.ToImage());
+ Image image = jpegFrame.ToImage();
+ if (showOverlayRect && overlayRect != null && overlayThickness > 0)
+ {
+ using (var grph = Graphics.FromImage(image))
+ {
+ if (penWidth != overlayThickness)
+ {
+ penWidth = overlayThickness;
+ pen = new Pen(Color.Green, penWidth);
+ }
+ grph.DrawRectangle(pen, overlayRect);
+ }
+ }
+ UiBridge.Bridge.OnImage(this.cameraIdx, image);
jpegFrame.Clear();
break;
case RtpFrame.STATE.Error:
diff --git a/TBF/Rig/TestMethods/LiveStream/Component.cs b/TBF/Rig/TestMethods/LiveStream/Component.cs
index 63d888700..f495a431d 100644
--- a/TBF/Rig/TestMethods/LiveStream/Component.cs
+++ b/TBF/Rig/TestMethods/LiveStream/Component.cs
@@ -35,7 +35,7 @@ namespace TBF.Rig.TestMethods.LiveStream
public IList Execute(Test test, int idummy, bool bdummy)
{
- return (new LiveStreamSeq()).Execute(test, myCfg.HiResolution);
+ return (new LiveStreamSeq()).Execute(test, myCfg);
}
}
}
diff --git a/TBF/Rig/TestMethods/LiveStream/LiveStreamCfg.cs b/TBF/Rig/TestMethods/LiveStream/LiveStreamCfg.cs
index a6c57907d..8a28e6b8a 100644
--- a/TBF/Rig/TestMethods/LiveStream/LiveStreamCfg.cs
+++ b/TBF/Rig/TestMethods/LiveStream/LiveStreamCfg.cs
@@ -1,10 +1,11 @@
///
-/// Copyright (c) 2017 Sensus Metering Systems
+/// Copyright (c) 2017-2022 Sensus Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
-using System.IO;
using System.Xml.Serialization;
+using Common;
+using Config.Entities;
using TBF.Rig.Generic;
using TBF.Resources;
@@ -17,17 +18,30 @@ namespace TBF.Rig.TestMethods.LiveStream
public IComponentCfgCtrl GetControl(IList cmpntEntities) { return new CfgCtrl(); }
-
+ /// Serialized parameters
public bool HiResolution;
+ /// Test parameters
+ [XmlIgnore]
+ public TestParams TestParams;
+ public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; }
+ public override IParamsProvider CreateTestParamsProvider() { return new TestParams(true); }
+ public override IParamsProvider GetUITestParamsProvider(Test test)
+ {
+ return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
+ }
+
/// Private parameterless constructor invoked by all other (public) constructors
- LiveStreamCfg() {}
+ LiveStreamCfg()
+ {
+ TestParams = new TestParams(true);
+ }
public LiveStreamCfg(IComponentFactory factory, string name)
: this()
{
- this.Factory = factory;
+ Factory = factory;
Name = name;
ParentName = string.Empty;
HiResolution = false;
diff --git a/TBF/Rig/TestMethods/LiveStream/LiveStreamSeq.cs b/TBF/Rig/TestMethods/LiveStream/LiveStreamSeq.cs
index ed07aaead..ca9f1c43a 100644
--- a/TBF/Rig/TestMethods/LiveStream/LiveStreamSeq.cs
+++ b/TBF/Rig/TestMethods/LiveStream/LiveStreamSeq.cs
@@ -1,5 +1,5 @@
///
-/// Copyright (c) 2017 Sensus Metering Systems
+/// Copyright (c) 2017-2022 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using log4net;
@@ -14,7 +14,7 @@ namespace TBF.Rig.TestMethods.LiveStream
private static readonly ILog log = LogManager.GetLogger(typeof(LiveStreamSeq));
- public IList Execute(Test test, bool hiResolution)
+ public IList Execute(Test test, LiveStreamCfg cfg)
{
IList e = new List(); /// Events from currently running operations
Event retVal = Event.Done;
@@ -32,8 +32,17 @@ namespace TBF.Rig.TestMethods.LiveStream
GenericDevices.ICamera camera = (rr as GenericDevices.IRegReaderStillCamera).Camera;
if (!cameras.Contains(camera))
{
+ if (cfg.TestParams != null && cfg.TestParams.ShowOverlayRect)
+ {
+ camera.ShowOverlayRect = true;
+ camera.OverlayRect = new System.Drawing.Rectangle(cfg.TestParams.OverlayLeft,
+ cfg.TestParams.OverlayTop,
+ cfg.TestParams.OverlayWidth,
+ cfg.TestParams.OverlayHeight);
+ camera.OverlayThickness = cfg.TestParams.OverlayThickness;
+ }
cameras.Add(camera);
- liveStreamOps.Add(camera.LiveStreamOp(hiResolution));
+ liveStreamOps.Add(camera.LiveStreamOp(cfg.HiResolution));
}
}
}
@@ -57,6 +66,15 @@ namespace TBF.Rig.TestMethods.LiveStream
}
while (!e.Contains(Event.OK));
+ /// Turn the overlay in live images off
+ foreach (var rr in sensPath.RegisterReaders)
+ {
+ if (rr is GenericDevices.IRegReaderStillCamera)
+ {
+ (rr as GenericDevices.IRegReaderStillCamera).Camera.ShowOverlayRect = false;
+ }
+ }
+
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, 1, Progress.Completed));
return new List { retVal };
}
diff --git a/TBF/Rig/TestMethods/LiveStream/TestParams.cs b/TBF/Rig/TestMethods/LiveStream/TestParams.cs
new file mode 100644
index 000000000..54bf5207c
--- /dev/null
+++ b/TBF/Rig/TestMethods/LiveStream/TestParams.cs
@@ -0,0 +1,162 @@
+///
+/// Copyright (c) 2022 Sensus Slovensko a.s.
+///
+using System;
+using System.IO;
+using System.Text;
+using System.Xml.Serialization;
+using Common;
+using Config.Entities;
+using TBF.Rig.Generic;
+using TBF.Rig.Sequences;
+using TBF.Resources;
+
+namespace TBF.Rig.TestMethods.LiveStream
+{
+ public class TestParams : TestParamsBase, IParamsProvider, ITestParams
+ {
+ public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestParams) })[0];
+ public override XmlSerializer GetSerializer() { return Serializer; }
+
+ public bool ShowOverlayRect;
+ public int OverlayLeft;
+ public int OverlayTop;
+ public int OverlayWidth;
+ public int OverlayHeight;
+ public int OverlayThickness;
+
+ public override void InitializeAll()
+ {
+ ShowOverlayRect = false;
+ OverlayLeft = 0;
+ OverlayTop = 0;
+ OverlayWidth = 0;
+ OverlayHeight = 0;
+ OverlayThickness = 2;
+ }
+
+
+ string[] paramNames = new string[]
+ {
+ "Show overlay rectangle",
+ "Left",
+ "Top",
+ "Width",
+ "Height",
+ "Thickness",
+ };
+ public override string ParamName(int i) { return paramNames[i]; }
+ public override int ParamsCount() { return paramNames.Length; }
+
+ public override string ToString(int i)
+ {
+ switch (i)
+ {
+ case 0: return ShowOverlayRect ? Strings.yes : Strings.no;
+ case 1: return OverlayLeft.ToString();
+ case 2: return OverlayTop.ToString();
+ case 3: return OverlayWidth.ToString();
+ case 4: return OverlayHeight.ToString();
+ case 5: return OverlayThickness.ToString();
+ default: return string.Empty;
+ }
+ }
+
+ public CfgUpdateFlags UpdateParam(int i, string str)
+ {
+ switch (i)
+ {
+ case 0: ShowOverlayRect = (str == Strings.yes); return CfgUpdateFlags.None;
+ case 1: OverlayLeft = int.Parse(str); return CfgUpdateFlags.None;
+ case 2: OverlayTop = int.Parse(str); return CfgUpdateFlags.None;
+ case 3: OverlayWidth = int.Parse(str); return CfgUpdateFlags.None;
+ case 4: OverlayHeight = int.Parse(str); return CfgUpdateFlags.None;
+ case 5: OverlayThickness = int.Parse(str); return CfgUpdateFlags.None;
+ default:
+ return CfgUpdateFlags.None;
+ }
+ }
+
+ public bool ValidateParam(int i, string str, out string message)
+ {
+ message = string.Empty;
+ int ival;
+
+ switch (i)
+ {
+ case 0:
+ if (str == Strings.yes || str == Strings.no) return true;
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ if (int.TryParse(str, out ival) && ival >= 0) return true;
+ break;
+
+ default:
+ message = "Invalid index";
+ return false;
+ }
+
+ message = ParamName(i) + " is invalid";
+ return false;
+ }
+
+ void CopyContentTo(TestParams prms)
+ {
+ prms.ShowOverlayRect = ShowOverlayRect;
+ prms.OverlayLeft = OverlayLeft;
+ prms.OverlayTop = OverlayTop;
+ prms.OverlayWidth = OverlayWidth;
+ prms.OverlayHeight = OverlayHeight;
+ prms.OverlayThickness = OverlayThickness;
+ }
+
+ public IParamsProvider Clone()
+ {
+ TestParams pars = new TestParams();
+ CopyContentTo(pars);
+ return pars;
+ }
+
+ public override void UpdateFromDbEntity(ComponentTest dbEntity)
+ {
+ if (dbEntity == null) return;
+ try
+ {
+ TestParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as TestParams;
+
+ testParamsEntity = dbEntity;
+ componentName = dbEntity.CmpntName;
+ test = dbEntity.Test;
+
+ if (tmp != null) tmp.CopyContentTo(this);
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// Parameterless constructor initializes the parameters
+ ///
+ public TestParams()
+ {
+ }
+
+ public TestParams(bool initialize)
+ {
+ if (initialize) InitializeAll();
+ }
+
+ public TestParams(ComponentTest testParamsEntity, string componentName, Test test)
+ {
+ this.testParamsEntity = testParamsEntity;
+ this.componentName = componentName;
+ this.test = test;
+ }
+ }
+}
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index 52138c75d..958c51e01 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -1630,6 +1630,7 @@
+