コード例 #1
0
    public IDiscoveryDocumentBuilder <TEntity> ConfigureSensor <TEntity>(string deviceId, string entityId, string uniqueId = null) where TEntity : IHassDiscoveryDocument
    {
        uniqueId ??= $"{deviceId}_{entityId}".ToLower();

        IDiscoveryDocumentBuilder builder = _discoveryDocuments.GetOrAdd(uniqueId, s =>
        {
            string discoveryTopic = TopicBuilder.GetDiscoveryTopic <TEntity>(deviceId, entityId);

            DiscoveryDocumentBuilder <TEntity> newBuilder = new DiscoveryDocumentBuilder <TEntity>(this)
            {
                Discovery = ActivatorUtilities.CreateInstance <TEntity>(_serviceProvider, discoveryTopic, uniqueId),
                DeviceId  = deviceId,
                EntityId  = entityId
            };

            if (_config.AutoConfigureAttributesTopics && newBuilder.Discovery is IHasJsonAttributes)
            {
                newBuilder.ConfigureTopics(HassTopicKind.JsonAttributes);
            }

            return(newBuilder);
        });

        return((IDiscoveryDocumentBuilder <TEntity>)builder);
    }
コード例 #2
0
    public static IDiscoveryDocumentBuilder <TEntity> ConfigureTopics <TEntity>(this IDiscoveryDocumentBuilder <TEntity> builder, params HassTopicKind[] topicKinds) where TEntity : IHassDiscoveryDocument
    {
        foreach (HassTopicKind topicKind in topicKinds)
        {
            string topic = builder.HassMqttManager.TopicBuilder.GetServiceTopic(builder.DeviceId, builder.EntityId, topicKind.AsString(EnumFormat.EnumMemberValue));
            builder.Discovery.SetTopic(topicKind, topic);
        }

        return(builder);
    }
コード例 #3
0
    public static IDiscoveryDocumentBuilder <TEntity> ConfigureAliveService <TEntity>(this IDiscoveryDocumentBuilder <TEntity> builder) where TEntity : IHassDiscoveryDocument, IHasAvailability
    {
        AvailabilityDecoratorService decorator = builder.HassMqttManager.GetService <AvailabilityDecoratorService>();

        if (decorator == null)
        {
            throw new InvalidOperationException($"Unable to locate the Alive services. Did you forget to configure services.{nameof(AddHassConnectedEntityService)}?");
        }

        return(builder.ConfigureDiscovery(discovery => decorator.ApplyAvailabilityInformation(discovery)));
    }
コード例 #4
0
 public static IDiscoveryDocumentBuilder <TEntity> SetHassPoolProperties <TEntity>(this IDiscoveryDocumentBuilder <TEntity> sensor, SwimmingPool pool) where TEntity : MqttSensorDiscoveryBase
 {
     return(sensor.ConfigureDevice(device =>
     {
         device.Name = pool.Name;
         device.Identifiers = new[] { pool.SwimmingPoolId };
     }));
 }
コード例 #5
0
 public static ISensorContainer GetSensor <TEntity>(this IDiscoveryDocumentBuilder <TEntity> builder) where TEntity : IHassDiscoveryDocument => builder.HassMqttManager.GetSensor(builder.DeviceId, builder.EntityId);
コード例 #6
0
 public static IDiscoveryDocumentBuilder <TEntity> ConfigureDevice <TEntity>(this IDiscoveryDocumentBuilder <TEntity> builder, DeviceConfigure configure) where TEntity : IHassDiscoveryDocument
 {
     configure(builder.Discovery.Device);
     return(builder);
 }
コード例 #7
0
 public static IDiscoveryDocumentBuilder <TEntity> ConfigureDiscovery <TEntity>(this IDiscoveryDocumentBuilder <TEntity> builder, DiscoveryConfigure <TEntity> configure) where TEntity : IHassDiscoveryDocument
 {
     configure(builder.Discovery);
     return(builder);
 }
