diff --git a/Controllers/HueDataController.cs b/Controllers/HueDataController.cs index 2837104f..82f8f072 100644 --- a/Controllers/HueDataController.cs +++ b/Controllers/HueDataController.cs @@ -12,11 +12,19 @@ namespace HueDream.Controllers { [Route("api/[controller]")] [ApiController] public class HueDataController : ControllerBase { + private DreamSync ds; + private DreamData userData; + + public HueDataController() { + ds = new DreamSync(); + userData = new DreamData(); + CheckSync(); + } + // GET: api/HueData/action?action=... [HttpGet("action")] public JsonResult Get(string action) { string message = "Unrecognized action"; - DreamData userData = new DreamData(); Console.Write("Now we're cooking: " + action); if (action == "connectDreamScreen") { string dsIp = userData.DS_IP; @@ -72,13 +80,11 @@ public JsonResult Get(string action) { // GET: api/HueData/json [HttpGet("json")] public IActionResult Get() { - DreamData userData = new DreamData(); return Ok(userData); } [HttpGet("lights")] public IActionResult GetWhatever() { - DreamData userData = new DreamData(); return Ok(userData); } @@ -92,13 +98,14 @@ public static string Get(int id) { // POST: api/HueData [HttpPost] public void Post(string value) { - DreamData userData = new DreamData(); string[] keys = Request.Form.Keys.ToArray(); Console.WriteLine("We have a post: " + value); + bool mapLights = false; List> lightMap = new List>(); foreach (string key in keys) { Console.WriteLine("We have a key and value: " + key + " " + Request.Form[key]); if (key.Contains("lightMap")) { + mapLights = true; int lightId = int.Parse(key.Replace("lightMap", "")); lightMap.Add(new KeyValuePair(lightId, Request.Form[key])); } else if (key == "ds_ip") { @@ -108,7 +115,7 @@ public void Post(string value) { } else if (key == "hue_sync") { string val = Request.Form[key]; bool res = false; - if (val == "on") { + if (val == "true") { res = true; } else { res = false; @@ -116,13 +123,12 @@ public void Post(string value) { userData.HUE_SYNC = res; } } - userData.HUE_MAP = lightMap; + if (mapLights) userData.HUE_MAP = lightMap; userData.saveData(); - CheckSync(userData); + CheckSync(); } - private static void CheckSync(DreamData userData) { - DreamSync ds = new DreamSync(); + private void CheckSync() { if (userData.DS_IP != "0.0.0.0" && userData.HUE_SYNC && !ds.doSync) { Console.WriteLine("Starting Dreamscreen sync!"); Task.Run(() => ds.startSync()); @@ -130,6 +136,6 @@ private static void CheckSync(DreamData userData) { Console.WriteLine("Stopping sync."); ds.StopSync(); } - } + } } } diff --git a/Dockerfile b/Dockerfile index 868ad05b..664f09db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,8 +12,10 @@ RUN dotnet build "HueDream.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "HueDream.csproj" -c Release -o /app/publish - +RUN mkdir -p /etc/huedream FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "HueDream.dll"] \ No newline at end of file +ENTRYPOINT ["dotnet", "HueDream.dll"] + +VOLUME /etc/huedream \ No newline at end of file diff --git a/DreamScreenControl/DreamScreen.cs b/DreamScreenControl/DreamScreen.cs index 340d2472..41e850a2 100644 --- a/DreamScreenControl/DreamScreen.cs +++ b/DreamScreenControl/DreamScreen.cs @@ -6,7 +6,6 @@ using System.Net; using System.Net.Sockets; using System.Text; -using System.Threading; namespace HueDream.DreamScreenControl { class DreamScreen { @@ -34,6 +33,7 @@ class DreamScreen { private Socket dreamScreenSocket; private int Port = 8888; private IPEndPoint endPoint; + private IPEndPoint receiverPort; private byte groupNumber = 0; private UdpClient receiver; public bool listening = false; @@ -47,7 +47,7 @@ public DreamScreen(string remoteIP) { for (int i = 0; i < colors.Length; i++) { colors[i] = new string[] { "FF", "FF", "FF" }; } - dreamScreenSocket = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); + dreamScreenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); dreamScreenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1); //getMode(); } @@ -63,7 +63,8 @@ public void getMode() { Listen(); } - public void startListening() { + public void StartListening() { + Console.WriteLine("Listen called."); sendUDPWrite((byte)0x01, (byte)0x0C, new byte[] { (byte)0x01 }, (byte)0x10); Listen(); } @@ -71,7 +72,7 @@ public void startListening() { public void Listen() { if (!listening) { // Create UDP client - IPEndPoint receiverPort = new IPEndPoint(IPAddress.Any, 8888); ; + receiverPort = new IPEndPoint(IPAddress.Any, 8888); ; receiver = new UdpClient(); receiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); receiver.EnableBroadcast = true; @@ -84,8 +85,8 @@ public void Listen() { } public void StopListening() { + Console.WriteLine("Listening canceled."); if (listening) { - dreamScreenSocket.Close(); listening = false; } } @@ -133,7 +134,12 @@ private void DataReceived(IAsyncResult ar) { } // Restart listening for udp data packages - c.BeginReceive(DataReceived, ar.AsyncState); + if (listening) { + c.BeginReceive(DataReceived, ar.AsyncState); + } else { + Console.WriteLine("Closing listening socket."); + dreamScreenSocket.Close(); + } } @@ -196,9 +202,9 @@ void sendUDPWrite(byte command1, byte command2, byte[] payload, byte flag = (byt var byteSend = stream.ToArray(); // CRC - response.Write(calculateCrc(byteSend)); + response.Write(CalculateCrc(byteSend)); string msg = BitConverter.ToString(stream.ToArray()); - sendUDPUnicast(stream.ToArray()); + SendUDPUnicast(stream.ToArray()); } } } @@ -210,6 +216,7 @@ void requestState() { using (BinaryWriter response = new BinaryWriter(stream)) { // Magic header response.Write((byte)0xFC); + // Hacky implementation, but itttt works response.Write((byte)0x05); response.Write((byte)0xFF); response.Write((byte)0x30); @@ -218,14 +225,14 @@ void requestState() { response.Write((byte)0x2A); var byteSend = stream.ToArray(); // CRC - response.Write(calculateCrc(byteSend)); + response.Write(CalculateCrc(byteSend)); string msg = BitConverter.ToString(stream.ToArray()); - sendUDPUnicast(stream.ToArray()); + SendUDPUnicast(stream.ToArray()); } } } - private byte calculateCrc(byte[] data) { + private byte CalculateCrc(byte[] data) { byte size = (byte)(data[1] + 1); byte crc = (byte)0; for (byte cntr = (byte)0; cntr < size; cntr = (byte)(cntr + 1)) { @@ -234,7 +241,7 @@ private byte calculateCrc(byte[] data) { return crc; } - private void sendUDPUnicast(byte[] data) { + private void SendUDPUnicast(byte[] data) { dreamScreenSocket.SendTo(data, endPoint); } @@ -250,7 +257,7 @@ public DreamScreenState(string byteString) { if (magic == "FC") { string type = bytesIn[bytesIn.Length - 2]; string state = bytesIn[33]; - + if (type == "01") { typeString = "DreamScreen"; } else if (type == "02") { @@ -274,5 +281,5 @@ public DreamScreenState(string byteString) { } } - + } diff --git a/HueControl/HueBridge.cs b/HueControl/HueBridge.cs index 760d92d7..636daa3f 100644 --- a/HueControl/HueBridge.cs +++ b/HueControl/HueBridge.cs @@ -1,5 +1,4 @@ -using HueDream.DreamScreenControl; -using HueDream.HueDream; +using HueDream.HueDream; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Q42.HueApi; @@ -11,7 +10,6 @@ using Q42.HueApi.Streaming.Models; using System; using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Text; using System.Threading; @@ -23,13 +21,16 @@ public class HueBridge { public string bridgeKey { get; set; } public string bridgeUser { get; set; } - public bool bridgeAuth; + public bool doEntertain { set; get; } - public List> bridgeLights; - public string[][] colors { get; set; } + private readonly bool bridgeAuth; + + public List> bridgeLights { get; } + private string[][] colors; private static readonly HttpClient httpClient = new HttpClient(); + public HueBridge() { DreamData dd = new DreamData(); bridgeIp = dd.HUE_IP; @@ -39,25 +40,37 @@ public HueBridge() { bridgeLights = dd.HUE_MAP; } - public async Task startEntertainment() { + public string[][] getColors() { + return colors; + } + + public void setColors(string[][] colorIn) { + colors = colorIn; + } + + public async Task Entertain() { Console.WriteLine("Starting entertainment, " + bridgeIp + " " + bridgeUser + " " + bridgeKey); StreamingHueClient client = new StreamingHueClient(bridgeIp, bridgeUser, bridgeKey); - var lightList = (from kvp in bridgeLights select kvp.Key.ToString()).Distinct().ToList(); + var lightList = new List(); + foreach (KeyValuePair kvp in bridgeLights) { + if (kvp.Value != "-1") { + lightList.Add(kvp.Key.ToString()); + } + } + Console.WriteLine("Light List: " + JsonConvert.SerializeObject(lightList)); //Get the entertainment group var all = await client.LocalHueClient.GetEntertainmentGroups(); var targetGroup = ""; - foreach(Group eg in all) { + foreach (Group eg in all) { if (eg.Name == "HueDream2") { - Console.WriteLine("Got our group"); + Console.WriteLine("Entertainment Group found: " + eg.Id); targetGroup = eg.Id; - } else { - Console.WriteLine("Group is " + eg.Name); } } if (targetGroup == "") { - Console.WriteLine("Creating target group."); + Console.WriteLine("Creating Entertainment Group."); string group = ""; try { Dictionary data = new Dictionary(); @@ -70,33 +83,33 @@ public async Task startEntertainment() { var responseString = await response.Content.ReadAsStringAsync(); var responseData = JToken.Parse(JsonConvert.SerializeObject(responseString)); if (responseData["Success"] != null) { - group = (string) responseData["Success"]["id"]; + group = (string)responseData["Success"]["id"]; } } catch (ArgumentNullException e) { Console.WriteLine("Null Exception!"); } - Console.WriteLine("Target group creation complete..."); + Console.WriteLine("Target group creation complete."); if (group != "") targetGroup = group; } //Create a streaming group if (targetGroup != "") { - Group sg = await client.LocalHueClient.GetGroupAsync(targetGroup); - Console.WriteLine("Creating streaming group: " + targetGroup); + Group sg = await client.LocalHueClient.GetGroupAsync(targetGroup).ConfigureAwait(false); var entGroup = new StreamingGroup(sg.Locations); //Connect to the streaming group - await client.Connect(targetGroup); + await client.Connect(targetGroup).ConfigureAwait(false); Console.WriteLine("Connected."); //Start auto updating this entertainment group client.AutoUpdate(entGroup, CancellationToken.None); Console.WriteLine("AutoUpdate Enabled."); EntertainmentLayer entertainmentLayer = entGroup.GetNewLayer(isBaseLayer: true); - while (true) { - foreach(KeyValuePair lights in bridgeLights) { + Console.WriteLine("Beginning entertainment stream."); + while (doEntertain) { + foreach (KeyValuePair lights in bridgeLights) { if (lights.Value != "-1") { - int mapId = Int32.Parse(lights.Value); + int mapId = int.Parse(lights.Value); string[] colorString = colors[mapId]; - foreach(EntertainmentLight light in entertainmentLayer) { + foreach (EntertainmentLight light in entertainmentLayer) { if (light.Id == lights.Key) { string colorStrings = string.Join("", colorString); light.State.SetRGBColor(new RGBColor(colorStrings)); @@ -105,13 +118,29 @@ public async Task startEntertainment() { } } } - } + client.LocalHueClient.SetStreamingAsync(targetGroup, false); + client.Close(); + Console.WriteLine("Entertainment stream completed."); } else { Console.WriteLine("Target Group creation failed!"); } } + + public void startEntertainment() { + if (!doEntertain) { + Console.WriteLine("Starting entertainment."); + doEntertain = true; + var task = Task.Run(async () => await Entertain().ConfigureAwait(false)); + } + } + + public void stopEntertainment() { + Console.WriteLine("Stopping entertainment stream."); + doEntertain = false; + } + public RegisterEntertainmentResult checkAuth() { try { ILocalHueClient client = new LocalHueClient(bridgeIp); @@ -131,7 +160,7 @@ public static string findBridge() { string bridgeIp = ""; Console.WriteLine("Looking for bridges"); IBridgeLocator locator = new HttpBridgeLocator(); - var task = Task.Run(async () => await locator.LocateBridgesAsync(TimeSpan.FromSeconds(5))); + var task = Task.Run(async () => await locator.LocateBridgesAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(false)); var bridgeIPs = task.Result; foreach (LocatedBridge bIp in bridgeIPs) { Console.WriteLine("Bridge IP is " + bIp.IpAddress); @@ -146,11 +175,11 @@ public List> getLights() { if (bridgeIp != "0.0.0.0" && bridgeAuth) { ILocalHueClient client = new LocalHueClient(bridgeIp); client.Initialize(bridgeUser); - var task = Task.Run(async () => await client.GetLightsAsync()); + var task = Task.Run(async () => await client.GetLightsAsync().ConfigureAwait(false)); var lightArray = task.Result; foreach (Light light in lightArray) { if (light.Type == "Extended color light") { - lights.Add(new KeyValuePair(Int32.Parse(light.Id), light.Name)); + lights.Add(new KeyValuePair(int.Parse(light.Id), light.Name)); } } } diff --git a/HueDream/DreamData.cs b/HueDream/DreamData.cs index 967f4104..5c6d6c77 100644 --- a/HueDream/DreamData.cs +++ b/HueDream/DreamData.cs @@ -20,6 +20,22 @@ public class DreamData { public List> HUE_MAP { get; set; } public DreamData() { + if (Directory.Exists("/etc/huedream")) { + Console.WriteLine("Directory exists."); + if (File.Exists(iniPath)) { + Console.WriteLine("We should move our ini to /etc"); + File.Copy(iniPath, "/etc/huedream/huedream.ini"); + if (File.Exists("/etc/huedream/huedream.ini")) { + Console.WriteLine("File moved, updating INI path."); + File.Delete(iniPath); + } + } + if (File.Exists("/etc/huedream/huedream.ini")) { + iniPath = "/etc/huedream/huedream.ini"; + } + } + + if (!File.Exists(iniPath)) { DS_IP = "0.0.0.0"; HUE_IP = HueBridge.findBridge(); @@ -41,7 +57,6 @@ public DreamData() { data["MAIN"]["HUE_MAP"] = JsonConvert.SerializeObject(HUE_MAP); parser.WriteFile(iniPath, data); } else { - Console.Write("We have our ini!"); loadData(); } } diff --git a/HueDream/DreamSync.cs b/HueDream/DreamSync.cs index 874dcd17..cac6b7b5 100644 --- a/HueDream/DreamSync.cs +++ b/HueDream/DreamSync.cs @@ -1,9 +1,6 @@ using HueDream.DreamScreenControl; using HueDream.HueControl; using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace HueDream.HueDream { public class DreamSync { @@ -13,45 +10,43 @@ public class DreamSync { private DreamData dreamData; System.Threading.Thread sender; public bool doSync { get; set; } - public string[][] colors { get; } public DreamSync() { dreamData = new DreamData(); if (dreamData.DS_IP != "0.0.0.0") { hueBridge = new HueBridge(); dreamScreen = new DreamScreen(dreamData.DS_IP); - } + } } public void startSync() { if (doSync) { Console.WriteLine("Sync is already started..."); - } else { - if (dreamData.HUE_SYNC && dreamData.HUE_AUTH) { - Console.WriteLine("Starting sync."); - doSync = true; - sender = new System.Threading.Thread(SyncData); - sender.IsBackground = true; - sender.Start(); - } + } else { + Console.WriteLine("Starting sync."); + doSync = true; + dreamScreen.StartListening(); + hueBridge.startEntertainment(); + sender = new System.Threading.Thread(SyncData); + sender.IsBackground = true; + sender.Start(); + } } public void StopSync() { Console.WriteLine("Stopping sync."); - doSync = false; - if (sender.Join(200) == false) { - sender.Abort(); - } - sender = null; + doSync = false; + dreamScreen.StopListening(); + hueBridge.stopEntertainment(); } private void SyncData() { - dreamScreen.startListening(); - Task bill = hueBridge.startEntertainment(); + Console.WriteLine("SyncData called"); while (doSync) { // Read updating color var from dreamscreen - hueBridge.colors = dreamScreen.colors; + hueBridge.setColors(dreamScreen.colors); } + Console.WriteLine("Dosync completed."); } } } diff --git a/Startup.cs b/Startup.cs index 7130cf11..bdd739c8 100644 --- a/Startup.cs +++ b/Startup.cs @@ -1,4 +1,3 @@ -using HueDream.DreamScreenControl; using HueDream.HueDream; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -13,10 +12,10 @@ public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; DreamData dreamData = new DreamData(); - DreamSync ds = new DreamSync(); + DreamSync ds = new DreamSync(); if (dreamData.DS_IP != "0.0.0.0" && dreamData.HUE_SYNC) { - Console.WriteLine("Starting Dreamscreen sync!"); - Task.Run(() => ds.startSync()); + //Console.WriteLine("Starting Dreamscreen sync!"); + //Task.Run(() => ds.startSync()); } } diff --git a/Views/Home/Index.cshtml b/Views/Home/Index.cshtml index 27d35911..e929d20e 100644 --- a/Views/Home/Index.cshtml +++ b/Views/Home/Index.cshtml @@ -19,7 +19,7 @@
- +
@@ -40,12 +40,12 @@
- +
- +
@@ -64,11 +64,7 @@
- -
- - -
+
diff --git a/Views/Home/Privacy.cshtml b/Views/Home/Privacy.cshtml deleted file mode 100644 index af4fb195..00000000 --- a/Views/Home/Privacy.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@{ - ViewData["Title"] = "Privacy Policy"; -} -

@ViewData["Title"]

- -

Use this page to detail your site's privacy policy.

diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml index 078849d9..ebdb7ccf 100644 --- a/Views/Shared/_Layout.cshtml +++ b/Views/Shared/_Layout.cshtml @@ -4,8 +4,9 @@ @ViewData["Title"] - HueDream - - + + +