/// <summary> /// Blocks until the specified learning operation is complete. /// </summary> /// <param name="lessonId">ID of the learning operation which was started.</param> public void AwaitLearningResult(string lessonId) { if (device == null || consecutiveCommandFailures >= 5) { LoadDeviceInfo_Throttled(); } BindState state = GetCurrentLearningState(); while (state?.bindId == lessonId && state.bindStart + 5000 > TimeUtil.GetTimeInMsSinceEpoch()) { Thread.Sleep(100); state = GetCurrentLearningState(); } lock (myLock) { if (_learningState?.bindId == lessonId) { BroadLinkCmd cmd = BroadLinkCommands.commands.Get(_learningState.hotkeyId); if (cmd == null) { return; } try { Task <RMCommand> finishLearningTask = device.ReadLearningDataAsync(); finishLearningTask.Wait(); if (finishLearningTask.Result != null) { cmd.type = finishLearningTask.Result.Type; cmd.codes = finishLearningTask.Result.GetPulses(); BroadLinkCommands.Save(); } } catch (Exception ex) { string exMsg = ex.InnerException != null ? ex.InnerException.Message : ex.Message; Logger.Info("BroadLink Controller \"" + name + "\" failed to learn command codes. " + exMsg); } _learningState = null; } } }
public BroadLinkCmd UnlearnCommandCodes(string lessonId) { if (_learningState != null) { lock (myLock) { if (_learningState != null) { BroadLinkCmd cmd = BroadLinkCommands.commands.Get(_learningState.hotkeyId); if (cmd != null) { cmd.codes = null; } BroadLinkCommands.Save(); Logger.Info("[" + _learningState.bindId + "] Command Learning - UNLEARN" + (cmd != null ? "" : " FAILED: Command " + _learningState.hotkeyId + " did not exist")); _learningState = null; return(cmd); } } } return(null); }
public static void HandleRequest(HttpProcessor p, string jsonStr) { object response = null; try { dynamic requestObj = JsonConvert.DeserializeObject(jsonStr); string cmd = Try.Get(() => (string)requestObj.cmd); switch (cmd) { case "log_get": { int nextLine = (int)requestObj.nextLine; long logId = (long)requestObj.logId; if (logId == -1) { logId = ServiceWrapper.logReader.readerId; } else if (logId != ServiceWrapper.logReader.readerId) { response = new ResultLogGet("REFRESH", -1, ServiceWrapper.logReader.readerId, null); break; } List <string> lines = ServiceWrapper.logReader.GetLogUpdate(logId, ref nextLine); response = new ResultLogGet("OK", nextLine, ServiceWrapper.logReader.readerId, lines); break; } #region Hotkeys case "hotkey_reorder": case "hotkey_names": case "hotkey_list": case "hotkey_new": case "hotkey_get": case "hotkey_update": case "hotkey_delete": { response = NamedItemAPI(requestObj, ServiceWrapper.config.hotkeys); break; } case "beginHotkeyBind": { int hotkeyId = requestObj.hotkeyId; string bindId = ServiceWrapper.hotkeyManager.BeginHotkeyBind(hotkeyId); if (bindId == null) { response = new ResultFailWithReason("hotkey not found"); } else if (bindId == "") { response = new ResultFailWithReason("another bind is already in progress"); } else { response = new ResultWithData(bindId); } break; } case "endHotkeyBind": { int hotkeyId = requestObj.hotkeyId; Hotkey hotkey = ServiceWrapper.config.hotkeys.Get(hotkeyId); if (hotkey == null) { response = new ResultFailWithReason("hotkey not found"); break; } string bindId = requestObj.bindId; if (string.IsNullOrWhiteSpace(bindId)) { response = new ResultFailWithReason("invalid bindId"); break; } while (bindId == ServiceWrapper.hotkeyManager.GetCurrentBindId()) { Thread.Sleep(100); } response = new ResultWithData(hotkey); break; } case "cancelHotkeyBind": { string bindId = requestObj.bindId; if (string.IsNullOrWhiteSpace(bindId)) { response = new ResultFailWithReason("invalid bindId"); break; } ServiceWrapper.hotkeyManager.CancelHotkeyBind(bindId); response = new ResultSuccess(); break; } case "unbindHotkey": { string bindId = requestObj.bindId; if (string.IsNullOrWhiteSpace(bindId)) { response = new ResultFailWithReason("invalid bindId"); break; } Hotkey hotkey = ServiceWrapper.hotkeyManager.UnbindHotkey(bindId); if (hotkey != null) { response = new ResultWithData(hotkey); } else { response = new ResultFailWithReason("Unable to unbind hotkey. Please try again."); } break; } case "executeHotkey": { int hotkeyId = requestObj.hotkeyId; string error = ServiceWrapper.hotkeyManager.ExecuteHotkeyById(hotkeyId); if (error == null) { response = new ResultSuccess(); } else { response = new ResultFailWithReason("Hotkey manual execution failed: " + error); } break; } #endregion #region BroadLink case "broadlink_reorder": case "broadlink_names": case "broadlink_list": case "broadlink_new": case "broadlink_get": case "broadlink_update": case "broadlink_delete": { response = NamedItemAPI(requestObj, ServiceWrapper.config.broadLinks); break; } case "broadlink_command_short_names": { response = new ResultWithData(IRBlasters.IRCommands.GetIRCommandShortNames()); break; } #endregion #region BroadLink Commands case "broadlinkcmd_reorder": case "broadlinkcmd_names": case "broadlinkcmd_list": case "broadlinkcmd_new": case "broadlinkcmd_get": case "broadlinkcmd_update": case "broadlinkcmd_delete": { response = NamedItemAPI(requestObj, BroadLinkCommands.commands, (Action)(() => { BroadLinkCommands.Save(ServiceWrapper.BroadLinkCommandsFile); })); break; } case "broadlinkcmd_reload_commands": { BroadLinkCommands.Load(ServiceWrapper.BroadLinkCommandsFile); response = new ResultSuccess(); break; } case "beginBroadlinkCommandLearn": { int controllerId = requestObj.controllerId; int commandId = requestObj.commandId; string lessonId = BroadLinkCommands.BeginLearning(controllerId, commandId); if (lessonId == null) { response = new ResultFailWithReason("hotkey not found"); } else if (lessonId == "") { response = new ResultFailWithReason("another bind is already in progress"); } else { response = new ResultWithData(lessonId); } break; } case "endBroadlinkCommandLearn": { int controllerId = requestObj.controllerId; int commandId = requestObj.commandId; BroadLinkCmd command = BroadLinkCommands.commands.Get(commandId); if (command == null) { response = new ResultFailWithReason("command not found"); break; } string lessonId = requestObj.lessonId; if (string.IsNullOrWhiteSpace(lessonId)) { response = new ResultFailWithReason("invalid lessonId"); break; } BroadLinkCommands.AwaitLearningResult(controllerId, lessonId); response = new ResultWithData(command); break; } case "cancelBroadlinkCommandLearn": { int controllerId = requestObj.controllerId; string lessonId = requestObj.lessonId; if (string.IsNullOrWhiteSpace(lessonId)) { response = new ResultFailWithReason("invalid lessonId"); break; } BroadLinkCommands.CancelLearning(controllerId, lessonId); response = new ResultSuccess(); break; } case "unlearnBroadlinkCommand": { int controllerId = requestObj.controllerId; string lessonId = requestObj.lessonId; if (string.IsNullOrWhiteSpace(lessonId)) { response = new ResultFailWithReason("invalid lessonId"); break; } BroadLinkCmd command = BroadLinkCommands.UnlearnCommandCodes(controllerId, lessonId); if (command != null) { response = new ResultWithData(command); } else { response = new ResultFailWithReason("Unable to unbind command. Please try again."); } break; } #endregion #region iTach case "itach_reorder": case "itach_names": case "itach_list": case "itach_new": case "itach_get": case "itach_update": case "itach_delete": { response = NamedItemAPI(requestObj, ServiceWrapper.config.iTachs); break; } case "ir_command_short_names": { response = new ResultWithData(IRBlasters.IRCommands.GetIRCommandShortNames()); break; } case "itach_reload_commands": { iTachCommands.Load(ServiceWrapper.iTachCommandsFile); response = new ResultSuccess(); break; } #endregion #region Vera case "vera_reorder": case "vera_names": case "vera_list": case "vera_new": case "vera_get": case "vera_update": case "vera_delete": { response = NamedItemAPI(requestObj, ServiceWrapper.config.veras); break; } case "vera_command_list": { List <object> list = new List <object>(); Parallel.ForEach(ServiceWrapper.config.veras.List(), vera => { ConcurrentDictionary <int, string> map = vera.GetDeviceIdToDisplayNameMap(); if (map != null) { int[] DeviceIds = map.Keys.ToArray(); string[] Names = DeviceIds.Select(id => map[id]).ToArray(); lock (list) { list.Add(new { Id = vera.id, Name = vera.name, DeviceIds = DeviceIds, Names = Names }); } } }); response = new ResultWithData(list); break; } case "vera_reload_commands": { int success = 0; int failure = 0; Parallel.ForEach(ServiceWrapper.config.veras.List(), vera => { if (vera.LoadDisplayNames(true)) { Interlocked.Increment(ref success); } else { Interlocked.Increment(ref failure); } }); response = new ResultWithData("Vera Command Loading complete. Successful loads: " + success + ". Failed loads: " + failure); break; } #endregion #region HomeAssistant case "hass_reorder": case "hass_names": case "hass_list": case "hass_new": case "hass_get": case "hass_update": case "hass_delete": { response = NamedItemAPI(requestObj, ServiceWrapper.config.homeAssistantServers); break; } case "hass_entities": { List <object> list = new List <object>(); Parallel.ForEach(ServiceWrapper.config.homeAssistantServers.List(), hass => { List <object> listFromOneServer = hass.GetCommandList(); list.AddRange(listFromOneServer); }); response = new ResultWithData(list); break; } case "hass_load": { int success = 0; int failure = 0; Parallel.ForEach(ServiceWrapper.config.homeAssistantServers.List(), hass => { if (hass.Load()) { Interlocked.Increment(ref success); } else { Interlocked.Increment(ref failure); } }); response = new ResultWithData("HomeAssistant Entity Loading complete. Successful loads: " + success + ". Failed loads: " + failure); break; } #endregion default: response = new ResultFail() { error = "command \"" + cmd + "\" not supported" }; break; } } catch (Exception ex) { Logger.Debug(ex); response = new ResultFail() { error = "An unexpected error occurred. " + ex.ToString() }; } finally { if (response == null) { response = new ResultFail() { error = "Application Error: A response was not generated, so this response was generated as a fallback." } } ; p.CompressResponseIfCompatible(); p.writeSuccess(jsonType); p.outputStream.Write(JsonConvert.SerializeObject(response)); } }