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 @@ +