using System; using System.IO; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using Inspectron.HawkEye.Protocol.Interfaces; using Inspectron.HawkEye.UDPB; using Newtonsoft.Json; namespace Inspectron.HawkEye.Protocol { public class ImageServer { private readonly IImageSource _imageSource; private readonly ICameraControl _cameraControl; private readonly ILightControl _lightControl; private readonly UDPBSocket _commandSocket = new UDPBSocket(); private readonly UDPBSocket _imageSocket = new UDPBSocket(); private bool _autoTrigger; private bool _applySettings; private CameraSettings _imageSettingsToApply=new CameraSettings(){ImageSettings = new ImageSettings()}; public ImageServer(IImageSource imageSource, ICameraControl cameraControl, ILightControl lightControl) { _imageSource = imageSource; _cameraControl = cameraControl; _lightControl = lightControl; _imageSocket.LossSimulation = 0; } public void Start() { _commandSocket.Listen(IPAddress.Any, 27001); var th = new Thread(ReceiveLoop); th.Start(); if (File.Exists("settings.json")) { var settings = JsonConvert.DeserializeObject(File.ReadAllText("settings.json")); _imageSettingsToApply = settings; ApplyParameters(settings); } } public void ApplyParameters(CameraSettings cameraSettings) { _cameraControl.SetParameters(cameraSettings); _lightControl.SetLight(cameraSettings.LightPwm1, cameraSettings.LightPwm2); } private void SaveSettingsLocally() { File.WriteAllText("settings.json", JsonConvert.SerializeObject(_imageSettingsToApply)); } private void ReceiveLoop() { while (true) { var data = _commandSocket.Receive(); try { ProcessCommand(data); } catch (Exception e) { Console.WriteLine(e); } } } private void TriggerLoop() { while (_autoTrigger) { if (_applySettings) { ApplyParameters(_imageSettingsToApply); _applySettings = false; } try { SendImage(); } catch { return; } } } private void ProcessCommand(byte[] data) { Console.WriteLine(((ECommand) data[0]).ToString()); switch ((ECommand) data[0]) { case ECommand.Connect: { var port = new byte[4]; Array.Copy(data, 1, port, 0, 4); _imageSocket.Connect(new IPEndPoint((_commandSocket.LastConnection as IPEndPoint).Address, BitConverter.ToInt32(port,0)),null); var databytes = new byte[1000]; var settings = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_imageSettingsToApply)); Array.Copy(settings, 0, databytes, 1, settings.Length); databytes[0] = (byte) ECommand.Settings; _commandSocket.SendData(databytes); } break; case ECommand.Trigger: { Task.Run(() => { SendImage(); }); } break; case ECommand.StartContinuous: { _autoTrigger = true; var th = new Thread(TriggerLoop); th.Start(); } break; case ECommand.StopContinuous: { _autoTrigger = false; } break; case ECommand.Settings: { var databytes = new byte[999]; Array.Copy(data, 1, databytes, 0, 999); var settings = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(databytes)); _imageSettingsToApply = settings; if (_autoTrigger) _applySettings = true; else ApplyParameters(_imageSettingsToApply); } break; case ECommand.SaveSettings: { SaveSettingsLocally(); } break; default: throw new ArgumentOutOfRangeException(); } } private void SendImage() { var image = _imageSource.GetImage(); var b = new byte[image.Length + 1]; b[0] = (byte) EData.Image; Array.Copy(image, 0, b, 1, image.Length); _imageSocket.SendData(b); } } }