diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 906ae68..a45f8fe 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -27,7 +27,7 @@ ColorControl Maassoft 0 - 4.2.3.0 + 4.3.0.0 false true true @@ -242,9 +242,10 @@ + - + MainForm.cs diff --git a/ColorControl/LgDevice.cs b/ColorControl/LgDevice.cs index af93b18..dba70d1 100644 --- a/ColorControl/LgDevice.cs +++ b/ColorControl/LgDevice.cs @@ -33,7 +33,8 @@ namespace ColorControl Active, Power_Off, Suspend, - Active_Standby + Active_Standby, + Screen_Off } public enum PowerOffSource @@ -123,6 +124,8 @@ namespace ColorControl AddGenericPictureAction("gameOptimizationHDMI3", typeof(OffToOn), category: "other"); AddGenericPictureAction("gameOptimizationHDMI4", typeof(OffToOn), category: "other"); AddGenericPictureAction("adjustingLuminance", minValue: -50, maxValue: 50); + AddInvokableAction("turnScreenOff", new Func, bool>(TurnScreenOffAction)); + AddInvokableAction("turnScreenOn", new Func, bool>(TurnScreenOnAction)); } private void AddInvokableAction(string name, Func, bool> function) @@ -377,6 +380,14 @@ namespace ColorControl key = keyValue[0]; parameters = keyValue[1].Substring(0, keyValue[1].Length - 1).Split(';'); } + + var delay = 0; + if (keySpec.Length == 2) + { + delay = Utils.ParseInt(keySpec[1]); + } + + var executeKey = true; var action = _invokableActions.FirstOrDefault(a => a.Name.Equals(key, StringComparison.OrdinalIgnoreCase)); if (action != null) { @@ -385,23 +396,25 @@ namespace ColorControl ExecuteAction(action, parameters); } - continue; + executeKey = false; } if (ExternalServiceHandler != null && parameters != null) { if (ExternalServiceHandler(key, parameters)) { - continue; + executeKey = false; } } - if (keySpec.Length == 2) - { - SendKey(mouse, key, int.Parse(keySpec[1])); - } - else + if (executeKey) { SendKey(mouse, key); + delay = delay == 0 ? 180 : delay; + } + + if (delay > 0) + { + await Task.Delay(delay); } } } @@ -425,7 +438,7 @@ namespace ColorControl function(null); } - private void SendKey(LgWebOsMouseService mouse, string key, int delay = 180) + private void SendKey(LgWebOsMouseService mouse, string key) { if (key.Length == 1 && int.TryParse(key, out _)) { @@ -433,7 +446,6 @@ namespace ColorControl } var button = (ButtonType)Enum.Parse(typeof(ButtonType), key); mouse.SendButton(button); - Thread.Sleep(delay); } public async Task GetMouseAsync() @@ -651,6 +663,22 @@ namespace ColorControl return Wake(); } + private bool TurnScreenOffAction(Dictionary parameters) + { + var task = _lgTvApi.TurnScreenOff(); + Utils.WaitForTask(task); + + return true; + } + + private bool TurnScreenOnAction(Dictionary parameters) + { + var task = _lgTvApi.TurnScreenOn(); + Utils.WaitForTask(task); + + return true; + } + private bool GenericPictureAction(Dictionary parameters) { var settingName = parameters["name"].ToString(); diff --git a/ColorControl/Properties/AssemblyInfo.cs b/ColorControl/Properties/AssemblyInfo.cs index 2e931de..ef59674 100644 --- a/ColorControl/Properties/AssemblyInfo.cs +++ b/ColorControl/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.2.3.0")] -[assembly: AssemblyFileVersion("4.2.3.0")] +[assembly: AssemblyVersion("4.3.0.0")] +[assembly: AssemblyFileVersion("4.3.0.0")] diff --git a/ColorControl/Resources/LG_register.json b/ColorControl/Resources/LG_register.json new file mode 100644 index 0000000..bcd828d --- /dev/null +++ b/ColorControl/Resources/LG_register.json @@ -0,0 +1,77 @@ +{ + "type":"register", + "id":"register_0", + "payload":{ + "forcePairing":false, + "pairingType":"PROMPT", + "client-key":"CLIENTKEYGOESHERE", + "manifest":{ + "manifestVersion":1, + "appVersion":"1.1", + "signed":{ + "created":"20140509", + "appId":"com.lge.test", + "vendorId":"com.lge", + "localizedAppNames":{ + "":"LG Remote App", + "ko-KR":"리모컨 앱", + "zxx-XX":"ЛГ Rэмotэ AПП" + }, + "localizedVendorNames":{ + "":"LG Electronics" + }, + "permissions":[ + "TEST_SECURE", + "CONTROL_INPUT_TEXT", + "CONTROL_MOUSE_AND_KEYBOARD", + "READ_INSTALLED_APPS", + "READ_LGE_SDX", + "READ_NOTIFICATIONS", + "SEARCH", + "WRITE_SETTINGS", + "WRITE_NOTIFICATION_ALERT", + "CONTROL_POWER", + "READ_CURRENT_CHANNEL", + "READ_RUNNING_APPS", + "READ_UPDATE_INFO", + "UPDATE_FROM_REMOTE_APP", + "READ_LGE_TV_INPUT_EVENTS", + "READ_TV_CURRENT_TIME" + ], + "serial":"2f930e2d2cfe083771f68e4fe7bb07" + }, + "permissions":[ + "LAUNCH", + "LAUNCH_WEBAPP", + "APP_TO_APP", + "CLOSE", + "TEST_OPEN", + "TEST_PROTECTED", + "CONTROL_AUDIO", + "CONTROL_DISPLAY", + "CONTROL_INPUT_JOYSTICK", + "CONTROL_INPUT_MEDIA_RECORDING", + "CONTROL_INPUT_MEDIA_PLAYBACK", + "CONTROL_INPUT_TV", + "CONTROL_POWER", + "CONTROL_TV_SCREEN", + "READ_APP_STATUS", + "READ_CURRENT_CHANNEL", + "READ_INPUT_DEVICE_LIST", + "READ_NETWORK_STATE", + "READ_RUNNING_APPS", + "READ_TV_CHANNEL_LIST", + "WRITE_NOTIFICATION_TOAST", + "READ_POWER_STATE", + "READ_COUNTRY_INFO", + "READ_SETTINGS" + ], + "signatures":[ + { + "signatureVersion":1, + "signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw==" + } + ] + } + } +} \ No newline at end of file diff --git a/ColorControl/lgtv/LgTvApi.cs b/ColorControl/lgtv/LgTvApi.cs index 0d5aed6..4a4b273 100644 --- a/ColorControl/lgtv/LgTvApi.cs +++ b/ColorControl/lgtv/LgTvApi.cs @@ -108,11 +108,6 @@ namespace LgTv private List _channelList; private List _appList; private string _ip; - - private const string BEFORE_PAIR_HAND_SHAKE = "{\"type\":\"register\",\"id\":\"register_0\",\"payload\":{\"forcePairing\":false,\"pairingType\":\"PROMPT\",\"manifest\":{\"manifestVersion\":1,\"appVersion\":\"1.1\",\"signed\":{\"created\":\"20140509\",\"appId\":\"com.lge.test\",\"vendorId\":\"com.lge\",\"localizedAppNames\":{\"\":\"LG Remote App\",\"ko-KR\":\"리모컨 앱\",\"zxx-XX\":\"ЛГ Rэмotэ AПП\"},\"localizedVendorNames\":{\"\":\"LG Electronics\"},\"permissions\":[\"TEST_SECURE\",\"CONTROL_INPUT_TEXT\",\"CONTROL_MOUSE_AND_KEYBOARD\",\"READ_INSTALLED_APPS\",\"READ_LGE_SDX\",\"READ_NOTIFICATIONS\",\"SEARCH\",\"WRITE_SETTINGS\",\"WRITE_NOTIFICATION_ALERT\",\"CONTROL_POWER\",\"READ_CURRENT_CHANNEL\",\"READ_RUNNING_APPS\",\"READ_UPDATE_INFO\",\"UPDATE_FROM_REMOTE_APP\",\"READ_LGE_TV_INPUT_EVENTS\",\"READ_TV_CURRENT_TIME\"],\"serial\":\"2f930e2d2cfe083771f68e4fe7bb07\"},\"permissions\":[\"LAUNCH\",\"LAUNCH_WEBAPP\",\"APP_TO_APP\",\"CLOSE\",\"TEST_OPEN\",\"TEST_PROTECTED\",\"CONTROL_AUDIO\",\"CONTROL_DISPLAY\",\"CONTROL_INPUT_JOYSTICK\",\"CONTROL_INPUT_MEDIA_RECORDING\",\"CONTROL_INPUT_MEDIA_PLAYBACK\",\"CONTROL_INPUT_TV\",\"CONTROL_POWER\",\"READ_APP_STATUS\",\"READ_CURRENT_CHANNEL\",\"READ_INPUT_DEVICE_LIST\",\"READ_NETWORK_STATE\",\"READ_RUNNING_APPS\",\"READ_TV_CHANNEL_LIST\",\"WRITE_NOTIFICATION_TOAST\",\"READ_POWER_STATE\",\"READ_COUNTRY_INFO\",\"READ_SETTINGS\"],\"signatures\":[{\"signatureVersion\":1,\"signature\":\"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw==\"}]}}}"; - - private const string AFTER_PAIR_HAND_SHAKE = "{\"type\":\"register\",\"id\":\"register_0\",\"payload\":{\"forcePairing\":false,\"pairingType\":\"PROMPT\",\"client-key\":\"CLIENTKEYGOESHERE\",\"manifest\":{\"manifestVersion\":1,\"appVersion\":\"1.1\",\"signed\":{\"created\":\"20140509\",\"appId\":\"com.lge.test\",\"vendorId\":\"com.lge\",\"localizedAppNames\":{\"\":\"LG Remote App\",\"ko-KR\":\"리모컨 앱\",\"zxx-XX\":\"ЛГ Rэмotэ AПП\"},\"localizedVendorNames\":{\"\":\"LG Electronics\"},\"permissions\":[\"TEST_SECURE\",\"CONTROL_INPUT_TEXT\",\"CONTROL_MOUSE_AND_KEYBOARD\",\"READ_INSTALLED_APPS\",\"READ_LGE_SDX\",\"READ_NOTIFICATIONS\",\"SEARCH\",\"WRITE_SETTINGS\",\"WRITE_NOTIFICATION_ALERT\",\"CONTROL_POWER\",\"READ_CURRENT_CHANNEL\",\"READ_RUNNING_APPS\",\"READ_UPDATE_INFO\",\"UPDATE_FROM_REMOTE_APP\",\"READ_LGE_TV_INPUT_EVENTS\",\"READ_TV_CURRENT_TIME\"],\"serial\":\"2f930e2d2cfe083771f68e4fe7bb07\"},\"permissions\":[\"LAUNCH\",\"LAUNCH_WEBAPP\",\"APP_TO_APP\",\"CLOSE\",\"TEST_OPEN\",\"TEST_PROTECTED\",\"CONTROL_AUDIO\",\"CONTROL_DISPLAY\",\"CONTROL_INPUT_JOYSTICK\",\"CONTROL_INPUT_MEDIA_RECORDING\",\"CONTROL_INPUT_MEDIA_PLAYBACK\",\"CONTROL_INPUT_TV\",\"CONTROL_POWER\",\"READ_APP_STATUS\",\"READ_CURRENT_CHANNEL\",\"READ_INPUT_DEVICE_LIST\",\"READ_NETWORK_STATE\",\"READ_RUNNING_APPS\",\"READ_TV_CHANNEL_LIST\",\"WRITE_NOTIFICATION_TOAST\",\"READ_POWER_STATE\",\"READ_COUNTRY_INFO\",\"READ_SETTINGS\"],\"signatures\":[{\"signatureVersion\":1,\"signature\":\"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw==\"}]}}}"; - private string _currentPairKey; private string webSocketUri; @@ -149,18 +144,21 @@ namespace LgTv public async Task MakeHandShake() { + var registerJson = Utils.GetResourceFile("LG_register.json"); + _currentPairKey = _keyStore.GetClientKey(); - if (_currentPairKey != null && !_currentPairKey.All(k => k == '\0') && _keyStore.HasValidHandShake(BEFORE_PAIR_HAND_SHAKE)) + if (_currentPairKey != null && !_currentPairKey.All(k => k == '\0') && _keyStore.HasValidHandShake(registerJson)) { - var key = AFTER_PAIR_HAND_SHAKE.Replace("CLIENTKEYGOESHERE", _currentPairKey); + var key = registerJson.Replace("CLIENTKEYGOESHERE", _currentPairKey); var conn = await _connection.SendCommandAsync(key); _keyStore.SaveClientKey((string)conn.clientKey); return; } - dynamic result = await _connection.SendCommandAsync(BEFORE_PAIR_HAND_SHAKE); + var registerJsonRemovedKey = registerJson.Replace("CLIENTKEYGOESHERE", string.Empty); + dynamic result = await _connection.SendCommandAsync(registerJsonRemovedKey); _keyStore.SaveClientKey(result.clientKey); - _keyStore.SaveHandShake(BEFORE_PAIR_HAND_SHAKE); + _keyStore.SaveHandShake(registerJson); } @@ -302,6 +300,17 @@ namespace LgTv { await _connection.SendCommandAsync(new RequestMessage("3d", "ssap://com.webos.service.tv.display/set3DOff")); } + + public async Task TurnScreenOff() + { + await _connection.SendCommandAsync(new RequestMessage("", "ssap://com.webos.service.tvpower/power/turnOffScreen")); + } + + public async Task TurnScreenOn() + { + await _connection.SendCommandAsync(new RequestMessage("", "ssap://com.webos.service.tvpower/power/turnOnScreen")); + } + public async Task IsTurnedOn3D() { //Response: { returnValue: true, status3D: { status: true, pattern: ’2Dto3D’ } }