Compare commits

1 Commits

Author SHA1 Message Date
57c1c3e282 fix adding two cams with same ip 2025-05-31 23:44:27 +02:00
7 changed files with 134 additions and 181 deletions

77
MainForm.Designer.cs generated
View File

@@ -33,26 +33,26 @@
statusStripMain = new StatusStrip();
toolStripStatusLabel = new ToolStripStatusLabel();
toolStripStatusDisco = new ToolStripStatusLabel();
menuStrip = new MenuStrip();
menuStrip1 = new MenuStrip();
discoveryToolStripMenuItem = new ToolStripMenuItem();
discoverToolStripMenuItem = new ToolStripMenuItem();
toolStripSeparator2 = new ToolStripSeparator();
manualAddToolStripMenuItem = new ToolStripMenuItem();
toolStripSeparator1 = new ToolStripSeparator();
saveToolStripMenuItem = new ToolStripMenuItem();
loadToolStripMenuItem = new ToolStripMenuItem();
aboutStripMenuItem = new ToolStripMenuItem();
toolStripSeparator2 = new ToolStripSeparator();
discoverToolStripMenuItem = new ToolStripMenuItem();
statusStripMain.SuspendLayout();
menuStrip.SuspendLayout();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// lbMain
//
lbMain.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lbMain.FormattingEnabled = true;
lbMain.Location = new Point(12, 38);
lbMain.ItemHeight = 15;
lbMain.Location = new Point(12, 23);
lbMain.Name = "lbMain";
lbMain.Size = new Size(776, 379);
lbMain.Size = new Size(776, 394);
lbMain.TabIndex = 0;
lbMain.MouseDoubleClick += lbMain_MouseDoubleClick;
//
@@ -73,16 +73,17 @@
// toolStripStatusDisco
//
toolStripStatusDisco.Name = "toolStripStatusDisco";
toolStripStatusDisco.Size = new Size(0, 17);
toolStripStatusDisco.Size = new Size(111, 17);
toolStripStatusDisco.Text = "";
//
// menuStrip
// menuStrip1
//
menuStrip.Items.AddRange(new ToolStripItem[] { discoveryToolStripMenuItem, aboutStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(800, 24);
menuStrip.TabIndex = 2;
menuStrip.Text = "menuStrip1";
menuStrip1.Items.AddRange(new ToolStripItem[] { discoveryToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(800, 24);
menuStrip1.TabIndex = 2;
menuStrip1.Text = "menuStrip1";
//
// discoveryToolStripMenuItem
//
@@ -91,51 +92,42 @@
discoveryToolStripMenuItem.Size = new Size(70, 20);
discoveryToolStripMenuItem.Text = "Discovery";
//
// discoverToolStripMenuItem
//
discoverToolStripMenuItem.Name = "discoverToolStripMenuItem";
discoverToolStripMenuItem.Size = new Size(166, 22);
discoverToolStripMenuItem.Text = "Discover cameras";
discoverToolStripMenuItem.Click += discoverToolStripMenuItem_Click;
//
// toolStripSeparator2
//
toolStripSeparator2.Name = "toolStripSeparator2";
toolStripSeparator2.Size = new Size(163, 6);
//
// manualAddToolStripMenuItem
//
manualAddToolStripMenuItem.Name = "manualAddToolStripMenuItem";
manualAddToolStripMenuItem.Size = new Size(166, 22);
manualAddToolStripMenuItem.Size = new Size(180, 22);
manualAddToolStripMenuItem.Text = "Add manually";
manualAddToolStripMenuItem.Click += manualAddToolStripMenuItem_Click;
//
// toolStripSeparator1
//
toolStripSeparator1.Name = "toolStripSeparator1";
toolStripSeparator1.Size = new Size(163, 6);
toolStripSeparator1.Size = new Size(177, 6);
//
// saveToolStripMenuItem
//
saveToolStripMenuItem.Name = "saveToolStripMenuItem";
saveToolStripMenuItem.Size = new Size(166, 22);
saveToolStripMenuItem.Size = new Size(180, 22);
saveToolStripMenuItem.Text = "Save";
saveToolStripMenuItem.Click += saveToolStripMenuItem_Click;
//
// loadToolStripMenuItem
//
loadToolStripMenuItem.Name = "loadToolStripMenuItem";
loadToolStripMenuItem.Size = new Size(166, 22);
loadToolStripMenuItem.Size = new Size(180, 22);
loadToolStripMenuItem.Text = "Load";
loadToolStripMenuItem.Click += loadToolStripMenuItem_Click;
//
// aboutStripMenuItem
// toolStripSeparator2
//
aboutStripMenuItem.Alignment = ToolStripItemAlignment.Right;
aboutStripMenuItem.Name = "aboutStripMenuItem";
aboutStripMenuItem.Size = new Size(52, 20);
aboutStripMenuItem.Text = "About";
aboutStripMenuItem.Click += aboutStripMenuItem_Click;
toolStripSeparator2.Name = "toolStripSeparator2";
toolStripSeparator2.Size = new Size(177, 6);
//
// discoverToolStripMenuItem
//
discoverToolStripMenuItem.Name = "discoverToolStripMenuItem";
discoverToolStripMenuItem.Size = new Size(180, 22);
discoverToolStripMenuItem.Text = "Discover cameras";
//
// MainForm
//
@@ -143,16 +135,16 @@
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(statusStripMain);
Controls.Add(menuStrip);
Controls.Add(menuStrip1);
Controls.Add(lbMain);
Icon = (Icon)resources.GetObject("$this.Icon");
MainMenuStrip = menuStrip;
MainMenuStrip = menuStrip1;
Name = "MainForm";
Text = "RoboSpot MotionCamera finder";
statusStripMain.ResumeLayout(false);
statusStripMain.PerformLayout();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
@@ -162,7 +154,7 @@
private ListBox lbMain;
private StatusStrip statusStripMain;
private ToolStripStatusLabel toolStripStatusLabel;
private MenuStrip menuStrip;
private MenuStrip menuStrip1;
private ToolStripMenuItem discoveryToolStripMenuItem;
private ToolStripMenuItem saveToolStripMenuItem;
private ToolStripMenuItem loadToolStripMenuItem;
@@ -171,6 +163,5 @@
private ToolStripMenuItem manualAddToolStripMenuItem;
private ToolStripMenuItem discoverToolStripMenuItem;
private ToolStripSeparator toolStripSeparator2;
private ToolStripMenuItem aboutStripMenuItem;
}
}

View File

@@ -14,13 +14,10 @@ namespace robospot_camera_finder
{
public partial class MainForm : Form
{
// Version
public string VERSION = "1.2.0";
public string VERSION = "1.0.0";
// Main list containing all cameras
private BindingList<Camera> all_cameras = new();
// Camera credentials
public static string cam_username = "admin";
public static string cam_password = "RoboSpot10";
@@ -31,29 +28,29 @@ namespace robospot_camera_finder
private const byte DEF_REQ_SCAN = 1;
private const byte RES_REQ_SCAN = 11;
// UDP clients
private UdpClient sendClient;
private UdpClient receiveClient;
private bool isDiscovering = false;
// Camera class
public class Camera
{
public Camera(string name, string ip, string id)
public Camera(string name, string ip, string location, string serial)
{
camera_name = name;
camera_ip = ip;
camera_id = id;
camera_location = location;
camera_serial = serial;
}
public string camera_name { get; set; }
public string camera_ip { get; set; }
public string camera_id { get; set; }
public string camera_location { get; set; }
public string camera_serial { get; set; }
}
// Discovery packet struc
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DataPacketIPv4
{
@@ -142,10 +139,9 @@ namespace robospot_camera_finder
InitializeUdpClients();
// Discover cameras
DiscoverCameras();
discover_cameras();
}
// Inits UDP clients
private void InitializeUdpClients()
{
try
@@ -161,8 +157,7 @@ namespace robospot_camera_finder
}
}
// Add cameras to the main list
private void AddCamera(Camera new_camera)
private void add_camera(Camera new_camera)
{
if (all_cameras.Count == 0)
{
@@ -170,7 +165,7 @@ namespace robospot_camera_finder
}
else
{
Camera find_cam = all_cameras.FirstOrDefault(cam => cam.camera_id == new_camera.camera_id);
Camera find_cam = all_cameras.FirstOrDefault(cam => cam.camera_serial == new_camera.camera_serial);
if (find_cam != null)
{
@@ -184,6 +179,67 @@ namespace robospot_camera_finder
}
}
private void lbMain_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (lbMain.SelectedItem != null)
{
toolStripStatusLabel.Text = "Loading camera...";
Camera camera = all_cameras.FirstOrDefault<Camera>(cam => cam.camera_ip.ToString() == lbMain.SelectedValue.ToString());
Form viewer = new StreamViewer(lbMain.GetItemText(lbMain.SelectedItem), lbMain.SelectedValue.ToString(), camera, this);
viewer.Show();
toolStripStatusLabel.Text = "";
}
}
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
string json = "";
OpenFileDialog openFile = new OpenFileDialog();
openFile.Filter = "json file (*.json)|*.json";
openFile.RestoreDirectory = true;
if (openFile.ShowDialog() == DialogResult.OK)
{
json = File.ReadAllText(openFile.FileName);
List<Camera> cameras_in_file = JsonSerializer.Deserialize<List<Camera>>(json);
foreach (Camera new_camera in cameras_in_file)
{
add_camera(new_camera);
}
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
string json = JsonSerializer.Serialize<BindingList<Camera>>(all_cameras, new JsonSerializerOptions
{
WriteIndented = true
});
SaveFileDialog saveFile = new SaveFileDialog();
saveFile.Filter = "json file (*.json)|*.json";
saveFile.RestoreDirectory = true;
if (saveFile.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(saveFile.FileName, json);
}
}
private void manualAddToolStripMenuItem_Click(object sender, EventArgs e)
{
Manual_IP_Form manualForm = new Manual_IP_Form();
if (manualForm.ShowDialog(this) == DialogResult.OK)
{
string ipAddress = manualForm.ipAddress;
Camera camera_to_add = new Camera("Camera " + ipAddress, ipAddress, "", "CAM_FINDER_" + DateTime.Now.Ticks.ToString());
add_camera(camera_to_add);
}
}
// Helper method to convert structure to byte array
private byte[] StructureToByteArray(DataPacketIPv4 packet)
{
@@ -367,13 +423,14 @@ namespace robospot_camera_finder
Camera discoveredCamera = new Camera(
$"{deviceName} - ({cameraIP})",
cameraIP,
packetId
$"MAC: {macAddress}",
packetId // Using packet_id as serial for uniqueness
);
// Add camera to list (must be done on UI thread)
this.Invoke(new Action(() =>
{
AddCamera(discoveredCamera);
add_camera(discoveredCamera);
toolStripStatusLabel.Text = $"Found camera: {cameraName} ({cameraIP})";
}));
}
@@ -389,7 +446,7 @@ namespace robospot_camera_finder
}
// Main discovery method
private async void DiscoverCameras()
private async void discover_cameras()
{
if (isDiscovering)
{
@@ -409,7 +466,6 @@ namespace robospot_camera_finder
isDiscovering = true;
toolStripStatusLabel.Text = "Discovering cameras...";
discoverToolStripMenuItem.Enabled = false;
try
{
@@ -435,68 +491,6 @@ namespace robospot_camera_finder
{
isDiscovering = false;
toolStripStatusLabel.Text = $"Discovery complete. Found {all_cameras.Count} cameras.";
discoverToolStripMenuItem.Enabled = true;
}
}
private void lbMain_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (lbMain.SelectedItem != null)
{
toolStripStatusLabel.Text = "Loading camera...";
Camera camera = all_cameras.FirstOrDefault<Camera>(cam => cam.camera_ip.ToString() == lbMain.SelectedValue.ToString());
Form viewer = new StreamViewer(camera, this);
viewer.Show();
toolStripStatusLabel.Text = "";
}
}
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
string json = "";
OpenFileDialog openFile = new OpenFileDialog();
openFile.Filter = "json file (*.json)|*.json";
openFile.RestoreDirectory = true;
if (openFile.ShowDialog() == DialogResult.OK)
{
json = File.ReadAllText(openFile.FileName);
List<Camera> cameras_in_file = JsonSerializer.Deserialize<List<Camera>>(json);
foreach (Camera new_camera in cameras_in_file)
{
AddCamera(new_camera);
}
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
string json = JsonSerializer.Serialize<BindingList<Camera>>(all_cameras, new JsonSerializerOptions
{
WriteIndented = true
});
SaveFileDialog saveFile = new SaveFileDialog();
saveFile.Filter = "json file (*.json)|*.json";
saveFile.RestoreDirectory = true;
if (saveFile.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(saveFile.FileName, json);
}
}
private void manualAddToolStripMenuItem_Click(object sender, EventArgs e)
{
Manual_IP_Form manualForm = new Manual_IP_Form();
if (manualForm.ShowDialog(this) == DialogResult.OK)
{
string ipAddress = manualForm.ipAddress;
Camera camera_to_add = new Camera("Camera " + ipAddress, ipAddress, ipAddress);
AddCamera(camera_to_add);
}
}
@@ -514,15 +508,5 @@ namespace robospot_camera_finder
base.OnFormClosing(e);
}
private void discoverToolStripMenuItem_Click(object sender, EventArgs e)
{
DiscoverCameras();
}
private void aboutStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("RoboSpot Camera Finder v" + VERSION, "RoboSpot Camera Finder", MessageBoxButtons.OK);
}
}
}