コード例 #8
0
        private void CreateEntities(UponorResponseContainer values)
        {
            // System
            string uHomeDeviceId = HassUniqueIdBuilder.GetUhomeDeviceId();

            {
                const string entityId = "uhome";
                _hassMqttManager.ConfigureSensor <MqttSensor>(uHomeDeviceId, entityId)
                .ConfigureTopics(HassTopicKind.State, HassTopicKind.JsonAttributes)
                .ConfigureDevice(device =>
                {
                    if (!device.Identifiers.Contains(uHomeDeviceId))
                    {
                        device.Identifiers.Add(uHomeDeviceId);
                    }

                    device.Name         = "Uponor U@Home";
                    device.Manufacturer = "Uponor";
                })
                .ConfigureAliveService();

                _hassMqttManager.ConfigureSensor <MqttSensor>(uHomeDeviceId, "average_temperature")
                .ConfigureTopics(HassTopicKind.State)
                .ConfigureDevice(device =>
                {
                    if (!device.Identifiers.Contains(uHomeDeviceId))
                    {
                        device.Identifiers.Add(uHomeDeviceId);
                    }

                    device.Name         = "Uponor U@Home";
                    device.Manufacturer = "Uponor";
                })
                .ConfigureDiscovery(discovery =>
                {
                    discovery.Name = "Uponor Average Temperature";
                    discovery.UnitOfMeasurement = "°C";
                    discovery.DeviceClass       = HassSensorDeviceClass.Temperature;
                })
                .ConfigureAliveService();
            }

            // Controllers
            foreach (int controller in _detailsContainer.GetAvailableControllers())
            {
                string       deviceId = HassUniqueIdBuilder.GetControllerDeviceId(controller);
                const string entityId = "controller";

                _hassMqttManager.ConfigureSensor <MqttSensor>(deviceId, entityId)
                .ConfigureTopics(HassTopicKind.State, HassTopicKind.JsonAttributes)
                .ConfigureDevice(device =>
                {
                    if (!device.Identifiers.Contains(deviceId))
                    {
                        device.Identifiers.Add(deviceId);
                    }

                    device.Name         = $"Uponor Controller {controller}";
                    device.Manufacturer = "Uponor";
                    device.ViaDevice    = uHomeDeviceId;
                })
                .ConfigureAliveService();
            }

            // Outdoor sensors
            foreach (int controller in _detailsContainer.GetAvailableOutdoorSensors())
            {
                string       controllerId = HassUniqueIdBuilder.GetControllerDeviceId(controller);
                const string entityId     = "outdoor_sensor";

                _hassMqttManager.ConfigureSensor <MqttSensor>(controllerId, entityId)
                .ConfigureTopics(HassTopicKind.State)
                .ConfigureDevice(device =>
                {
                    if (!device.Identifiers.Contains(controllerId))
                    {
                        device.Identifiers.Add(controllerId);
                    }

                    device.Name         = $"Uponor Controller {controller}";
                    device.Manufacturer = "Uponor";
                    device.ViaDevice    = controllerId;
                })
                .ConfigureDiscovery(discovery =>
                {
                    discovery.Name              = $"Controller {controller} Outdoor Sensor";
                    discovery.DeviceClass       = HassSensorDeviceClass.Temperature;
                    discovery.UnitOfMeasurement = "°C";
                    discovery.StateClass        = HassStateClass.Measurement;
                })
                .ConfigureAliveService();
            }

            // Thermostats
            void SetThermostatDeviceInfo <TEntity>(IDiscoveryDocumentBuilder <TEntity> builder, string name, string deviceId, string controllerId) where TEntity : IHassDiscoveryDocument
            {
                builder.ConfigureDevice(device =>
                {
                    if (!device.Identifiers.Contains(deviceId))
                    {
                        device.Identifiers.Add(deviceId);
                    }

                    device.Name         = name;
                    device.Manufacturer = "Uponor";
                    device.ViaDevice    = controllerId;
                });
            }

            foreach ((int controller, int thermostat) in _detailsContainer.GetAvailableThermostats())
            {
                string controllerId = HassUniqueIdBuilder.GetControllerDeviceId(controller);
                string deviceId     = HassUniqueIdBuilder.GetThermostatDeviceId(controller, thermostat);

                // Name
                string deviceName = $"Thermostat {controller}.{thermostat}";
                if (values.TryGetValue(UponorObjects.Thermostat(UponorThermostats.RoomName, controller, thermostat),
                                       UponorProperties.Value, out string stringVal) && !string.IsNullOrWhiteSpace(stringVal))
                {
                    deviceName = stringVal;
                }

                // Climate
                IDiscoveryDocumentBuilder <MqttClimate> climateBuilder = _hassMqttManager.ConfigureSensor <MqttClimate>(deviceId, "temp")
                                                                         .ConfigureTopics(HassTopicKind.JsonAttributes)
                                                                         .ConfigureTopics(HassTopicKind.CurrentTemperature, HassTopicKind.AwayModeState, HassTopicKind.Action, HassTopicKind.ModeState)
                                                                         .ConfigureTopics(HassTopicKind.TemperatureCommand, HassTopicKind.TemperatureState)
                                                                         .ConfigureDiscovery(discovery =>
                {
                    discovery.Name      = $"{deviceName} Thermostat";
                    discovery.Precision = 0.1f;
                    discovery.TempStep  = 0.5f;
                })
                                                                         .ConfigureAliveService();

                SetThermostatDeviceInfo(climateBuilder, deviceName, deviceId, controllerId);

                // Hacks: HASS has an odd way of determining what Climate devices do.
                // With HASS, the mode of the device is what the device is set to do. Ie, in a heating-only climate system, they will _always_ be heating
                // While I prefer that the device is shown as what it's currently doing, given my "auto" settings.
                switch (_operationConfig.OperationMode)
                {
                case OperationMode.Normal:
                    climateBuilder.Discovery.Modes = new[] { "auto" };
                    break;

                case OperationMode.ModeWorkaround:
                    climateBuilder.Discovery.Modes = new[] { "off", _detailsContainer.HcMode == HcMode.Heating ? "heat" : "cool" };
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (values.TryGetValue(UponorObjects.Thermostat(UponorThermostats.MinSetpoint, controller, thermostat),
                                       UponorProperties.Value, out float floatVal))
                {
                    climateBuilder.Discovery.MinTemp = floatVal;
                }

                if (values.TryGetValue(UponorObjects.Thermostat(UponorThermostats.MaxSetpoint, controller, thermostat),
                                       UponorProperties.Value, out floatVal))
                {
                    climateBuilder.Discovery.MaxTemp = floatVal;
                }

                // Temperature
                IDiscoveryDocumentBuilder <MqttSensor> sensorBuilder = _hassMqttManager.ConfigureSensor <MqttSensor>(deviceId, "temperature")
                                                                       .ConfigureTopics(HassTopicKind.State)
                                                                       .ConfigureDiscovery(discovery =>
                {
                    discovery.Name              = $"{deviceName} Temperature";
                    discovery.DeviceClass       = HassSensorDeviceClass.Temperature;
                    discovery.UnitOfMeasurement = "°C";
                    discovery.StateClass        = HassStateClass.Measurement;
                })
                                                                       .ConfigureAliveService();

                SetThermostatDeviceInfo(sensorBuilder, deviceName, deviceId, controllerId);

                // Humidity
                sensorBuilder = _hassMqttManager.ConfigureSensor <MqttSensor>(deviceId, "humidity")
                                .ConfigureTopics(HassTopicKind.State)
                                .ConfigureDiscovery(discovery =>
                {
                    discovery.Name              = $"{deviceName} Humidity";
                    discovery.DeviceClass       = HassSensorDeviceClass.Humidity;
                    discovery.UnitOfMeasurement = "%";
                    discovery.StateClass        = HassStateClass.Measurement;
                })
                                .ConfigureAliveService();

                SetThermostatDeviceInfo(sensorBuilder, deviceName, deviceId, controllerId);

                // Battery sensor
                sensorBuilder = _hassMqttManager.ConfigureSensor <MqttSensor>(deviceId, "battery")
                                .ConfigureTopics(HassTopicKind.State)
                                .ConfigureDiscovery(discovery =>
                {
                    discovery.Name              = $"{deviceName} Battery";
                    discovery.DeviceClass       = HassSensorDeviceClass.Battery;
                    discovery.UnitOfMeasurement = "%";
                })
                                .ConfigureAliveService();

                SetThermostatDeviceInfo(sensorBuilder, deviceName, deviceId, controllerId);

                // Alarm sensor
                IDiscoveryDocumentBuilder <MqttBinarySensor> binarySensorBuilder = _hassMqttManager.ConfigureSensor <MqttBinarySensor>(deviceId, "alarms")
                                                                                   .ConfigureTopics(HassTopicKind.State, HassTopicKind.JsonAttributes)
                                                                                   .ConfigureDiscovery(discovery =>
                {
                    discovery.Name        = $"{deviceName} Alarms";
                    discovery.DeviceClass = HassBinarySensorDeviceClass.Problem;
                })
                                                                                   .ConfigureAliveService();

                SetThermostatDeviceInfo(binarySensorBuilder, deviceName, deviceId, controllerId);
            }
        }