diff --git a/ColorControl/AppContext.cs b/ColorControl/AppContext.cs index 08b9127..ae67d98 100644 --- a/ColorControl/AppContext.cs +++ b/ColorControl/AppContext.cs @@ -2,6 +2,8 @@ { public class AppContext { + public static AppContext CurrentContext { get; private set; } + public Config Config { get; private set; } public StartUpParams StartUpParams { get; private set; } @@ -10,6 +12,8 @@ public AppContext(Config config, StartUpParams startUpParams) { Config = config; StartUpParams = startUpParams; + + CurrentContext = this; } } } diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index fa24a7a..9ad684e 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -27,7 +27,7 @@ ColorControl Maassoft 0 - 3.0.0.0 + 3.1.0.0 false true true diff --git a/ColorControl/LgDevice.cs b/ColorControl/LgDevice.cs index 1dbbda0..3ba8c95 100644 --- a/ColorControl/LgDevice.cs +++ b/ColorControl/LgDevice.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -58,6 +59,8 @@ public async Task Connect(int retries = 3) _lgTvApi = await LgTvApi.CreateLgTvApi(IpAddress, retries); //Test(); + //_lgTvApi.Test3(); + //_lgTvApi.SetSystemSettings(); return _lgTvApi != null; } catch (Exception ex) @@ -310,6 +313,15 @@ internal async Task WakeAndConnectWithRetries(int retries = 5) } } + if (result) + { + var resumeScript = Path.Combine(Program.DataDir, "ResumeScript.bat"); + if (File.Exists(resumeScript)) + { + Utils.StartProcess(resumeScript); + } + } + return result; } @@ -354,5 +366,20 @@ internal void ConvertToCustom() { IsCustom = true; } + + internal async Task SetBacklight(int backlight) + { + await _lgTvApi.SetSystemSettings("backlight", backlight.ToString()); + } + + public async Task SetOLEDMotionPro(string mode) + { + await _lgTvApi.SetConfig("tv.model.motionProMode", mode); + } + + internal async Task SetConfig(string key, string value) + { + await _lgTvApi.SetConfig(key, value); + } } } diff --git a/ColorControl/LgService.cs b/ColorControl/LgService.cs index dfb67a7..1eff85b 100644 --- a/ColorControl/LgService.cs +++ b/ColorControl/LgService.cs @@ -482,6 +482,12 @@ private void PowerModeChanged(object sender, PowerModeChangedEventArgs e) NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED); try { + var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat"); + if (File.Exists(standByScript)) + { + Utils.StartProcess(standByScript); + } + Logger.Debug("Powering off tv..."); var task = PowerOffOnShutdownOrResume(PowerOnOffState.StandBy); Utils.WaitForTask(task); diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs index fa20d76..046ab1f 100644 --- a/ColorControl/MainForm.Designer.cs +++ b/ColorControl/MainForm.Designer.cs @@ -104,6 +104,7 @@ private void InitializeComponent() this.lvAmdPresets = new System.Windows.Forms.ListView(); this.tabLG = new System.Windows.Forms.TabPage(); this.scLgController = new System.Windows.Forms.SplitContainer(); + this.btnLgExpert = new System.Windows.Forms.Button(); this.chkLgRemoteControlShow = new System.Windows.Forms.CheckBox(); this.label3 = new System.Windows.Forms.Label(); this.cbxLgDevices = new System.Windows.Forms.ComboBox(); @@ -176,6 +177,11 @@ private void InitializeComponent() this.label7 = new System.Windows.Forms.Label(); this.lblInfo = new System.Windows.Forms.Label(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); + this.mnuLgExpert = new System.Windows.Forms.ContextMenuStrip(this.components); + this.mnuLgExpertBacklight = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuLgOLEDMotionPro = new System.Windows.Forms.ToolStripMenuItem(); + this.miLgEnableMotionPro = new System.Windows.Forms.ToolStripMenuItem(); + this.miLgDisableMotionPro = new System.Windows.Forms.ToolStripMenuItem(); this.tcMain.SuspendLayout(); this.tabNVIDIA.SuspendLayout(); this.mnuNvPresets.SuspendLayout(); @@ -199,6 +205,7 @@ private void InitializeComponent() this.tabInfo.SuspendLayout(); this.grpNVIDIAInfo.SuspendLayout(); this.groupBox3.SuspendLayout(); + this.mnuLgExpert.SuspendLayout(); this.SuspendLayout(); // // tcMain @@ -932,6 +939,7 @@ private void InitializeComponent() // // scLgController.Panel1 // + this.scLgController.Panel1.Controls.Add(this.btnLgExpert); this.scLgController.Panel1.Controls.Add(this.chkLgRemoteControlShow); this.scLgController.Panel1.Controls.Add(this.label3); this.scLgController.Panel1.Controls.Add(this.cbxLgDevices); @@ -967,6 +975,17 @@ private void InitializeComponent() this.scLgController.SplitterDistance = 767; this.scLgController.TabIndex = 43; // + // btnLgExpert + // + this.btnLgExpert.ContextMenuStrip = this.mnuLgExpert; + this.btnLgExpert.Location = new System.Drawing.Point(315, 34); + this.btnLgExpert.Name = "btnLgExpert"; + this.btnLgExpert.Size = new System.Drawing.Size(75, 23); + this.btnLgExpert.TabIndex = 44; + this.btnLgExpert.Text = "Expert..."; + this.btnLgExpert.UseVisualStyleBackColor = true; + this.btnLgExpert.Click += new System.EventHandler(this.btnLgExpert_Click); + // // chkLgRemoteControlShow // this.chkLgRemoteControlShow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -1343,7 +1362,7 @@ private void InitializeComponent() this.grpNvidiaOptions.Controls.Add(this.pbGradient); this.grpNvidiaOptions.Location = new System.Drawing.Point(412, 6); this.grpNvidiaOptions.Name = "grpNvidiaOptions"; - this.grpNvidiaOptions.Size = new System.Drawing.Size(514, 304); + this.grpNvidiaOptions.Size = new System.Drawing.Size(536, 304); this.grpNvidiaOptions.TabIndex = 6; this.grpNvidiaOptions.TabStop = false; this.grpNvidiaOptions.Text = "NVIDIA options - test dithering"; @@ -1407,7 +1426,7 @@ private void InitializeComponent() this.pbGradient.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbGradient.Location = new System.Drawing.Point(6, 92); this.pbGradient.Name = "pbGradient"; - this.pbGradient.Size = new System.Drawing.Size(502, 205); + this.pbGradient.Size = new System.Drawing.Size(524, 205); this.pbGradient.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.pbGradient.TabIndex = 0; this.pbGradient.TabStop = false; @@ -1668,11 +1687,12 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.edtLog.Location = new System.Drawing.Point(6, 35); + this.edtLog.MaxLength = 327670; this.edtLog.Multiline = true; this.edtLog.Name = "edtLog"; this.edtLog.ReadOnly = true; this.edtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.edtLog.Size = new System.Drawing.Size(920, 415); + this.edtLog.Size = new System.Drawing.Size(942, 415); this.edtLog.TabIndex = 0; // // tabInfo @@ -1696,7 +1716,7 @@ private void InitializeComponent() this.grpNVIDIAInfo.Controls.Add(this.tvNVIDIAInfo); this.grpNVIDIAInfo.Location = new System.Drawing.Point(397, 6); this.grpNVIDIAInfo.Name = "grpNVIDIAInfo"; - this.grpNVIDIAInfo.Size = new System.Drawing.Size(477, 443); + this.grpNVIDIAInfo.Size = new System.Drawing.Size(551, 443); this.grpNVIDIAInfo.TabIndex = 4; this.grpNVIDIAInfo.TabStop = false; this.grpNVIDIAInfo.Text = "NVIDIA info"; @@ -1719,7 +1739,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.tvNVIDIAInfo.Location = new System.Drawing.Point(6, 19); this.tvNVIDIAInfo.Name = "tvNVIDIAInfo"; - this.tvNVIDIAInfo.Size = new System.Drawing.Size(465, 389); + this.tvNVIDIAInfo.Size = new System.Drawing.Size(539, 389); this.tvNVIDIAInfo.TabIndex = 0; // // groupBox3 @@ -1761,6 +1781,45 @@ private void InitializeComponent() this.lblInfo.TabIndex = 1; this.lblInfo.Text = "Info"; // + // mnuLgExpert + // + this.mnuLgExpert.ImageScalingSize = new System.Drawing.Size(20, 20); + this.mnuLgExpert.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuLgExpertBacklight, + this.mnuLgOLEDMotionPro}); + this.mnuLgExpert.Name = "mnuLgButtons"; + this.mnuLgExpert.Size = new System.Drawing.Size(236, 70); + this.mnuLgExpert.Opening += new System.ComponentModel.CancelEventHandler(this.mnuLgExpert_Opening); + // + // mnuLgExpertBacklight + // + this.mnuLgExpertBacklight.Name = "mnuLgExpertBacklight"; + this.mnuLgExpertBacklight.Size = new System.Drawing.Size(235, 22); + this.mnuLgExpertBacklight.Text = "Backlight"; + // + // mnuLgOLEDMotionPro + // + this.mnuLgOLEDMotionPro.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miLgEnableMotionPro, + this.miLgDisableMotionPro}); + this.mnuLgOLEDMotionPro.Name = "mnuLgOLEDMotionPro"; + this.mnuLgOLEDMotionPro.Size = new System.Drawing.Size(235, 22); + this.mnuLgOLEDMotionPro.Text = "OLED Motion Pro (B9/C9 only)"; + // + // miLgEnableMotionPro + // + this.miLgEnableMotionPro.Name = "miLgEnableMotionPro"; + this.miLgEnableMotionPro.Size = new System.Drawing.Size(207, 22); + this.miLgEnableMotionPro.Text = "Enable OLED Motion Pro"; + this.miLgEnableMotionPro.Click += new System.EventHandler(this.miLgEnableMotionPro_Click); + // + // miLgDisableMotionPro + // + this.miLgDisableMotionPro.Name = "miLgDisableMotionPro"; + this.miLgDisableMotionPro.Size = new System.Drawing.Size(207, 22); + this.miLgDisableMotionPro.Text = "Disable OLED Motion Pro"; + this.miLgDisableMotionPro.Click += new System.EventHandler(this.miLgDisableMotionPro_Click); + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1811,6 +1870,7 @@ private void InitializeComponent() this.grpNVIDIAInfo.ResumeLayout(false); this.groupBox3.ResumeLayout(false); this.groupBox3.PerformLayout(); + this.mnuLgExpert.ResumeLayout(false); this.ResumeLayout(false); } @@ -1963,6 +2023,12 @@ private void InitializeComponent() private System.Windows.Forms.Label lblLgError; private System.Windows.Forms.CheckBox chkLgRemoteControlShow; private System.ComponentModel.BackgroundWorker backgroundWorker1; + private System.Windows.Forms.Button btnLgExpert; + private System.Windows.Forms.ContextMenuStrip mnuLgExpert; + private System.Windows.Forms.ToolStripMenuItem mnuLgExpertBacklight; + private System.Windows.Forms.ToolStripMenuItem mnuLgOLEDMotionPro; + private System.Windows.Forms.ToolStripMenuItem miLgEnableMotionPro; + private System.Windows.Forms.ToolStripMenuItem miLgDisableMotionPro; } } diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index 4d2cfeb..fa9c010 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -15,6 +15,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Text; using System.Threading.Tasks; using System.Windows.Forms; @@ -1565,12 +1566,15 @@ private void LoadLog() { var filename = Path.Combine(_dataDir, "LogFile.txt"); - var log = "No log file found"; + var lines = new[] { "No log file found" }; if (File.Exists(filename)) { - log = File.ReadAllText(filename); + lines = File.ReadAllLines(filename); } - edtLog.Text = log; + var reversedLines = lines.Reverse().ToList(); + var builder = new StringBuilder(); + reversedLines.ForEach(line => builder.AppendLine(line)); + edtLog.Text = builder.ToString(); } private void LoadInfo() @@ -2433,5 +2437,51 @@ private void chkLgRemoteControlShow_CheckedChanged(object sender, EventArgs e) scLgController.Panel2Collapsed = !chkLgRemoteControlShow.Checked; _lgService.Config.ShowRemoteControl = chkLgRemoteControlShow.Checked; } + + private void mnuLgExpert_Opening(object sender, CancelEventArgs e) + { + mnuLgOLEDMotionPro.Visible = _lgService.SelectedDevice?.Name.Contains("C9") ?? _lgService.SelectedDevice?.Name.Contains("B9") ?? false; + + if (mnuLgExpertBacklight.DropDownItems.Count == 0) + { + for (var i = 0; i <= 10; i++) + { + var name = (i * 10).ToString(); + + var item = mnuLgExpertBacklight.DropDownItems.Add(name); + item.Click += btnLgExpertBacklight_Click; + } + } + } + + private void btnLgExpert_Click(object sender, EventArgs e) + { + mnuLgExpert.Show(btnLgExpert, btnLgExpert.PointToClient(Cursor.Position)); + } + + private void btnLgExpertBacklight_Click(object sender, EventArgs e) + { + var item = sender as ToolStripItem; + var backlight = int.Parse(item.Text); + + _lgService.SelectedDevice?.SetBacklight(backlight); + } + + private void miLgEnableMotionPro_Click(object sender, EventArgs e) + { + if (MessageForms.QuestionYesNo("Are you sure you want to enable OLED Motion Pro? This app and its creator are in no way accountable for any damages it may cause to your tv.") == DialogResult.Yes) + { + _lgService.SelectedDevice?.SetOLEDMotionPro("OLED Motion Pro"); + + MessageForms.InfoOk("Setting applied."); + } + } + + private void miLgDisableMotionPro_Click(object sender, EventArgs e) + { + _lgService.SelectedDevice?.SetOLEDMotionPro("OLED Motion"); + + MessageForms.InfoOk("Setting applied."); + } } } \ No newline at end of file diff --git a/ColorControl/MainForm.resx b/ColorControl/MainForm.resx index e2818cd..69e375d 100644 --- a/ColorControl/MainForm.resx +++ b/ColorControl/MainForm.resx @@ -123,6 +123,9 @@ 278, 17 + + 583, 17 + 147, 17 diff --git a/ColorControl/Properties/AssemblyInfo.cs b/ColorControl/Properties/AssemblyInfo.cs index c969fec..1eb9aa2 100644 --- a/ColorControl/Properties/AssemblyInfo.cs +++ b/ColorControl/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // 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("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.1.0.0")] +[assembly: AssemblyFileVersion("3.1.0.0")] diff --git a/ColorControl/Utils.cs b/ColorControl/Utils.cs index ba0ff54..c0cb636 100644 --- a/ColorControl/Utils.cs +++ b/ColorControl/Utils.cs @@ -696,7 +696,7 @@ public static Process GetProcessByName(string name, bool skipCurrent = true) return null; } - public static void StartProcess(string fileName, string arguments) + public static void StartProcess(string fileName, string arguments = null) { var process = Process.Start(fileName, arguments); } diff --git a/ColorControl/lgtv/LgTvApi.cs b/ColorControl/lgtv/LgTvApi.cs index 63515fc..2ca3be9 100644 --- a/ColorControl/lgtv/LgTvApi.cs +++ b/ColorControl/lgtv/LgTvApi.cs @@ -39,7 +39,7 @@ public Task ControlButton(object oK) return null; } - private string _currentPariKey; + private string _currentPairKey; private string webSocketUri; public static async Task CreateLgTvApi(string ip, int retries = 1) @@ -75,10 +75,10 @@ public string GetIpAddress() public async Task MakeHandShake() { - _currentPariKey = _keyStore.GetClientKey(); - if (_currentPariKey != null) + _currentPairKey = _keyStore.GetClientKey(); + if (_currentPairKey != null && !_currentPairKey.All(k => k == '\0')) { - var key = AFTER_PAIR_HAND_SHAKE.Replace("CLIENTKEYGOESHERE", _currentPariKey); + var key = AFTER_PAIR_HAND_SHAKE.Replace("CLIENTKEYGOESHERE", _currentPairKey); var conn = await _connection.SendCommandAsync(key); _keyStore.SaveClientKey((string)conn.clientKey); return; @@ -365,11 +365,56 @@ public async Task LaunchYouTube(Uri uri) return (string)response.sessionId; } - public async Task Test() + public async Task SetSystemSettings(string key, string value) { - var msg = JObject.Parse(@"{ ""configs"": { ""tv.model.motionProMode"": ""OLED Motion Pro"" } }"); - var requestMessage = new RequestMessage("luna://com.webos.service.config/setConfigs", msg); + var lunauri = "luna://com.webos.settingsservice/setSystemSettings"; + + var @params = JObject.Parse(@"{ ""category"": ""picture"", ""settings"": { """ + key + @""": """ + value + @""" } }"); + + await ExecuteRequest(lunauri, @params); + } + + public async Task SetConfig(string key, string value) + { + var lunauri = "luna://com.webos.service.config/setConfigs"; + + var @params = JObject.Parse(@"{ ""configs"": { """ + key + @""": """ + value + @""" } }"); + + await ExecuteRequest(lunauri, @params); + } + + private async Task ExecuteRequest(string lunauri, object @params) + { + var buttons = new[] + { + new { + label = "", + onClick = lunauri, + @params = @params + } + }; + + var payload = new + { + message = "Applying...", + buttons = buttons, + onclose = new { uri = lunauri, @params = @params }, + onfail = new { uri = lunauri, @params = @params } + }; + + var requestMessage = new RequestMessage("ssap://system.notifications/createAlert", payload); var response = await _connection.SendCommandAsync(requestMessage); + + var alertId = (string)response.alertId; + if (alertId != null) + { + var closeAlert = new + { + alertId = alertId + }; + requestMessage = new RequestMessage("ssap://system.notifications/closeAlert", closeAlert); + await _connection.SendCommandAsync(requestMessage); + } } public void Close()