diff --git a/FanTrayIcon/TrayIcon.cs b/FanTrayIcon/TrayIcon.cs index 612e457..8b53780 100644 --- a/FanTrayIcon/TrayIcon.cs +++ b/FanTrayIcon/TrayIcon.cs @@ -1,11 +1,11 @@ -using Microsoft.Win32; -using System; +using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Windows.Forms; +using Microsoft.Win32; namespace FanTrayIcon { @@ -43,7 +43,7 @@ public TrayIcon(string IP) itemWebUI.Click += new EventHandler(itemWebUI_Click); itemConsole = new ToolStripMenuItem(); - itemConsole.Text = "Show Console Window"; + itemConsole.Text = "Show Console Window (Log)"; itemConsole.CheckOnClick = true; itemConsole.Click += new EventHandler(itemConsole_Click); diff --git a/HTFanControl/Controllers/LIRCController.cs b/HTFanControl/Controllers/LIRCController.cs index 1b5ee85..f7e5ef9 100644 --- a/HTFanControl/Controllers/LIRCController.cs +++ b/HTFanControl/Controllers/LIRCController.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; +using HTFanControl.Util; namespace HTFanControl.Controllers { @@ -13,7 +13,6 @@ class LIRCController : IController { private Socket _lircSocket; private Dictionary _lircMapping; - private readonly string _rootPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); private Settings _settings; @@ -154,10 +153,10 @@ private bool SendLIRCBytes(byte[] cmd) private void LoadLIRCMapping() { _lircMapping = null; - if (File.Exists(Path.Combine(_rootPath, "lircmapping.txt"))) + if (File.Exists(Path.Combine(ConfigHelper._rootPath, "lircmapping.txt"))) { _lircMapping = new Dictionary(); - string[] mappingFile = File.ReadAllLines(Path.Combine(_rootPath, "lircmapping.txt")); + string[] mappingFile = File.ReadAllLines(Path.Combine(ConfigHelper._rootPath, "lircmapping.txt")); foreach (string s in mappingFile) { diff --git a/HTFanControl/Controllers/MQTTController.cs b/HTFanControl/Controllers/MQTTController.cs index 095e083..b08cb20 100644 --- a/HTFanControl/Controllers/MQTTController.cs +++ b/HTFanControl/Controllers/MQTTController.cs @@ -3,6 +3,7 @@ using MQTTnet.Client.Options; using System; using System.Threading; +using HTFanControl.Util; namespace HTFanControl.Controllers { @@ -38,6 +39,7 @@ public bool Connect() IMqttClientOptions options = new MqttClientOptionsBuilder() .WithTcpServer(_settings.MQTT_IP, port) + .WithCredentials(_settings.MQTT_User, _settings.MQTT_Pass) .Build(); IAsyncResult result = _mqttClient.ConnectAsync(options); @@ -114,7 +116,6 @@ public bool SendCMD(string cmd) else { mqttPayload = ""; - Console.WriteLine("(Ignored OFF Command)"); } } diff --git a/HTFanControl/HTFanControl.csproj b/HTFanControl/HTFanControl.csproj index 525acc8..61589f3 100644 --- a/HTFanControl/HTFanControl.csproj +++ b/HTFanControl/HTFanControl.csproj @@ -6,9 +6,9 @@ htfancontrol.ico Debug;ReleaseWin;ReleaseLinux true - 0.2.1.0 - 0.2.1.0 - 0.2.0 + 0.3.0.0 + 0.3.0.0 + 0.3.0 4D Theater Wind Effect - DIY Home Theater Project nicko88 nicko88 @@ -37,16 +37,16 @@ - + + - @@ -55,8 +55,9 @@ - + + @@ -66,19 +67,18 @@ - - + - + - - + + diff --git a/HTFanControl/Log.cs b/HTFanControl/Log.cs deleted file mode 100644 index e5e8b49..0000000 --- a/HTFanControl/Log.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; - -namespace HTFanControl -{ - public static class Log - { - private static readonly string _path = Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), $"{DateTime.Now:MM.dd.yy-hh.mm-tt}_log.txt"); - public static void WriteLine(string line) - { - File.AppendAllText(_path, line + Environment.NewLine); - } - } -} \ No newline at end of file diff --git a/HTFanControl/HTFanControl.cs b/HTFanControl/Main/HTFanControl.cs similarity index 88% rename from HTFanControl/HTFanControl.cs rename to HTFanControl/Main/HTFanControl.cs index ecf872d..637c776 100644 --- a/HTFanControl/HTFanControl.cs +++ b/HTFanControl/Main/HTFanControl.cs @@ -1,32 +1,30 @@ -using HTFanControl.Players; -using System; +using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using HTFanControl.Timers; using System.IO.Compression; using HTFanControl.Controllers; +using HTFanControl.Players; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Main { class HTFanControl { - public readonly string _rootPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); - public string _errorStatus; public string _windtrackError; - public long _loadedVideoTime = 0; + public long _loadedVideoTime; public string _loadedVideoFilename; public string _currentWindtrackPath; public string _windTrackHeader; public int _curCmdIndex = -1; - public int _nextCmdIndex = 0; + public int _nextCmdIndex; public bool _isPlaying = false; public bool _isEnabled = true; public bool _hasOffset = false; - public double _offset = 0; + public double _offset; public bool _offsetEnabled = false; public List> _videoTimeCodes; @@ -39,8 +37,12 @@ class HTFanControl public Settings _settings; + public Log _log; + public HTFanControl() { + _log = new Log(); + _settings = Settings.LoadSettings(); Settings.SaveSettings(_settings); @@ -115,7 +117,7 @@ private void SelectSyncSource() public async void SelectVideo(string fileName) { - ExtractWindtrack(Path.Combine(_rootPath, "windtracks", fileName + ".zip"), true); + ExtractWindtrack(Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".zip"), true); _loadedVideoFilename = "Loading Video Fingerprints..."; _windTrackHeader = "Loading Windtrack..."; @@ -153,11 +155,11 @@ public void ToggleFan() { _errorStatus = _fanController.ErrorStatus; } - Console.WriteLine("Fans Disabled"); + _log.LogMsg("Fans Disabled"); } else { - Console.WriteLine("Fans Enabled"); + _log.LogMsg("Fans Enabled"); _isEnabled = true; @@ -171,7 +173,7 @@ public void ToggleFan() { _errorStatus = _fanController.ErrorStatus; } - Console.WriteLine($"Sent CMD: {_videoTimeCodes[_curCmdIndex].Item1.ToString("G").Substring(2, 12)},{_videoTimeCodes[_curCmdIndex].Item2}"); + _log.LogMsg($"Sent CMD: {_videoTimeCodes[_curCmdIndex].Item1.ToString("G").Substring(2, 12)},{_videoTimeCodes[_curCmdIndex].Item2}"); } } catch { } @@ -262,11 +264,11 @@ private void SendCmd(PositionTimer videoTimer, (string cmd, int index) command) try { - Console.WriteLine($"Sent CMD: {_videoTimeCodes[i].Item1.ToString("G").Substring(2, 12)},{fanCmd}"); + _log.LogMsg($"Sent CMD: {_videoTimeCodes[i].Item1.ToString("G").Substring(2, 12)},{fanCmd}"); } catch { - Console.WriteLine($"Sent CMD: {fanCmd}"); + _log.LogMsg($"Sent CMD: {fanCmd}"); } if (_isEnabled) @@ -287,9 +289,9 @@ private string GetWindtrackFilePath(string fileName, string filePath) //look for windtrack .txt in tmp folder try { - if (File.Exists(Path.Combine(_rootPath, "tmp", fileName + ".txt"))) + if (File.Exists(Path.Combine(ConfigHelper._rootPath, "tmp", fileName + ".txt"))) { - validFilePath = Path.Combine(_rootPath, "tmp", fileName + ".txt"); + validFilePath = Path.Combine(ConfigHelper._rootPath, "tmp", fileName + ".txt"); } } catch { } @@ -297,10 +299,10 @@ private string GetWindtrackFilePath(string fileName, string filePath) //look for windtrack .zip archive in windtracks folder try { - if (string.IsNullOrEmpty(validFilePath) && File.Exists(Path.Combine(_rootPath, "windtracks", fileName + ".zip"))) + if (string.IsNullOrEmpty(validFilePath) && File.Exists(Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".zip"))) { - ExtractWindtrack(Path.Combine(_rootPath, "windtracks", fileName + ".zip"), false); - validFilePath = Path.Combine(_rootPath, "tmp", fileName + ".txt"); + ExtractWindtrack(Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".zip"), false); + validFilePath = Path.Combine(ConfigHelper._rootPath, "tmp", fileName + ".txt"); } } catch { } @@ -311,7 +313,7 @@ private string GetWindtrackFilePath(string fileName, string filePath) if (string.IsNullOrEmpty(validFilePath) && File.Exists(Path.Combine(filePath, fileName + ".zip"))) { ExtractWindtrack(Path.Combine(filePath, fileName + ".zip"), false); - validFilePath = Path.Combine(_rootPath, "tmp", fileName + ".txt"); + validFilePath = Path.Combine(ConfigHelper._rootPath, "tmp", fileName + ".txt"); } } catch { } @@ -319,9 +321,9 @@ private string GetWindtrackFilePath(string fileName, string filePath) //LEGACY look in windtrack folder try { - if (string.IsNullOrEmpty(validFilePath) && File.Exists(Path.Combine(_rootPath, "windtracks", fileName + ".txt"))) + if (string.IsNullOrEmpty(validFilePath) && File.Exists(Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".txt"))) { - validFilePath = Path.Combine(_rootPath, "windtracks", fileName + ".txt"); + validFilePath = Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".txt"); } } catch { } @@ -412,14 +414,7 @@ private void LoadVideoTimecodes(string fileName, string filePath) double? timeCode = null; try { - if (isFanCmd) - { - timeCode = TimeSpan.Parse(lineData[0]).TotalMilliseconds - _settings.GlobalOffsetMS; - } - else - { - timeCode = TimeSpan.Parse(lineData[0]).TotalMilliseconds; - } + timeCode = TimeSpan.Parse(lineData[0]).TotalMilliseconds; } catch { @@ -444,6 +439,11 @@ private void LoadVideoTimecodes(string fileName, string filePath) } } + if (isFanCmd) + { + timeCode = timeCode - _settings.GlobalOffsetMS; + } + rawPrevTime = (double)timeCode; if (isFanCmd) @@ -506,7 +506,7 @@ private void LoadVideoTimecodes(string fileName, string filePath) private void ExtractWindtrack(string filePath, bool extractFingerprint) { - DirectoryInfo tmp = new DirectoryInfo(Path.Combine(_rootPath, "tmp")); + DirectoryInfo tmp = new DirectoryInfo(Path.Combine(ConfigHelper._rootPath, "tmp")); foreach (FileInfo file in tmp.GetFiles()) { file.Delete(); @@ -518,11 +518,12 @@ private void ExtractWindtrack(string filePath, bool extractFingerprint) { using ZipArchive archive = ZipFile.OpenRead(filePath); - archive.Entries.Where(e => e.Name.Equals("commands.txt")).Single().ExtractToFile(Path.Combine(_rootPath, "tmp", fileName + ".txt"), true); + archive.Entries.Where(e => e.Name.Equals("commands.txt")).Single().ExtractToFile(Path.Combine(ConfigHelper._rootPath, "tmp", fileName + ".txt"), true); if (extractFingerprint) { - archive.Entries.Where(e => e.Name.Equals("full.fingerprints")).Single().ExtractToFile(Path.Combine(_rootPath, "tmp", fileName + ".fingerprints"), true); + Directory.CreateDirectory(Path.Combine(ConfigHelper._rootPath, "tmp", "fingerprint")); + archive.Entries.Where(e => e.Name.Equals("full.fingerprints")).Single().ExtractToFile(Path.Combine(new string[] { ConfigHelper._rootPath, "tmp", "fingerprint", "audio" }), true); } } catch diff --git a/HTFanControl/WebUI.cs b/HTFanControl/Main/WebUI.cs similarity index 87% rename from HTFanControl/WebUI.cs rename to HTFanControl/Main/WebUI.cs index e40ec84..b56b26b 100644 --- a/HTFanControl/WebUI.cs +++ b/HTFanControl/Main/WebUI.cs @@ -14,14 +14,16 @@ using System.Net.Http.Headers; using OpenTK.Audio.OpenAL; using System.IO.Compression; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Main { class WebUI { private readonly string _version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3); private readonly Thread _httpThread; private readonly HTFanControl _HTFanCtrl; + private bool _webUIEnabled = true; private bool _waitForFile = false; public WebUI() @@ -38,7 +40,7 @@ private void StartListen() listener.Prefixes.Add("http://*:5500/"); listener.Start(); - while (true) + while (_webUIEnabled) { IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ProcessRequest), listener); result.AsyncWaitHandle.WaitOne(); @@ -83,12 +85,6 @@ private void ProcessRequest(IAsyncResult result) case "/savesettings": SaveSettings(request); break; - case "/raspiwifi": - htmlResponse = RasPiWiFiPage(); - break; - case "/savewifi": - SaveWiFi(request); - break; case "/downloadlist": htmlResponse = DownloadListPage(request); break; @@ -154,6 +150,25 @@ private void ProcessRequest(IAsyncResult result) case "/loadedwindtrackdata": htmlResponse = LoadedWindTrackData(); break; + case "/logviewer": + htmlResponse = GetHtml("logviewer"); + break; + case "/logdata": + htmlResponse = LogData(); + break; + case "/crashlogs": + htmlResponse = CrashlogsPage(); + break; + case "/viewcrashlog": + htmlResponse = ViewCrashlog(request); + break; + case "/deletelogs": + try + { + Directory.Delete(Path.Combine(ConfigHelper._rootPath, "crashlogs"), true); + } + catch { } + break; case "/selectvideo": htmlResponse = SelectVideoPage(); break; @@ -169,9 +184,8 @@ private void ProcessRequest(IAsyncResult result) case "/checkupdate": htmlResponse = CheckUpdatePage(); break; - case "/raspiupdate": - ($"nohup {Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "updater.sh")} &>/dev/null &").Bash(); - Environment.Exit(0); + case "/linuxupdate": + LinuxUpdate(); break; case "/shutdown": Environment.Exit(0); @@ -294,7 +308,7 @@ private string GetStatusData() } else { - if (!string.IsNullOrEmpty(_HTFanCtrl._loadedVideoFilename)) + if (!string.IsNullOrEmpty(_HTFanCtrl._loadedVideoFilename) && _HTFanCtrl._loadedVideoFilename != "Loading Video Fingerprints...") { htmlData.AppendLine("No wind track file found named: " + _HTFanCtrl._loadedVideoFilename + ".txt"); htmlData.AppendLine("

"); @@ -332,11 +346,13 @@ private string SettingsPage() if (ConfigHelper.GetOS() == "win") { - html = html.Replace("/*{showraspi}*/", "display: none;"); + html = html.Replace("/*{showlinux}*/", "display: none;"); + html = html.Replace("/*{hidelinux}*/", "display: initial;"); } else { - html = html.Replace("/*{showraspi}*/", "display: initial;"); + html = html.Replace("/*{showlinux}*/", "display: initial;"); + html = html.Replace("/*{hidelinux}*/", "display: none;"); } if (_HTFanCtrl._settings.ControllerType == "LIRC") @@ -355,6 +371,9 @@ private string SettingsPage() html = html.Replace("{MqttIP}", _HTFanCtrl._settings.MQTT_IP); html = html.Replace("{MqttPort}", _HTFanCtrl._settings.MQTT_Port.ToString()); + html = html.Replace("{MqttUser}", _HTFanCtrl._settings.MQTT_User); + html = html.Replace("{MqttPass}", _HTFanCtrl._settings.MQTT_Pass); + 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)); @@ -444,6 +463,8 @@ private void SaveSettings(HttpListenerRequest request) _HTFanCtrl._settings.LIRC_Remote = data.RootElement.GetProperty("LircRemote").GetString(); _HTFanCtrl._settings.MQTT_IP = data.RootElement.GetProperty("MqttIP").GetString(); _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_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(); @@ -467,59 +488,6 @@ private void SaveSettings(HttpListenerRequest request) } } - private static string RasPiWiFiPage() - { - string html = GetHtml("raspiwifi"); - try - { - string netplan = ("cat /etc/netplan/50-cloud-init.yaml").Bash(); - - int ssidStart = netplan.IndexOf("access-points:") + 30; - int ssidEnd = netplan.IndexOf("password:") - 19; - string ssid = netplan[ssidStart..ssidEnd]; - - int passwordStart = netplan.IndexOf("password:") + 10; - int passwordEnd = netplan.Length - 1; - string password = netplan[passwordStart..passwordEnd]; - - html = html.Replace("{ssid}", ssid); - html = html.Replace("{password}", password); - } - catch { } - - return html; - } - - private static void SaveWiFi(HttpListenerRequest request) - { - string wifiInfoJSON = GetPostBody(request); - - if (!string.IsNullOrEmpty(wifiInfoJSON)) - { - string netplan = ""; - try - { - Assembly assembly = Assembly.GetExecutingAssembly(); - string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith("50-cloud-init.yaml")); - - using Stream stream = assembly.GetManifestResourceStream(resourceName); - using StreamReader reader = new StreamReader(stream); - netplan = reader.ReadToEnd(); - } - catch { } - - using JsonDocument data = JsonDocument.Parse(wifiInfoJSON); - string ssid = data.RootElement.GetProperty("ssid").GetString(); - string password = data.RootElement.GetProperty("password").GetString(); - - netplan = netplan.Replace("{ssid}", ssid); - netplan = netplan.Replace("{pass}", password); - - ($"echo \"{netplan}\" > /etc/netplan/50-cloud-init.yaml").Bash(); - "netplan apply".Bash(); - } - } - private string CheckUpdatePage() { string html = GetHtml("checkupdate"); @@ -543,9 +511,9 @@ private string CheckUpdatePage() if (_version != latest) { - if (ConfigHelper.GetOS() == "raspi") + if (ConfigHelper.GetOS() != "win") { - sb.AppendLine(@""); + sb.AppendLine(@""); } else { @@ -564,6 +532,14 @@ private string CheckUpdatePage() return html; } + private void LinuxUpdate() + { + $"wget -O {Path.Combine(ConfigHelper._rootPath, "update.sh")} https://raw.githubusercontent.com/nicko88/HTFanControl/master/install/update.sh".Bash(); + $"bash {Path.Combine(ConfigHelper._rootPath, "update.sh")}".Bash(); + + _webUIEnabled = false; + } + private static string DownloadListPage(HttpListenerRequest request) { string html = GetHtml("downloadlist"); @@ -617,7 +593,7 @@ private static string DownloadListPage(HttpListenerRequest request) return html; } - private string DownloadPage(HttpListenerRequest request) + private static string DownloadPage(HttpListenerRequest request) { string html = GetHtml("download"); string downloadInfo = GetPostBody(request); @@ -632,10 +608,10 @@ private string DownloadPage(HttpListenerRequest request) using WebClient client = new WebClient(); client.Headers.Add("User-Agent", ".netapp"); - client.DownloadFile(url, Path.Combine(_HTFanCtrl._rootPath, "tmp", filename[1] + ".zip")); + client.DownloadFile(url, Path.Combine(ConfigHelper._rootPath, "tmp", filename[1] + ".zip")); string windCodes = ""; - using ZipArchive zip = ZipFile.Open(Path.Combine(_HTFanCtrl._rootPath, "tmp", filename[1] + ".zip"), ZipArchiveMode.Read); + using ZipArchive zip = ZipFile.Open(Path.Combine(ConfigHelper._rootPath, "tmp", filename[1] + ".zip"), ZipArchiveMode.Read); foreach (ZipArchiveEntry entry in zip.Entries) { if (entry.Name == "commands.txt") @@ -664,7 +640,7 @@ private string ManagePage() } string html = GetHtml("manage"); - string[] files = Directory.GetFiles(Path.Combine(_HTFanCtrl._rootPath, "windtracks")); + string[] files = Directory.GetFiles(Path.Combine(ConfigHelper._rootPath, "windtracks")); List fileList = new List(files); fileList.Sort(); @@ -679,7 +655,7 @@ private string ManagePage() return html; } - private string EditPage(HttpListenerRequest request) + private static string EditPage(HttpListenerRequest request) { string html = GetHtml("edit"); string editInfo = GetPostBody(request); @@ -693,11 +669,11 @@ private string EditPage(HttpListenerRequest request) { if (values[1].EndsWith(".txt")) { - windCodes = File.ReadAllText(Path.Combine(_HTFanCtrl._rootPath, "windtracks", HttpUtility.UrlDecode(values[1]))); + windCodes = File.ReadAllText(Path.Combine(ConfigHelper._rootPath, "windtracks", HttpUtility.UrlDecode(values[1]))); } else { - using ZipArchive zip = ZipFile.Open(Path.Combine(_HTFanCtrl._rootPath, "windtracks", HttpUtility.UrlDecode(values[1])), ZipArchiveMode.Read); + using ZipArchive zip = ZipFile.Open(Path.Combine(ConfigHelper._rootPath, "windtracks", HttpUtility.UrlDecode(values[1])), ZipArchiveMode.Read); foreach (ZipArchiveEntry entry in zip.Entries) { if (entry.Name == "commands.txt") @@ -726,7 +702,7 @@ private void UploadFile(HttpListenerRequest request) try { - SaveUploadFile(request, Path.Combine(_HTFanCtrl._rootPath, "windtracks", filename)); + SaveUploadFile(request, Path.Combine(ConfigHelper._rootPath, "windtracks", filename)); } catch { } } @@ -740,7 +716,7 @@ private void RenameFile(HttpListenerRequest request) try { string ext = Path.GetExtension(renameInfo); - File.Move(Path.Combine(_HTFanCtrl._rootPath, "windtracks", renameInfo), Path.Combine(_HTFanCtrl._rootPath, "windtracks", _HTFanCtrl._loadedVideoFilename + ext), true); + File.Move(Path.Combine(ConfigHelper._rootPath, "windtracks", renameInfo), Path.Combine(ConfigHelper._rootPath, "windtracks", _HTFanCtrl._loadedVideoFilename + ext), true); } catch { } _HTFanCtrl.ReInitialize(false); @@ -757,7 +733,7 @@ private void DeleteFile(HttpListenerRequest request) { try { - File.Delete(Path.Combine(_HTFanCtrl._rootPath, "windtracks", deleteInfo)); + File.Delete(Path.Combine(ConfigHelper._rootPath, "windtracks", deleteInfo)); } catch { } _HTFanCtrl.ReInitialize(false); @@ -778,7 +754,7 @@ private void SaveFile(HttpListenerRequest request) try { - File.Move(Path.Combine(_HTFanCtrl._rootPath, "tmp", saveInfo + ".zip"), Path.Combine(_HTFanCtrl._rootPath, "windtracks", fileName + ".zip"), true); + File.Move(Path.Combine(ConfigHelper._rootPath, "tmp", saveInfo + ".zip"), Path.Combine(ConfigHelper._rootPath, "windtracks", fileName + ".zip"), true); } catch { } @@ -840,7 +816,10 @@ private static string GetAudioDevices() foreach (string device in devices) { - sb.AppendFormat(@"{0}" + "\n", device); + if (device != "ALSA Default") + { + sb.AppendFormat(@"{0}" + "\n", device); + } } } catch @@ -885,6 +864,8 @@ private string LoadedWindTrackData() if (_HTFanCtrl._videoTimeCodes != null) { + sb.Append(@"
"); + for (int i = 0; i < _HTFanCtrl._videoTimeCodes.Count; i++) { if(i == _HTFanCtrl._curCmdIndex) @@ -901,6 +882,8 @@ private string LoadedWindTrackData() sb.AppendLine("
"); } + + sb.Append("
"); } else { @@ -910,11 +893,83 @@ private string LoadedWindTrackData() return sb.ToString(); } - private string SelectVideoPage() + private string LogData() + { + string timeMsg = "Current time: "; + if (_HTFanCtrl._settings.MediaPlayerType == "Audio") + { + timeMsg = "Last time match: "; + } + + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("
"); + sb.AppendLine(@"(View Crashlogs)"); + sb.AppendLine("

"); + + sb.AppendLine(GetCurrentMovie()); + sb.AppendLine("

"); + sb.AppendLine(timeMsg + TimeSpan.FromMilliseconds(_HTFanCtrl._loadedVideoTime).ToString("G").Substring(2, 12)); + sb.AppendLine("

"); + + sb.Append(@"
"); + + foreach (string s in _HTFanCtrl._log.RealtimeLog) + { + sb.AppendLine(s); + sb.AppendLine("
"); + } + + sb.Append("
"); + + return sb.ToString(); + } + + private static string CrashlogsPage() + { + string html = GetHtml("crashlogs"); + string[] crashlogs = new string[0]; + try + { + crashlogs = Directory.GetFiles(Path.Combine(ConfigHelper._rootPath, "crashlogs")); + } + catch { } + + StringBuilder sb = new StringBuilder(); + foreach (string s in crashlogs) + { + sb.AppendFormat(@"{1}" + "\n", Path.GetFileName(s), Path.GetFileName(s).Replace(".txt", "")); + } + + html = html.Replace("{body}", sb.ToString()); + + return html; + } + + private string ViewCrashlog(HttpListenerRequest request) + { + string html = ""; + string crashlogName = GetPostBody(request); + + if (!string.IsNullOrEmpty(crashlogName)) + { + string[] values = crashlogName.Split('='); + + try + { + html = File.ReadAllText(Path.Combine(ConfigHelper._rootPath, "crashlogs", values[1])); + } + catch { } + } + + return html; + } + + private static string SelectVideoPage() { string html = GetHtml("selectvideo"); - string[] files = Directory.GetFiles(Path.Combine(_HTFanCtrl._rootPath, "windtracks")); + string[] files = Directory.GetFiles(Path.Combine(ConfigHelper._rootPath, "windtracks")); List fileList = new List(files); fileList.Sort(); @@ -967,7 +1022,7 @@ private void FanCmd(HttpListenerRequest request) { string fanCmdInfo = GetPostBody(request); - Console.WriteLine($"Sent CMD: {fanCmdInfo}"); + _HTFanCtrl._log.LogMsg($"Sent CMD: {fanCmdInfo}"); _HTFanCtrl._fanController.SendCMD(fanCmdInfo); } diff --git a/HTFanControl/Players/AudioSync.cs b/HTFanControl/Players/AudioSync.cs index 724605a..3b412e8 100644 --- a/HTFanControl/Players/AudioSync.cs +++ b/HTFanControl/Players/AudioSync.cs @@ -12,8 +12,9 @@ using System.IO; using System.Net.Http; using System.Linq; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Main { class AudioSync { @@ -45,7 +46,7 @@ public AudioSync(HTFanControl hTFanControl) { _hTFanControl = hTFanControl; - if(File.Exists(Path.Combine(_hTFanControl._rootPath, "testaccuracy.txt"))) + if(File.Exists(Path.Combine(ConfigHelper._rootPath, "testaccuracy.txt"))) { verifyAccuracy = true; } @@ -71,8 +72,7 @@ public void Stop() { if (_modelService != null) { - Console.WriteLine("Stop Listening..."); - //Log.WriteLine("Stop Listening..."); + _hTFanControl._log.LogMsg("Stop Listening..."); } _state = ""; @@ -94,9 +94,9 @@ private void LoadFingerprint(string fileName) string validFilePath = null; try { - if (File.Exists(Path.Combine(_hTFanControl._rootPath, "tmp", fileName + ".fingerprints"))) + if (File.Exists(Path.Combine(new string[] { ConfigHelper._rootPath, "tmp", "fingerprint", "audio" }))) { - validFilePath = Path.Combine(_hTFanControl._rootPath, "tmp", fileName + ".fingerprints"); + validFilePath = Path.Combine(new string[] { ConfigHelper._rootPath, "tmp", "fingerprint" }); } _modelService = new InMemoryModelService(validFilePath); @@ -111,8 +111,7 @@ private async void StartMatching(CancellationToken cancellationToken) { _realtimeSource = new BlockingCollection(); - Console.WriteLine("Start Listening..."); - //Log.WriteLine("Start Listening..."); + _hTFanControl._log.LogMsg("Start Listening..."); _state = "(listening...)"; try @@ -129,31 +128,29 @@ private void FoundMatch(AVQueryResult aVQueryResult) ResultEntry resultEntry = aVQueryResult.ResultEntries.First().Audio; _timeJump = false; - TimeSpan matchTime = TimeSpan.FromSeconds(resultEntry.TrackMatchStartsAt + resultEntry.QueryLength + TimeSpan.FromMilliseconds(aVQueryResult.QueryCommandStats.Audio.TotalDurationMilliseconds).TotalSeconds + 0.12); + TimeSpan matchTime = TimeSpan.FromSeconds(resultEntry.TrackMatchStartsAt + resultEntry.QueryLength + 0.12 /*+ TimeSpan.FromMilliseconds(aVQueryResult.QueryCommandStats.Audio.TotalDurationMilliseconds).TotalSeconds*/); if (matchTime > _lastMatchTime.Add(TimeSpan.FromMinutes(5)) || matchTime < _lastMatchTime.Subtract(TimeSpan.FromMinutes(5))) { _timeJump = true; _lastMatchTime = matchTime; - Console.WriteLine("Time Jump Detected"); - //Log.WriteLine("Time Jump Detected"); + _hTFanControl._log.LogMsg("Time Jump Detected"); } if (!_timeJump) { - Console.WriteLine($"Match Found: {matchTime:G}"); - //Log.WriteLine($"Match Found: {matchTime:G}"); + _hTFanControl._log.LogMsg($"Match Found: {matchTime.ToString("G").Substring(2, 12)}"); _hTFanControl._loadedVideoTime = Convert.ToInt64(matchTime.TotalMilliseconds); _hTFanControl.UpdateTime(); _lastMatchTime = matchTime; + + if (verifyAccuracy) + { + VerifyAccuracy(matchTime); + } } //_pause.Change(10000, Timeout.Infinite); - - if (verifyAccuracy) - { - VerifyAccuracy(matchTime); - } } } @@ -168,20 +165,19 @@ private void VerifyAccuracy(TimeSpan audioTime) HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(html); - position = long.Parse(doc.GetElementbyId("position").InnerText); + position = long.Parse(doc.GetElementbyId("position").InnerText) + 21; } catch { } TimeSpan playerTime = TimeSpan.FromMilliseconds(position); - string matchResult = $"Accuracy:{audioTime.Subtract(playerTime).TotalMilliseconds} AudioTime:{audioTime:G} PlayerTime:{playerTime:G}"; - Console.WriteLine(matchResult); - //Log.WriteLine(matchResult); + string matchResult = $"Accuracy:{audioTime.Subtract(playerTime).TotalMilliseconds} AudioTime:{audioTime.ToString("G").Substring(2, 12)} PlayerTime:{playerTime.ToString("G").Substring(2, 12)}"; + _hTFanControl._log.LogMsg(matchResult); } //private void Pause(object o) //{ // _pause.Change(Timeout.Infinite, Timeout.Infinite); - // Console.WriteLine("PAUSED"); + // _hTFanControl._log.LogMsg("PAUSED"); //} private void RecordOpenTK(object cancellationToken) @@ -243,6 +239,7 @@ public async Task GetBestMatchForStream(BlockingCollection { config.ResultEntryFilter = new TrackMatchLengthEntryFilter(3d); config.SuccessCallback = result => FoundMatch(result); + config.AutomaticSkipDetection = true; return config; }) .UsingServices(_modelService) diff --git a/HTFanControl/Players/KodiPlayer.cs b/HTFanControl/Players/KodiPlayer.cs index 11079ac..4e9bbbf 100644 --- a/HTFanControl/Players/KodiPlayer.cs +++ b/HTFanControl/Players/KodiPlayer.cs @@ -1,11 +1,11 @@ -using HTFanControl.Players; -using System; +using System; using System.IO; using System.Net.Http; using System.Text.Json; using System.Web; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Players { class KodiPlayer : IPlayer { diff --git a/HTFanControl/Players/MPCPlayer.cs b/HTFanControl/Players/MPCPlayer.cs index 516092b..1292af6 100644 --- a/HTFanControl/Players/MPCPlayer.cs +++ b/HTFanControl/Players/MPCPlayer.cs @@ -1,11 +1,11 @@ -using HTFanControl.Players; -using System; +using System; using System.IO; using System.Net.Http; using System.Text.Json; using System.Web; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Players { class MPCPlayer : IPlayer { diff --git a/HTFanControl/Players/PlexPlayer.cs b/HTFanControl/Players/PlexPlayer.cs index 6e8d687..8f1cc5b 100644 --- a/HTFanControl/Players/PlexPlayer.cs +++ b/HTFanControl/Players/PlexPlayer.cs @@ -1,12 +1,12 @@ -using HTFanControl.Players; -using System; +using System; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Xml.Linq; +using HTFanControl.Util; -namespace HTFanControl +namespace HTFanControl.Players { class PlexPlayer : IPlayer { diff --git a/HTFanControl/Program.cs b/HTFanControl/Program.cs index 8f7330d..8f12e2f 100644 --- a/HTFanControl/Program.cs +++ b/HTFanControl/Program.cs @@ -3,12 +3,12 @@ using System.IO; using System.Reflection; using System.Threading.Tasks; +using HTFanControl.Util; namespace HTFanControl { class Program { - private static string _rootDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); static void Main(string[] args) { if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location)).Length > 1) @@ -18,6 +18,16 @@ static void Main(string[] args) AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + if (!Directory.Exists(Path.Combine(ConfigHelper._rootPath, "windtracks"))) + { + Directory.CreateDirectory(Path.Combine(ConfigHelper._rootPath, "windtracks")); + } + + if (!Directory.Exists(Path.Combine(ConfigHelper._rootPath, "tmp"))) + { + Directory.CreateDirectory(Path.Combine(ConfigHelper._rootPath, "tmp")); + } + if (ConfigHelper.GetOS() == "win") { ConfigHelper.SetupWin(); @@ -25,33 +35,27 @@ static void Main(string[] args) Task.Factory.StartNew(() => new FanTrayIcon.TrayIcon(ConfigHelper.GetIP())); #endif } - - if (!Directory.Exists(Path.Combine(_rootDir, "windtracks"))) - { - Directory.CreateDirectory(Path.Combine(_rootDir, "windtracks")); - } - - if (!Directory.Exists(Path.Combine(_rootDir, "tmp"))) + else { - Directory.CreateDirectory(Path.Combine(_rootDir, "tmp")); + ConfigHelper.SetupLinux(); } Console.WriteLine("http://" + ConfigHelper.GetIP() + ":5500"); - _ = new WebUI(); + _ = new Main.WebUI(); } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; - if (!Directory.Exists(Path.Combine(_rootDir, "crashlogs"))) + if (!Directory.Exists(Path.Combine(ConfigHelper._rootPath, "crashlogs"))) { - Directory.CreateDirectory(Path.Combine(_rootDir, "crashlogs")); + Directory.CreateDirectory(Path.Combine(ConfigHelper._rootPath, "crashlogs")); } string crash = ex.Message + "\n\n" + ex.InnerException + "\n\n" + ex.Source + "\n\n" + ex.StackTrace; - File.WriteAllText(Path.Combine(_rootDir, "crashlogs", DateTime.Now.ToString("MM.dd.yy-hh.mm-tt") + ".txt"), crash); + File.WriteAllText(Path.Combine(ConfigHelper._rootPath, "crashlogs", DateTime.Now.ToString("MM.dd.yy-hh.mm-tt") + ".txt"), crash); } } } \ No newline at end of file diff --git a/HTFanControl/Properties/PublishProfiles/linux.pubxml b/HTFanControl/Properties/PublishProfiles/linux.pubxml new file mode 100644 index 0000000..2f70c0a --- /dev/null +++ b/HTFanControl/Properties/PublishProfiles/linux.pubxml @@ -0,0 +1,17 @@ + + + + + ReleaseLinux + Any CPU + bin\Publish\linux + FileSystem + net5.0-windows7.0 + linux-x64 + true + True + True + + \ No newline at end of file diff --git a/HTFanControl/Properties/PublishProfiles/raspi64.pubxml b/HTFanControl/Properties/PublishProfiles/raspi64.pubxml new file mode 100644 index 0000000..5288d10 --- /dev/null +++ b/HTFanControl/Properties/PublishProfiles/raspi64.pubxml @@ -0,0 +1,17 @@ + + + + + ReleaseLinux + Any CPU + bin\Publish\raspi64 + FileSystem + net5.0-windows7.0 + linux-arm64 + true + True + True + + \ No newline at end of file diff --git a/HTFanControl/ConfigHelper.cs b/HTFanControl/Util/ConfigHelper.cs similarity index 70% rename from HTFanControl/ConfigHelper.cs rename to HTFanControl/Util/ConfigHelper.cs index b03528f..8397d76 100644 --- a/HTFanControl/ConfigHelper.cs +++ b/HTFanControl/Util/ConfigHelper.cs @@ -1,23 +1,26 @@ using System; using System.Diagnostics; +using System.IO; using System.Net; using System.Net.Sockets; -namespace HTFanControl +namespace HTFanControl.Util { public static class ConfigHelper { + public static readonly string _rootPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); + public static string GetIP() { var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) { - if (ip.AddressFamily == AddressFamily.InterNetwork) + if (ip.AddressFamily == AddressFamily.InterNetwork && !ip.ToString().StartsWith("127")) { return ip.ToString(); } } - return "error"; + return "IPerror"; } public static string GetOS() @@ -32,6 +35,10 @@ public static string GetOS() { OS = "raspi"; } + else + { + OS = "linux"; + } return OS; } @@ -64,6 +71,11 @@ public static void SetupWin() WinRegistry.SetMPCHCTimerInterval(); } + public static void SetupLinux() + { + $"chmod -R 7777 {_rootPath}".Bash(); + } + public static string RunCmd(string filename, string arguments, bool admin) { Process process = new Process(); @@ -97,4 +109,28 @@ public static string RunCmd(string filename, string arguments, bool admin) return output; } } + + public static class ShellHelper + { + public static string Bash(this string cmd) + { + string escapedArgs = cmd.Replace("\"", "\\\""); + + Process process = new Process() + { + StartInfo = new ProcessStartInfo + { + FileName = "/bin/bash", + Arguments = $"-c \"{escapedArgs}\"", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + } + }; + process.Start(); + string result = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + return result; + } + } } \ No newline at end of file diff --git a/HTFanControl/Util/Log.cs b/HTFanControl/Util/Log.cs new file mode 100644 index 0000000..f7701c1 --- /dev/null +++ b/HTFanControl/Util/Log.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace HTFanControl.Util +{ + public class Log + { + private readonly string _logPath = Path.Combine(ConfigHelper._rootPath, "EventLog.txt"); + + public LinkedList RealtimeLog { get; } = new LinkedList(); + + public Log() + { + try + { + File.Delete(_logPath); + } + catch { } + } + + public void LogMsg(string line) + { + string timestamp = $"[{DateTime.Now:hh:mm:ss.fff}]: "; + + Console.WriteLine($"{timestamp}{line}"); + + try + { + File.AppendAllText(_logPath, $"{timestamp}{line}{Environment.NewLine}"); + } + catch { } + + RealtimeLog.AddFirst($"{timestamp}{line}"); + if(RealtimeLog.Count > 50) + { + RealtimeLog.RemoveLast(); + } + } + } +} \ No newline at end of file diff --git a/HTFanControl/Settings.cs b/HTFanControl/Util/Settings.cs similarity index 76% rename from HTFanControl/Settings.cs rename to HTFanControl/Util/Settings.cs index 15cbbbb..8e09c6f 100644 --- a/HTFanControl/Settings.cs +++ b/HTFanControl/Util/Settings.cs @@ -1,14 +1,12 @@ using System; -using System.Diagnostics; using System.IO; using System.Text.Json; using System.Text.Json.Serialization; -namespace HTFanControl +namespace HTFanControl.Util { class Settings { - private static readonly string _rootPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); public string MediaPlayerType { get; set; } public string MediaPlayerIP { get; set; } public int MediaPlayerPort { get; set; } @@ -18,6 +16,8 @@ class Settings public string LIRC_Remote { get; set; } public string MQTT_IP { get; set; } public int MQTT_Port { get; set; } + public string MQTT_User { get; set; } + public string MQTT_Pass { get; set; } public string MQTT_OFF_Topic { get; set; } public string MQTT_OFF_Payload { get; set; } public string MQTT_ECO_Topic { get; set; } @@ -50,16 +50,27 @@ public static Settings LoadSettings() options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault; options.WriteIndented = true; - string jsonSettings = File.ReadAllText(Path.Combine(_rootPath, "HTFanControlSettings.json")); + string jsonSettings = File.ReadAllText(Path.Combine(ConfigHelper._rootPath, "HTFanControlSettings.json")); settings = JsonSerializer.Deserialize(jsonSettings, options); } catch { //default values settings.MediaPlayerType = "Kodi"; - settings.MediaPlayerIP = "127.0.0.1"; + settings.MediaPlayerIP = "192.168.1.100"; settings.MediaPlayerPort = 8080; settings.ControllerType = "MQTT"; + settings.MQTT_IP = "127.0.0.1"; + settings.MQTT_OFF_Topic = "cmnd/HTFan/EVENT"; + settings.MQTT_OFF_Payload = "s0"; + settings.MQTT_ECO_Topic = "cmnd/HTFan/EVENT"; + settings.MQTT_ECO_Payload = "s1"; + settings.MQTT_LOW_Topic = "cmnd/HTFan/EVENT"; + settings.MQTT_LOW_Payload = "s2"; + settings.MQTT_MED_Topic = "cmnd/HTFan/EVENT"; + settings.MQTT_MED_Payload = "s3"; + settings.MQTT_HIGH_Topic = "cmnd/HTFan/EVENT"; + settings.MQTT_HIGH_Payload = "s4"; settings.GlobalOffsetMS = 2000; settings.SpinupOffsetMS = 750; settings.SpindownOffsetMS = 250; @@ -79,7 +90,7 @@ public static string SaveSettings(Settings settings) string jsonSettings = JsonSerializer.Serialize(settings, options); - File.WriteAllText(Path.Combine(_rootPath, "HTFanControlSettings.json"), jsonSettings); + File.WriteAllText(Path.Combine(ConfigHelper._rootPath, "HTFanControlSettings.json"), jsonSettings); } catch(Exception e) { diff --git a/HTFanControl/WinRegistry.cs b/HTFanControl/Util/WinRegistry.cs similarity index 98% rename from HTFanControl/WinRegistry.cs rename to HTFanControl/Util/WinRegistry.cs index 0b58f7b..b2e85c0 100644 --- a/HTFanControl/WinRegistry.cs +++ b/HTFanControl/Util/WinRegistry.cs @@ -1,6 +1,6 @@ using Microsoft.Win32; -namespace HTFanControl +namespace HTFanControl.Util { class WinRegistry { diff --git a/HTFanControl/html/50-cloud-init.yaml b/HTFanControl/html/50-cloud-init.yaml deleted file mode 100644 index 51c5613..0000000 --- a/HTFanControl/html/50-cloud-init.yaml +++ /dev/null @@ -1,12 +0,0 @@ -network: - ethernets: - eth0: - dhcp4: true - optional: true - version: 2 - wifis: - wlan0: - dhcp4: true - access-points: - "{ssid}": - password: "{pass}" \ No newline at end of file diff --git a/HTFanControl/html/checkupdate.html b/HTFanControl/html/checkupdate.html index e0170ed..5362d08 100644 --- a/HTFanControl/html/checkupdate.html +++ b/HTFanControl/html/checkupdate.html @@ -17,14 +17,14 @@ @@ -48,40 +42,29 @@ a:hover { color: white; } - + body { color: white; background-color: black; } - .ngroup { - outline: 1px solid gray; - padding-top: 6px; - padding-left: 4px; - padding-right: 4px; - margin-bottom: 8px; - display: table; - } - - .nrow { - display: flex; + span { + padding-top: 4px; + padding-bottom: 4px; + padding-left: 8px; + padding-right: 8px; } - - .nitem { - margin-bottom: 6px; - flex-shrink: 1; - } - + ul { - display: flex; - margin-left: -15px; - margin-right: -15px; - } + display: flex; + margin-left: -15px; + margin-right: -15px; + } - li { - flex-grow: 1; - text-align: center; - } + li { + flex-grow: 1; + text-align: center; + } .nav-tabs .nav-link.active { color: lightgreen; @@ -98,33 +81,34 @@ -
+
+ + - + Click an item below to view the crashlog. + {body} -

WiFi Settings

-
-
-
SSID
-
+
+ -
-
Password
-
+
+ +
-
- -
+
\ No newline at end of file diff --git a/HTFanControl/html/download.html b/HTFanControl/html/download.html index ad0fda0..e99062e 100644 --- a/HTFanControl/html/download.html +++ b/HTFanControl/html/download.html @@ -111,7 +111,9 @@


- {windtrack} +
+ {windtrack} +
diff --git a/HTFanControl/html/edit.html b/HTFanControl/html/edit.html index 9af4fc2..8a2283e 100644 --- a/HTFanControl/html/edit.html +++ b/HTFanControl/html/edit.html @@ -130,7 +130,10 @@

- {windtrack} + +
+ {windtrack} +
diff --git a/HTFanControl/html/fantester.html b/HTFanControl/html/fantester.html index 2d422a7..e074690 100644 --- a/HTFanControl/html/fantester.html +++ b/HTFanControl/html/fantester.html @@ -88,7 +88,10 @@ Status + - @@ -236,13 +242,13 @@

Settings

-
+
-
+
LIRC IP
Port
@@ -252,27 +258,31 @@

Settings

@@ -335,11 +345,12 @@

Settings

-

{version} +

+

diff --git a/HTFanControl/updater.sh b/HTFanControl/updater.sh deleted file mode 100644 index 82d6eb5..0000000 --- a/HTFanControl/updater.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -wget https://github.com/nicko88/HTFanControl/releases/latest/download/HTFanControl_RasPi.zip -rm HTFanControl -unzip HTFanControl_RasPi.zip -rm HTFanControl_RasPi.zip -chmod +x HTFanControl -nohup ./HTFanControl &>/dev/null & diff --git a/Readme.md b/Readme.md index b43e255..4047c14 100644 --- a/Readme.md +++ b/Readme.md @@ -1,3 +1,4 @@ + # HTFanControl #### 4D Theater Wind Effect - DIY Home Theater Project @@ -17,6 +18,19 @@ Otherwise come join the community forum thread to ask questions [here](https://w You can find help from me (user: [SirMaster](https://www.avsforum.com/forum/members/8147918-sirmaster.html)) or other users of HTFanControl there. +### Raspberry Pi / Linux Installation +This install script is intended to install HTFanControl on RasPi or standard Linux running a Debian-based distribution using systemd. It may work on other distributions but it has not been tested. You can also download the Linux release and install it manually onto your particular Linux machine. + +This script will ask to install HTFanControl and also additionally mosquitto MQTT broker which is needed to control the fan relay switch over the network. +#### Install + sudo wget https://raw.githubusercontent.com/nicko88/HTFanControl/master/install/install.sh && sudo bash install.sh +#### Update +There is an update function built into the app at the bottom of the Settings screen, or you can run the update script manually here: + + sudo wget https://raw.githubusercontent.com/nicko88/HTFanControl/master/install/update.sh && sudo bash update.sh +#### Uninstall + sudo wget https://raw.githubusercontent.com/nicko88/HTFanControl/master/install/uninstall.sh && sudo bash uninstall.sh + ### Wind Tracks HTFanControl uses specially created wind track files for each movie with coded time stamps and wind speeds. diff --git a/install/HTFanControl.service b/install/HTFanControl.service new file mode 100644 index 0000000..d635380 --- /dev/null +++ b/install/HTFanControl.service @@ -0,0 +1,9 @@ +[Unit] +Description=HTFanControl +After=multi-user.target + +[Service] +ExecStart=/opt/HTFanControl/HTFanControl + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/install/install.sh b/install/install.sh new file mode 100644 index 0000000..50fd33b --- /dev/null +++ b/install/install.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +case $(uname -m) in + *"arm"*) + file="HTFanControl_RasPi.zip" + ;; + + *"aarch"*) + file="HTFanControl_RasPi64.zip" + ;; + + *"x86_64"*) + file="HTFanControl_Linux.zip" + ;; +esac + +read -p "Are you sure you want to INSTALL HTFanControl? [y/n]" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + mkdir /opt/HTFanControl + wget -O /tmp/$file https://github.com/nicko88/HTFanControl/releases/latest/download/$file + unzip /tmp/$file -d /opt/HTFanControl + chmod +x /opt/HTFanControl/HTFanControl + wget -O /lib/systemd/system/HTFanControl.service https://raw.githubusercontent.com/nicko88/HTFanControl/master/install/HTFanControl.service + systemctl daemon-reload + systemctl enable HTFanControl.service + service HTFanControl start + rm /tmp/$file +fi + +read -p "Do you also want to INSTALL mosquitto MQTT broker? [y/n]" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + apt-get update + apt-get install -y mosquitto + systemctl daemon-reload + systemctl enable mosquitto.service + echo "allow_anonymous true" >> /etc/mosquitto/mosquitto.conf + echo "listener 1883" >> /etc/mosquitto/mosquitto.conf + service mosquitto restart +fi + +rm install.sh \ No newline at end of file diff --git a/install/uninstall.sh b/install/uninstall.sh new file mode 100644 index 0000000..877ef6c --- /dev/null +++ b/install/uninstall.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +read -p "Are you sure you want to UNINSTALL HTFanControl? [y/n]" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + service HTFanControl stop + systemctl disable HTFanControl.service + rm /lib/systemd/system/HTFanControl.service + systemctl daemon-reload + rm -rf /opt/HTFanControl +fi + +read -p "Do you also want to UNINSTALL mosquitto MQTT broker? [y/n]" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + service mosquitto stop + systemctl disable mosquitto.service + rm /lib/systemd/system/mosquitto.service + systemctl daemon-reload + apt-get autoremove mosquitto --purge -y +fi + +rm uninstall.sh \ No newline at end of file diff --git a/install/update.sh b/install/update.sh new file mode 100644 index 0000000..18b6d0c --- /dev/null +++ b/install/update.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +case $(uname -m) in + *"arm"*) + file="HTFanControl_RasPi.zip" + ;; + + *"aarch"*) + file="HTFanControl_RasPi64.zip" + ;; + + *"x86_64"*) + file="HTFanControl_Linux.zip" + ;; +esac + +wget -O /tmp/$file https://github.com/nicko88/HTFanControl/releases/latest/download/$file +rm /opt/HTFanControl/HTFanControl +unzip /tmp/$file -d /opt/HTFanControl +chmod +x /opt/HTFanControl/HTFanControl +rm /tmp/$file +rm /opt/HTFanControl/update.sh +rm update.sh +service HTFanControl restart \ No newline at end of file