diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj
index 4902b35..02ca566 100644
--- a/ColorControl/ColorControl.csproj
+++ b/ColorControl/ColorControl.csproj
@@ -27,7 +27,7 @@
ColorControl
Maassoft
0
- 3.2.1.0
+ 3.2.2.0
false
true
true
diff --git a/ColorControl/ColorDataConverter.cs b/ColorControl/ColorDataConverter.cs
index de541a6..0872404 100644
--- a/ColorControl/ColorDataConverter.cs
+++ b/ColorControl/ColorDataConverter.cs
@@ -1,5 +1,4 @@
using NvAPIWrapper.Display;
-using NvAPIWrapper.Native.Display;
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
@@ -22,33 +21,7 @@ public override IDictionary Serialize(object obj, JavaScriptSeri
public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer)
{
- var format = ColorDataFormat.RGB;
- var dynamicRange = ColorDataDynamicRange.VESA;
- var colorDepth = ColorDataDepth.BPC8;
- var colorimetry = ColorDataColorimetry.Auto;
- var selectionPolicy = ColorDataSelectionPolicy.User;
- object value;
- if (dictionary.TryGetValue("ColorFormat", out value))
- {
- format = (ColorDataFormat)Enum.ToObject(typeof(ColorDataFormat), value);
- }
- if (dictionary.TryGetValue("ColorDepth", out value))
- {
- colorDepth = (ColorDataDepth)Enum.ToObject(typeof(ColorDataDepth), value);
- }
- if (dictionary.TryGetValue("Colorimetry", out value))
- {
- colorimetry = (ColorDataColorimetry)Enum.ToObject(typeof(ColorDataColorimetry), value);
- }
- if (dictionary.TryGetValue("DynamicRange", out value))
- {
- dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
- }
- if (dictionary.TryGetValue("SelectionPolicy", out value))
- {
- selectionPolicy = (ColorDataSelectionPolicy)Enum.ToObject(typeof(ColorDataSelectionPolicy), value);
- }
- return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy, desktopColorDepth: ColorDataDesktopDepth.Default);
+ return NvPreset.GenerateColorData(dictionary);
}
}
}
diff --git a/ColorControl/LgDevice.cs b/ColorControl/LgDevice.cs
index 0efcf98..57a44c2 100644
--- a/ColorControl/LgDevice.cs
+++ b/ColorControl/LgDevice.cs
@@ -20,6 +20,22 @@ public class InvokableAction
public decimal MaxValue { get; set; }
}
+ public enum PowerState
+ {
+ Unknown,
+ Active,
+ Power_Off,
+ Suspend,
+ Active_Standby
+ }
+
+ public enum PowerOffSource
+ {
+ Unknown,
+ App,
+ Manually
+ }
+
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public string Name { get; private set; }
@@ -35,10 +51,17 @@ public class InvokableAction
public bool PowerOffOnStandby { get; set; }
public bool PowerSwitchOnScreenSaver { get; set; }
+ [JsonIgnore]
+ public PowerState CurrentState { get; set; }
+
[JsonIgnore]
private LgTvApi _lgTvApi;
[JsonIgnore]
private bool _justWokeUp;
+ [JsonIgnore]
+ public PowerOffSource PoweredOffBy { get; private set; }
+
+ public bool PoweredOffViaApp { get; private set; }
[JsonIgnore]
private List _invokableActions = new List();
@@ -87,7 +110,9 @@ private void AddGenericPictureAction(string name, Type type = null, decimal minV
{
Name = name,
Function = new Func, bool>(GenericPictureAction),
- EnumType = type
+ EnumType = type,
+ MinValue = minValue,
+ MaxValue = maxValue
};
_invokableActions.Add(action);
@@ -95,7 +120,8 @@ private void AddGenericPictureAction(string name, Type type = null, decimal minV
public override string ToString()
{
- return (IsDummy ? string.Empty : (IsCustom ? "Custom: " : "Auto detect: ")) + $"{Name}" + (!string.IsNullOrEmpty(IpAddress) ? $" ({IpAddress})" : string.Empty);
+ //return (IsDummy ? string.Empty : (IsCustom ? "Custom: " : "Auto detect: ")) + $"{Name}" + (!string.IsNullOrEmpty(IpAddress) ? $" ({IpAddress})" : string.Empty);
+ return $"{(IsDummy ? string.Empty : (IsCustom ? "Custom: " : "Auto detect: "))}{Name}{(!string.IsNullOrEmpty(IpAddress) ? ", " + IpAddress : string.Empty)}";
}
public async Task Connect(int retries = 3)
@@ -114,6 +140,14 @@ public async Task Connect(int retries = 3)
{
ModelName = info.modelName;
}
+
+ //await _lgTvApi.SubscribeVolume(VolumeChanged);
+ await _lgTvApi.SubscribePowerState(PowerStateChanged);
+
+ //await _lgTvApi.SetInput("HDMI_1");
+ //await Task.Delay(2000);
+ //await _lgTvApi.SetConfig("com.palm.app.settings.enableHdmiPcLabel", true);
+ //await _lgTvApi.SetInput("HDMI_2");
}
return _lgTvApi != null;
}
@@ -125,6 +159,40 @@ public async Task Connect(int retries = 3)
}
}
+ public bool VolumeChanged(dynamic payload)
+ {
+ return true;
+ }
+ public bool PowerStateChanged(dynamic payload)
+ {
+ Logger.Debug($"[{Name}] Power state change: " + JsonConvert.SerializeObject(payload));
+
+ var state = ((string)payload.state).Replace(' ', '_');
+
+ PowerState newState;
+ if (Enum.TryParse(state, out newState))
+ {
+ CurrentState = newState;
+
+ if (CurrentState == PowerState.Active)
+ {
+ if (payload.processing == null)
+ {
+ PoweredOffViaApp = false;
+ }
+ }
+ else {
+ PoweredOffBy = PoweredOffViaApp ? PowerOffSource.App : PowerOffSource.Manually;
+ }
+ }
+ else
+ {
+ CurrentState = PowerState.Unknown;
+ Logger.Warn($"Unknown power state: {state}");
+ }
+ return true;
+ }
+
public bool IsConnected()
{
return !_lgTvApi?.ConnectionClosed ?? false;
@@ -303,7 +371,10 @@ internal async Task PowerOff()
return false;
}
+ PoweredOffViaApp = true;
+
await _lgTvApi.TurnOff();
+
return true;
}
diff --git a/ColorControl/LgService.cs b/ColorControl/LgService.cs
index 569d128..206fa6c 100644
--- a/ColorControl/LgService.cs
+++ b/ColorControl/LgService.cs
@@ -429,6 +429,12 @@ internal void WakeAfterStartupOrResume(PowerOnOffState state = PowerOnOffState.S
state == PowerOnOffState.ScreenSaver && d.PowerSwitchOnScreenSaver);
foreach (var device in wakeDevices)
{
+ if (device.PoweredOffBy == LgDevice.PowerOffSource.Manually)
+ {
+ Logger.Debug($"[{device.Name}]: device was manually powered off by user, not powering on");
+ continue;
+ }
+
device.DisposeConnection();
var _ = device.WakeAndConnectWithRetries(Config.PowerOnRetries);
}
diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs
index 3469fea..b8ed7a1 100644
--- a/ColorControl/MainForm.Designer.cs
+++ b/ColorControl/MainForm.Designer.cs
@@ -994,7 +994,7 @@ private void InitializeComponent()
this.miLgExpertSeparator1,
this.mnuLgExpertBacklight});
this.mnuLgExpert.Name = "mnuLgButtons";
- this.mnuLgExpert.Size = new System.Drawing.Size(321, 76);
+ this.mnuLgExpert.Size = new System.Drawing.Size(321, 54);
this.mnuLgExpert.Opening += new System.ComponentModel.CancelEventHandler(this.mnuLgExpert_Opening);
//
// mnuLgOLEDMotionPro
@@ -1056,6 +1056,7 @@ private void InitializeComponent()
// cbxLgDevices
//
this.cbxLgDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cbxLgDevices.DropDownWidth = 400;
this.cbxLgDevices.FormattingEnabled = true;
this.cbxLgDevices.Location = new System.Drawing.Point(86, 8);
this.cbxLgDevices.Name = "cbxLgDevices";
diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs
index cdca8c0..03b8eda 100644
--- a/ColorControl/MainForm.cs
+++ b/ColorControl/MainForm.cs
@@ -52,6 +52,7 @@ public partial class MainForm : Form
private StartUpParams StartUpParams { get; }
private AmdService _amdService;
+ private bool _skipResize;
public MainForm(AppContext appContext)
{
@@ -541,6 +542,11 @@ private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
private void MainForm_Resize(object sender, EventArgs e)
{
+ if (_skipResize)
+ {
+ return;
+ }
+
if (WindowState == FormWindowState.Minimized)
{
if (_config.MinimizeToTray)
@@ -578,8 +584,16 @@ private void LoadConfig()
Utils.RegisterShortcut(Handle, SHORTCUTID_SCREENSAVER, _config.ScreenSaverShortcut);
}
- Width = _config.FormWidth;
- Height = _config.FormHeight;
+ _skipResize = true;
+ try
+ {
+ Width = _config.FormWidth;
+ Height = _config.FormHeight;
+ }
+ finally
+ {
+ _skipResize = false;
+ }
}
private void SaveConfig()
diff --git a/ColorControl/NvPreset.cs b/ColorControl/NvPreset.cs
index 2ca3e68..3a3dcbf 100644
--- a/ColorControl/NvPreset.cs
+++ b/ColorControl/NvPreset.cs
@@ -51,7 +51,7 @@ public NvPreset(NvPreset preset): this()
displayName = preset.displayName;
var colorData = preset.colorData;
- this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: colorData.SelectionPolicy);
+ this.colorData = new ColorData(colorData.ColorFormat, dynamicRange: colorData.DynamicRange, colorDepth: colorData.ColorDepth, colorSelectionPolicy: ColorDataSelectionPolicy.User);
applyColorData = preset.applyColorData;
applyHDR = preset.applyHDR;
@@ -206,11 +206,16 @@ public static ColorData GenerateColorData(IDictionary dictionary
{
dynamicRange = (ColorDataDynamicRange)Enum.ToObject(typeof(ColorDataDynamicRange), value);
}
- if (dictionary.TryGetValue("SelectionPolicy", out value))
+ if (dictionary.TryGetValue("SelectionPolicy", out _))
{
- selectionPolicy = (ColorDataSelectionPolicy)Enum.ToObject(typeof(ColorDataSelectionPolicy), value);
+ selectionPolicy =
+ colorDepth == ColorDataDepth.Default &&
+ format >= ColorDataFormat.Default &&
+ colorimetry >= ColorDataColorimetry.Default &&
+ dynamicRange == ColorDataDynamicRange.Auto ?
+ ColorDataSelectionPolicy.BestQuality : selectionPolicy;
}
- return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy);
+ return new ColorData(format, dynamicRange: dynamicRange, colorimetry: colorimetry, colorDepth: colorDepth, colorSelectionPolicy: selectionPolicy, desktopColorDepth: ColorDataDesktopDepth.Default);
}
}
diff --git a/ColorControl/Properties/AssemblyInfo.cs b/ColorControl/Properties/AssemblyInfo.cs
index 5d35f19..710f786 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.2.1.0")]
-[assembly: AssemblyFileVersion("3.2.1.0")]
+[assembly: AssemblyVersion("3.2.2.0")]
+[assembly: AssemblyFileVersion("3.2.2.0")]
diff --git a/ColorControl/lgtv/LgTvApi.cs b/ColorControl/lgtv/LgTvApi.cs
index 136a2db..56a4b91 100644
--- a/ColorControl/lgtv/LgTvApi.cs
+++ b/ColorControl/lgtv/LgTvApi.cs
@@ -307,7 +307,7 @@ public async Task GetVolume()
}
public async Task> GetInputList()
{
- var requestMessage = new RequestMessage("input","ssap://tv/getExternalInputList");
+ var requestMessage = new RequestMessage("input","ssap://tv/getExternalInputList");
var results = await _connection.SendCommandAsync(requestMessage);
var l = new List();
foreach (var result in results)
@@ -326,6 +326,20 @@ public async Task SetInput(string id)
await _connection.SendCommandAsync(requestMessage);
}
+ public async Task SubscribeVolume(Func callback, dynamic payload = null)
+ {
+ var requestMessage = new RequestMessage("ssap://audio/getVolume", null, "subscribe");
+
+ await _connection.SubscribeAsync(requestMessage, callback);
+ }
+
+ public async Task SubscribePowerState(Func callback, dynamic payload = null)
+ {
+ var requestMessage = new RequestMessage("ssap://com.webos.service.tvpower/power/getPowerState", null, "subscribe");
+
+ await _connection.SubscribeAsync(requestMessage, callback);
+ }
+
public async Task> GetLaunchPoints()
{
_appList = new List();
@@ -436,6 +450,15 @@ public async Task SetConfig(string key, string value)
await ExecuteRequest(lunauri, @params);
}
+ public async Task SetConfig(string key, bool value)
+ {
+ var lunauri = "luna://com.webos.service.config/setConfigs";
+
+ var @params = JObject.Parse(@"{ ""configs"": { """ + key + @""": " + value.ToString().ToLowerInvariant() + @" } }");
+
+ await ExecuteRequest(lunauri, @params);
+ }
+
private async Task ExecuteRequest(string lunauri, object @params)
{
var buttons = new[]
diff --git a/ColorControl/lgtv/LgTvConnection.cs b/ColorControl/lgtv/LgTvConnection.cs
index 3652877..e662fd0 100644
--- a/ColorControl/lgtv/LgTvConnection.cs
+++ b/ColorControl/lgtv/LgTvConnection.cs
@@ -29,6 +29,7 @@ public class LgTvApiCore : IDisposable
public event IsConnectedDelegate IsConnected;
private readonly ConcurrentDictionary> _tokens = new ConcurrentDictionary>();
+ private readonly ConcurrentDictionary> _callbacks = new ConcurrentDictionary>();
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
@@ -135,6 +136,20 @@ public Task SendCommandAsync(RequestMessage message)
return SendCommandAsync(rawMessage.Id, serialized);
}
+ public Task SubscribeAsync(RequestMessage message, Func callback)
+ {
+ var rawMessage = new RawRequestMessage(message, ++_commandCount);
+ var serialized = JsonConvert.SerializeObject(rawMessage, new JsonSerializerSettings()
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ ContractResolver = new CamelCasePropertyNamesContractResolver()
+ });
+
+ _callbacks.TryAdd(rawMessage.Id, callback);
+
+ return SendCommandAsync(rawMessage.Id, serialized);
+ }
+
private void Connection_Closed(IWebSocket sender, WebSocketClosedEventArgs args)
{
MessageWebSocket webSocket = Interlocked.Exchange(ref _connection, null);
@@ -177,6 +192,11 @@ private void Connection_MessageReceived(MessageWebSocket sender, MessageWebSocke
// taskSource.SetCanceled();
//}
taskCompletion.TrySetResult(obj.payload);
+
+ if (_callbacks.TryGetValue(id, out Func callback))
+ {
+ callback(obj.payload);
+ }
}
}
}
diff --git a/ColorControl/lgtv/RequestMessage.cs b/ColorControl/lgtv/RequestMessage.cs
index fb769db..0ddc6e0 100644
--- a/ColorControl/lgtv/RequestMessage.cs
+++ b/ColorControl/lgtv/RequestMessage.cs
@@ -9,10 +9,14 @@ public RequestMessage(string prefix, string uri)
Prefix = prefix;
Uri = uri;
}
- public RequestMessage(string uri,object payload)
+ public RequestMessage(string uri, object payload, string type = "request")
{
Uri = uri;
- Payload = JsonConvert.SerializeObject(payload);
+ if (payload != null)
+ {
+ Payload = JsonConvert.SerializeObject(payload);
+ }
+ Type = type;
}
public string Prefix { get; set; }