public void SetDeviceAvailability(string friendlyName, bool isOnline)
        {
            Bridge Update(Bridge state)
            {
                var device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));

                if (device == null)
                {
                    device = new ZigbeeDevice.Builder {
                        FriendlyName = friendlyName, IsAvailable = isOnline
                    };
                    state = state.WithDevices(devices => devices.Add(device));
                }

                if (device.IsAvailable == isOnline)
                {
                    return(state);
                }

                var newDevice = device.WithIsAvailable(isOnline);

                state = state.WithDevices(devices => devices.Replace(device, newDevice));

                return(state);
            }

            ImmutableInterlocked.Update(ref _currentState, Update);
        }
        public ZigbeeDevice NewDevice(string friendlyName, string zigbeeId, string modelId)
        {
            ZigbeeDevice device = null;

            Bridge Update(Bridge state)
            {
                device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));

                if (device == null)
                {
                    device = new ZigbeeDevice.Builder
                    {
                        FriendlyName = friendlyName,
                        IsAvailable  = true,
                        ZigbeeId     = zigbeeId,
                        ModelId      = modelId
                    };
                    state = state.WithDevices(devices => devices.Add(device));
                }

                return(state);
            }

            ImmutableInterlocked.Update(ref _currentState, Update);

            return(device);
        }
예제 #3
0
        public ZigbeeDevice UpdateDevice(string friendlyName, string jsonPayload, out bool forceLastSeen)
        {
            ZigbeeDevice device      = null;
            var          json        = JObject.Parse(jsonPayload);
            var          linkQuality = json["linkquality"]?.Value <ushort>();
            var          battery     = json["battery"]?.Value <decimal>();

            forceLastSeen = !ParseDateTimeOffset(json["last_seen"], out var lastSeen);

            Bridge Update(Bridge state)
            {
                device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));
                if (device == null)
                {
                    device = new ZigbeeDevice.Builder
                    {
                        FriendlyName = friendlyName,
                        LastSeen     = lastSeen
                    };

                    state = state.WithDevices(devices => devices.Add(device));
                }

                if (lastSeen.HasValue || battery.HasValue)
                {
                    ZigbeeDevice.Builder builder = device;
                    if (lastSeen.HasValue)
                    {
                        builder.LastSeen = lastSeen;
                    }

                    if (battery.HasValue)
                    {
                        builder.BatteryLevel = battery;
                    }

                    ZigbeeDevice newDevice = builder;

                    if (newDevice != device)
                    {
                        state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                        device = newDevice;
                    }
                }

                return(state);
            }

            UpdateState(Update);

            return(device);
        }
        public ZigbeeDevice UpdateDevice(string friendlyName, string jsonPayload)
        {
            ZigbeeDevice device      = null;
            var          json        = JObject.Parse(jsonPayload);
            var          linkQuality = json["linkquality"]?.Value <ushort>();
            var          lastSeen    = json["last_seen"]?.Value <DateTime>();

            Bridge Update(Bridge state)
            {
                device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));
                if (device == null)
                {
                    device = new ZigbeeDevice.Builder
                    {
                        FriendlyName = friendlyName,
                        LastSeen     = lastSeen
                    };

                    state = state.WithDevices(devices => devices.Add(device));
                }

                if (lastSeen.HasValue)
                {
                    var newDevice = device.WithLastSeen(lastSeen);

                    if (newDevice != device)
                    {
                        state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                        device = newDevice;
                    }
                }

                return(state);
            }

            ImmutableInterlocked.Update(ref _currentState, Update);

            return(device);
        }
        public HomeAssistantEntity SetDeviceEntity(
            string zigbeeId,
            string entityClass,
            string component,
            string configPayload,
            Func <string, string> friendlyNameFromTopicDelegate)
        {
            HomeAssistantEntity entity = null;

            var json = JObject.Parse(configPayload);

            var entityName = json["name"]?.Value <string>();
            var entityId   = json["unique_id"]?.Value <string>();
            var deviceName = json["device"]["name"]?.Value <string>();
            var deviceIds  = json["device"]["identifiers"]?.FirstOrDefault()?.Value <string>();

            Bridge Update(Bridge state)
            {
                var device = state.Devices.FirstOrDefault(d => d.ZigbeeId != null && d.ZigbeeId.Equals(zigbeeId));

                if (device == null)
                {
                    // no device with this zigbeeId is known, try to find device from payload
                    var topic = json["state_topic"].Value <string>()
                                ?? json["json_attributes_topic"].Value <string>()
                                ?? json["availability_topic"].Value <string>();

                    if (topic == null)
                    {
                        _logger.LogWarning($"Unable to find a source topic for entity {zigbeeId}-{entityClass}-{component}.");
                        return(state);                        // there's nothing we can do here
                    }

                    var friendlyName = friendlyNameFromTopicDelegate(topic);

                    if (friendlyName == null)
                    {
                        _logger.LogWarning($"Unable to find friendly name from topic {topic} in entity {zigbeeId}-{entityClass}-{component}.");
                        return(state);                        // there's nothing we can do here
                    }

                    device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));
                    if (device == null)
                    {
                        device = new ZigbeeDevice.Builder {
                            FriendlyName = friendlyName, UniqueId = zigbeeId, ZigbeeId = zigbeeId
                        };
                        state = state.WithDevices(devices => devices.Add(device));
                    }
                }

                if (device.ZigbeeId != zigbeeId)
                {
                    ZigbeeDevice newDevice = device.WithUniqueId(zigbeeId);

                    if (newDevice != device)
                    {
                        state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                        device = newDevice;
                    }
                }

                entity = device.Entities.FirstOrDefault(e => e.Component.Equals(component));
                if (entity == null)
                {
                    entity = new HomeAssistantEntity.Builder
                    {
                        EntityId    = entityId,
                        Component   = component,
                        Name        = entityName,
                        DeviceClass = entityClass
                    };
                    ZigbeeDevice newDevice = device.WithEntities(entities => entities.Add(entity));

                    if (newDevice != device)
                    {
                        state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                        device = newDevice;
                    }
                }

                if (deviceName != null || deviceIds != null)
                {
                    ZigbeeDevice newDevice = device
                                             .WithName(deviceName)
                                             .WithUniqueId(deviceIds);

                    if (newDevice != device)
                    {
                        state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                        device = newDevice;
                    }
                }

                return(state);
            }

            ImmutableInterlocked.Update(ref _currentState, Update);

            return(entity);
        }
