/// <summary> /// Generate Home Assistant configuration file entries for the sensors in the provided device. /// </summary> /// <param name="definition">Device properties</param> /// <returns>Configuration file entries covering all sensors defined in the device</returns> public KeyedCollection <ConfigEntry> TransformConfig(DeviceDefinition definition) { if (definition.Sensors == null) { return(new KeyedCollection <ConfigEntry>()); } if (string.IsNullOrWhiteSpace(definition.DeviceId)) { throw new ValidationException($"{nameof(definition.DeviceId)} requires a value."); } var configs = new KeyedCollection <ConfigEntry>(); foreach (var sensor in definition.Sensors) { if (sensor.Type.EndsWith("button")) { // Buttons processed separately below. } else if (sensor.Type.EndsWith(SensorType.Threshold)) { var attribute = Regex.Replace(sensor.Type, $"-?{SensorType.Threshold}$", string.Empty); if (string.IsNullOrWhiteSpace(attribute)) { throw new ValidationException("Threshold attribute is missing"); } if (string.IsNullOrWhiteSpace(sensor.OnCondition)) { throw new ValidationException("Threshold on condition is missing"); } var config = FormatSensorDefinition(EntityType.BinarySensor, new SensorConfig { Type = SensorType.Threshold, Name = definition.Name, Platform = definition.Platform, DeviceId = definition.DeviceId, DeviceName = definition.Name, DeviceClass = sensor.DeviceClass, Icon = sensor.Icon, ThresholdAttribute = attribute, ThresholdOnCondition = sensor.OnCondition, Customize = sensor.Customize, }); configs.Add(EntityType.BinarySensor, config); } else if (sensor.Type == SensorType.PowerCycleOnOff) { if (!definition.Sensors.Any(i => i.Type == SensorType.PowerCycle)) { throw new ValidationException("Can't have a power cycle on-off sensor without a power cycle sensor."); } var config = FormatTemplateDefinition(EntityType.BinarySensor, new TemplateSensorConfig { Name = definition.Name, Icon = sensor.Icon, ValueTemplate = $"states.{GetSensorEntityId(SensorType.PowerCycle, definition)}.state not in ['unknown','off']", }); configs.Add(EntityType.BinarySensor, config); } else { // Figure out whether it should be a binary sensor var entityType = GetSensorEntityType(sensor.Type); // Generate a reasonably human-friendly name, depending on the type of sensor. var name = GetSensorName(sensor.Type, definition); var friendlyName = GetSensorFriendlyName(sensor.Type, definition); if (friendlyName != name && (sensor.Customize == null || !sensor.Customize.ContainsKey("friendly_name"))) { if (sensor.Customize == null) { sensor.Customize = new Dictionary <string, string>(); } sensor.Customize.Add("friendly_name", friendlyName); } // Identify sensors which are set by Home Assistant var platform = new[] { SensorType.PowerCycle }.Contains(sensor.Type) ? Platform.HomeAssistant : definition.Platform; var config = FormatSensorDefinition(entityType, new SensorConfig { Type = sensor.Type, Name = name, Platform = platform, DeviceId = definition.DeviceId, DeviceName = definition.Name, DeviceClass = sensor.DeviceClass, Icon = sensor.Icon, Customize = sensor.Customize, }); configs.Add(entityType, config); } } var buttonConfigs = ProcessButtonDefinition(definition); configs.AddMany(EntityType.BinarySensor, buttonConfigs); return(configs); }