private async Task<string> GetApiKeyWithBridgeButtonClick(PhilipsHueBridge bridge)
        {
            var endTime = DateTime.UtcNow.AddSeconds(30);
            var client = new LocalHueClient(bridge.IpAddress);

            while (DateTime.UtcNow < endTime)
            {
                try
                {
                    var machineName = Environment.MachineName.Replace(' ', '_');

                    if (machineName.Length > 19)
                    {
                        machineName = machineName.Substring(0, 19);
                    }

                    var appKey = await client.RegisterAsync("Xpressive.Home", machineName);
                    return appKey;
                }
                catch { }

                await Task.Delay(TimeSpan.FromSeconds(1));
            }

            return null;
        }
        public async Task UpdateExistingBridges()
        {
            IBridgeLocator       locator = new HttpBridgeLocator();
            List <LocatedBridge> bridges = (await locator.LocateBridgesAsync(TimeSpan.FromSeconds(5))).ToList();

            // Lets try to find some more
            locator = new SsdpBridgeLocator();
            IEnumerable <LocatedBridge> extraBridges = await locator.LocateBridgesAsync(TimeSpan.FromSeconds(5));

            foreach (LocatedBridge extraBridge in extraBridges)
            {
                if (bridges.All(b => b.BridgeId != extraBridge.BridgeId))
                {
                    bridges.Add(extraBridge);
                }
            }

            int updatedBridges = 0;

            foreach (LocatedBridge locatedBridge in bridges)
            {
                PhilipsHueBridge storedBridge = _storedBridgesSetting.Value.FirstOrDefault(s => s.BridgeId == locatedBridge.BridgeId);
                if (storedBridge != null && storedBridge.IpAddress != locatedBridge.IpAddress)
                {
                    storedBridge.IpAddress = locatedBridge.IpAddress;
                    updatedBridges++;
                }
            }

            if (updatedBridges > 0)
            {
                _storedBridgesSetting.Save();
                _logger.Information("Updated IP addresses of {updatedBridges} Hue Bridge(s)", updatedBridges);
            }
        }
Exemple #3
0
        protected void UpdateGroups(PhilipsHueBridge bridge, List <Group> groups)
        {
            foreach (Group group in groups)
            {
                string         groupKey       = $"{bridge.BridgeId}-{group.Id}";
                GroupDataModel groupDataModel = DynamicChild <GroupDataModel>(groupKey);
                if (groupDataModel != null)
                {
                    groupDataModel.HueGroup = group;
                }
                else
                {
                    groupDataModel = AddDynamicChild(new GroupDataModel(@group, bridge.BridgeInfo), groupKey);
                    Groups.Add(groupDataModel);
                }

                groupDataModel.DataModelDescription.Name = groupDataModel.Name;
            }

            // Remove groups that no longer exist
            List <GroupDataModel> groupsToRemove = Groups
                                                   .Where(dmg => dmg.HueBridge.Config.BridgeId == bridge.BridgeId && groups.All(g => g.Id == dmg.HueGroup.Id))
                                                   .ToList();

            foreach (GroupDataModel groupDataModel in groupsToRemove)
            {
                RemoveDynamicChild(groupDataModel);
                Groups.Remove(groupDataModel);
            }
        }
        private async Task HandleHueBridge(PhilipsHueBridge bridge)
        {
            var variableName = $"PhilipsHue.{bridge.Id}.ApiKey";
            var apiKey = _variableRepository.Get<StringVariable>(variableName)?.Value;

            if (string.IsNullOrEmpty(apiKey))
            {
                _messageQueue.Publish(new NotifyUserMessage("Found new Philips Hue Bridge. Please press the Button to connect."));
                apiKey = await GetApiKeyWithBridgeButtonClick(bridge);

                if (string.IsNullOrEmpty(apiKey))
                {
                    lock (_lock)
                    {
                        _bridges.Remove(bridge.Id);
                    }

                    return;
                }

                _messageQueue.Publish(new UpdateVariableMessage(variableName, apiKey));
            }

            OnBridgeFound(bridge);
        }
        protected void UpdateGroups(PhilipsHueBridge bridge, List <Group> groups)
        {
            // Add or update missing groups
            foreach (Group group in groups)
            {
                string groupKey = $"{bridge.BridgeId}-{group.Id}";

                GroupDataModel groupDataModel = null;
                if (TryGetDynamicChild(groupKey, out DynamicChild <GroupDataModel> dynamicChild))
                {
                    groupDataModel = dynamicChild.Value;
                }

                if (groupDataModel != null)
                {
                    groupDataModel.HueGroup = group;
                }
                else
                {
                    groupDataModel = AddDynamicChild(groupKey, new GroupDataModel(group, bridge.BridgeInfo), group.Name).Value;
                    Groups.Add(groupDataModel);
                }
            }

            // Remove groups that no longer exist
            List <GroupDataModel> groupsToRemove = Groups
                                                   .Where(dmg => dmg.HueBridge.Config?.BridgeId == bridge.BridgeId && groups.All(g => g.Id == dmg.HueGroup.Id))
                                                   .ToList();

            foreach (GroupDataModel groupDataModel in groupsToRemove)
            {
                RemoveDynamicChildByKey($"{bridge.BridgeId}-{groupDataModel.HueGroup.Id}");
                Groups.Remove(groupDataModel);
            }
        }
 protected PhilipsHueDevice(string index, string id, string name, PhilipsHueBridge bridge)
 {
     Id = id;
     Name = name;
     _index = index;
     _bridge = bridge;
 }
