Skip to content

Commit

Permalink
Added advanced MQTT mode for defining unlimited custom MQTT commands,…
Browse files Browse the repository at this point in the history
… v0.4.0
  • Loading branch information
nicko88 committed Mar 17, 2023
1 parent 22492ba commit 1688067
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 97 deletions.
31 changes: 27 additions & 4 deletions FanTrayIcon/TrayIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
Expand All @@ -11,7 +13,6 @@ namespace FanTrayIcon
{
public class TrayIcon
{
string _IP;
string _port;
string _instanceName;

Expand All @@ -28,9 +29,31 @@ public class TrayIcon
const int SW_HIDE = 0;
const int SW_SHOW = 5;

public TrayIcon(string IP, string port, string instanceName)
private static string IP
{
get
{
string IP = "IPError";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if ((item.NetworkInterfaceType == NetworkInterfaceType.Ethernet || item.NetworkInterfaceType == NetworkInterfaceType.Wireless80211) &&
!item.Description.ToLower().Contains("virtual") && !item.Name.ToLower().Contains("virtual") && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork && !ip.Address.ToString().StartsWith("127"))
{
IP = ip.Address.ToString();
}
}
}
}
return IP;
}
}

public TrayIcon(string port, string instanceName)
{
_IP = IP;
_port = port;
_instanceName = instanceName;

Expand Down Expand Up @@ -101,7 +124,7 @@ private void trayIcon_DoubleClick(object sender, EventArgs e)

private void itemWebUI_Click(object sender, EventArgs e)
{
string url = $"http://{_IP}:{_port}";
string url = $"http://{IP}:{_port}";

try
{
Expand Down
13 changes: 10 additions & 3 deletions HTFanControl/Controllers/LIRCController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ class LIRCController : IController
private Settings _settings;

private bool _isOFF = true;
private bool _ONcmd = false;
private bool _needONcmd = false;

public string ErrorStatus { get; private set; }

public LIRCController(Settings settings)
{
_settings = settings;
_ONcmd = _settings.LIRC_ON_Delay > 0;
_needONcmd = _settings.LIRC_ON_Delay > 0;
}

public bool SendCMD(string cmd)
Expand All @@ -29,7 +29,7 @@ public bool SendCMD(string cmd)
bool goodResult = true;

//case when fan needs to be turned ON before a command can be sent
if (_ONcmd && _isOFF)
if (_needONcmd && _isOFF)
{
if (cmd != "OFF")
{
Expand Down Expand Up @@ -76,6 +76,7 @@ private bool SendLIRCBytes(byte[] cmd)
try
{
_lircSocket.Send(cmd);
Log.LogTrace(Encoding.ASCII.GetString(cmd));

if ((_lircSocket.Poll(1000, SelectMode.SelectRead) && (_lircSocket.Available == 0)) || !_lircSocket.Connected)
{
Expand All @@ -95,6 +96,7 @@ private bool SendLIRCBytes(byte[] cmd)
Connect();

_lircSocket.Send(cmd);
Log.LogTrace(Encoding.ASCII.GetString(cmd));

if ((_lircSocket.Poll(1000, SelectMode.SelectRead) && (_lircSocket.Available == 0)) || !_lircSocket.Connected)
{
Expand Down Expand Up @@ -132,6 +134,11 @@ public bool Connect()
_lircSocket.EndConnect(result);

Thread.Sleep(25);

if (ConfigHelper.OS != "win")
{
SendLIRCBytes(Encoding.ASCII.GetBytes($"SET_TRANSMITTERS 1 2 3 4\n"));
}
}
catch
{
Expand Down
69 changes: 47 additions & 22 deletions HTFanControl/Controllers/MQTTController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,67 @@ public bool SendCMD(string cmd)
Connect();
}

string mqttTopic = cmd switch
string MQTT_Topic;
string MQTT_Payload;

if (!_settings.MQTT_Advanced_Mode)
{
"OFF" => _settings.MQTT_OFF_Topic,
"ECO" => _settings.MQTT_ECO_Topic,
"LOW" => _settings.MQTT_LOW_Topic,
"MED" => _settings.MQTT_MED_Topic,
"HIGH" => _settings.MQTT_HIGH_Topic,
_ => _settings.MQTT_OFF_Topic,
};
string mqttPayload = cmd switch
MQTT_Topic = cmd switch
{
"OFF" => _settings.MQTT_OFF_Topic,
"ECO" => _settings.MQTT_ECO_Topic,
"LOW" => _settings.MQTT_LOW_Topic,
"MED" => _settings.MQTT_MED_Topic,
"HIGH" => _settings.MQTT_HIGH_Topic,
_ => null,
};
MQTT_Payload = cmd switch
{
"OFF" => _settings.MQTT_OFF_Payload,
"ECO" => _settings.MQTT_ECO_Payload,
"LOW" => _settings.MQTT_LOW_Payload,
"MED" => _settings.MQTT_MED_Payload,
"HIGH" => _settings.MQTT_HIGH_Payload,
_ => null,
};
}
else
{
"OFF" => _settings.MQTT_OFF_Payload,
"ECO" => _settings.MQTT_ECO_Payload,
"LOW" => _settings.MQTT_LOW_Payload,
"MED" => _settings.MQTT_MED_Payload,
"HIGH" => _settings.MQTT_HIGH_Payload,
_ => _settings.MQTT_OFF_Payload,
};
_settings.MQTT_Topics.TryGetValue(cmd, out MQTT_Topic);
_settings.MQTT_Payloads.TryGetValue(cmd, out MQTT_Payload);
}

//case when using IR over MQTT and fan needs to be turned ON before a command can be sent
if (_ONcmd && _isOFF)
{
if(cmd != "OFF")
{
string ON_Topic = null;
string ON_Payload = null;

try
{
if (!_settings.MQTT_Advanced_Mode)
{
ON_Topic = _settings.MQTT_ON_Topic;
ON_Payload = _settings.MQTT_ON_Payload;
}
else
{
_settings.MQTT_Topics.TryGetValue("ON", out ON_Topic);
_settings.MQTT_Payloads.TryGetValue("ON", out ON_Payload);
}

MqttApplicationMessage message = new MqttApplicationMessageBuilder()
.WithTopic(_settings.MQTT_ON_Topic)
.WithPayload(_settings.MQTT_ON_Payload)
.WithTopic(ON_Topic)
.WithPayload(ON_Payload)
.Build();

_mqttClient.PublishAsync(message);
}
catch
{
ErrorStatus = @$"({DateTime.Now:h:mm:ss tt}) Failed turning fan ON by sending Topic: ""{_settings.MQTT_ON_Topic}"" and Payload: ""{_settings.MQTT_ON_Payload}"" To: {_settings.MQTT_IP}:{_settings.MQTT_Port}";
ErrorStatus = @$"({DateTime.Now:h:mm:ss tt}) Failed turning fan ON by sending Topic: ""{ON_Topic}"" and Payload: ""{ON_Payload}"" To: {_settings.MQTT_IP}:{_settings.MQTT_Port}";
return false;
}

Expand All @@ -84,16 +109,16 @@ public bool SendCMD(string cmd)
try
{
MqttApplicationMessage message = new MqttApplicationMessageBuilder()
.WithTopic(mqttTopic)
.WithPayload(mqttPayload)
.WithTopic(MQTT_Topic)
.WithPayload(MQTT_Payload)
.Build();

IAsyncResult result = _mqttClient.PublishAsync(message);
result.AsyncWaitHandle.WaitOne(1000);
}
catch
{
ErrorStatus = @$"({DateTime.Now:h:mm:ss tt}) Failed sending Topic: ""{mqttTopic}"" and Payload: ""{mqttPayload}"" To: {_settings.MQTT_IP}:{_settings.MQTT_Port}";
ErrorStatus = @$"({DateTime.Now:h:mm:ss tt}) Failed sending Topic: ""{MQTT_Topic}"" and Payload: ""{MQTT_Payload}"" To: {_settings.MQTT_IP}:{_settings.MQTT_Port}";
return false;
}
}
Expand Down
8 changes: 4 additions & 4 deletions HTFanControl/HTFanControl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<ApplicationIcon>htfancontrol.ico</ApplicationIcon>
<Configurations>Debug;ReleaseWin;ReleaseLinux</Configurations>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<AssemblyVersion>0.3.4.0</AssemblyVersion>
<FileVersion>0.3.4.0</FileVersion>
<Version>0.3.4</Version>
<AssemblyVersion>0.4.0.0</AssemblyVersion>
<FileVersion>0.4.0.0</FileVersion>
<Version>0.4.0.0</Version>
<Description>4D Theater Wind Effect - DIY Home Theater Project</Description>
<Copyright>nicko88</Copyright>
<Authors>nicko88</Authors>
Expand Down Expand Up @@ -76,7 +76,7 @@
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="MQTTnet" Version="3.1.2" />
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" />
<PackageReference Include="OpenTK.OpenAL" Version="4.7.7" />
<PackageReference Include="SoundFingerprinting" Version="8.5.1" />
<PackageReference Include="SoundFingerprinting.Emy" Version="8.5.1" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion HTFanControl/Main/HTFanControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ private void LoadVideoTimecodes(string fileName, string filePath)
}
}

if(timeCode != null)
if (timeCode != null)
{
if (isFanCmd)
{
Expand Down
48 changes: 44 additions & 4 deletions HTFanControl/Main/WebUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,11 @@ private string SettingsPage()
html = html.Replace("{MqttUser}", _HTFanCtrl._settings.MQTT_User);
html = html.Replace("{MqttPass}", _HTFanCtrl._settings.MQTT_Pass);

if(_HTFanCtrl._settings.MQTT_Advanced_Mode)
{
html = html.Replace("{MqttAdvancedMode}", "checked");
}

html = html.Replace("{MqttOFFtopic}", HttpUtility.HtmlEncode(_HTFanCtrl._settings.MQTT_OFF_Topic));
html = html.Replace("{MqttOFFpayload}", HttpUtility.HtmlEncode(_HTFanCtrl._settings.MQTT_OFF_Payload));
html = html.Replace("{MqttECOtopic}", HttpUtility.HtmlEncode(_HTFanCtrl._settings.MQTT_ECO_Topic));
Expand Down Expand Up @@ -514,6 +519,7 @@ private void SaveSettings(HttpListenerRequest request)
_HTFanCtrl._settings.MQTT_Port = int.TryParse(data.RootElement.GetProperty("MqttPort").GetString(), out int MqttPort) ? MqttPort : 1883;
_HTFanCtrl._settings.MQTT_User = data.RootElement.GetProperty("MqttUser").GetString();
_HTFanCtrl._settings.MQTT_Pass = data.RootElement.GetProperty("MqttPass").GetString();
_HTFanCtrl._settings.MQTT_Advanced_Mode = data.RootElement.GetProperty("MqttAdvancedMode").GetBoolean();
_HTFanCtrl._settings.MQTT_OFF_Topic = data.RootElement.GetProperty("MqttOFFtopic").GetString();
_HTFanCtrl._settings.MQTT_OFF_Payload = data.RootElement.GetProperty("MqttOFFpayload").GetString();
_HTFanCtrl._settings.MQTT_ECO_Topic = data.RootElement.GetProperty("MqttECOtopic").GetString();
Expand Down Expand Up @@ -550,11 +556,45 @@ private void SaveSettings(HttpListenerRequest request)
_HTFanCtrl._settings.MediaPlayerType = data.RootElement.GetProperty("MediaPlayer").GetString();
_HTFanCtrl._settings.PlexToken = data.RootElement.GetProperty("PlexToken").GetString();

if(_HTFanCtrl._settings.MQTT_Advanced_Mode && _HTFanCtrl._settings.MQTT_Topics is null)
{
ConvertToAdvMQTT();
}
else
{
_HTFanCtrl._settings.MQTT_Topics = null;
_HTFanCtrl._settings.MQTT_Payloads = null;
}

Settings.SaveSettings(_HTFanCtrl._settings);
_HTFanCtrl.ReInitialize(true);
}
}

private void ConvertToAdvMQTT()
{
_HTFanCtrl._settings.MQTT_Topics = new Dictionary<string, string>();
_HTFanCtrl._settings.MQTT_Payloads = new Dictionary<string, string>();

_HTFanCtrl._settings.MQTT_Topics.Add("OFF", _HTFanCtrl._settings.MQTT_OFF_Topic);
_HTFanCtrl._settings.MQTT_Topics.Add("ECO", _HTFanCtrl._settings.MQTT_ECO_Topic);
_HTFanCtrl._settings.MQTT_Topics.Add("LOW", _HTFanCtrl._settings.MQTT_LOW_Topic);
_HTFanCtrl._settings.MQTT_Topics.Add("MED", _HTFanCtrl._settings.MQTT_MED_Topic);
_HTFanCtrl._settings.MQTT_Topics.Add("HIGH", _HTFanCtrl._settings.MQTT_HIGH_Topic);

_HTFanCtrl._settings.MQTT_Payloads.Add("OFF", _HTFanCtrl._settings.MQTT_OFF_Payload);
_HTFanCtrl._settings.MQTT_Payloads.Add("ECO", _HTFanCtrl._settings.MQTT_ECO_Payload);
_HTFanCtrl._settings.MQTT_Payloads.Add("LOW", _HTFanCtrl._settings.MQTT_LOW_Payload);
_HTFanCtrl._settings.MQTT_Payloads.Add("MED", _HTFanCtrl._settings.MQTT_MED_Payload);
_HTFanCtrl._settings.MQTT_Payloads.Add("HIGH", _HTFanCtrl._settings.MQTT_HIGH_Payload);

if (_HTFanCtrl._settings.MQTT_ON_Delay > 0)
{
_HTFanCtrl._settings.MQTT_Topics.Add("ON", _HTFanCtrl._settings.MQTT_ON_Topic);
_HTFanCtrl._settings.MQTT_Payloads.Add("ON", _HTFanCtrl._settings.MQTT_ON_Payload);
}
}

private string CheckUpdatePage()
{
string html = GetHtml("checkupdate");
Expand All @@ -578,7 +618,7 @@ private string CheckUpdatePage()

if (_version != latest)
{
if (ConfigHelper.GetOS() != "win")
if (ConfigHelper.OS != "win")
{
sb.AppendLine(@"<button id=""btnupdate"" onclick=""linuxupdate();"" class=""btn btn-primary"">Update HTFanControl</button>");
}
Expand Down Expand Up @@ -891,7 +931,7 @@ private static string GetAudioDevices()
}
catch
{
if (ConfigHelper.GetOS() == "win")
if (ConfigHelper.OS == "win")
{
sb.AppendLine("OpenAL not installed.");
sb.AppendLine("<br/>");
Expand Down Expand Up @@ -995,7 +1035,7 @@ private string LogData()
private static string CrashlogsPage()
{
string html = GetHtml("crashlogs");
string[] crashlogs = new string[0];
string[] crashlogs = Array.Empty<string>();
try
{
crashlogs = Directory.GetFiles(Path.Combine(ConfigHelper._rootPath, "crashlogs"));
Expand All @@ -1013,7 +1053,7 @@ private static string CrashlogsPage()
return html;
}

private string ViewCrashlog(HttpListenerRequest request)
private static string ViewCrashlog(HttpListenerRequest request)
{
string html = "";
string crashlogName = GetPostBody(request);
Expand Down
6 changes: 2 additions & 4 deletions HTFanControl/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,18 @@ static void Main(string[] args)
Directory.CreateDirectory(Path.Combine(ConfigHelper._rootPath, "tmp"));
}

if (ConfigHelper.GetOS() == "win")
if (ConfigHelper.OS == "win")
{
ConfigHelper.SetupWin(port, instanceName);
#if (RELEASE || DEBUG)
Task.Factory.StartNew(() => new FanTrayIcon.TrayIcon(ConfigHelper.GetIP(), port, instanceName));
Task.Factory.StartNew(() => new FanTrayIcon.TrayIcon(port, instanceName));
#endif
}
else
{
ConfigHelper.SetupLinux();
}

Console.WriteLine($"http://{ConfigHelper.GetIP()}:{port}");

_ = new Main.WebUI(port, instanceName);
}

Expand Down
Loading

0 comments on commit 1688067

Please sign in to comment.