mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Add volume to SensorDeviceClass (#77960)
* Add volume to SensorDeviceClass * Adjust recorder * Adjust tests * Adjust sensor UNIT_CONVERTERS * Adjust recorder * Update strings.json
This commit is contained in:
parent
d8a15f3dda
commit
12e4d18038
@ -13,8 +13,6 @@ from homeassistant.const import (
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
ENERGY_MEGA_WATT_HOUR,
|
||||
ENERGY_WATT_HOUR,
|
||||
VOLUME_CUBIC_FEET,
|
||||
VOLUME_CUBIC_METERS,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback, valid_entity_id
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
@ -27,6 +25,7 @@ from homeassistant.util.unit_conversion import (
|
||||
PressureConverter,
|
||||
SpeedConverter,
|
||||
TemperatureConverter,
|
||||
VolumeConverter,
|
||||
)
|
||||
|
||||
from .const import MAX_QUEUE_BACKLOG
|
||||
@ -131,7 +130,7 @@ async def ws_handle_get_statistics_during_period(
|
||||
vol.Optional("pressure"): vol.In(PressureConverter.VALID_UNITS),
|
||||
vol.Optional("speed"): vol.In(SpeedConverter.VALID_UNITS),
|
||||
vol.Optional("temperature"): vol.In(TemperatureConverter.VALID_UNITS),
|
||||
vol.Optional("volume"): vol.Any(VOLUME_CUBIC_FEET, VOLUME_CUBIC_METERS),
|
||||
vol.Optional("volume"): vol.In(VolumeConverter.VALID_UNITS),
|
||||
}
|
||||
),
|
||||
}
|
||||
@ -336,7 +335,10 @@ async def ws_adjust_sum_statistics(
|
||||
ENERGY_WATT_HOUR,
|
||||
):
|
||||
return True
|
||||
if statistics_unit == VOLUME_CUBIC_METERS and display_unit == VOLUME_CUBIC_FEET:
|
||||
if (
|
||||
statistics_unit == VolumeConverter.NORMALIZED_UNIT
|
||||
and display_unit in VolumeConverter.VALID_UNITS
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -64,6 +64,7 @@ from homeassistant.util.unit_conversion import (
|
||||
PressureConverter,
|
||||
SpeedConverter,
|
||||
TemperatureConverter,
|
||||
VolumeConverter,
|
||||
)
|
||||
|
||||
from .const import CONF_STATE_CLASS # noqa: F401
|
||||
@ -185,6 +186,9 @@ class SensorDeviceClass(StrEnum):
|
||||
# voltage (V)
|
||||
VOLTAGE = "voltage"
|
||||
|
||||
# volume (VOLUME_*)
|
||||
VOLUME = "volume"
|
||||
|
||||
|
||||
DEVICE_CLASSES_SCHEMA: Final = vol.All(vol.Lower, vol.Coerce(SensorDeviceClass))
|
||||
|
||||
@ -221,6 +225,7 @@ UNIT_CONVERTERS: dict[str, type[BaseUnitConverter]] = {
|
||||
SensorDeviceClass.PRESSURE: PressureConverter,
|
||||
SensorDeviceClass.SPEED: SpeedConverter,
|
||||
SensorDeviceClass.TEMPERATURE: TemperatureConverter,
|
||||
SensorDeviceClass.VOLUME: VolumeConverter,
|
||||
}
|
||||
|
||||
UNIT_RATIOS: dict[str, dict[str, float]] = {
|
||||
@ -232,6 +237,7 @@ UNIT_RATIOS: dict[str, dict[str, float]] = {
|
||||
TEMP_FAHRENHEIT: 1.8,
|
||||
TEMP_KELVIN: 1.0,
|
||||
},
|
||||
SensorDeviceClass.VOLUME: VolumeConverter.UNIT_CONVERSION,
|
||||
}
|
||||
|
||||
# mypy: disallow-any-generics
|
||||
|
@ -58,9 +58,10 @@ CONF_IS_REACTIVE_POWER = "is_reactive_power"
|
||||
CONF_IS_SIGNAL_STRENGTH = "is_signal_strength"
|
||||
CONF_IS_SULPHUR_DIOXIDE = "is_sulphur_dioxide"
|
||||
CONF_IS_TEMPERATURE = "is_temperature"
|
||||
CONF_IS_VALUE = "is_value"
|
||||
CONF_IS_VOLATILE_ORGANIC_COMPOUNDS = "is_volatile_organic_compounds"
|
||||
CONF_IS_VOLTAGE = "is_voltage"
|
||||
CONF_IS_VALUE = "is_value"
|
||||
CONF_IS_VOLUME = "is_volume"
|
||||
|
||||
ENTITY_CONDITIONS = {
|
||||
SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_IS_APPARENT_POWER}],
|
||||
@ -94,6 +95,7 @@ ENTITY_CONDITIONS = {
|
||||
{CONF_TYPE: CONF_IS_VOLATILE_ORGANIC_COMPOUNDS}
|
||||
],
|
||||
SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_IS_VOLTAGE}],
|
||||
SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_IS_VOLUME}],
|
||||
DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_IS_VALUE}],
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,10 @@ CONF_SIGNAL_STRENGTH = "signal_strength"
|
||||
CONF_SPEED = "speed"
|
||||
CONF_SULPHUR_DIOXIDE = "sulphur_dioxide"
|
||||
CONF_TEMPERATURE = "temperature"
|
||||
CONF_VALUE = "value"
|
||||
CONF_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
||||
CONF_VOLTAGE = "voltage"
|
||||
CONF_VALUE = "value"
|
||||
CONF_VOLUME = "volume"
|
||||
|
||||
ENTITY_TRIGGERS = {
|
||||
SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_APPARENT_POWER}],
|
||||
@ -93,6 +94,7 @@ ENTITY_TRIGGERS = {
|
||||
{CONF_TYPE: CONF_VOLATILE_ORGANIC_COMPOUNDS}
|
||||
],
|
||||
SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_VOLTAGE}],
|
||||
SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_VOLUME}],
|
||||
DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_VALUE}],
|
||||
}
|
||||
|
||||
|
@ -61,11 +61,12 @@ DEFAULT_STATISTICS = {
|
||||
UNIT_CONVERTERS: dict[str, type[BaseUnitConverter]] = {
|
||||
SensorDeviceClass.DISTANCE: DistanceConverter,
|
||||
SensorDeviceClass.ENERGY: EnergyConverter,
|
||||
SensorDeviceClass.GAS: VolumeConverter,
|
||||
SensorDeviceClass.POWER: PowerConverter,
|
||||
SensorDeviceClass.PRESSURE: PressureConverter,
|
||||
SensorDeviceClass.SPEED: SpeedConverter,
|
||||
SensorDeviceClass.TEMPERATURE: TemperatureConverter,
|
||||
SensorDeviceClass.GAS: VolumeConverter,
|
||||
SensorDeviceClass.VOLUME: VolumeConverter,
|
||||
}
|
||||
|
||||
# Keep track of entities for which a warning about decreasing value has been logged
|
||||
|
@ -6,7 +6,10 @@
|
||||
"is_battery_level": "Current {entity_name} battery level",
|
||||
"is_carbon_monoxide": "Current {entity_name} carbon monoxide concentration level",
|
||||
"is_carbon_dioxide": "Current {entity_name} carbon dioxide concentration level",
|
||||
"is_current": "Current {entity_name} current",
|
||||
"is_distance": "Current {entity_name} distance",
|
||||
"is_energy": "Current {entity_name} energy",
|
||||
"is_frequency": "Current {entity_name} frequency",
|
||||
"is_gas": "Current {entity_name} gas",
|
||||
"is_humidity": "Current {entity_name} humidity",
|
||||
"is_illuminance": "Current {entity_name} illuminance",
|
||||
@ -19,26 +22,27 @@
|
||||
"is_pm10": "Current {entity_name} PM10 concentration level",
|
||||
"is_pm25": "Current {entity_name} PM2.5 concentration level",
|
||||
"is_power": "Current {entity_name} power",
|
||||
"is_power_factor": "Current {entity_name} power factor",
|
||||
"is_pressure": "Current {entity_name} pressure",
|
||||
"is_reactive_power": "Current {entity_name} reactive power",
|
||||
"is_signal_strength": "Current {entity_name} signal strength",
|
||||
"is_speed": "Current {entity_name} speed",
|
||||
"is_sulphur_dioxide": "Current {entity_name} sulphur dioxide concentration level",
|
||||
"is_temperature": "Current {entity_name} temperature",
|
||||
"is_current": "Current {entity_name} current",
|
||||
"is_energy": "Current {entity_name} energy",
|
||||
"is_frequency": "Current {entity_name} frequency",
|
||||
"is_power_factor": "Current {entity_name} power factor",
|
||||
"is_value": "Current {entity_name} value",
|
||||
"is_volatile_organic_compounds": "Current {entity_name} volatile organic compounds concentration level",
|
||||
"is_voltage": "Current {entity_name} voltage",
|
||||
"is_value": "Current {entity_name} value"
|
||||
"is_volume": "Current {entity_name} volume"
|
||||
},
|
||||
"trigger_type": {
|
||||
"apparent_power": "{entity_name} apparent power changes",
|
||||
"battery_level": "{entity_name} battery level changes",
|
||||
"carbon_monoxide": "{entity_name} carbon monoxide concentration changes",
|
||||
"carbon_dioxide": "{entity_name} carbon dioxide concentration changes",
|
||||
"current": "{entity_name} current changes",
|
||||
"distance": "{entity_name} distance changes",
|
||||
"energy": "{entity_name} energy changes",
|
||||
"frequency": "{entity_name} frequency changes",
|
||||
"gas": "{entity_name} gas changes",
|
||||
"humidity": "{entity_name} humidity changes",
|
||||
"illuminance": "{entity_name} illuminance changes",
|
||||
@ -51,19 +55,17 @@
|
||||
"pm10": "{entity_name} PM10 concentration changes",
|
||||
"pm25": "{entity_name} PM2.5 concentration changes",
|
||||
"power": "{entity_name} power changes",
|
||||
"power_factor": "{entity_name} power factor changes",
|
||||
"pressure": "{entity_name} pressure changes",
|
||||
"reactive_power": "{entity_name} reactive power changes",
|
||||
"signal_strength": "{entity_name} signal strength changes",
|
||||
"speed": "{entity_name} speed changes",
|
||||
"sulphur_dioxide": "{entity_name} sulphur dioxide concentration changes",
|
||||
"temperature": "{entity_name} temperature changes",
|
||||
"current": "{entity_name} current changes",
|
||||
"energy": "{entity_name} energy changes",
|
||||
"frequency": "{entity_name} frequency changes",
|
||||
"power_factor": "{entity_name} power factor changes",
|
||||
"value": "{entity_name} value changes",
|
||||
"volatile_organic_compounds": "{entity_name} volatile organic compounds concentration changes",
|
||||
"voltage": "{entity_name} voltage changes",
|
||||
"value": "{entity_name} value changes"
|
||||
"volume": "{entity_name} volume changes"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
|
@ -30,7 +30,8 @@
|
||||
"is_temperature": "Current {entity_name} temperature",
|
||||
"is_value": "Current {entity_name} value",
|
||||
"is_volatile_organic_compounds": "Current {entity_name} volatile organic compounds concentration level",
|
||||
"is_voltage": "Current {entity_name} voltage"
|
||||
"is_voltage": "Current {entity_name} voltage",
|
||||
"is_volume": "Current {entity_name} volume"
|
||||
},
|
||||
"trigger_type": {
|
||||
"apparent_power": "{entity_name} apparent power changes",
|
||||
@ -62,7 +63,8 @@
|
||||
"temperature": "{entity_name} temperature changes",
|
||||
"value": "{entity_name} value changes",
|
||||
"volatile_organic_compounds": "{entity_name} volatile organic compounds concentration changes",
|
||||
"voltage": "{entity_name} voltage changes"
|
||||
"voltage": "{entity_name} voltage changes",
|
||||
"volume": "{entity_name} volume changes"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
|
@ -100,6 +100,26 @@ TEMPERATURE_SENSOR_F_ATTRIBUTES = {
|
||||
"state_class": "measurement",
|
||||
"unit_of_measurement": "°F",
|
||||
}
|
||||
VOLUME_SENSOR_FT3_ATTRIBUTES = {
|
||||
"device_class": "volume",
|
||||
"state_class": "measurement",
|
||||
"unit_of_measurement": "ft³",
|
||||
}
|
||||
VOLUME_SENSOR_M3_ATTRIBUTES = {
|
||||
"device_class": "volume",
|
||||
"state_class": "measurement",
|
||||
"unit_of_measurement": "m³",
|
||||
}
|
||||
VOLUME_SENSOR_FT3_ATTRIBUTES_TOTAL = {
|
||||
"device_class": "volume",
|
||||
"state_class": "total",
|
||||
"unit_of_measurement": "ft³",
|
||||
}
|
||||
VOLUME_SENSOR_M3_ATTRIBUTES_TOTAL = {
|
||||
"device_class": "volume",
|
||||
"state_class": "total",
|
||||
"unit_of_measurement": "m³",
|
||||
}
|
||||
|
||||
|
||||
async def test_statistics_during_period(hass, hass_ws_client, recorder_mock):
|
||||
@ -175,6 +195,8 @@ async def test_statistics_during_period(hass, hass_ws_client, recorder_mock):
|
||||
(TEMPERATURE_SENSOR_C_ATTRIBUTES, 10, 10, {"temperature": "°C"}, 10),
|
||||
(TEMPERATURE_SENSOR_C_ATTRIBUTES, 10, 10, {"temperature": "°F"}, 50),
|
||||
(TEMPERATURE_SENSOR_C_ATTRIBUTES, 10, 10, {"temperature": "K"}, 283.15),
|
||||
(VOLUME_SENSOR_M3_ATTRIBUTES, 10, 10, {"volume": "m³"}, 10),
|
||||
(VOLUME_SENSOR_M3_ATTRIBUTES, 10, 10, {"volume": "ft³"}, 353.14666),
|
||||
],
|
||||
)
|
||||
async def test_statistics_during_period_unit_conversion(
|
||||
@ -266,6 +288,8 @@ async def test_statistics_during_period_unit_conversion(
|
||||
(ENERGY_SENSOR_KWH_ATTRIBUTES, 10, 10, {"energy": "Wh"}, 10000),
|
||||
(GAS_SENSOR_M3_ATTRIBUTES, 10, 10, {"volume": "m³"}, 10),
|
||||
(GAS_SENSOR_M3_ATTRIBUTES, 10, 10, {"volume": "ft³"}, 353.147),
|
||||
(VOLUME_SENSOR_M3_ATTRIBUTES_TOTAL, 10, 10, {"volume": "m³"}, 10),
|
||||
(VOLUME_SENSOR_M3_ATTRIBUTES_TOTAL, 10, 10, {"volume": "ft³"}, 353.147),
|
||||
],
|
||||
)
|
||||
async def test_sum_statistics_during_period_unit_conversion(
|
||||
@ -583,6 +607,10 @@ async def test_statistics_during_period_bad_end_time(
|
||||
(METRIC_SYSTEM, TEMPERATURE_SENSOR_C_ATTRIBUTES, "°C", "°C", "temperature"),
|
||||
(IMPERIAL_SYSTEM, TEMPERATURE_SENSOR_F_ATTRIBUTES, "°F", "°C", "temperature"),
|
||||
(METRIC_SYSTEM, TEMPERATURE_SENSOR_F_ATTRIBUTES, "°F", "°C", "temperature"),
|
||||
(IMPERIAL_SYSTEM, VOLUME_SENSOR_FT3_ATTRIBUTES, "ft³", "m³", "volume"),
|
||||
(METRIC_SYSTEM, VOLUME_SENSOR_FT3_ATTRIBUTES, "ft³", "m³", "volume"),
|
||||
(IMPERIAL_SYSTEM, VOLUME_SENSOR_FT3_ATTRIBUTES_TOTAL, "ft³", "m³", "volume"),
|
||||
(METRIC_SYSTEM, VOLUME_SENSOR_FT3_ATTRIBUTES_TOTAL, "ft³", "m³", "volume"),
|
||||
],
|
||||
)
|
||||
async def test_list_statistic_ids(
|
||||
@ -1376,6 +1404,8 @@ async def test_backup_end_without_start(
|
||||
(METRIC_SYSTEM, SPEED_SENSOR_MPH_ATTRIBUTES, "m/s", "speed"),
|
||||
(METRIC_SYSTEM, TEMPERATURE_SENSOR_C_ATTRIBUTES, "°C", "temperature"),
|
||||
(METRIC_SYSTEM, TEMPERATURE_SENSOR_F_ATTRIBUTES, "°C", "temperature"),
|
||||
(METRIC_SYSTEM, VOLUME_SENSOR_FT3_ATTRIBUTES, "m³", "volume"),
|
||||
(METRIC_SYSTEM, VOLUME_SENSOR_M3_ATTRIBUTES, "m³", "volume"),
|
||||
],
|
||||
)
|
||||
async def test_get_statistics_metadata(
|
||||
|
@ -23,6 +23,10 @@ from homeassistant.const import (
|
||||
STATE_UNKNOWN,
|
||||
TEMP_CELSIUS,
|
||||
TEMP_FAHRENHEIT,
|
||||
VOLUME_CUBIC_FEET,
|
||||
VOLUME_CUBIC_METERS,
|
||||
VOLUME_FLUID_OUNCE,
|
||||
VOLUME_LITERS,
|
||||
)
|
||||
from homeassistant.core import State
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
@ -549,6 +553,31 @@ async def test_custom_unit(
|
||||
100,
|
||||
SensorDeviceClass.SPEED,
|
||||
),
|
||||
# Volume
|
||||
(
|
||||
VOLUME_CUBIC_METERS,
|
||||
VOLUME_CUBIC_FEET,
|
||||
VOLUME_CUBIC_FEET,
|
||||
100,
|
||||
3531,
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
(
|
||||
VOLUME_FLUID_OUNCE,
|
||||
VOLUME_LITERS,
|
||||
VOLUME_LITERS,
|
||||
78,
|
||||
2.3,
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
(
|
||||
VOLUME_CUBIC_METERS,
|
||||
"peer_distance",
|
||||
VOLUME_CUBIC_METERS,
|
||||
100,
|
||||
100,
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_custom_unit_change(
|
||||
|
@ -98,6 +98,8 @@ def set_time_zone():
|
||||
("speed", "mph", "mph", "m/s", "speed", 13.050847, -10, 30),
|
||||
("temperature", "°C", "°C", "°C", "temperature", 13.050847, -10, 30),
|
||||
("temperature", "°F", "°F", "°C", "temperature", 13.050847, -10, 30),
|
||||
("volume", "m³", "m³", "m³", "volume", 13.050847, -10, 30),
|
||||
("volume", "ft³", "ft³", "m³", "volume", 13.050847, -10, 30),
|
||||
],
|
||||
)
|
||||
def test_compile_hourly_statistics(
|
||||
@ -359,18 +361,22 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
|
||||
(IMPERIAL_SYSTEM, "distance", "mi", "mi", "m", "distance", 1),
|
||||
(IMPERIAL_SYSTEM, "energy", "kWh", "kWh", "kWh", "energy", 1),
|
||||
(IMPERIAL_SYSTEM, "energy", "Wh", "Wh", "kWh", "energy", 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "EUR", "EUR", "EUR", None, 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
|
||||
(IMPERIAL_SYSTEM, "gas", "m³", "m³", "m³", "volume", 1),
|
||||
(IMPERIAL_SYSTEM, "gas", "ft³", "ft³", "m³", "volume", 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "EUR", "EUR", "EUR", None, 1),
|
||||
(IMPERIAL_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
|
||||
(IMPERIAL_SYSTEM, "volume", "m³", "m³", "m³", "volume", 1),
|
||||
(IMPERIAL_SYSTEM, "volume", "ft³", "ft³", "m³", "volume", 1),
|
||||
(METRIC_SYSTEM, "distance", "m", "m", "m", "distance", 1),
|
||||
(METRIC_SYSTEM, "distance", "mi", "mi", "m", "distance", 1),
|
||||
(METRIC_SYSTEM, "energy", "kWh", "kWh", "kWh", "energy", 1),
|
||||
(METRIC_SYSTEM, "energy", "Wh", "Wh", "kWh", "energy", 1),
|
||||
(METRIC_SYSTEM, "monetary", "EUR", "EUR", "EUR", None, 1),
|
||||
(METRIC_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
|
||||
(METRIC_SYSTEM, "gas", "m³", "m³", "m³", "volume", 1),
|
||||
(METRIC_SYSTEM, "gas", "ft³", "ft³", "m³", "volume", 1),
|
||||
(METRIC_SYSTEM, "monetary", "EUR", "EUR", "EUR", None, 1),
|
||||
(METRIC_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
|
||||
(METRIC_SYSTEM, "volume", "m³", "m³", "m³", "volume", 1),
|
||||
(METRIC_SYSTEM, "volume", "ft³", "ft³", "m³", "volume", 1),
|
||||
],
|
||||
)
|
||||
async def test_compile_hourly_sum_statistics_amount(
|
||||
@ -1569,6 +1575,8 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
|
||||
("speed", "mph", 30),
|
||||
("temperature", "°C", 30),
|
||||
("temperature", "°F", 30),
|
||||
("volume", "m³", 30),
|
||||
("volume", "ft³", 30),
|
||||
],
|
||||
)
|
||||
def test_compile_hourly_statistics_unchanged(
|
||||
@ -1660,6 +1668,8 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog):
|
||||
("speed", "mph", 30),
|
||||
("temperature", "°C", 30),
|
||||
("temperature", "°F", 30),
|
||||
("volume", "m³", 30),
|
||||
("volume", "ft³", 30),
|
||||
],
|
||||
)
|
||||
def test_compile_hourly_statistics_unavailable(
|
||||
@ -1751,6 +1761,10 @@ def test_compile_hourly_statistics_fails(hass_recorder, caplog):
|
||||
("measurement", "speed", "mph", "mph", "m/s", "speed", "mean"),
|
||||
("measurement", "temperature", "°C", "°C", "°C", "temperature", "mean"),
|
||||
("measurement", "temperature", "°F", "°F", "°C", "temperature", "mean"),
|
||||
("measurement", "volume", "m³", "m³", "m³", "volume", "mean"),
|
||||
("measurement", "volume", "ft³", "ft³", "m³", "volume", "mean"),
|
||||
("total", "volume", "m³", "m³", "m³", "volume", "sum"),
|
||||
("total", "volume", "ft³", "ft³", "m³", "volume", "sum"),
|
||||
],
|
||||
)
|
||||
def test_list_statistic_ids(
|
||||
|
Loading…
x
Reference in New Issue
Block a user