Exemple #7
0
        private void AddOrUpdateAccessory(PhilipsHueBridge bridge, Sensor accessory)
        {
            string accessoryKey = $"{bridge.BridgeId}-{accessory.Id}";

            AccessoryDataModel accessoryDataModel = null;

            if (TryGetDynamicChild(accessoryKey, out DynamicChild dynamicChild))
            {
                accessoryDataModel = (AccessoryDataModel)dynamicChild.BaseValue;
            }

            if (accessoryDataModel != null)
            {
                accessoryDataModel.HueSensor = accessory;
            }
            else
            {
                accessoryDataModel = accessory.Type switch
                {
                    "ZLLSwitch" => AddDynamicChild(accessoryKey, new DimmerSwitch(accessory), accessory.Name).Value,
                    "ZGPSwitch" => AddDynamicChild(accessoryKey, new Tap(accessory), accessory.Name).Value,
                    _ => null
                };
            }

            if (accessoryDataModel != null)
            {
                accessoryDataModel.DataModelDescription.Name = accessoryDataModel.Name;
            }
        }
Exemple #8
0
        private void AddOrUpdateAccessory(PhilipsHueBridge bridge, Sensor accessory)
        {
            string             accessoryKey       = $"{bridge.BridgeId}-{accessory.Id}";
            AccessoryDataModel accessoryDataModel = DynamicChild <AccessoryDataModel>(accessoryKey);

            if (accessoryDataModel != null)
            {
                accessoryDataModel.HueSensor = accessory;
            }
            else
            {
                switch (accessory.Type)
                {
                case "ZLLSwitch":
                    accessoryDataModel = AddDynamicChild(new DimmerSwitch(accessory), accessoryKey);
                    break;

                case "ZGPSwitch":
                    accessoryDataModel = AddDynamicChild(new Tap(accessory), accessoryKey);
                    break;
                }
            }

            accessoryDataModel.DataModelDescription.Name = accessoryDataModel.Name;
        }
Exemple #9
0
 public void UpdateContents(PhilipsHueBridge bridge, List <Sensor> sensors)
 {
     // Motion sensors are split into multiple parts but they share most of their unique ID
     foreach (IGrouping <string, Sensor> sensorGroup in sensors.GroupBy(s => string.Join('-', s.UniqueId.Split("-").Take(2))))
     {
         if (sensorGroup.Count() == 1)
         {
             AddOrUpdateAccessory(bridge, sensorGroup.First());
         }
         else
         {
             AddOrUpdateMotionSensor(bridge, sensorGroup.ToList());
         }
     }
 }
Exemple #10
0
        public void UpdateContents(PhilipsHueBridge bridge, List <Light> lights)
        {
            foreach (Light light in lights)
            {
                List <GroupDataModel> groups = Groups
                                               .Where(g => g.HueGroup.Lights.Any(l => l.Equals(light.Id)) && g.HueBridge.Config.BridgeId.Equals(bridge.BridgeId, StringComparison.OrdinalIgnoreCase))
                                               .ToList();

                GroupDataModel roomGroup = groups.FirstOrDefault(g => g.GroupType == GroupType.Room);
                foreach (GroupDataModel groupDataModel in groups)
                {
                    groupDataModel.AddOrUpdateLight(light, roomGroup);
                }
            }
        }
Exemple #11
0
 public void UpdateContents(PhilipsHueBridge bridge, List <Sensor> sensors)
 {
     // Motion sensors are split into multiple parts but they share most of their unique ID
     // ReSharper disable once ConditionIsAlwaysTrueOrFalse - It is in fact nullable
     foreach (IGrouping <string, Sensor> sensorGroup in sensors.Where(s => s.UniqueId != null).GroupBy(s => string.Join('-', s.UniqueId.Split("-").Take(2))))
     {
         if (sensorGroup.Count() == 1)
         {
             AddOrUpdateAccessory(bridge, sensorGroup.First());
         }
         else
         {
             AddOrUpdateMotionSensor(bridge, sensorGroup.ToList());
         }
     }
 }
