private static void HandleZoomAndFocus(DateTime nextEventTime, WebClient wc, CameraDefinition cam, string zoom, string focus) { double dbl; bool SetZoom = !string.IsNullOrWhiteSpace(zoom) && double.TryParse(zoom, out dbl); bool FocusIsEmpty = string.IsNullOrWhiteSpace(focus); bool ManualFocus = FocusIsEmpty ? false : double.TryParse(focus, out dbl); // There are 4 cases if (SetZoom) { if (ManualFocus) { // Case 1: Manual Zoom, Manual Focus Thread.Sleep(3000); // Do this in a loop, because Dahua's API is buggy. // Often, the first command causes only focus to happen. // The second typically causes zoom and autofocus. // The third or fourth usually causes our manual focus level to be set. for (int i = 0; i < 5; i++) { WebRequestRobust(nextEventTime, wc, cam.GetUrlBase() + "cgi-bin/devVideoInput.cgi?action=adjustFocus&focus=" + focus + "&zoom=" + zoom); Thread.Sleep(Math.Max(1, cam.secondsBetweenLensCommands) * 1000); } } else { // Case 2: Manual Zoom, Autofocus focus = zoom; Thread.Sleep(3000); // Do this in a loop, because Dahua's API is buggy. // Often, the first command causes only focus to happen. // The second typically causes zoom and autofocus. // The third or fourth usually causes our manual focus level to be set. for (int i = 0; i < 4; i++) { WebRequestRobust(nextEventTime, wc, cam.GetUrlBase() + "cgi-bin/devVideoInput.cgi?action=adjustFocus&focus=" + focus + "&zoom=" + zoom); Thread.Sleep(Math.Max(1, cam.secondsBetweenLensCommands) * 1000); } // This method has been, in my experience, reliable enough to call only once. WebRequestRobust(nextEventTime, wc, cam.GetUrlBase() + "cgi-bin/devVideoInput.cgi?action=autoFocus"); } } else { if (FocusIsEmpty || ManualFocus) { // Case 4: Don't zoom and don't focus. Do nothing. } else { // Case 3: Autofocus Only // This method has been, in my experience, reliable enough to call only once. WebRequestRobust(nextEventTime, wc, cam.GetUrlBase() + "cgi-bin/devVideoInput.cgi?action=autoFocus"); } } }