View File

@@ -120,7 +120,7 @@
<metadata name="statusStripMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>153, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<PublishDir>bin\Release\net9.0-windows\publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net9.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>

View File

@@ -1,4 +1,6 @@
namespace robospot_camera_finder
using LibVLCSharp.Forms.Shared;
namespace robospot_camera_finder
{
partial class StreamViewer
{

View File

@@ -8,30 +8,29 @@ namespace robospot_camera_finder
public LibVLC _libVLC;
public MediaPlayer _mp;
MainForm.Camera camera;
string cam_ip = "";
const int MAX_ZOOM_PULSE = 9999;
const int MIN_ZOOM_PULSE = 10;
int max_zoom_pulse = 9999;
int min_zoom_pulse = 10;
bool zoomTestSeqFlag = false;
public StreamViewer(MainForm.Camera cam, MainForm mainForm)
public StreamViewer(string name, string ip, MainForm.Camera camera, MainForm mainForm)
{
InitializeComponent();
_libVLC = new LibVLC();
_mp = new MediaPlayer(_libVLC);
camera = cam;
cam_ip = ip;
this.Text = name;
this.Text = camera.camera_name;
if (!cam.camera_ip.StartsWith("10."))
if (!cam_ip.StartsWith("10."))
{
MessageBox.Show("Camera is not on the 10.0.0.0/8 network, the RoboSpot might not find it.", "Wrong IP", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
string rtsp_link = "rtsp://" + camera.camera_ip + "/profile2/media.smp";
string rtsp_link = "rtsp://" + ip + "/profile2/media.smp";
updateZoomSlider();
@@ -46,7 +45,7 @@ namespace robospot_camera_finder
private void updateZoomSlider()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + camera.camera_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=query&action=view&Query=Zoom");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + cam_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=query&action=view&Query=Zoom");
request.Credentials = new NetworkCredential(MainForm.cam_username, MainForm.cam_password);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string text;
@@ -60,16 +59,16 @@ namespace robospot_camera_finder
private void sendZoomValue(string zoom_pulse)
{
// clamp values to allowed range
if (int.Parse(zoom_pulse) < MIN_ZOOM_PULSE)
if (int.Parse(zoom_pulse) < min_zoom_pulse)
{
zoom_pulse = MIN_ZOOM_PULSE.ToString();
zoom_pulse = min_zoom_pulse.ToString();
}
if (int.Parse(zoom_pulse) > MAX_ZOOM_PULSE)
if (int.Parse(zoom_pulse) > max_zoom_pulse)
{
zoom_pulse = MAX_ZOOM_PULSE.ToString();
zoom_pulse = max_zoom_pulse.ToString();
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + camera.camera_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=absolute&action=control&ZoomPulse=" + zoom_pulse);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + cam_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=absolute&action=control&ZoomPulse=" + zoom_pulse);
request.Credentials = new NetworkCredential(MainForm.cam_username, MainForm.cam_password);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
@@ -77,7 +76,7 @@ namespace robospot_camera_finder
private void sendZoomValueManual(string zoom_value)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + camera.camera_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=continuous&NormalizedSpeed=True&action=control&Channel=0&Zoom=" + zoom_value);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + cam_ip + "/stw-cgi/ptzcontrol.cgi?msubmenu=continuous&NormalizedSpeed=True&action=control&Channel=0&Zoom=" + zoom_value);
request.Credentials = new NetworkCredential(MainForm.cam_username, MainForm.cam_password);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
@@ -106,13 +105,13 @@ namespace robospot_camera_finder
private void btnZoomMax_Click(object sender, EventArgs e)
{
tbZoom.Value = MAX_ZOOM_PULSE;
tbZoom.Value = max_zoom_pulse;
sendZoomValue(tbZoom.Value.ToString());
}
private void btnZoomMin_Click(object sender, EventArgs e)
{
tbZoom.Value = MIN_ZOOM_PULSE;
tbZoom.Value = min_zoom_pulse;
sendZoomValue(tbZoom.Value.ToString());
}
@@ -131,12 +130,12 @@ namespace robospot_camera_finder
{
if (zoomTestSeqFlag)
{
tbZoom.Value = MIN_ZOOM_PULSE;
tbZoom.Value = min_zoom_pulse;
sendZoomValue(tbZoom.Value.ToString());
zoomTestSeqFlag = false;
} else
{
tbZoom.Value = MAX_ZOOM_PULSE;
tbZoom.Value = max_zoom_pulse;
sendZoomValue(tbZoom.Value.ToString());
zoomTestSeqFlag = true;
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<TargetFramework>net9.0-windows7.0</TargetFramework>
<RootNamespace>robospot_camera_finder</RootNamespace>
<Nullable>disable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
@@ -13,20 +13,13 @@
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="LibVLCSharp" Version="3.8.2" />
<PackageReference Include="LibVLCSharp.Forms" Version="3.8.2" />
<PackageReference Include="LibVLCSharp.WinForms" Version="3.8.2" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.20" />
</ItemGroup>