Add support for CJMS11 camera integration
Introduced the CJMS11 camera component and its factory in TbfComponents. Added implementation for the CJMS11 camera class, along with unit tests to validate its functionality and integration. This enhances existing camera support in the system.
This commit is contained in:
parent
a20b0761fd
commit
891795b101
@ -1,18 +1,29 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AComponent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003F1c_003F3d03a130_003FComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AContainerControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003Fb3_003F54768651_003FContainerControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003F01_003F35d9c974_003FControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F6e_003Fc16f1098_003FIList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AImage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1af41839925b4409b823837d7b5f29d691940_003Fcc_003Fba3dfabe_003FImage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F92_003Fe3eb9ff2_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATcpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003Fdb_003Fe9bb8972_003FTcpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATestMethodInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4472e9d6a19b4c92bcc9a80bd60ca17d26da8_003F98_003F3ffb6d31_003FTestMethodInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUdpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003Fdb_003Fe89b26d3_003FUdpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUserControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003Fc3_003F7d8608ff_003FUserControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/ShowAdvancedOptions/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/TestProjectMapping/=743DF7DB_002DC7B6_002D42EB_002D986D_002D0F485E5588E4/@EntryIndexedValue">77EB589F-C670-4489-AAD6-2A3C02061FD1</s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/TestProjectMapping/=8648FD92_002DCDA1_002D4C3A_002DB5F9_002DFE547CE1FA48/@EntryIndexedValue">77EB589F-C670-4489-AAD6-2A3C02061FD1</s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/TestTemplateMapping/=MSTest/@EntryIndexedValue">d6790ab7-33c2-4425-b2c9-51480cd1a852</s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=311ca613_002Da634_002D4e0f_002Db9fb_002D4b7af9b7abb2/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" Name="GetCorrection" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=311ca613_002Da634_002D4e0f_002Db9fb_002D4b7af9b7abb2/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="GetCorrection" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<TestAncestor>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Entities.MeasurementCorrectionTest.GetCorrection</TestId>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Rig.Modbus.Meret.AdjustableScale.AdjustableMeterTest.GetCorrection</TestId>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Rig.Network.Camera.KeyenceIV3G120.CameraTest.RtpListener</TestId>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Rig.Network.Camera.KeyenceIV3G120.CameraTest.Initialize</TestId>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Rig.Network.Camera.CJMS11.CameraTest.Initialize</TestId>
|
||||
</TestAncestor>
|
||||
</SessionState></s:String>
|
||||
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=fee81c72_002D0b13_002D439c_002D8921_002D12878bb8cd86/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="Initialize" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=fee81c72_002D0b13_002D439c_002D8921_002D12878bb8cd86/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" Name="Initialize" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<TestAncestor>
|
||||
<TestId>MSTest::77EB589F-C670-4489-AAD6-2A3C02061FD1::.NETFramework,Version=v4.7.2::TBFTests.Rig.Network.Camera.KeyenceIV3G120.CameraTest.Initialize</TestId>
|
||||
</TestAncestor>
|
||||
@ -22,17 +33,21 @@
|
||||
|
||||
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=Miscellaneous_0020Files_002FWyqupug/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FResources_002FStrings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FResources_002FStrings/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FDataEntry_002FStandartCameraPurchaseOrder_002FCycleBeginningForm/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FDataEntry_002FStandartCameraPurchaseOrder_002FCycleEndForm/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FDataEntry_002FStandartCameraPurchaseOrder_002FCycleEndForm/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FDataEntry_002FStandartCameraPurchaseOrder_002FTestStartEndForm/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FAdapterFTP_002FNetadapterCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FKeyenceIV3G120_002FCameraCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FRoiForFixedStartKeyence_002FRoiCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FAdapterFTP_002FNetadapterCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FCJMS11_002FCameraCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FCJMS11_002FTerminalDlg/@EntryIndexedValue">False</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FRestAPI_002FRestApiCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FKeyenceIV3G120_002FCameraCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FRoiForFixedStartCJMS11_002FRoiCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FCamera_002FRoiForFixedStartKeyence_002FRoiCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FNetwork_002FRestAPI_002FRestApiCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FOutput_002FPrinters_002FGroupPrinting_002FSingle_002FPrinterCfgCtrl/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FOutput_002FPrinters_002FGroupPrinting_002FSingle_002FPrinterTestBenchComponentSelectorDlg/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FOutput_002FPrinters_002FGroupPrinting_002FSingle_002FPrinterTestBenchComponentSelectorDlg/@EntryIndexedValue">False</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FRig_002FRegisterReaders_002FFrequencyMeterFromUniCB_002FRRCfgCtrl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=TBF_002FUI_002FBench_002FComponents_002FComponentsManagerDlg/@EntryIndexedValue">False</s:Boolean>
|
||||
|
||||
999
TBF/Rig/Network/Camera/CJMS11/Camera.cs
Normal file
999
TBF/Rig/Network/Camera/CJMS11/Camera.cs
Normal file
@ -0,0 +1,999 @@
|
||||
///
|
||||
/// Copyright (c) 2017-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Renci.SshNet;
|
||||
using Common;
|
||||
using TBF.Rig.Network.Telnet;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Network.Camera.CJMS11.POJO;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
/// <summary>
|
||||
/// This class implements: (1) Camera device, (2) Measurement operation
|
||||
/// </summary>
|
||||
public class Camera : ComponentBase, GenericDevices.ICamera, Generic.IDevice, IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Camera));
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}: Name={1}, Addr={2}, IP={3}, s/n={4}, SD={5}",
|
||||
this.GetType().Namespace.Substring(8),
|
||||
CameraCfg.Name,
|
||||
CameraCfg.HardwareAddress,
|
||||
CameraCfg.DebugLevel == DebugMode.Simulate ? "simulated" : ((ipAddress == null) ? "not detected" : ipAddress.ToString()),
|
||||
CameraCfg.DebugLevel == DebugMode.Simulate ? "simulated" : (string.IsNullOrEmpty(cpuSerialNr) ? "not detected" : cpuSerialNr),
|
||||
CameraCfg.DebugLevel == DebugMode.Simulate ? "simulated" : (string.IsNullOrEmpty(sdCardVer) ? "not detected" : sdCardVer));
|
||||
}
|
||||
|
||||
|
||||
private const int iPort = 32456;
|
||||
string ClpUserName = string.Empty; /// Either "tbf" or "pi" after a successful detection
|
||||
const string ClpPassword = "C1ern4V0d4";
|
||||
|
||||
private static Object fileUploadLock = new Object();
|
||||
|
||||
|
||||
///
|
||||
/// Properties
|
||||
///
|
||||
public readonly CameraCfg CameraCfg;
|
||||
public readonly GenericDevices.INetworkAdapter NetAdapter;
|
||||
|
||||
public IPAddress IPAddress { get { return ipAddress; } }
|
||||
IPAddress ipAddress;
|
||||
|
||||
public string CpuHardware { get { return cpuHardware; } }
|
||||
string cpuHardware;
|
||||
|
||||
public string CpuRevision { get { return cpuRevision; } }
|
||||
string cpuRevision;
|
||||
|
||||
public string CpuSerialNr { get { return cpuSerialNr; } }
|
||||
string cpuSerialNr;
|
||||
|
||||
public string SDCardVer { get { return sdCardVer; } }
|
||||
string sdCardVer;
|
||||
|
||||
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;
|
||||
///
|
||||
static int nextCameraIdx = 0;
|
||||
|
||||
static int GetCameraIdx()
|
||||
{
|
||||
return 2;
|
||||
} //nextCameraIdx++; } /// Used in Initialize()
|
||||
|
||||
///
|
||||
/// Telnet support
|
||||
///
|
||||
const string TelnetPrompt = "$ ";
|
||||
const bool TelnetSkipFirstLine = true;
|
||||
public Telnet.TelnetClient Telnet;
|
||||
private TerminalDlg terminalDlg;
|
||||
string sha1sumResponse;
|
||||
bool sha1sumResponseProcessed;
|
||||
|
||||
///
|
||||
/// scp support
|
||||
///
|
||||
Thread scpThread;
|
||||
PasswordConnectionInfo connectionInfo;
|
||||
bool scpConnected;
|
||||
bool stopScpThreadFlag;
|
||||
string scpRemoteFileName; /// Camera file name
|
||||
string scpLocalFileName; /// Local PC file name
|
||||
enum ScpCommand
|
||||
{
|
||||
None,
|
||||
Get,
|
||||
Put,
|
||||
}
|
||||
ScpCommand scpCommand;
|
||||
|
||||
|
||||
const int UdpPortBase = 20000; /// Port base for all UDP protocols
|
||||
|
||||
///
|
||||
/// MJpeg RTP protocol support
|
||||
///
|
||||
int rtpTcpLocalPort;
|
||||
TcpClient rtpTcpClient;
|
||||
Thread rtpListenerThread;
|
||||
NetworkStream rtpStream = null;
|
||||
StreamReader rtpReader = null;
|
||||
static bool stopRtpListenerFlag;
|
||||
|
||||
///
|
||||
/// RTCP protocol (reserved)
|
||||
///
|
||||
int rtcpUdpLocalPort;
|
||||
|
||||
///
|
||||
/// Measurement results protocol
|
||||
///
|
||||
int msrmntUdpLocalPort;
|
||||
UdpClient msrmntUdpClient; /// If != null msrmntListenerThread
|
||||
Thread msrmntListenerThread;
|
||||
static bool stopMsrmntListenerFlag;
|
||||
|
||||
|
||||
///
|
||||
/// ROI related parameters
|
||||
///
|
||||
RoisAndResults roisAndResults;
|
||||
///
|
||||
public void ClearRoiParams() { roisAndResults.ClearRoiParams(); }
|
||||
public int RegisterRoi(string roiParams) { return roisAndResults.RegisterRoi(roiParams); }
|
||||
public int GetResult(int roiHandle, out long timeMs) { return roisAndResults.GetResult(roiHandle, out timeMs); }
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
cameraIdx = GetCameraIdx();
|
||||
|
||||
running = false;
|
||||
Telnet = null;
|
||||
terminalDlg = null;
|
||||
roisAndResults = new RoisAndResults(); /// object for measurement results, writes/reads to/from this object are locked
|
||||
|
||||
// if (CameraCfg.DebugLevel == DebugMode.Simulate)
|
||||
// {
|
||||
// UiBridge.Bridge.OnCameraInfo(cameraIdx, string.Format("{0} s/n {1} si simulated", Name, CameraCfg.HardwareAddress));
|
||||
// return;
|
||||
// }
|
||||
|
||||
/// Detect a camera
|
||||
bool cameraDetected = DetectJMSCamera(CameraCfg.HardwareAddress % 100, ref ipAddress, true,
|
||||
out cpuHardware, out cpuRevision, out cpuSerialNr, out sdCardVer);
|
||||
|
||||
if (CameraCfg.DebugLevel == DebugMode.AutoDetect)
|
||||
{
|
||||
CameraCfg.DebugLevel = cameraDetected ? DebugMode.DetectedOn : DebugMode.DetectedOff;
|
||||
}
|
||||
else if (!cameraDetected)
|
||||
{
|
||||
throw new Exception(string.Format("{0}={1}", Strings.Address, CameraCfg.HardwareAddress));
|
||||
}
|
||||
|
||||
if (cameraDetected)
|
||||
{
|
||||
UiBridge.Bridge.OnCameraInfo(cameraIdx, string.Format("{0} ver.{1} {2} s/n {3}", Name, sdCardVer, ipAddress, CameraCfg.HardwareAddress));
|
||||
|
||||
ClpUserName = (sdCardVer.Length > 0 && sdCardVer[0] == '1') ? "tbf" : "pi";
|
||||
|
||||
StartRtpListener(IPAddress, iPort);
|
||||
StartMsrmntListener(IPAddress, msrmntUdpLocalPort);
|
||||
|
||||
connectionInfo = new PasswordConnectionInfo(IPAddress.ToString(), ClpUserName, ClpPassword);
|
||||
|
||||
/// Open telnet clint and start the log-in process
|
||||
Telnet = new Telnet.TelnetClient(this, CameraCfg.Name, ClpUserName, ClpPassword, TelnetPrompt, TelnetSkipFirstLine, CameraCfg.DisplayTerminal);
|
||||
|
||||
Telnet.promptReceivedHandler += delegate(object sndr, PromptReceivedEventArgs a)
|
||||
{
|
||||
OnPromptReceived(sndr, a);
|
||||
};
|
||||
|
||||
if (CameraCfg.DisplayTerminal)
|
||||
{
|
||||
terminalDlg = new TerminalDlg(CameraCfg.Name, Telnet);
|
||||
terminalDlg.Show();
|
||||
}
|
||||
|
||||
Telnet.Enqueue(new Telnet.Command(Network.Telnet.CmdAction.CONNECT, ipAddress.ToString(), 10, 30));
|
||||
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}' 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}' NOT detected: Id={1} addr={2}", Name, CameraIdx, CameraCfg.HardwareAddress);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDevice()
|
||||
{
|
||||
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
|
||||
{
|
||||
running = false;
|
||||
|
||||
stopScpThreadFlag = true;
|
||||
stopRtpListenerFlag = true;
|
||||
stopMsrmntListenerFlag = true;
|
||||
|
||||
if (Telnet != null)
|
||||
{
|
||||
Telnet.Dispose();
|
||||
Telnet = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDevice2()
|
||||
{
|
||||
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
|
||||
{
|
||||
if (scpThread != null && scpThread.IsAlive) scpThread.Join(50);
|
||||
if (rtpListenerThread != null) rtpListenerThread.Join(50);
|
||||
if (msrmntListenerThread != null) msrmntListenerThread.Join(50);
|
||||
|
||||
if (rtpTcpClient != null)
|
||||
{
|
||||
rtpTcpClient.Close();
|
||||
rtpTcpClient = null;
|
||||
}
|
||||
|
||||
if (msrmntUdpClient != null)
|
||||
{
|
||||
msrmntUdpClient.Close();
|
||||
msrmntUdpClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
|
||||
{
|
||||
if (sha1sumResponse != null && !sha1sumResponseProcessed)
|
||||
{
|
||||
scpThread = new Thread(new ThreadStart(ScpWorker));
|
||||
scpThread.Start();
|
||||
|
||||
sha1sumResponseProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void RunDeviceAfter() { }
|
||||
|
||||
|
||||
void OnPromptReceived(object sndr, PromptReceivedEventArgs a)
|
||||
{
|
||||
if (sha1sumResponse == null)
|
||||
{
|
||||
sha1sumResponse = a.Response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||
{
|
||||
if (CfgChangeHandler == null) return;
|
||||
try { CfgChangeHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||
|
||||
public override void StartChangeHandler()
|
||||
{
|
||||
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||
{
|
||||
CameraCfg tmpcfg = args.Cfg as CameraCfg;
|
||||
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
|
||||
{
|
||||
if (args.Command == CfgChangeCmd.CfgChange)
|
||||
{
|
||||
CameraCfg.TestImagesMode = tmpcfg.TestImagesMode;
|
||||
CameraCfg.TestImagesCount = tmpcfg.TestImagesCount;
|
||||
CameraCfg.IPAddressCJMS = tmpcfg.IPAddressCJMS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Detect the camera with specified hardware address (DIP switches).
|
||||
/// Optionally set camera date and time.
|
||||
/// </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, ref IPAddress ipAddress, bool setDateTime, out string hardware, out string revision, out string serial, out string sdCardVer)
|
||||
{
|
||||
for (int trials = 1; trials <= 3; trials++)
|
||||
{
|
||||
UdpClient udpClient = new UdpClient();
|
||||
|
||||
try
|
||||
{
|
||||
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.Debug(msg);
|
||||
Console.WriteLine(msg);
|
||||
|
||||
return true; /// Camera detected
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Camera {0} with HWAddress={1} not detected : {2}", CameraCfg.Name, CameraCfg.HardwareAddress, exc.Message);
|
||||
}
|
||||
|
||||
udpClient.Close();
|
||||
}
|
||||
|
||||
ipAddress = null;
|
||||
hardware = null;
|
||||
revision = null;
|
||||
serial = null;
|
||||
sdCardVer = null;
|
||||
return false; /// No camera detected
|
||||
}
|
||||
|
||||
bool DetectJMSCamera(int hwAddress, ref IPAddress ipAddress, bool setDateTime, out string hardware, out string revision, out string serial, out string sdCardVer)
|
||||
{
|
||||
string command_CFG = "get_cfg";
|
||||
if (CameraCfg.IPAddressCJMS != null)
|
||||
{
|
||||
TcpClient tcpClient = new TcpClient();
|
||||
// Get network stream
|
||||
NetworkStream stream = null;
|
||||
StreamReader reader = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
tcpClient.Connect(CameraCfg.IPAddressCJMS, iPort);
|
||||
log.Debug(string.Format("Camera connected to server {0}:{1}.", CameraCfg.IPAddressCJMS, iPort));
|
||||
ipAddress = IPAddress.Parse(CameraCfg.IPAddressCJMS);
|
||||
// Get network stream
|
||||
stream = tcpClient.GetStream();
|
||||
stream.ReadTimeout = 1000;
|
||||
reader = new StreamReader(stream, Encoding.ASCII);
|
||||
|
||||
// Send command
|
||||
DateTime detectionStart = DateTime.Now;
|
||||
byte[] commandBytes = Encoding.ASCII.GetBytes(command_CFG);
|
||||
stream.Write(commandBytes, 0, commandBytes.Length);
|
||||
Console.WriteLine("Command sent.");
|
||||
|
||||
|
||||
string responseAnswer = "";
|
||||
try
|
||||
{
|
||||
int iReads = 0;
|
||||
while (true)
|
||||
{
|
||||
//get config
|
||||
responseAnswer = reader.ReadLine();
|
||||
log.Debug(string.Format("received from camera: {0}", responseAnswer));
|
||||
|
||||
|
||||
if (responseAnswer.Contains(command_CFG))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (iReads > 5)
|
||||
{
|
||||
log.Error($"Maximum Count of unexcepted answers excited!");
|
||||
break;
|
||||
}
|
||||
|
||||
iReads++;
|
||||
}
|
||||
}
|
||||
catch (IOException ioEx)
|
||||
{
|
||||
log.Error($"Timeout or IO error while reading from camera: {ioEx.Message}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error(string.Format("Error while reading from camera: {0}", e.Message));
|
||||
}
|
||||
|
||||
double duration_ms = (DateTime.Now - detectionStart).TotalMilliseconds;
|
||||
|
||||
hardware = string.Empty;
|
||||
revision = string.Empty;
|
||||
serial = string.Empty;
|
||||
sdCardVer = string.Empty;
|
||||
|
||||
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(),
|
||||
responseAnswer);
|
||||
log.Debug(msg);
|
||||
Console.WriteLine(msg);
|
||||
|
||||
return true; /// Camera detected
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Camera {0} with HWAddress={1} not detected : {2}", CameraCfg.Name,
|
||||
CameraCfg.HardwareAddress, exc.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Clean up
|
||||
if (reader != null)
|
||||
reader.Close();
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
if (tcpClient.Connected)
|
||||
tcpClient.Close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (CameraCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
ipAddress = null;
|
||||
hardware = null;
|
||||
revision = null;
|
||||
serial = null;
|
||||
sdCardVer = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
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 ScpWorker()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var scpClient = new ScpClient(connectionInfo))
|
||||
{
|
||||
scpClient.Connect();
|
||||
|
||||
DirectoryInfo dirInfo = null;
|
||||
if (sdCardVer.Length > 0)
|
||||
{
|
||||
switch (sdCardVer[0])
|
||||
{
|
||||
case '1':
|
||||
dirInfo = new DirectoryInfo(Path.Combine(System.Windows.Forms.Application.StartupPath, "CameraBinaryFiles"));
|
||||
break;
|
||||
case '2':
|
||||
dirInfo = new DirectoryInfo(Path.Combine(System.Windows.Forms.Application.StartupPath, "CameraBinaryFiles2"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirInfo != null)
|
||||
{
|
||||
///
|
||||
/// Synchronize files in camera /home/tbf/clp directory with the files in "TBF/CameraBinaryFiles" project folder
|
||||
///
|
||||
using (var sshClient = new SshClient(connectionInfo))
|
||||
{
|
||||
sshClient.Connect();
|
||||
|
||||
SHA1 sha1calculator = SHA1.Create();
|
||||
StringBuilder sha1str = new StringBuilder();
|
||||
|
||||
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();
|
||||
|
||||
// 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(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();
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scpConnected = scpClient.IsConnected;
|
||||
running = true;
|
||||
|
||||
///
|
||||
/// Run SCP command loop
|
||||
///
|
||||
while (scpConnected && !stopScpThreadFlag)
|
||||
{
|
||||
switch (scpCommand)
|
||||
{
|
||||
case ScpCommand.Get:
|
||||
scpCommand = ScpCommand.None;
|
||||
scpClient.Download(scpRemoteFileName, new System.IO.FileInfo(scpLocalFileName));
|
||||
break;
|
||||
|
||||
case ScpCommand.Put:
|
||||
scpCommand = ScpCommand.None;
|
||||
scpClient.Upload(new System.IO.FileInfo(scpLocalFileName), scpRemoteFileName);
|
||||
break;
|
||||
|
||||
default:
|
||||
Thread.Sleep(250);
|
||||
break;
|
||||
}
|
||||
|
||||
scpConnected = scpClient.IsConnected;
|
||||
}
|
||||
|
||||
running = false;
|
||||
scpClient.Disconnect();
|
||||
scpConnected = false;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat( "Exception in {0} ScpWorker(): {1}", Name, exc.Message);
|
||||
if (exc.InnerException != null)
|
||||
{
|
||||
log.ErrorFormat(" Inner exception: {0}", exc.InnerException.Message);
|
||||
}
|
||||
|
||||
scpConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download a file from the camera via SCP
|
||||
/// </summary>
|
||||
/// <param name="srcFileName"></param>
|
||||
/// <returns>0 (success), -1 (busy), -2 (no session)</returns>
|
||||
public int DownloadFile(string srcFileName, string dstFileName)
|
||||
{
|
||||
if (!scpConnected) return -2;
|
||||
if (scpCommand != ScpCommand.None) return -1;
|
||||
|
||||
scpRemoteFileName = srcFileName;
|
||||
scpLocalFileName = dstFileName;
|
||||
scpCommand = ScpCommand.Get;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upload a file to the camera via SCP
|
||||
/// </summary>
|
||||
/// <param name="srcFileName"></param>
|
||||
/// <returns>0 (success), -1 (busy), -2 (no session)</returns>
|
||||
public int UploadFile(string srcFileName, string dstFileName)
|
||||
{
|
||||
if (!scpConnected) return -2;
|
||||
if (scpCommand != ScpCommand.None) return -1;
|
||||
|
||||
scpLocalFileName = srcFileName;
|
||||
scpRemoteFileName = dstFileName;
|
||||
scpCommand = ScpCommand.Put;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// listener for multiple - repetetive image receiving
|
||||
/// </summary>
|
||||
/// <detail>
|
||||
/// method uses reader to receive data from camera
|
||||
/// </detail>
|
||||
/// <param name="localIP"></param>
|
||||
/// <param name="localPort"></param>
|
||||
|
||||
private void StartRtpListener(IPAddress localIP, int localPort)
|
||||
{
|
||||
rtpTcpClient = new TcpClient(new IPEndPoint(localIP, localPort));
|
||||
rtpListenerThread = new Thread(new ThreadStart(RtpListener));
|
||||
rtpListenerThread.Start();
|
||||
}
|
||||
|
||||
void RtpListener()
|
||||
{
|
||||
JpegFrame jpegFrame = new JpegFrame();
|
||||
bool synced = false;
|
||||
int penWidth = 1;
|
||||
Pen pen = new Pen(Color.Green, penWidth);
|
||||
|
||||
rtpStream = rtpTcpClient.GetStream();
|
||||
rtpStream.ReadTimeout = 1000;
|
||||
rtpReader = new StreamReader(rtpStream, Encoding.ASCII);
|
||||
|
||||
while (!stopRtpListenerFlag)
|
||||
{
|
||||
try
|
||||
{
|
||||
string responseAnswer = rtpReader.ReadLine();
|
||||
|
||||
if (responseAnswer.Length > 0)
|
||||
{
|
||||
/// Process the packet
|
||||
JmsPacket newPacket = new JmsPacket(responseAnswer);
|
||||
// if (synced)
|
||||
// {
|
||||
/// Sychronized: process the new packet
|
||||
switch (newPacket.JmsMessage.Command)
|
||||
{
|
||||
case CommandM.grab_image_:
|
||||
ParsedImage parsedImage = newPacket.JmsMessage.getImage();
|
||||
if (parsedImage.Encoding == ImageType.BASE_64)
|
||||
{
|
||||
Image image = parsedImage.Image;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case CommandM.close_:
|
||||
synced = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//}
|
||||
// else if (newPacket.Mark)
|
||||
// {
|
||||
// /// Synchronize when a packet with Mark occurs, process the next packet
|
||||
// jpegFrame.Clear();
|
||||
// synced = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// /// Stay unsynchronized
|
||||
// }
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
string msg = string.Format("Exception in MJpeg RTP listener thread: {0}", exc.Message);
|
||||
log.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void StartMsrmntListener(IPAddress localIP, int localPort)
|
||||
{
|
||||
msrmntUdpClient = new UdpClient(new IPEndPoint(localIP, localPort));
|
||||
msrmntListenerThread = new Thread(new ThreadStart(MsrmntListener));
|
||||
msrmntListenerThread.Start();
|
||||
}
|
||||
|
||||
void MsrmntListener()
|
||||
{
|
||||
StringBuilder toBeProcessed = new StringBuilder();
|
||||
int[] angles = new int[RoisAndResults.MaxRegisteredRois];
|
||||
|
||||
while (!stopMsrmntListenerFlag)
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint endpoint = null;
|
||||
Byte[] data = msrmntUdpClient.Receive(ref endpoint);
|
||||
|
||||
toBeProcessed.Append(Encoding.ASCII.GetString(data, 0, data.Length));
|
||||
log.DebugFormat("MeasurementUdpListener() ... toBeProcessed = {0}", toBeProcessed);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int from = toBeProcessed.ToString().IndexOf('[');
|
||||
if (from < 0) break;
|
||||
|
||||
int len = toBeProcessed.ToString(from + 1, toBeProcessed.Length - from - 1).IndexOf(']');
|
||||
if (len < 0) break;
|
||||
|
||||
string[] pulsesArr = toBeProcessed.ToString(from + 1, len).Split(new char[] { ';' });
|
||||
|
||||
bool fmtError = false;
|
||||
long timeMs;
|
||||
if ((pulsesArr.Length >= 2) &&
|
||||
(pulsesArr.Length <= RoisAndResults.MaxRegisteredRois + 1) &&
|
||||
long.TryParse(pulsesArr[0], out timeMs))
|
||||
{
|
||||
for (int i = 1; i < pulsesArr.Length; i++)
|
||||
{
|
||||
int val;
|
||||
if (int.TryParse(pulsesArr[i], out val))
|
||||
{
|
||||
angles[i - 1] = Math.Abs(val); /// TODO: pozerat CW/CCW a podla toho dat +/-
|
||||
}
|
||||
else
|
||||
{
|
||||
fmtError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fmtError) roisAndResults.SetResults(timeMs, angles);
|
||||
}
|
||||
|
||||
toBeProcessed.Remove(0, from + len + 2);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
string msg = string.Format("Exception in the measurement listener thread: {0}", exc.Message);
|
||||
log.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//public void OnMeasurementDataReceived(object sender, MeasuredDataEventArgs msrmtData)
|
||||
//{
|
||||
// string[] pulsesArr = msrmtData.MeasuredData.Split(new char[] { ';' });
|
||||
|
||||
// uint uiVal;
|
||||
// if (result != null && result.Length + 1 == pulsesArr.Length && uint.TryParse(pulsesArr[0], out uiVal))
|
||||
// {
|
||||
// cameraTimeMs = (long)uiVal;
|
||||
|
||||
// for (int i = 0; i < result.Length; i++)
|
||||
// {
|
||||
// int val;
|
||||
// if (int.TryParse(pulsesArr[i + 1], out val))
|
||||
// {
|
||||
// result[i] = Math.Abs(val);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
public IOperation LiveStreamOp(bool hiRes)
|
||||
{
|
||||
int wid = hiRes ? 1280 : 640;
|
||||
int hgh = hiRes ? 960 : 480;
|
||||
string command = string.Format("/opt/vc/bin/raspivid -t 0 -cd MJPEG -w {0} -h {1} -fps 30 -b 8000000 -o - | gst-launch-1.0 fdsrc ! \"image/jpeg,framerate=30/1\" ! jpegparse ! rtpjpegpay ! udpsink host={2} port={3}",
|
||||
wid, hgh, NetAdapter.IPAddress, rtpTcpLocalPort);
|
||||
//string command = string.Format("~/userland/build/bin/raspivid -t 0 -cd MJPEG -w {0} -h {1} -fps 30 -b 8000000 -o - | gst-launch-1.0 fdsrc ! \"image/jpeg,framerate=30/1\" ! jpegparse ! rtpjpegpay ! udpsink host={2} port={3}",
|
||||
// wid, hgh, NetAdapter.IPAddress, rtpUdpLocalPort);
|
||||
|
||||
return new LiveStreamOp(this, Telnet, command);
|
||||
}
|
||||
|
||||
|
||||
public IOperation GrabImagesOp(string[] imgFileNames, bool blackAndWhite, bool lowResolution, ImageRotation imageRotation)
|
||||
{
|
||||
return new GrabImagesOp(this, imgFileNames, blackAndWhite, lowResolution, imageRotation);
|
||||
}
|
||||
|
||||
|
||||
public IOperation MeasurementOp()
|
||||
{
|
||||
if (Telnet != null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
string command;
|
||||
bool measurementCommandSent;
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
/// Prepare the telent command
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i <= roisAndResults.RegisteredRoisCount; i++)
|
||||
{
|
||||
sb.Append(" ");
|
||||
sb.Append(roisAndResults.GetRoiParams(i));
|
||||
}
|
||||
|
||||
int logImagesArg;
|
||||
switch (CameraCfg.TestImagesMode)
|
||||
{
|
||||
default:
|
||||
case TestImagesMode.None:
|
||||
case TestImagesMode.LoadImages:
|
||||
logImagesArg = 0;
|
||||
break;
|
||||
case TestImagesMode.SaveFirstImages:
|
||||
logImagesArg = CameraCfg.TestImagesCount;
|
||||
break;
|
||||
case TestImagesMode.SaveLastImages:
|
||||
logImagesArg = -CameraCfg.TestImagesCount;
|
||||
break;
|
||||
}
|
||||
|
||||
command = string.Format("clp/Measurement -udp {0} {1}{2}{3} 1 7 0 0 {4}",
|
||||
NetAdapter.IPAddress,
|
||||
msrmntUdpLocalPort,
|
||||
(CameraCfg.TestImagesMode == TestImagesMode.LoadImages) ? (" -l " + CameraCfg.TestImagesCount.ToString()) : string.Empty,
|
||||
sb,
|
||||
logImagesArg);
|
||||
|
||||
measurementCommandSent = false;
|
||||
|
||||
/// If ready send (=enqueue) the command
|
||||
if (Telnet.State == TelnetClient.TelnetState.Inactive)
|
||||
{
|
||||
log.WarnFormat("{0} SEND_MSRMNT_CMD: {1}", Name, command);
|
||||
Telnet.Enqueue(new Telnet.Command(CmdAction.SEND_MSRMNT_CMD, command));
|
||||
measurementCommandSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Event Run()
|
||||
{
|
||||
if (!measurementCommandSent)
|
||||
{
|
||||
/// When ready send (=enqueue) the command
|
||||
if (Telnet.State == TelnetClient.TelnetState.Inactive)
|
||||
{
|
||||
log.WarnFormat("{0} SEND_MSRMNT_CMD: {1}", Name, command);
|
||||
Telnet.Enqueue(new Telnet.Command(CmdAction.SEND_MSRMNT_CMD, command));
|
||||
measurementCommandSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (measurementCommandSent)
|
||||
{
|
||||
log.WarnFormat("{0} SEND_COMMAND: CTRL-Q", Name);
|
||||
Telnet.Enqueue(new Telnet.Command(CmdAction.SEND_COMMAND, TelnetClient.Q_Command));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
TBF/Rig/Network/Camera/CJMS11/CameraCfg.cs
Normal file
74
TBF/Rig/Network/Camera/CJMS11/CameraCfg.cs
Normal file
@ -0,0 +1,74 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public enum TestImagesMode
|
||||
{
|
||||
None,
|
||||
SaveFirstImages,
|
||||
SaveLastImages,
|
||||
LoadImages,
|
||||
Count,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
public class CameraCfg : ComponentCfgBase, IChildComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(CameraCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new CameraCfgCtrl(); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public int HardwareAddress;
|
||||
public bool DisplayTerminal;
|
||||
|
||||
[XmlIgnore]
|
||||
public TestImagesMode TestImagesMode;
|
||||
|
||||
[XmlIgnore]
|
||||
public int TestImagesCount;
|
||||
|
||||
public string IPAddressCJMS;
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
CameraCfg() { }
|
||||
|
||||
public CameraCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = "Network.Adapter";
|
||||
HardwareAddress = 1;
|
||||
TestImagesMode = TestImagesMode.None;
|
||||
TestImagesCount = 3000;
|
||||
DebugLevel = DebugMode.AutoDetect;
|
||||
IPAddressCJMS = "192.168.1.100";
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, s/n={1}, Terminal={2}, TestImagesMode={3}, TestImagesCount={4}, Parent={5}, IPAddressCJMS={6}",
|
||||
Name,
|
||||
HardwareAddress,
|
||||
DisplayTerminal ? Strings.yes : Strings.no,
|
||||
TestImagesMode,
|
||||
TestImagesCount,
|
||||
ParentName,
|
||||
IPAddressCJMS);
|
||||
}
|
||||
}
|
||||
}
|
||||
276
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.cs
Normal file
276
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.cs
Normal file
@ -0,0 +1,276 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Castle.Components.DictionaryAdapter.Xml;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Network.Adapter;
|
||||
using TBF.UI.Bench.Components;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public partial class CameraCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger(typeof(CameraCfgCtrl));
|
||||
ComponentParametersDlg parent;
|
||||
|
||||
private bool isIPCalculated = false;
|
||||
|
||||
public bool ShowMore
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
CameraCfg config;
|
||||
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as CameraCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public CameraCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void PumpCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
Localize();
|
||||
|
||||
parent = ParentForm as ComponentParametersDlg;
|
||||
if (parent == null) return;
|
||||
|
||||
if (parent.CmpntEntities != null)
|
||||
{
|
||||
foreach (var cmpnt in parent.CmpntEntities)
|
||||
{
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Adapter.Factory)
|
||||
{
|
||||
parentNameComboBox.Items.Add(cmpnt.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TestImagesMode mode = 0; mode < TestImagesMode.Count; mode++)
|
||||
{
|
||||
testImagesModeComboBox.Items.Add(mode.ToString());
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void Localize()
|
||||
{
|
||||
nameLabel.Text = Strings.Name;
|
||||
parentNameLabel.Text = Strings.Parent_name;
|
||||
hwAddressLabel.Text = Strings.Serial_number;
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
|
||||
hwAddressTextBox.Text = config.HardwareAddress.ToString();
|
||||
displayTerminalCheckBox.Checked = config.DisplayTerminal;
|
||||
testImagesModeComboBox.Text = config.TestImagesMode.ToString();
|
||||
testImagesCountTextBox.Text = config.TestImagesCount.ToString();
|
||||
if (!(isIPCalculated && (config.IPAddressCJMS == null || config.IPAddressCJMS.Equals(""))))
|
||||
{
|
||||
ipAddressTextBox.Text = config.IPAddressCJMS;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
parentNameComboBox.Enabled = true;
|
||||
hwAddressTextBox.Enabled = true;
|
||||
displayTerminalCheckBox.Enabled = true;
|
||||
testImagesModeComboBox.Enabled = true;
|
||||
testImagesCountTextBox.Enabled = true;
|
||||
ipAddressTextBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, parentNameLabel.Text);
|
||||
}
|
||||
|
||||
if (!int.TryParse(hwAddressTextBox.Text, out dummy) || dummy % 100 > 63)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, hwAddressLabel.Text);
|
||||
}
|
||||
|
||||
TestImagesMode newTestImagesMode = TestImagesMode.Invalid;
|
||||
for (TestImagesMode mode = 0; mode < TestImagesMode.Count; mode++)
|
||||
{
|
||||
if (testImagesModeComboBox.Text == mode.ToString()) newTestImagesMode = mode;
|
||||
}
|
||||
|
||||
if (newTestImagesMode == TestImagesMode.Invalid)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, testImagesModeLabel.Text);
|
||||
}
|
||||
|
||||
if (!int.TryParse(testImagesCountTextBox.Text, out dummy) || dummy < 0 || dummy > 3000
|
||||
|| ((dummy == 0) && (newTestImagesMode != TestImagesMode.None)))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, testImagesCountLabel.Text);
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
string newParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
|
||||
int newHWAddress = int.Parse(hwAddressTextBox.Text);
|
||||
TestImagesMode newTestImagesMode = 0;
|
||||
for (TestImagesMode mode = 0; mode < TestImagesMode.Count; mode++)
|
||||
{
|
||||
if (testImagesModeComboBox.Text == mode.ToString()) newTestImagesMode = mode;
|
||||
}
|
||||
|
||||
int newTestImagesCount = int.Parse(testImagesCountTextBox.Text);
|
||||
|
||||
|
||||
if (config.Name != nameTextBox.Text ||
|
||||
config.ParentName != newParentName ||
|
||||
config.HardwareAddress != newHWAddress ||
|
||||
config.DisplayTerminal != displayTerminalCheckBox.Checked ||
|
||||
(config.IPAddressCJMS != ipAddressTextBox.Text && !ipAddressTextBox.Text.Contains("?"))
|
||||
)
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
config.ParentName = newParentName;
|
||||
config.HardwareAddress = newHWAddress;
|
||||
config.DisplayTerminal = displayTerminalCheckBox.Checked;
|
||||
if (!ipAddressTextBox.Text.Contains("?"))
|
||||
{
|
||||
config.IPAddressCJMS = ipAddressTextBox.Text;
|
||||
}
|
||||
|
||||
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
|
||||
}
|
||||
|
||||
|
||||
if (config.TestImagesMode != newTestImagesMode ||
|
||||
config.TestImagesCount != newTestImagesCount)
|
||||
{
|
||||
config.TestImagesMode = newTestImagesMode;
|
||||
config.TestImagesCount = newTestImagesCount;
|
||||
|
||||
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.VolatileChange);
|
||||
}
|
||||
|
||||
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
|
||||
{
|
||||
Camera.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
private void parentNameComboBox_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (parent == null) return;
|
||||
|
||||
if (parent.CmpntEntities != null)
|
||||
{
|
||||
foreach (var cmpnt in parent.CmpntEntities)
|
||||
{
|
||||
IComponentFactory cmpntFactoryFromClassName =
|
||||
TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName);
|
||||
if (cmpntFactoryFromClassName is TBF.Rig.Network.Adapter.Factory)
|
||||
{
|
||||
NetadapterCfg netadapterCfg =
|
||||
cmpntFactoryFromClassName.CmpntCfgFromCmpntEntity(cmpnt) as NetadapterCfg;
|
||||
string adapterDescription = netadapterCfg.Description;
|
||||
AdapterInfo netadapter = AdapterInfo.GetNetAdapter(adapterDescription);
|
||||
ipAddressAdapterTextBox.Text = netadapter.IPAddress.ToString();
|
||||
if (config.IPAddressCJMS == null || config.IPAddressCJMS.Equals(""))
|
||||
{
|
||||
ipAddressTextBox.Text = getAdatpterIP(netadapter);
|
||||
}
|
||||
|
||||
isIPCalculated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string getAdatpterIP(AdapterInfo netadapter)
|
||||
{
|
||||
List<string> ipSegments = GetIPAddressInSegments(netadapter.IPAddress.ToString());
|
||||
|
||||
string address = string.Format(
|
||||
"{0}.{1}.{2}.???",
|
||||
ipSegments[0],
|
||||
ipSegments[1],
|
||||
ipSegments[2]
|
||||
);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
private List<string> GetIPAddressInSegments(string ipAddress)
|
||||
{
|
||||
List<string> ipAddressSegments = new List<string>();
|
||||
// Regular expression to match IPv4 and capture 4 segments
|
||||
string pattern = @"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$";
|
||||
|
||||
Match match = Regex.Match(ipAddress, pattern);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
ipAddressSegments.Add(match.Groups[1].Value);
|
||||
ipAddressSegments.Add(match.Groups[2].Value);
|
||||
ipAddressSegments.Add(match.Groups[3].Value);
|
||||
ipAddressSegments.Add(match.Groups[4].Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Error("Invalid IP address format.");
|
||||
}
|
||||
|
||||
return ipAddressSegments;
|
||||
}
|
||||
}
|
||||
}
|
||||
260
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.designer.cs
generated
Normal file
260
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.designer.cs
generated
Normal file
@ -0,0 +1,260 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
partial class CameraCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.hwAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.hwAddressLabel = new System.Windows.Forms.Label();
|
||||
this.parentNameLabel = new System.Windows.Forms.Label();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.displayTerminalCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.testImagesCountTextBox = new System.Windows.Forms.TextBox();
|
||||
this.testImagesCountLabel = new System.Windows.Forms.Label();
|
||||
this.testImagesModeComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.testImagesModeLabel = new System.Windows.Forms.Label();
|
||||
this.ipAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.iPAddressLabel = new System.Windows.Forms.Label();
|
||||
this.ipAddressAdapterTextBox = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// hwAddressTextBox
|
||||
//
|
||||
this.hwAddressTextBox.Enabled = false;
|
||||
this.hwAddressTextBox.Location = new System.Drawing.Point(198, 209);
|
||||
this.hwAddressTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.hwAddressTextBox.Name = "hwAddressTextBox";
|
||||
this.hwAddressTextBox.Size = new System.Drawing.Size(193, 26);
|
||||
this.hwAddressTextBox.TabIndex = 6;
|
||||
//
|
||||
// hwAddressLabel
|
||||
//
|
||||
this.hwAddressLabel.AutoSize = true;
|
||||
this.hwAddressLabel.Location = new System.Drawing.Point(42, 213);
|
||||
this.hwAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.hwAddressLabel.Name = "hwAddressLabel";
|
||||
this.hwAddressLabel.Size = new System.Drawing.Size(107, 20);
|
||||
this.hwAddressLabel.TabIndex = 5;
|
||||
this.hwAddressLabel.Text = "Serial number";
|
||||
//
|
||||
// parentNameLabel
|
||||
//
|
||||
this.parentNameLabel.AutoSize = true;
|
||||
this.parentNameLabel.Location = new System.Drawing.Point(42, 106);
|
||||
this.parentNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.parentNameLabel.Name = "parentNameLabel";
|
||||
this.parentNameLabel.Size = new System.Drawing.Size(100, 20);
|
||||
this.parentNameLabel.TabIndex = 3;
|
||||
this.parentNameLabel.Text = "Parent name";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(198, 63);
|
||||
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(193, 26);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(42, 68);
|
||||
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(51, 20);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(194, 26);
|
||||
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(125, 20);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// parentNameComboBox
|
||||
//
|
||||
this.parentNameComboBox.Enabled = false;
|
||||
this.parentNameComboBox.FormattingEnabled = true;
|
||||
this.parentNameComboBox.Location = new System.Drawing.Point(198, 102);
|
||||
this.parentNameComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.parentNameComboBox.Name = "parentNameComboBox";
|
||||
this.parentNameComboBox.Size = new System.Drawing.Size(193, 28);
|
||||
this.parentNameComboBox.TabIndex = 4;
|
||||
this.parentNameComboBox.TextChanged += new System.EventHandler(this.parentNameComboBox_TextChanged);
|
||||
//
|
||||
// displayTerminalCheckBox
|
||||
//
|
||||
this.displayTerminalCheckBox.AutoSize = true;
|
||||
this.displayTerminalCheckBox.Enabled = false;
|
||||
this.displayTerminalCheckBox.Location = new System.Drawing.Point(200, 255);
|
||||
this.displayTerminalCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.displayTerminalCheckBox.Name = "displayTerminalCheckBox";
|
||||
this.displayTerminalCheckBox.Size = new System.Drawing.Size(146, 24);
|
||||
this.displayTerminalCheckBox.TabIndex = 7;
|
||||
this.displayTerminalCheckBox.Text = "Display terminal";
|
||||
this.displayTerminalCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// testImagesCountTextBox
|
||||
//
|
||||
this.testImagesCountTextBox.Enabled = false;
|
||||
this.testImagesCountTextBox.Location = new System.Drawing.Point(198, 335);
|
||||
this.testImagesCountTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.testImagesCountTextBox.Name = "testImagesCountTextBox";
|
||||
this.testImagesCountTextBox.Size = new System.Drawing.Size(67, 26);
|
||||
this.testImagesCountTextBox.TabIndex = 12;
|
||||
//
|
||||
// testImagesCountLabel
|
||||
//
|
||||
this.testImagesCountLabel.AutoSize = true;
|
||||
this.testImagesCountLabel.Location = new System.Drawing.Point(42, 339);
|
||||
this.testImagesCountLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.testImagesCountLabel.Name = "testImagesCountLabel";
|
||||
this.testImagesCountLabel.Size = new System.Drawing.Size(139, 20);
|
||||
this.testImagesCountLabel.TabIndex = 11;
|
||||
this.testImagesCountLabel.Text = "Test images count";
|
||||
//
|
||||
// testImagesModeComboBox
|
||||
//
|
||||
this.testImagesModeComboBox.Enabled = false;
|
||||
this.testImagesModeComboBox.FormattingEnabled = true;
|
||||
this.testImagesModeComboBox.Location = new System.Drawing.Point(198, 295);
|
||||
this.testImagesModeComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.testImagesModeComboBox.Name = "testImagesModeComboBox";
|
||||
this.testImagesModeComboBox.Size = new System.Drawing.Size(193, 28);
|
||||
this.testImagesModeComboBox.TabIndex = 14;
|
||||
//
|
||||
// testImagesModeLabel
|
||||
//
|
||||
this.testImagesModeLabel.AutoSize = true;
|
||||
this.testImagesModeLabel.Location = new System.Drawing.Point(42, 299);
|
||||
this.testImagesModeLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.testImagesModeLabel.Name = "testImagesModeLabel";
|
||||
this.testImagesModeLabel.Size = new System.Drawing.Size(139, 20);
|
||||
this.testImagesModeLabel.TabIndex = 13;
|
||||
this.testImagesModeLabel.Text = "Test images mode";
|
||||
//
|
||||
// ipAddressTextBox
|
||||
//
|
||||
this.ipAddressTextBox.Enabled = false;
|
||||
this.ipAddressTextBox.Location = new System.Drawing.Point(198, 176);
|
||||
this.ipAddressTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.ipAddressTextBox.Name = "ipAddressTextBox";
|
||||
this.ipAddressTextBox.Size = new System.Drawing.Size(193, 26);
|
||||
this.ipAddressTextBox.TabIndex = 15;
|
||||
//
|
||||
// iPAddressLabel
|
||||
//
|
||||
this.iPAddressLabel.AutoSize = true;
|
||||
this.iPAddressLabel.Location = new System.Drawing.Point(42, 176);
|
||||
this.iPAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.iPAddressLabel.Name = "iPAddressLabel";
|
||||
this.iPAddressLabel.Size = new System.Drawing.Size(89, 20);
|
||||
this.iPAddressLabel.TabIndex = 16;
|
||||
this.iPAddressLabel.Text = "IP address:";
|
||||
//
|
||||
// ipAddressAdapterTextBox
|
||||
//
|
||||
this.ipAddressAdapterTextBox.Enabled = false;
|
||||
this.ipAddressAdapterTextBox.Location = new System.Drawing.Point(200, 140);
|
||||
this.ipAddressAdapterTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.ipAddressAdapterTextBox.Name = "ipAddressAdapterTextBox";
|
||||
this.ipAddressAdapterTextBox.Size = new System.Drawing.Size(193, 26);
|
||||
this.ipAddressAdapterTextBox.TabIndex = 17;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(42, 140);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(150, 20);
|
||||
this.label1.TabIndex = 18;
|
||||
this.label1.Text = "Adapter IP address:";
|
||||
//
|
||||
// CameraCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.ipAddressAdapterTextBox);
|
||||
this.Controls.Add(this.iPAddressLabel);
|
||||
this.Controls.Add(this.ipAddressTextBox);
|
||||
this.Controls.Add(this.testImagesModeComboBox);
|
||||
this.Controls.Add(this.testImagesModeLabel);
|
||||
this.Controls.Add(this.hwAddressTextBox);
|
||||
this.Controls.Add(this.hwAddressLabel);
|
||||
this.Controls.Add(this.testImagesCountTextBox);
|
||||
this.Controls.Add(this.testImagesCountLabel);
|
||||
this.Controls.Add(this.displayTerminalCheckBox);
|
||||
this.Controls.Add(this.parentNameComboBox);
|
||||
this.Controls.Add(this.parentNameLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.Name = "CameraCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(603, 391);
|
||||
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
|
||||
private System.Windows.Forms.TextBox ipAddressAdapterTextBox;
|
||||
|
||||
private System.Windows.Forms.TextBox ipAddressTextBox;
|
||||
private System.Windows.Forms.Label iPAddressLabel;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox hwAddressTextBox;
|
||||
private System.Windows.Forms.Label hwAddressLabel;
|
||||
private System.Windows.Forms.Label parentNameLabel;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.ComboBox parentNameComboBox;
|
||||
private System.Windows.Forms.CheckBox displayTerminalCheckBox;
|
||||
private System.Windows.Forms.TextBox testImagesCountTextBox;
|
||||
private System.Windows.Forms.Label testImagesCountLabel;
|
||||
private System.Windows.Forms.ComboBox testImagesModeComboBox;
|
||||
private System.Windows.Forms.Label testImagesModeLabel;
|
||||
}
|
||||
}
|
||||
120
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.resx
Normal file
120
TBF/Rig/Network/Camera/CJMS11/CameraCfgCtrl.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
25
TBF/Rig/Network/Camera/CJMS11/Factory.cs
Normal file
25
TBF/Rig/Network/Camera/CJMS11/Factory.cs
Normal file
@ -0,0 +1,25 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } }
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new Camera(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Camera(cfg, components); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new CameraCfg(this.GetType().Namespace.Substring(8), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(CameraCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
224
TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs
Normal file
224
TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs
Normal file
@ -0,0 +1,224 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Network.Telnet;
|
||||
using System.IO;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class GrabImagesOp : IOperation
|
||||
{
|
||||
/// TODO: Implement support for grabbing multiple images, now imgFileNames.Lenght should be 1
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(GrabImagesOp));
|
||||
public override string ToString() { return string.Format("GrabImageOp()"); }
|
||||
|
||||
readonly Camera camera;
|
||||
readonly Telnet.TelnetClient telnet;
|
||||
readonly string[] imgFileNames;
|
||||
readonly bool blackAndWhite;
|
||||
readonly bool lowResolution;
|
||||
readonly ImageRotation imageRotation;
|
||||
|
||||
string command;
|
||||
bool grabImageCommandSent;
|
||||
string response;
|
||||
bool grabPassed;
|
||||
bool grabFailed;
|
||||
bool transferringGrabbedImage;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Events: Event.None or Event.Error
|
||||
/// </summary>
|
||||
/// <param name="camera">CLP1611.Camera reference</param>
|
||||
public GrabImagesOp(Camera camera, string[] imgFileNames, bool blackAndWhite, bool lowResolution, ImageRotation imageRotation)
|
||||
{
|
||||
/// TODO: Implement support for grabbing multiple images, now imgFileNames.Lenght should be 1
|
||||
|
||||
this.camera = camera;
|
||||
this.telnet = camera.Telnet;
|
||||
this.imgFileNames = imgFileNames;
|
||||
this.blackAndWhite = blackAndWhite;
|
||||
this.lowResolution = lowResolution;
|
||||
this.imageRotation = imageRotation;
|
||||
|
||||
grabImageCommandSent = false;
|
||||
transferringGrabbedImage = false;
|
||||
|
||||
if (camera.DebugLevel == DebugMode.Normal || camera.DebugLevel == DebugMode.DetectedOn)
|
||||
{
|
||||
telnet.promptReceivedHandler += delegate(object sndr, PromptReceivedEventArgs a)
|
||||
{
|
||||
OnPromptReceived(sndr, a);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void OnPromptReceived(object sndr, PromptReceivedEventArgs a)
|
||||
{
|
||||
response = a.Response;
|
||||
/// TODO
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
grabImageCommandSent = false;
|
||||
transferringGrabbedImage = false;
|
||||
|
||||
if ((imgFileNames != null) && (imgFileNames.Length > 0) && File.Exists(imgFileNames[0]))
|
||||
{
|
||||
///
|
||||
/// An image specified, (1) delete previous image, (2) check if this is a simulation
|
||||
///
|
||||
File.Delete(imgFileNames[0]);
|
||||
|
||||
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate || camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
|
||||
{
|
||||
///
|
||||
/// Camera is in simulation mode => create a simulated image
|
||||
///
|
||||
File.Copy(string.Format("{0}\\Pictures\\sample.jpg", Program.ExecutableDir), imgFileNames[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Event Run()
|
||||
{
|
||||
if ((imgFileNames == null) || (imgFileNames.Length < 1) || (imgFileNames[0] == null))
|
||||
{
|
||||
///
|
||||
/// No images to be grabbed => Done
|
||||
///
|
||||
return Event.GrabPassed;
|
||||
}
|
||||
else if (camera.CameraCfg.DebugLevel == DebugMode.Simulate ||
|
||||
camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
|
||||
{
|
||||
///
|
||||
/// Camera is in simulation mode => create a simulated image and complete
|
||||
///
|
||||
return Event.GrabPassed;
|
||||
}
|
||||
else if (!grabImageCommandSent)
|
||||
{
|
||||
///
|
||||
/// Normal operation, no command sent yet => (1) wait until telnet state = Inactive, (2) send a command
|
||||
///
|
||||
if (camera.Running && (telnet.State == TelnetClient.TelnetState.Inactive))
|
||||
{
|
||||
///
|
||||
/// State variables
|
||||
///
|
||||
response = null;
|
||||
|
||||
///
|
||||
/// Prepare a command
|
||||
///
|
||||
int rotation = 0;
|
||||
if (imageRotation == ImageRotation.Deg90)
|
||||
rotation = 90;
|
||||
else if (imageRotation == ImageRotation.Deg180)
|
||||
rotation = 180;
|
||||
else if (imageRotation == ImageRotation.Deg270)
|
||||
rotation = 270;
|
||||
|
||||
command = string.Format("clp/GrabImage {0} {1} -r {2} {3} -n 1 {4}",
|
||||
blackAndWhite ? "-bmp" : "-bmp", /// 0 ... file format and quality
|
||||
blackAndWhite ? "-y8" : "-rgb", /// 1 ... B&W / color
|
||||
rotation.ToString(), /// 2 ... roration
|
||||
lowResolution ? "-lr" : "-hr", /// 4 ... resolution
|
||||
"grabbed.bmp"); /// 5 ... filename
|
||||
|
||||
//
|
||||
// Send (or enqueue) command
|
||||
//
|
||||
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.CLEAR_RESPONSE));
|
||||
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, command));
|
||||
grabImageCommandSent = true;
|
||||
log.WarnFormat("{0} IP={1} command={2}", camera.Name, camera.IPAddress, command);
|
||||
}
|
||||
return Event.CameraBusy;
|
||||
}
|
||||
else if (grabPassed)
|
||||
{
|
||||
///
|
||||
/// Normal operation, grab passed => transfer/transferring the image
|
||||
///
|
||||
if (transferringGrabbedImage)
|
||||
{
|
||||
/// Grab passed and image transfer is in progress
|
||||
return Event.GrabPassed;
|
||||
}
|
||||
else if (0 == camera.DownloadFile(blackAndWhite ? "grabbed.jpg" : "grabbed.bmp", imgFileNames[0]))
|
||||
{
|
||||
/// File transfer successfully started
|
||||
transferringGrabbedImage = true;
|
||||
return Event.GrabPassed;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Wait until the previous image transfer completes
|
||||
return Event.CameraBusy;
|
||||
}
|
||||
}
|
||||
else if (grabFailed)
|
||||
{
|
||||
///
|
||||
/// Normal operation, grab failed => there in no image to transfer
|
||||
///
|
||||
return Event.GrabFailed;
|
||||
}
|
||||
else if (response != null)
|
||||
{
|
||||
///
|
||||
/// Normal operation
|
||||
///
|
||||
if (response.Contains("completed"))
|
||||
{
|
||||
grabPassed = true;
|
||||
|
||||
///
|
||||
/// Start the file transfer
|
||||
///
|
||||
if (0 == camera.DownloadFile(blackAndWhite ? "grabbed.jpg" : "grabbed.bmp", imgFileNames[0]))
|
||||
{
|
||||
/// File transfer successfully started
|
||||
transferringGrabbedImage = true;
|
||||
return Event.GrabPassed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.CameraBusy; /// File transfer not started yet
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grabFailed = true;
|
||||
return Event.GrabFailed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.CameraBusy;
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return;
|
||||
|
||||
if (grabImageCommandSent)
|
||||
{
|
||||
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, Telnet.TelnetClient.CtrlCCommand));
|
||||
log.WarnFormat("{0} IP={1} command=CTRL-C", camera.Name, camera.IPAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
54
TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs
Normal file
54
TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using TBF.Rig.Network.Camera.CJMS11.POJO;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class JmsMessage
|
||||
{
|
||||
private POJO.MessageStatus status;
|
||||
private CommandM command;
|
||||
private string payload;
|
||||
|
||||
private string orig_status;
|
||||
private string orig_command;
|
||||
private string orig_payload;
|
||||
|
||||
public POJO.MessageStatus Status
|
||||
{
|
||||
get => status;
|
||||
set => status = value;
|
||||
}
|
||||
|
||||
public CommandM Command
|
||||
{
|
||||
get => command;
|
||||
set => command = value;
|
||||
}
|
||||
|
||||
public string Payload
|
||||
{
|
||||
get => payload;
|
||||
set => payload = value;
|
||||
}
|
||||
|
||||
public JmsMessage(string status, string command, string payload)
|
||||
{
|
||||
this.status = MessageStatusEnum.GetCommandM(status);
|
||||
this.command = CommandMEnum.GetCommandM(command);
|
||||
|
||||
orig_status = status;
|
||||
orig_command = command;
|
||||
orig_payload = payload;
|
||||
}
|
||||
|
||||
public bool isMessageImageType(){
|
||||
return this.command == CommandM.grab_image_;
|
||||
}
|
||||
|
||||
public ParsedImage getImage(){
|
||||
if(isMessageImageType()){
|
||||
return JmsPacket.ImageParser(this.payload);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
90
TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs
Normal file
90
TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using log4net;
|
||||
using TBF.Rig.Network.Camera.CJMS11.POJO;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class JmsPacket
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(JmsPacket));
|
||||
|
||||
private JmsMessage jmsMessage;
|
||||
|
||||
public JmsMessage JmsMessage
|
||||
{
|
||||
get => jmsMessage;
|
||||
set => jmsMessage = value;
|
||||
}
|
||||
|
||||
public JmsPacket(string message)
|
||||
{
|
||||
string received_message = message;
|
||||
|
||||
try
|
||||
{
|
||||
if (ParseMessage(received_message))
|
||||
{
|
||||
//success
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("Error parsing message: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParseMessage(string message)
|
||||
{
|
||||
message = message.Trim();
|
||||
if (message.Length < 1) return false;
|
||||
|
||||
this.jmsMessage = JmsMessageFromString(message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static JmsMessage JmsMessageFromString(string message)
|
||||
{
|
||||
// Equivalent regex pattern
|
||||
var pattern = new Regex(@"^(ACK|NACK):\s*(\S+)\s*(?:~(.*)~)?\s*END$", RegexOptions.Singleline);
|
||||
|
||||
var match = pattern.Match(message);
|
||||
if (match.Success)
|
||||
{
|
||||
string status = match.Groups[1].Value;
|
||||
string commandStr = match.Groups[2].Value;
|
||||
string payload = match.Groups[3].Success ? match.Groups[3].Value : "";
|
||||
|
||||
return new JmsMessage(status, commandStr, payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Message format not recognized: {message}");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ParsedImage ImageParser(string payloadImage)
|
||||
{
|
||||
// Equivalent regex pattern
|
||||
var imagePattern = new Regex(@"IMAGE:([A-Z0-9_]+):\s*(.*?)\s*~IMAGE_END", RegexOptions.Singleline);
|
||||
|
||||
var match = imagePattern.Match(payloadImage);
|
||||
if (match.Success)
|
||||
{
|
||||
string encoding = match.Groups[1].Value;
|
||||
string imageData = match.Groups[2].Value;
|
||||
|
||||
return new ParsedImage(ImageTypeEnum.GetCommandM(encoding), imageData);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Payload does not match expected image format: {payloadImage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
68
TBF/Rig/Network/Camera/CJMS11/LiveStreamOp.cs
Normal file
68
TBF/Rig/Network/Camera/CJMS11/LiveStreamOp.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using log4net;
|
||||
using Common;
|
||||
using TBF.Rig.Network.Telnet;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class LiveStreamOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(LiveStreamOp));
|
||||
|
||||
readonly Camera camera;
|
||||
readonly Telnet.TelnetClient telnet;
|
||||
readonly string command;
|
||||
|
||||
bool liveStreamCommandSent;
|
||||
|
||||
/// <summary>
|
||||
/// Events: Event.None or Event.Error
|
||||
/// </summary>
|
||||
/// <param name="camera">CLP1611.Camera reference</param>
|
||||
public LiveStreamOp(Camera camera, Telnet.TelnetClient telnet, string command)
|
||||
{
|
||||
this.camera = camera;
|
||||
this.telnet = telnet;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
liveStreamCommandSent = false;
|
||||
}
|
||||
|
||||
public Event Run()
|
||||
{
|
||||
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return Event.None;
|
||||
|
||||
log.DebugFormat("Run(): telnet.State = {0}, liveStreamCommandSent = {1}", telnet.State, liveStreamCommandSent);
|
||||
|
||||
if (!liveStreamCommandSent)
|
||||
{
|
||||
if (camera.Running && (telnet.State == TelnetClient.TelnetState.Inactive))
|
||||
{
|
||||
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_STRING, command));
|
||||
liveStreamCommandSent = true;
|
||||
log.WarnFormat("{0} IP={1} command={2}", camera.Name, camera.IPAddress, command);
|
||||
}
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return;
|
||||
|
||||
log.DebugFormat("Stop(): telnet.State = {0}, liveStreamCommandSent = {1}", telnet.State, liveStreamCommandSent);
|
||||
|
||||
if (liveStreamCommandSent)
|
||||
{
|
||||
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, Telnet.TelnetClient.CtrlCCommand));
|
||||
log.WarnFormat("{0} IP={1} command=CTRL-C", camera.Name, camera.IPAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs
Normal file
22
TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs
Normal file
@ -0,0 +1,22 @@
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public enum CommandM
|
||||
{
|
||||
noCommand,
|
||||
unknown_, // special: only return - unknown command
|
||||
connect_, // special: only return - TCP connection created
|
||||
type_camera_,
|
||||
status_,
|
||||
prepare_camera_,
|
||||
grab_image_,
|
||||
send_,
|
||||
start_stream_,
|
||||
stop_stream_,
|
||||
get_cfg_,
|
||||
set_cfg_,
|
||||
close_,
|
||||
disconnect_,
|
||||
overload_config_,
|
||||
client_count_
|
||||
}
|
||||
}
|
||||
44
TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs
Normal file
44
TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public static class CommandMEnum
|
||||
{
|
||||
private static readonly Dictionary<CommandM, string> commandToString = new Dictionary<CommandM, string>
|
||||
{
|
||||
{ CommandM.noCommand, "noCommand" },
|
||||
{ CommandM.unknown_, "unknown" },
|
||||
{ CommandM.connect_, "connect" },
|
||||
{ CommandM.type_camera_, "type_camera" },
|
||||
{ CommandM.status_, "status" },
|
||||
{ CommandM.prepare_camera_, "prepare_camera" },
|
||||
{ CommandM.grab_image_, "grab_image" },
|
||||
{ CommandM.send_, "send" },
|
||||
{ CommandM.start_stream_, "start_stream" },
|
||||
{ CommandM.stop_stream_, "stop_stream" },
|
||||
{ CommandM.get_cfg_, "get_cfg" },
|
||||
{ CommandM.set_cfg_, "set_cfg" },
|
||||
{ CommandM.close_, "close" },
|
||||
{ CommandM.disconnect_, "disconnect" },
|
||||
{ CommandM.overload_config_, "overload_config" },
|
||||
{ CommandM.client_count_, "client_count" }
|
||||
};
|
||||
|
||||
|
||||
private static readonly Dictionary<string, CommandM> stringToCommand = commandToString.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
|
||||
|
||||
public static string GetVal(CommandM cmd)
|
||||
{
|
||||
return commandToString.TryGetValue(cmd, out var str) ? str : "unknown";
|
||||
}
|
||||
|
||||
public static CommandM GetCommandM(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return CommandM.noCommand;
|
||||
|
||||
return stringToCommand.TryGetValue(token, out var cmd) ? cmd : CommandM.noCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
TBF/Rig/Network/Camera/CJMS11/POJO/ImageType.cs
Normal file
10
TBF/Rig/Network/Camera/CJMS11/POJO/ImageType.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace TBF.Rig.Network.Camera.CJMS11.POJO
|
||||
{
|
||||
public enum ImageType
|
||||
{
|
||||
UNKNOWN,
|
||||
BASE_64,
|
||||
MJPEG,
|
||||
RGB888
|
||||
}
|
||||
}
|
||||
31
TBF/Rig/Network/Camera/CJMS11/POJO/ImageTypeEnum.cs
Normal file
31
TBF/Rig/Network/Camera/CJMS11/POJO/ImageTypeEnum.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11.POJO
|
||||
{
|
||||
public class ImageTypeEnum
|
||||
{
|
||||
private static readonly Dictionary<ImageType, string> commandToString = new Dictionary<ImageType, string>
|
||||
{
|
||||
{ ImageType.BASE_64, "BASE_64" },
|
||||
{ ImageType.MJPEG, "MJPEG" },
|
||||
{ ImageType.RGB888, "RGB888" },
|
||||
{ ImageType.UNKNOWN, "" }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, ImageType> stringToCommand = commandToString.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
|
||||
|
||||
public static string GetVal(ImageType cmd)
|
||||
{
|
||||
return commandToString.TryGetValue(cmd, out var str) ? str : "unknown";
|
||||
}
|
||||
|
||||
public static ImageType GetCommandM(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return ImageType.UNKNOWN;
|
||||
|
||||
return stringToCommand.TryGetValue(token, out var cmd) ? cmd : ImageType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
TBF/Rig/Network/Camera/CJMS11/POJO/MessageStatus.cs
Normal file
10
TBF/Rig/Network/Camera/CJMS11/POJO/MessageStatus.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace TBF.Rig.Network.Camera.CJMS11.POJO
|
||||
{
|
||||
public enum MessageStatus
|
||||
{
|
||||
UNDEFINED,
|
||||
ACK,
|
||||
NACK,
|
||||
ERROR
|
||||
}
|
||||
}
|
||||
31
TBF/Rig/Network/Camera/CJMS11/POJO/MessageStatusEnum.cs
Normal file
31
TBF/Rig/Network/Camera/CJMS11/POJO/MessageStatusEnum.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11.POJO
|
||||
{
|
||||
public class MessageStatusEnum
|
||||
{
|
||||
private static readonly Dictionary<MessageStatus, string> commandToString = new Dictionary<MessageStatus, string>
|
||||
{
|
||||
{ MessageStatus.UNDEFINED, "" },
|
||||
{ MessageStatus.ACK, "ACK" },
|
||||
{ MessageStatus.NACK, "NACK" },
|
||||
{ MessageStatus.ERROR, "ERROR" }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, MessageStatus> stringToCommand = commandToString.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
|
||||
|
||||
public static string GetVal(MessageStatus cmd)
|
||||
{
|
||||
return commandToString.TryGetValue(cmd, out var str) ? str : "undefined";
|
||||
}
|
||||
|
||||
public static MessageStatus GetCommandM(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return MessageStatus.UNDEFINED;
|
||||
|
||||
return stringToCommand.TryGetValue(token, out var cmd) ? cmd : MessageStatus.UNDEFINED;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
TBF/Rig/Network/Camera/CJMS11/POJO/ParsedImage.cs
Normal file
38
TBF/Rig/Network/Camera/CJMS11/POJO/ParsedImage.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using TBF.Rig.Network.Camera.CJMS11.POJO;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class ParsedImage
|
||||
{
|
||||
public ImageType Encoding { get; }
|
||||
public string ImageData { get; }
|
||||
|
||||
public Image Image { get { return (ImageData.Length>0 ? Base64ToImage(ImageData) : null); } }
|
||||
|
||||
public ParsedImage(ImageType encoding, string imageData)
|
||||
{
|
||||
Encoding = encoding;
|
||||
ImageData = imageData;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"ParsedImage{{encoding='{Encoding}', imageData='{ImageData}'}}";
|
||||
}
|
||||
|
||||
public static Image Base64ToImage(string base64Image)
|
||||
{
|
||||
byte[] imageBytes = Convert.FromBase64String(base64Image);
|
||||
|
||||
using (var ms = new MemoryStream(imageBytes))
|
||||
{
|
||||
return Image.FromStream(ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
TBF/Rig/Network/Camera/CJMS11/RoisAndResults.cs
Normal file
91
TBF/Rig/Network/Camera/CJMS11/RoisAndResults.cs
Normal file
@ -0,0 +1,91 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public class RoisAndResults
|
||||
{
|
||||
public const int MaxRegisteredRois = 4; /// Max. count of registered (and measured) ROI-s
|
||||
|
||||
public long CameraTimeMs;
|
||||
public int[] Angles;
|
||||
|
||||
private IList<string> roiParams;
|
||||
public int RegisteredRoisCount { get { return roiParams.Count; } }
|
||||
|
||||
|
||||
public RoisAndResults()
|
||||
{
|
||||
Angles = new int[MaxRegisteredRois];
|
||||
roiParams = new List<string>();
|
||||
}
|
||||
|
||||
|
||||
public void ClearRoiParams()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
roiParams.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public int RegisterRoi(string roiParam)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (this.roiParams.Count >= MaxRegisteredRois) return 0;
|
||||
|
||||
this.roiParams.Add(roiParam);
|
||||
return this.roiParams.Count; /// return a handle 1 .. MaxRegisteredRois
|
||||
}
|
||||
}
|
||||
|
||||
public string GetRoiParams(int roiHandle)
|
||||
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (roiHandle > 0 && roiHandle <= roiParams.Count)
|
||||
{
|
||||
return roiParams[roiHandle - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetResults(long timeMs, int[] angles)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
CameraTimeMs = timeMs;
|
||||
for (int i = 0; i < Math.Min(angles.Length, Angles.Length); i++)
|
||||
{
|
||||
Angles[i] = angles[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetResult(int roiHandle, out long timeMs)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (roiHandle > 0 && roiHandle <= roiParams.Count)
|
||||
{
|
||||
timeMs = CameraTimeMs;
|
||||
return Angles[roiHandle - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
timeMs = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.Designer.cs
generated
Normal file
62
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.Designer.cs
generated
Normal file
@ -0,0 +1,62 @@
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
partial class TerminalDlg
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.vtTextBox = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// vtTextBox
|
||||
//
|
||||
this.vtTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.vtTextBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.vtTextBox.Multiline = true;
|
||||
this.vtTextBox.Name = "vtTextBox";
|
||||
this.vtTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.vtTextBox.Size = new System.Drawing.Size(737, 437);
|
||||
this.vtTextBox.TabIndex = 0;
|
||||
//
|
||||
// TerminalDlg
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(737, 437);
|
||||
this.Controls.Add(this.vtTextBox);
|
||||
this.Name = "TerminalDlg";
|
||||
this.Text = "Terminal";
|
||||
this.Load += new System.EventHandler(this.Terminal_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox vtTextBox;
|
||||
}
|
||||
}
|
||||
37
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.cs
Normal file
37
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.Network.Telnet;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
public partial class TerminalDlg : Form
|
||||
{
|
||||
TelnetClient telnet;
|
||||
|
||||
public TerminalDlg()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public TerminalDlg(string name, TelnetClient telnet)
|
||||
{
|
||||
InitializeComponent();
|
||||
Text = name;
|
||||
this.telnet = telnet;
|
||||
}
|
||||
|
||||
private void Terminal_Load(object sender, EventArgs e)
|
||||
{
|
||||
telnet.vtTextChangedHandler += delegate(object sndr, VtTextChangedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<VtTextChangedEventArgs>(OnTextChanged), sndr, args); }
|
||||
else OnTextChanged(sndr, args);
|
||||
};
|
||||
}
|
||||
|
||||
void OnTextChanged(object sndr, VtTextChangedEventArgs args)
|
||||
{
|
||||
vtTextBox.Text = args.VtText;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.resx
Normal file
120
TBF/Rig/Network/Camera/CJMS11/TerminalDlg.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@ -42,14 +42,10 @@ namespace TBF.Rig.Network.Camera.Roi
|
||||
{
|
||||
foreach (var cmpnt in parent.CmpntEntities)
|
||||
{
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CLP1611.Factory)
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CJMS11.Factory)
|
||||
{
|
||||
parentNameComboBox.Items.Add(cmpnt.Name);
|
||||
}
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.Roi.Factory)
|
||||
{
|
||||
previousRoiComboBox.Items.Add(cmpnt.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
25
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Factory.cs
Normal file
25
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Factory.cs
Normal file
@ -0,0 +1,25 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return this.GetType().Namespace.Substring(8); } }
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new Roi(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Roi(cfg, components); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new RoiCfg(this.GetType().Namespace.Substring(8), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(RoiCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
115
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/ProcedureParams.cs
Normal file
115
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/ProcedureParams.cs
Normal file
@ -0,0 +1,115 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
public class ProcedureParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public double PulsesPerLtr; /// [l^-1]
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
PulsesPerLtr = 1.0;
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
Strings.PulsesPerLtr,
|
||||
};
|
||||
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 PulsesPerLtr.ToString();
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves parameters from UI controls
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifies whether strings in UI controls represent valid parameters
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
double dummy;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (Utils.TryParseUDouble(strValue, out dummy)) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(ProcedureParams prms)
|
||||
{
|
||||
prms.PulsesPerLtr = this.PulsesPerLtr;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
{
|
||||
ProcedureParams pars = new ProcedureParams();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
|
||||
{
|
||||
if (dbEntity == null) return;
|
||||
try
|
||||
{
|
||||
ProcedureParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as ProcedureParams;
|
||||
|
||||
procedureParamsEntity = dbEntity;
|
||||
componentName = dbEntity.CmpntName;
|
||||
procedure = dbEntity.Procedure;
|
||||
|
||||
if (tmp != null) tmp.CopyContentTo(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public ProcedureParams() { }
|
||||
|
||||
public ProcedureParams(bool initialize)
|
||||
{
|
||||
if (initialize) InitializeAll();
|
||||
}
|
||||
|
||||
public ProcedureParams(ComponentProcedure procedureParamsEntity, string componentName, Procedure procedure)
|
||||
{
|
||||
this.procedureParamsEntity = procedureParamsEntity;
|
||||
this.componentName = componentName;
|
||||
this.procedure = procedure;
|
||||
}
|
||||
}
|
||||
}
|
||||
139
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs
Normal file
139
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs
Normal file
@ -0,0 +1,139 @@
|
||||
///
|
||||
/// Copyright (c) 2017-2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
public class Roi : ComponentBase, GenericDevices.IRegReaderStillCamera
|
||||
{
|
||||
/// TODO: Implement support for sharing one camera by multiple ROI-s
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Roi));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
readonly RoiCfg roiCfg;
|
||||
|
||||
///
|
||||
/// Camera and ICamera
|
||||
///
|
||||
public readonly CLP1611.Camera NetCamera;
|
||||
public GenericDevices.ICamera Camera { get { return NetCamera as GenericDevices.ICamera; } }
|
||||
|
||||
public int Position
|
||||
{
|
||||
get
|
||||
{
|
||||
int firstDigitPos = Name.IndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });
|
||||
int position;
|
||||
return (firstDigitPos < 0) ? 0 : (int.TryParse(Name.Substring(firstDigitPos), out position) ? position : 0);
|
||||
}
|
||||
}
|
||||
public RegisterReaderType RegisterReaderType { get { return RegisterReaderType.Manual; } }
|
||||
public double PulsesPerLtr { get { return roiCfg.ProcParams.PulsesPerLtr; } }
|
||||
public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); } }
|
||||
|
||||
|
||||
double beginWMState;
|
||||
public double BeginWMState
|
||||
{
|
||||
get { return beginWMState; }
|
||||
set { beginWMState = value; }
|
||||
}
|
||||
|
||||
double endWMState;
|
||||
public double EndWMState
|
||||
{
|
||||
get { return endWMState; }
|
||||
set { endWMState = value; }
|
||||
}
|
||||
|
||||
public double WMVolume { get { return endWMState - beginWMState; } }
|
||||
|
||||
public int WMPulses { get { return (int)(WMVolume / LtrsPerPulse); } }
|
||||
|
||||
public int WMRefPulses { get { return StateMachine.ControlBoardMain.RefPulses; ; } }
|
||||
|
||||
|
||||
public Roi() { }
|
||||
|
||||
public Roi(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
{
|
||||
roiCfg = cfg as RoiCfg;
|
||||
NetCamera = TbfComponents.FindComponent(cfg.ParentName, components) as CLP1611.Camera;
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||
{
|
||||
if (CfgChangeHandler == null) return;
|
||||
try { CfgChangeHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||
|
||||
public override void StartChangeHandler()
|
||||
{
|
||||
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||
{
|
||||
RoiCfg tmpcfg = args.Cfg as RoiCfg;
|
||||
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
|
||||
{
|
||||
if (args.Command == CfgChangeCmd.CfgChange)
|
||||
{
|
||||
roiCfg.BlackAndWhite = tmpcfg.BlackAndWhite;
|
||||
roiCfg.LowResolution = tmpcfg.LowResolution;
|
||||
roiCfg.ImageRotation = tmpcfg.ImageRotation;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
log.DebugFormat("{0}:Clear()", Name);
|
||||
beginWMState = 0;
|
||||
endWMState = 0;
|
||||
}
|
||||
|
||||
|
||||
public IOperation GrabImageOp(string imageFileName)
|
||||
{
|
||||
return GrabImageOp(imageFileName, roiCfg.BlackAndWhite, roiCfg.LowResolution, roiCfg.ImageRotation);
|
||||
}
|
||||
|
||||
public IOperation GrabImageOp(string imageFileName,
|
||||
bool blackAndWhite, bool lowResolution, ImageRotation imageRotation)
|
||||
{
|
||||
if (NetCamera != null)
|
||||
{
|
||||
/// TODO: Implement support for sharing one camera by multiple ROI-s
|
||||
return NetCamera.GrabImagesOp(new string[] { imageFileName }, blackAndWhite, lowResolution, imageRotation);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public IValve GetValve()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs
Normal file
56
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs
Normal file
@ -0,0 +1,56 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
public class RoiCfg : ComponentCfgBase, IChildComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RoiCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new RoiCfgCtrl(); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public bool BlackAndWhite;
|
||||
public bool LowResolution;
|
||||
public ImageRotation ImageRotation;
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
public ProcedureParams ProcParams;
|
||||
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
|
||||
public override IParamsProvider CreateProcParamsProvider() { return new ProcedureParams(true); }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
RoiCfg()
|
||||
{
|
||||
ProcParams = new ProcedureParams(true);
|
||||
}
|
||||
|
||||
public RoiCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = "Camera";
|
||||
BlackAndWhite = false;
|
||||
LowResolution = true;
|
||||
ImageRotation = ImageRotation.None;
|
||||
DebugLevel = DebugMode.Inherit;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("{0} Camera={1} B&W={2}, LowRes={3}, Rotation={4}",
|
||||
Name, ParentName, BlackAndWhite, LowResolution, ImageRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
175
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs
Normal file
175
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs
Normal file
@ -0,0 +1,175 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Resources;
|
||||
using TBF.UI.Bench.Components;
|
||||
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
public partial class RoiCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger(typeof(RoiCfgCtrl));
|
||||
|
||||
ComponentParametersDlg parent;
|
||||
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
RoiCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as RoiCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public RoiCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void PumpCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
parent = ParentForm as ComponentParametersDlg;
|
||||
if (parent == null) return;
|
||||
|
||||
if (parent.CmpntEntities != null)
|
||||
{
|
||||
foreach (var cmpnt in parent.CmpntEntities)
|
||||
{
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CLP1611.Factory)
|
||||
{
|
||||
parentNameComboBox.Items.Add(cmpnt.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ImageRotation ir = 0; ir < ImageRotation.Count; ir++)
|
||||
{
|
||||
imageRotationComboBox.Items.Add(ir.ToDescription());
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
|
||||
blackAndWhiteCheckBox.Checked = config.BlackAndWhite;
|
||||
loResolutionCheckBox.Checked = config.LowResolution;
|
||||
imageRotationComboBox.Text = config.ImageRotation.ToDescription();
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
parentNameComboBox.Enabled = true;
|
||||
blackAndWhiteCheckBox.Enabled = true;
|
||||
loResolutionCheckBox.Enabled = true;
|
||||
imageRotationComboBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, parentNameLabel.Text);
|
||||
}
|
||||
|
||||
if (!imageRotationComboBox.Items.Contains(imageRotationComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, imageRotationLabel.Text);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
if (config.Name != nameTextBox.Text)
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
|
||||
}
|
||||
|
||||
string newParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
|
||||
if (config.ParentName != newParentName)
|
||||
{
|
||||
config.ParentName = newParentName;
|
||||
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
|
||||
}
|
||||
|
||||
if (config.BlackAndWhite != blackAndWhiteCheckBox.Checked)
|
||||
{
|
||||
config.BlackAndWhite = blackAndWhiteCheckBox.Checked;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.InvokeCfgChange);
|
||||
}
|
||||
|
||||
if (config.LowResolution != loResolutionCheckBox.Checked)
|
||||
{
|
||||
config.LowResolution = loResolutionCheckBox.Checked;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.InvokeCfgChange);
|
||||
}
|
||||
|
||||
for (ImageRotation ir = 0; ir < ImageRotation.Count; ir++)
|
||||
{
|
||||
if (imageRotationComboBox.Text == ir.ToDescription())
|
||||
{
|
||||
if (config.ImageRotation != ir)
|
||||
{
|
||||
config.ImageRotation = ir;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.InvokeCfgChange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
|
||||
{
|
||||
Roi.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCmdResponse(object sender, CmdResponseArgs args)
|
||||
{
|
||||
if (CmdResponseHandler == null) return;
|
||||
try { CmdResponseHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CmdResponseHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CmdResponseArgs> CmdResponseHandler;
|
||||
|
||||
public void StartResponseHandler() { }
|
||||
public void StopResponseHandler() { }
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
}
|
||||
}
|
||||
185
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs
generated
Normal file
185
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs
generated
Normal file
@ -0,0 +1,185 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
|
||||
{
|
||||
partial class RoiCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.parentNameLabel = new System.Windows.Forms.Label();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.imageRotationComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.imageRotationLabel = new System.Windows.Forms.Label();
|
||||
this.blackAndWhiteCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.loResolutionCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// parentNameLabel
|
||||
//
|
||||
this.parentNameLabel.AutoSize = true;
|
||||
this.parentNameLabel.Location = new System.Drawing.Point(20, 77);
|
||||
this.parentNameLabel.Name = "parentNameLabel";
|
||||
this.parentNameLabel.Size = new System.Drawing.Size(43, 13);
|
||||
this.parentNameLabel.TabIndex = 3;
|
||||
this.parentNameLabel.Text = "Camera";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(139, 49);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(174, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(20, 52);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(136, 26);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(114, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComponentClassName";
|
||||
//
|
||||
// parentNameComboBox
|
||||
//
|
||||
this.parentNameComboBox.Enabled = false;
|
||||
this.parentNameComboBox.FormattingEnabled = true;
|
||||
this.parentNameComboBox.Location = new System.Drawing.Point(139, 74);
|
||||
this.parentNameComboBox.Name = "parentNameComboBox";
|
||||
this.parentNameComboBox.Size = new System.Drawing.Size(174, 21);
|
||||
this.parentNameComboBox.TabIndex = 4;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(-211, -147);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(57, 13);
|
||||
this.label1.TabIndex = 5;
|
||||
this.label1.Text = "Arguments";
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.Enabled = false;
|
||||
this.textBox1.Location = new System.Drawing.Point(-125, -150);
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(372, 20);
|
||||
this.textBox1.TabIndex = 6;
|
||||
//
|
||||
// imageRotationComboBox
|
||||
//
|
||||
this.imageRotationComboBox.Enabled = false;
|
||||
this.imageRotationComboBox.FormattingEnabled = true;
|
||||
this.imageRotationComboBox.Location = new System.Drawing.Point(139, 154);
|
||||
this.imageRotationComboBox.Name = "imageRotationComboBox";
|
||||
this.imageRotationComboBox.Size = new System.Drawing.Size(93, 21);
|
||||
this.imageRotationComboBox.TabIndex = 8;
|
||||
//
|
||||
// imageRotationLabel
|
||||
//
|
||||
this.imageRotationLabel.AutoSize = true;
|
||||
this.imageRotationLabel.Location = new System.Drawing.Point(20, 157);
|
||||
this.imageRotationLabel.Name = "imageRotationLabel";
|
||||
this.imageRotationLabel.Size = new System.Drawing.Size(103, 13);
|
||||
this.imageRotationLabel.TabIndex = 7;
|
||||
this.imageRotationLabel.Text = "Image rotation (ccw)";
|
||||
//
|
||||
// blackAndWhiteCheckBox
|
||||
//
|
||||
this.blackAndWhiteCheckBox.AutoSize = true;
|
||||
this.blackAndWhiteCheckBox.Enabled = false;
|
||||
this.blackAndWhiteCheckBox.Location = new System.Drawing.Point(139, 108);
|
||||
this.blackAndWhiteCheckBox.Name = "blackAndWhiteCheckBox";
|
||||
this.blackAndWhiteCheckBox.Size = new System.Drawing.Size(93, 17);
|
||||
this.blackAndWhiteCheckBox.TabIndex = 5;
|
||||
this.blackAndWhiteCheckBox.Text = "Black && White";
|
||||
this.blackAndWhiteCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// loResolutionCheckBox
|
||||
//
|
||||
this.loResolutionCheckBox.AutoSize = true;
|
||||
this.loResolutionCheckBox.Enabled = false;
|
||||
this.loResolutionCheckBox.Location = new System.Drawing.Point(139, 131);
|
||||
this.loResolutionCheckBox.Name = "loResolutionCheckBox";
|
||||
this.loResolutionCheckBox.Size = new System.Drawing.Size(94, 17);
|
||||
this.loResolutionCheckBox.TabIndex = 6;
|
||||
this.loResolutionCheckBox.Text = "Low resolution";
|
||||
this.loResolutionCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RoiCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.imageRotationComboBox);
|
||||
this.Controls.Add(this.imageRotationLabel);
|
||||
this.Controls.Add(this.blackAndWhiteCheckBox);
|
||||
this.Controls.Add(this.loResolutionCheckBox);
|
||||
this.Controls.Add(this.parentNameComboBox);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.parentNameLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "RoiCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(500, 300);
|
||||
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label parentNameLabel;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.ComboBox parentNameComboBox;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
private System.Windows.Forms.ComboBox imageRotationComboBox;
|
||||
private System.Windows.Forms.Label imageRotationLabel;
|
||||
private System.Windows.Forms.CheckBox blackAndWhiteCheckBox;
|
||||
private System.Windows.Forms.CheckBox loResolutionCheckBox;
|
||||
}
|
||||
}
|
||||
120
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.resx
Normal file
120
TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@ -76,11 +76,13 @@ namespace TBF.Rig
|
||||
new Modbus.WaterAnalyzer.Factory(),
|
||||
new Network.Adapter.Factory(),
|
||||
new Network.AdapterFTP.Factory(),
|
||||
new Network.Camera.CJMS11.Factory(),
|
||||
new Network.Camera.CLP1611.Factory(),
|
||||
new Network.Camera.KeyenceIV3G120.Factory(),
|
||||
new Network.Camera.Display.Factory(),
|
||||
new Network.Camera.Roi.Factory(),
|
||||
new Network.Camera.RoiForFixedStart.Factory(),
|
||||
new Network.Camera.RoiForFixedStartCJMS11.Factory(),
|
||||
new Network.Camera.RoiForFixedStartKeyence.Factory(),
|
||||
new Network.Comet.Ambient.Factory(),
|
||||
new Network.RestAPI.Factory(),
|
||||
|
||||
@ -813,6 +813,33 @@
|
||||
<Compile Include="Rig\Network\Adapter\NetadapterCfgCtrl.designer.cs">
|
||||
<DependentUpon>NetadapterCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\Camera.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\CameraCfg.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.designer.cs">
|
||||
<DependentUpon>CameraCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\Factory.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\GrabImagesOp.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\JmsMessage.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\JmsPacket.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\LiveStreamOp.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandM.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandMEnum.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ImageType.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ImageTypeEnum.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatus.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatusEnum.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ParsedImage.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\RoisAndResults.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\TerminalDlg.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\TerminalDlg.Designer.cs">
|
||||
<DependentUpon>TerminalDlg.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\CLP1611\Camera.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CLP1611\CameraCfg.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CLP1611\CameraCfgCtrl.cs">
|
||||
@ -861,6 +888,16 @@
|
||||
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\Factory.cs" />
|
||||
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\GrabImagesOp.cs" />
|
||||
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\RoisAndResults.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\Factory.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\ProcedureParams.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\Roi.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\RoiCfg.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\RoiCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\RoiCfgCtrl.designer.cs">
|
||||
<DependentUpon>RoiCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartKeyence\Factory.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartKeyence\ProcedureParams.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartKeyence\Roi.cs" />
|
||||
@ -2891,6 +2928,12 @@
|
||||
<EmbeddedResource Include="Rig\Network\Adapter\NetadapterCfgCtrl.resx">
|
||||
<DependentUpon>NetadapterCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.resx">
|
||||
<DependentUpon>CameraCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\Network\Camera\CJMS11\TerminalDlg.resx">
|
||||
<DependentUpon>TerminalDlg.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\Network\Camera\CLP1611\CameraCfgCtrl.resx">
|
||||
<DependentUpon>CameraCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@ -2906,6 +2949,9 @@
|
||||
<EmbeddedResource Include="Rig\Network\Camera\KeyenceIV3G120\CameraCfgCtrl.resx">
|
||||
<DependentUpon>CameraCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\Network\Camera\RoiForFixedStartCJMS11\RoiCfgCtrl.resx">
|
||||
<DependentUpon>RoiCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\Network\Camera\RoiForFixedStartKeyence\RoiCfgCtrl.resx">
|
||||
<DependentUpon>RoiCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
30
TBFTests/Rig/Network/Camera/CJMS11/CameraTest.cs
Normal file
30
TBFTests/Rig/Network/Camera/CJMS11/CameraTest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Network.Camera.CJMS11;
|
||||
|
||||
namespace TBFTests.Rig.Network.Camera.CJMS11
|
||||
{
|
||||
[TestClass]
|
||||
[TestSubject(typeof(TBF.Rig.Network.Camera.CJMS11.Camera))]
|
||||
public class CameraTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void Initialize()
|
||||
{
|
||||
Factory factory = new Factory();
|
||||
IComponentCfg config = new CameraCfg("Network.Adapter", factory);
|
||||
|
||||
|
||||
TBF.Rig.Network.Camera.CJMS11.Camera camera = new TBF.Rig.Network.Camera.CJMS11.Camera(config, null);
|
||||
|
||||
camera.Initialize();
|
||||
|
||||
Thread.Sleep(10000);
|
||||
camera.Stop();
|
||||
Thread.Sleep(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,6 +97,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Entities\MeasurementCorrectionTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Rig\Network\Camera\CJMS11\CameraTest.cs" />
|
||||
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\CameraTest.cs" />
|
||||
<Compile Include="Rig\Network\Camera\RoiForFixedStartKeyence\RoiTest.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -1 +1 @@
|
||||
42f452de9b0393e2b8a43441d6acf2f1268eaff5eb4a5cb56624e462418cf079
|
||||
8f46c126994e2e4deda67fad3f33cb2a280d2b4b7ce364598de6bc2d540d1738
|
||||
|
||||
Loading…
Reference in New Issue
Block a user