예제 #6
0
        public ZigbeeDevice UpdateDevice(string friendlyName, string jsonPayload, out bool forceLastSeen)
        {
            ZigbeeDevice device = null;

            if (!TryParseJson(jsonPayload, out var json))
            {
                forceLastSeen = false;
                return(null);
            }

            var linkQuality = json["linkquality"]?.Value <ushort>();

            forceLastSeen = !ParseDateTimeOffset(json["last_seen"], out var lastSeen);

            Bridge Update(Bridge state)
            {
                device = state.Devices.FirstOrDefault(d => d.FriendlyName.Equals(friendlyName));
                if (device == null)
                {
                    device = new ZigbeeDevice.Builder
                    {
                        FriendlyName = friendlyName,
                        LastSeen     = lastSeen
                    };

                    state = state.WithDevices(devices => devices.Add(device));
                }

                var battery         = json["battery"]?.Value <decimal>();
                var updateAvailable = json["update_available"]?.Value <bool?>();

                if (!lastSeen.HasValue && !battery.HasValue && !updateAvailable.HasValue)
                {
                    return(state);
                }

                ZigbeeDevice.Builder builder = device;
                if (lastSeen.HasValue)
                {
                    builder.LastSeen = lastSeen;
                }

                if (battery.HasValue)
                {
                    builder.BatteryLevel = battery;
                }

                if (updateAvailable.HasValue)
                {
                    builder.IsOtaAvailable = updateAvailable;
                }

                ZigbeeDevice newDevice = builder;

                if (newDevice == device)
                {
                    return(state);
                }

                state  = state.WithDevices(devices => devices.Replace(device, newDevice));
                device = newDevice;

                return(state);
            }

            UpdateState(Update);

            return(device);
        }