Exemple #12
0
        private void AddOrUpdateMotionSensor(PhilipsHueBridge bridge, List <Sensor> sensors)
        {
            Sensor mainSensor = sensors.First(s => s.State.Presence != null);

            string sensorKey = $"{bridge.BridgeId}-{mainSensor.Id}";
            MotionSensorDataModel accessoryDataModel = DynamicChild <MotionSensorDataModel>(sensorKey);

            if (accessoryDataModel != null)
            {
                accessoryDataModel.Update(mainSensor, sensors);
            }
            else
            {
                accessoryDataModel = AddDynamicChild(new MotionSensorDataModel(mainSensor, sensors), sensorKey);
            }

            accessoryDataModel.DataModelDescription.Name = accessoryDataModel.Name;
        }
        private async void OnBridgeFound(object sender, PhilipsHueBridge bridge)
        {
            var variableName = $"PhilipsHue.{bridge.Id}.ApiKey";
            var apiKey = _variableRepository.Get<StringVariable>(variableName).Value;

            var client = new LocalHueClient(bridge.IpAddress, apiKey);
            var bulbs = await client.GetLightsAsync();
            var sensors = await client.GetSensorsAsync();

            if (bulbs != null)
            {
                foreach (var light in bulbs)
                {
                    var id = light.UniqueId.Replace(":", string.Empty).Replace("-", string.Empty);
                    var bulb = new PhilipsHueBulb(light.Id, id, light.Name, bridge)
                    {
                        Icon = "PhilipsHueIcon PhilipsHueIcon_" + light.ModelId,
                        Model = light.ModelId
                    };

                    OnBulbFound(bulb);
                }
            }

            if (sensors != null)
            {
                var presenceSensors = sensors
                    .Where(s => s.ModelId == "SML001" && s.Type == "ZLLPresence")
                    .ToList();

                foreach (var presenceSensor in presenceSensors)
                {
                    var id = presenceSensor.UniqueId.Replace(":", string.Empty).Replace("-", string.Empty);
                    var sensor = new PhilipsHuePresenceSensor(presenceSensor.Id, id, presenceSensor.Name, bridge)
                    {
                        Model = presenceSensor.ModelId,
                        Icon = "PhilipsHueIcon PhilipsHueIcon_PresenceSensor",
                        Battery = presenceSensor.Config.Battery ?? 100
                    };

                    OnPresenceSensorFound(sensor);
                }
            }
        }
        public void UpdateContents(PhilipsHueBridge bridge, List <Light> lights)
        {
            foreach (Light light in lights)
            {
                // Find dynamic children of the same bridge containing the lights we've received
                // TODO: Light IDs might be globally unique, won't need to ensure the bridge matches
                List <GroupDataModel> groups = Groups
                                               .Where(g => g.HueBridge.Config != null &&
                                                      g.HueGroup.Lights.Any(l => l.Equals(light.Id)) &&
                                                      g.HueBridge.Config.BridgeId.Equals(bridge.BridgeId, StringComparison.OrdinalIgnoreCase))
                                               .ToList();

                GroupDataModel roomGroup = groups.FirstOrDefault(g => g.GroupType == GroupType.Room);
                foreach (GroupDataModel groupDataModel in groups)
                {
                    groupDataModel.AddOrUpdateLight(light, roomGroup);
                }
            }
        }
        private void OnUpnpDeviceFound(object sender, IUpnpDeviceResponse e)
        {
            string bridgeId;
            if (!e.OtherHeaders.TryGetValue("hue-bridgeid", out bridgeId))
            {
                return;
            }

            PhilipsHueBridge bridge;
            bridgeId = bridgeId.ToLowerInvariant();

            lock (_lock)
            {
                if (_bridges.ContainsKey(bridgeId))
                {
                    return;
                }
                bridge = new PhilipsHueBridge(bridgeId, e.IpAddress);
                _bridges[bridgeId] = bridge;
            }

            Task.Run(() => HandleHueBridge(bridge));
        }
 protected bool Equals(PhilipsHueBridge other)
 {
     return(string.Equals(_id, other._id));
 }
 public PhilipsHueBulb(string index, string id, string name, PhilipsHueBridge bridge) : base(index, id, name, bridge)
 {
 }
 public void Update(PhilipsHueBridge bridge, List <Group> groups)
 {
     UpdateGroups(bridge, groups.Where(g => g.Type == GroupType.Zone).ToList());
 }
 private void OnBridgeFound(PhilipsHueBridge e)
 {
     BridgeFound?.Invoke(this, e);
 }
 public PhilipsHueBulb(string index, string id, string name, PhilipsHueBridge bridge) : base(index, id, name, bridge) { }
 public PhilipsHuePresenceSensor(string index, string id, string name, PhilipsHueBridge bridge) : base(index, id, name, bridge) { }