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); } }
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; }
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; } }
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; }
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()); } } }
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); } } }
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()); } } }
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 PhilipsHuePresenceSensor(string index, string id, string name, PhilipsHueBridge bridge) : base(index, id, name, bridge) { }