/// <summary> /// Sets color and temperature for a bulb and uses a transition time to the provided state /// </summary> /// <param name="bulb">Light bulb</param> /// <param name="hue">0..65535</param> /// <param name="saturation">0..65535</param> /// <param name="brightness">0..65535</param> /// <param name="kelvin">2700..9000</param> /// <param name="transitionDuration"></param> /// <returns></returns> public async Task SetColorAsync(LightBulb bulb, UInt16 hue, UInt16 saturation, UInt16 brightness, UInt16 kelvin, TimeSpan transitionDuration) { if (transitionDuration.TotalMilliseconds > UInt32.MaxValue || transitionDuration.Ticks < 0) { throw new ArgumentOutOfRangeException("transitionDuration"); } if (kelvin < 2500 || kelvin > 9000) { throw new ArgumentOutOfRangeException("kelvin", "Kelvin must be between 2500 and 9000"); } System.Diagnostics.Debug.WriteLine("Setting color to {0}", bulb.Endpoint); UInt32 duration = (UInt32)transitionDuration.TotalMilliseconds; var payload = new LightSetColorRequest(hue, saturation, brightness, kelvin, duration); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), false, true, 0, bulb.MacAddress, bulb.SendClient); var response = await _client.SendMessage(message, bulb.Endpoint); }
/// <summary> /// Sets the device power state /// </summary> public async Task SetDevicePowerStateAsync(Device device, bool isOn) { System.Diagnostics.Debug.WriteLine("Sending TurnDeviceOff to {0}", device.Endpoint); var payload = new DeviceSetPowerRequest(isOn); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), false, true, 0, device.MacAddress, device.SendClient); await _client.SendMessage(message, device.Endpoint); }
public void SendMessage(IUdpClient udpClient, LifxMessage message, IPEndPoint endpoint) { using (var memoryStream = new MemoryStream()) { message.WriteToStream(memoryStream); byte[] packet = memoryStream.ToArray(); udpClient.SendAsync(packet, packet.Length, endpoint.Address.ToString(), endpoint.Port); } }
/// <summary> /// Gets the current power state for a light bulb /// </summary> /// <param name="bulb"></param> /// <returns></returns> public async Task <bool> GetLightPowerAsync(LightBulb bulb) { var payload = new LightGetPowerRequest(); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), true, false, 0, bulb.MacAddress, bulb.SendClient); var response = await _client.SendMessage(message, bulb.Endpoint); return((response.Message.Payload is LightPowerResponse power) ? power.IsOn : throw new InvalidOperationException("wrong response")); }
/// <summary> /// Sets the label on the device /// </summary> public async Task SetDeviceLabelAsync(Device device, string label) { System.Diagnostics.Debug.WriteLine("Sending SetDeviceLabelAsync to {0}", device.Endpoint); var payload = new DeviceSetLabelRequest(label); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), false, true, 0, device.MacAddress, device.SendClient); await _client.SendMessage(message, device.Endpoint); }
/// <summary> /// Gets the device's host firmware /// </summary> public async Task <FirmwareVersion> GetDeviceHostFirmwareAsync(Device device) { System.Diagnostics.Debug.WriteLine("Sending GetDeviceHostFirmware to {0}", device.Endpoint); var payload = new DeviceGetHostFirmware(); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), true, false, 0, device.MacAddress, device.SendClient); var response = await _client.SendMessage(message, device.Endpoint); return((response.Message.Payload is StateHostFirmwareResponse versionResponse) ? new FirmwareVersion(versionResponse) : throw new InvalidOperationException("wrong response")); }
/// <summary> /// Gets the label for the device /// </summary> public async Task <string> GetDeviceLabelAsync(Device device) { System.Diagnostics.Debug.WriteLine("Sending GetDeviceLabel to {0}", device.Endpoint); var payload = new DeviceGetLabelRequest(); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), true, false, 0, device.MacAddress, device.SendClient); var response = await _client.SendMessage(message, device.Endpoint); return((response.Message.Payload is StateLabelResponse label) ? label.Label : throw new InvalidOperationException("wrong response")); }
private async Task SetLightPowerAsync(LightBulb bulb, TimeSpan transitionDuration, bool isOn) { if (bulb == null) { throw new ArgumentNullException("bulb"); } if (transitionDuration.TotalMilliseconds > UInt32.MaxValue || transitionDuration.Ticks < 0) { throw new ArgumentOutOfRangeException("transitionDuration"); } var payload = new LightSetPowerRequest(isOn, (UInt32)transitionDuration.TotalMilliseconds); var message = LifxMessage.CreateTargeted(payload, (uint)randomizer.Next(), false, true, 0, bulb.MacAddress, bulb.SendClient); var response = await _client.SendMessage(message, bulb.Endpoint); }
internal static LifxMessage FromPacket(byte[] data, IUdpClient respondClient) { using (MemoryStream ms = new MemoryStream(data)) { var headerBytes = new byte[36]; Array.Copy(data, headerBytes, headerBytes.Length); var header = LifxHeader.FromHeaderBytes(headerBytes); byte[] payload = null; if (data.Length > 36) { payload = new byte[data.Length - 36]; Array.Copy(data, 36, payload, 0, payload.Length); } return(LifxMessage.FromPayloadBytes(header, payload, respondClient)); } }
/// <summary> /// Begins searching for bulbs. /// </summary> /// <seealso cref="DeviceDiscovered"/> /// <seealso cref="DeviceLost"/> /// <seealso cref="StopDeviceDiscovery"/> public void StartDeviceDiscovery() { if (_DiscoverCancellationSource != null && !_DiscoverCancellationSource.IsCancellationRequested) { return; } _DiscoverCancellationSource = new CancellationTokenSource(); var token = _DiscoverCancellationSource.Token; var source = discoverSourceID = (uint)randomizer.Next(int.MaxValue); _client.UnhandledMessage += (o, e) => ProcessDeviceDiscoveryMessage(e.RemoteEndpoint, e.Message); //Start discovery thread Task.Run(async() => { while (!token.IsCancellationRequested) { try { System.Diagnostics.Debug.WriteLine("Sending GetServices"); var message = LifxMessage.CreateBroadcast(new GetServiceRequest(), source, true, false, 0); _client.BroadcastMessage(message); } catch { } await Task.Delay(5000); var lostDevices = devices.Where(d => (DateTime.UtcNow - d.LastSeen).TotalMinutes > 5).ToArray(); if (lostDevices.Any()) { foreach (var device in lostDevices) { devices.Remove(device); DiscoveredBulbs.Remove(device.MacAddressName); if (DeviceLost != null) { DeviceLost(this, new DeviceDiscoveryEventArgs() { Device = device }); } } } } }); }
private void ProcessDeviceDiscoveryMessage(IPEndPoint remoteEndpoint, LifxMessage msg) { string id = msg.Header.FrameAddress.TargetMacAddressName; //remoteAddress.ToString() if (DiscoveredBulbs.ContainsKey(id)) //already discovered { DiscoveredBulbs[id].LastSeen = DateTime.UtcNow; //Update datestamp DiscoveredBulbs[id].Endpoint = remoteEndpoint; return; } if (msg.Header.Frame.SourceIdentifier != discoverSourceID || //did we request the discovery? _DiscoverCancellationSource == null || _DiscoverCancellationSource.IsCancellationRequested) //did we cancel discovery? { return; } if (!(msg.Payload is StateServiceResponse stateServiceResponse)) { return; // not the message we were expecting } var device = new LightBulb() { Endpoint = remoteEndpoint, Service = stateServiceResponse.Service, LastSeen = DateTime.UtcNow, MacAddress = msg.Header.FrameAddress.TargetMacAddress, SendClient = msg.RespondClient, }; DiscoveredBulbs[id] = device; devices.Add(device); DeviceDiscovered?.Invoke(this, new DeviceDiscoveryEventArgs() { Device = device }); }
public async Task <LifxResponse> ReceiveMessage(IUdpClient udpClient) { var response = await udpClient.ReceiveAsync(); return(new LifxResponse(LifxMessage.FromPacket(response.ReceiveResult.Buffer, response.SendClient), response.ReceiveResult.RemoteEndPoint)); }
public LifxResponse(LifxMessage message, IPEndPoint remoteEndPoint) { Message = message; RemoteEndpoint = remoteEndPoint; }