mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
some mixing minor changes
This commit is contained in:
@@ -479,32 +479,33 @@ void showInfo() {
|
|||||||
if (ems_getMixingDeviceEnabled()) {
|
if (ems_getMixingDeviceEnabled()) {
|
||||||
myDebug_P(PSTR("")); // newline
|
myDebug_P(PSTR("")); // newline
|
||||||
myDebug_P(PSTR("%sMixing module data:%s"), COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
myDebug_P(PSTR("%sMixing module data:%s"), COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||||
// myDebug_P(PSTR(" Mixing: %s"), ems_getDeviceDescription(EMS_DEVICE_TYPE_MIXING, buffer_type,false));
|
myDebug_P(PSTR(" Mixing Module: %s"), ems_getDeviceDescription(EMS_DEVICE_TYPE_MIXING, buffer_type, false));
|
||||||
if (EMS_Boiler.switchTemp < EMS_VALUE_USHORT_NOTSET)
|
if ((EMS_Boiler.switchTemp < EMS_VALUE_USHORT_NOTSET) && (EMS_Boiler.switchTemp != 0)) {
|
||||||
_renderUShortValue("Switch temperature", "C", EMS_Boiler.switchTemp);
|
_renderUShortValue("Switch temperature", "C", EMS_Boiler.switchTemp);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t hc_num = 1; hc_num <= EMS_THERMOSTAT_MAXHC; hc_num++) {
|
for (uint8_t hc_num = 1; hc_num <= EMS_THERMOSTAT_MAXHC; hc_num++) {
|
||||||
if (EMS_Mixing.hc[hc_num - 1].active) {
|
if (EMS_MixingModule.hc[hc_num - 1].active) {
|
||||||
myDebug_P(PSTR(" Mixing Circuit %d"), hc_num);
|
myDebug_P(PSTR(" Mixing Circuit %d"), hc_num);
|
||||||
if (EMS_Mixing.hc[hc_num - 1].flowTemp < EMS_VALUE_USHORT_NOTSET)
|
if (EMS_MixingModule.hc[hc_num - 1].flowTemp < EMS_VALUE_USHORT_NOTSET)
|
||||||
_renderUShortValue(" Current flow temperature", "C", EMS_Mixing.hc[hc_num - 1].flowTemp);
|
_renderUShortValue(" Current flow temperature", "C", EMS_MixingModule.hc[hc_num - 1].flowTemp);
|
||||||
if (EMS_Mixing.hc[hc_num - 1].flowSetTemp != EMS_VALUE_INT_NOTSET)
|
if (EMS_MixingModule.hc[hc_num - 1].flowSetTemp != EMS_VALUE_INT_NOTSET)
|
||||||
_renderIntValue(" Setpoint flow temperature", "C", EMS_Mixing.hc[hc_num - 1].flowSetTemp);
|
_renderIntValue(" Setpoint flow temperature", "C", EMS_MixingModule.hc[hc_num - 1].flowSetTemp);
|
||||||
if (EMS_Mixing.hc[hc_num - 1].pumpMod != EMS_VALUE_INT_NOTSET)
|
if (EMS_MixingModule.hc[hc_num - 1].pumpMod != EMS_VALUE_INT_NOTSET)
|
||||||
_renderIntValue(" Current pump modulation", "%", EMS_Mixing.hc[hc_num - 1].pumpMod);
|
_renderIntValue(" Current pump modulation", "%", EMS_MixingModule.hc[hc_num - 1].pumpMod);
|
||||||
if (EMS_Mixing.hc[hc_num - 1].valveStatus != EMS_VALUE_INT_NOTSET)
|
if (EMS_MixingModule.hc[hc_num - 1].valveStatus != EMS_VALUE_INT_NOTSET)
|
||||||
_renderIntValue(" Current valve status", "", EMS_Mixing.hc[hc_num - 1].valveStatus);
|
_renderIntValue(" Current valve status", "", EMS_MixingModule.hc[hc_num - 1].valveStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint8_t wwc_num = 1; wwc_num <= EMS_THERMOSTAT_MAXWWC; wwc_num++) {
|
for (uint8_t wwc_num = 1; wwc_num <= EMS_THERMOSTAT_MAXWWC; wwc_num++) {
|
||||||
if (EMS_Mixing.wwc[wwc_num - 1].active) {
|
if (EMS_MixingModule.wwc[wwc_num - 1].active) {
|
||||||
myDebug_P(PSTR(" Warm Water Circuit %d"), wwc_num);
|
myDebug_P(PSTR(" Warm Water Circuit %d"), wwc_num);
|
||||||
if (EMS_Mixing.wwc[wwc_num - 1].flowTemp < EMS_VALUE_USHORT_NOTSET)
|
if (EMS_MixingModule.wwc[wwc_num - 1].flowTemp < EMS_VALUE_USHORT_NOTSET)
|
||||||
_renderUShortValue(" Current warm water temperature", "C", EMS_Mixing.wwc[wwc_num - 1].flowTemp);
|
_renderUShortValue(" Current warm water temperature", "C", EMS_MixingModule.wwc[wwc_num - 1].flowTemp);
|
||||||
if (EMS_Mixing.wwc[wwc_num - 1].pumpMod != EMS_VALUE_INT_NOTSET)
|
if (EMS_MixingModule.wwc[wwc_num - 1].pumpMod != EMS_VALUE_INT_NOTSET)
|
||||||
_renderIntValue(" Current pump status", "", EMS_Mixing.wwc[wwc_num - 1].pumpMod);
|
_renderIntValue(" Current pump status", "", EMS_MixingModule.wwc[wwc_num - 1].pumpMod);
|
||||||
if (EMS_Mixing.wwc[wwc_num - 1].tempStatus != EMS_VALUE_INT_NOTSET)
|
if (EMS_MixingModule.wwc[wwc_num - 1].tempStatus != EMS_VALUE_INT_NOTSET)
|
||||||
_renderIntValue(" Current temp status", "", EMS_Mixing.wwc[wwc_num - 1].tempStatus);
|
_renderIntValue(" Current temp status", "", EMS_MixingModule.wwc[wwc_num - 1].tempStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -779,7 +780,7 @@ void publishEMSValues(bool force) {
|
|||||||
JsonObject rootMixing = doc.to<JsonObject>();
|
JsonObject rootMixing = doc.to<JsonObject>();
|
||||||
|
|
||||||
for (uint8_t hc_v = 1; hc_v <= EMS_THERMOSTAT_MAXHC; hc_v++) {
|
for (uint8_t hc_v = 1; hc_v <= EMS_THERMOSTAT_MAXHC; hc_v++) {
|
||||||
_EMS_Mixing_HC * mixing = &EMS_Mixing.hc[hc_v - 1];
|
_EMS_MixingModule_HC * mixing = &EMS_MixingModule.hc[hc_v - 1];
|
||||||
|
|
||||||
// only send if we have an active Heating Circuit with real data
|
// only send if we have an active Heating Circuit with real data
|
||||||
if (mixing->active) {
|
if (mixing->active) {
|
||||||
@@ -799,7 +800,7 @@ void publishEMSValues(bool force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint8_t wwc_v = 1; wwc_v <= EMS_THERMOSTAT_MAXWWC; wwc_v++) {
|
for (uint8_t wwc_v = 1; wwc_v <= EMS_THERMOSTAT_MAXWWC; wwc_v++) {
|
||||||
_EMS_Mixing_WWC * mixing = &EMS_Mixing.wwc[wwc_v - 1];
|
_EMS_MixingModule_WWC * mixing = &EMS_MixingModule.wwc[wwc_v - 1];
|
||||||
// only send if we have an active Warm water Circuit with real data
|
// only send if we have an active Warm water Circuit with real data
|
||||||
if (mixing->active) {
|
if (mixing->active) {
|
||||||
// build new json object
|
// build new json object
|
||||||
|
|||||||
69
src/ems.cpp
69
src/ems.cpp
@@ -31,7 +31,7 @@ _EMS_Boiler EMS_Boiler; // for boiler
|
|||||||
_EMS_Thermostat EMS_Thermostat; // for thermostat
|
_EMS_Thermostat EMS_Thermostat; // for thermostat
|
||||||
_EMS_SolarModule EMS_SolarModule; // for solar modules
|
_EMS_SolarModule EMS_SolarModule; // for solar modules
|
||||||
_EMS_HeatPump EMS_HeatPump; // for heatpumps
|
_EMS_HeatPump EMS_HeatPump; // for heatpumps
|
||||||
_EMS_Mixing EMS_Mixing; // for mixing devices
|
_EMS_MixingModule EMS_MixingModule; // for mixing devices
|
||||||
|
|
||||||
// CRC lookup table with poly 12 for faster checking
|
// CRC lookup table with poly 12 for faster checking
|
||||||
const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26,
|
const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26,
|
||||||
@@ -119,20 +119,20 @@ void ems_init() {
|
|||||||
EMS_Thermostat.hc[i].curr_roomTemp = EMS_VALUE_SHORT_NOTSET;
|
EMS_Thermostat.hc[i].curr_roomTemp = EMS_VALUE_SHORT_NOTSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMS_Mixing.detected = false;
|
EMS_MixingModule.device_id = EMS_ID_NONE;
|
||||||
// init all mixing modules
|
// init all mixing modules
|
||||||
for (uint8_t i = 0; i < EMS_THERMOSTAT_MAXHC; i++) {
|
for (uint8_t i = 0; i < EMS_THERMOSTAT_MAXHC; i++) {
|
||||||
EMS_Mixing.hc[i].hc = i + 1;
|
EMS_MixingModule.hc[i].hc = i + 1;
|
||||||
EMS_Mixing.hc[i].flowTemp = EMS_VALUE_USHORT_NOTSET;
|
EMS_MixingModule.hc[i].flowTemp = EMS_VALUE_USHORT_NOTSET;
|
||||||
EMS_Mixing.hc[i].pumpMod = EMS_VALUE_INT_NOTSET;
|
EMS_MixingModule.hc[i].pumpMod = EMS_VALUE_INT_NOTSET;
|
||||||
EMS_Mixing.hc[i].valveStatus = EMS_VALUE_INT_NOTSET;
|
EMS_MixingModule.hc[i].valveStatus = EMS_VALUE_INT_NOTSET;
|
||||||
EMS_Mixing.hc[i].flowSetTemp = EMS_VALUE_INT_NOTSET;
|
EMS_MixingModule.hc[i].flowSetTemp = EMS_VALUE_INT_NOTSET;
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < EMS_THERMOSTAT_MAXWWC; i++) {
|
for (uint8_t i = 0; i < EMS_THERMOSTAT_MAXWWC; i++) {
|
||||||
EMS_Mixing.wwc[i].wwc = i + 1;
|
EMS_MixingModule.wwc[i].wwc = i + 1;
|
||||||
EMS_Mixing.wwc[i].flowTemp = EMS_VALUE_USHORT_NOTSET;
|
EMS_MixingModule.wwc[i].flowTemp = EMS_VALUE_USHORT_NOTSET;
|
||||||
EMS_Mixing.wwc[i].pumpMod = EMS_VALUE_INT_NOTSET;
|
EMS_MixingModule.wwc[i].pumpMod = EMS_VALUE_INT_NOTSET;
|
||||||
EMS_Mixing.wwc[i].tempStatus = EMS_VALUE_INT_NOTSET;
|
EMS_MixingModule.wwc[i].tempStatus = EMS_VALUE_INT_NOTSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UBAParameterWW
|
// UBAParameterWW
|
||||||
@@ -238,7 +238,7 @@ bool ems_getThermostatEnabled() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ems_getMixingDeviceEnabled() {
|
bool ems_getMixingDeviceEnabled() {
|
||||||
return EMS_Mixing.detected;
|
return EMS_MixingModule.device_id != EMS_ID_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ems_getSolarModuleEnabled() {
|
bool ems_getSolarModuleEnabled() {
|
||||||
@@ -1287,11 +1287,11 @@ void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
if (hc >= EMS_THERMOSTAT_MAXHC) {
|
if (hc >= EMS_THERMOSTAT_MAXHC) {
|
||||||
return; // invalid type
|
return; // invalid type
|
||||||
}
|
}
|
||||||
EMS_Mixing.hc[hc].active = true;
|
EMS_MixingModule.hc[hc].active = true;
|
||||||
|
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].flowTemp, EMS_OFFSET_MMPLUSStatusMessage_flow_temp);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].flowTemp, EMS_OFFSET_MMPLUSStatusMessage_flow_temp);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].pumpMod, EMS_OFFSET_MMPLUSStatusMessage_pump_mod);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].pumpMod, EMS_OFFSET_MMPLUSStatusMessage_pump_mod);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].valveStatus, EMS_OFFSET_MMPLUSStatusMessage_valve_status);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].valveStatus, EMS_OFFSET_MMPLUSStatusMessage_valve_status);
|
||||||
}
|
}
|
||||||
// Mixer warm water loading - 0x0231, 0x0232
|
// Mixer warm water loading - 0x0231, 0x0232
|
||||||
|
|
||||||
@@ -1300,11 +1300,11 @@ void _process_MMPLUSStatusMessageWW(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
if (wwc >= EMS_THERMOSTAT_MAXWWC) {
|
if (wwc >= EMS_THERMOSTAT_MAXWWC) {
|
||||||
return; // invalid type
|
return; // invalid type
|
||||||
}
|
}
|
||||||
EMS_Mixing.wwc[wwc].active = true;
|
EMS_MixingModule.wwc[wwc].active = true;
|
||||||
|
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.wwc[wwc].flowTemp, EMS_OFFSET_MMPLUSStatusMessage_WW_flow_temp);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.wwc[wwc].flowTemp, EMS_OFFSET_MMPLUSStatusMessage_WW_flow_temp);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.wwc[wwc].pumpMod, EMS_OFFSET_MMPLUSStatusMessage_WW_pump_mod);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.wwc[wwc].pumpMod, EMS_OFFSET_MMPLUSStatusMessage_WW_pump_mod);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.wwc[wwc].tempStatus, EMS_OFFSET_MMPLUSStatusMessage_WW_temp_status);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.wwc[wwc].tempStatus, EMS_OFFSET_MMPLUSStatusMessage_WW_temp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixer - 0xAB
|
// Mixer - 0xAB
|
||||||
@@ -1312,13 +1312,13 @@ void _process_MMPLUSStatusMessageWW(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
// We assume MM10 is on HC2 and WM10 is using HC1
|
// We assume MM10 is on HC2 and WM10 is using HC1
|
||||||
void _process_MMStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
void _process_MMStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
uint8_t hc = 1; // fixed to HC2
|
uint8_t hc = 1; // fixed to HC2
|
||||||
EMS_Mixing.hc[hc].active = true;
|
EMS_MixingModule.hc[hc].active = true;
|
||||||
|
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].flowTemp, EMS_OFFSET_MMStatusMessage_flow_temp);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].flowTemp, EMS_OFFSET_MMStatusMessage_flow_temp);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].pumpMod, EMS_OFFSET_MMStatusMessage_pump_mod);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].pumpMod, EMS_OFFSET_MMStatusMessage_pump_mod);
|
||||||
_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].flowSetTemp, EMS_OFFSET_MMStatusMessage_flow_set);
|
_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].flowSetTemp, EMS_OFFSET_MMStatusMessage_flow_set);
|
||||||
|
|
||||||
//_setValue(EMS_RxTelegram, &EMS_Mixing.hc[hc].valveStatus, EMS_OFFSET_MMStatusMessage_valve_status);
|
//_setValue(EMS_RxTelegram, &EMS_MixingModule.hc[hc].valveStatus, EMS_OFFSET_MMStatusMessage_valve_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1896,12 +1896,11 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
EMS_HeatPump.device_desc_p = device_desc_p;
|
EMS_HeatPump.device_desc_p = device_desc_p;
|
||||||
strlcpy(EMS_HeatPump.version, version, sizeof(EMS_HeatPump.version));
|
strlcpy(EMS_HeatPump.version, version, sizeof(EMS_HeatPump.version));
|
||||||
} else if (type == EMS_DEVICE_TYPE_MIXING) {
|
} else if (type == EMS_DEVICE_TYPE_MIXING) {
|
||||||
EMS_Mixing.device_id = device_id;
|
EMS_MixingModule.device_id = device_id;
|
||||||
EMS_Mixing.product_id = product_id;
|
EMS_MixingModule.product_id = product_id;
|
||||||
EMS_Mixing.device_desc_p = device_desc_p;
|
EMS_MixingModule.device_desc_p = device_desc_p;
|
||||||
EMS_Mixing.device_flags = flags;
|
EMS_MixingModule.device_flags = flags;
|
||||||
EMS_Mixing.detected = true;
|
strlcpy(EMS_MixingModule.version, version, sizeof(EMS_MixingModule.version));
|
||||||
strlcpy(EMS_Mixing.version, version, sizeof(EMS_Mixing.version));
|
|
||||||
ems_doReadCommand(EMS_TYPE_MMPLUSStatusMessage_HC1, device_id); // fetch MM values
|
ems_doReadCommand(EMS_TYPE_MMPLUSStatusMessage_HC1, device_id); // fetch MM values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2149,10 +2148,10 @@ char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, boo
|
|||||||
version = EMS_HeatPump.version;
|
version = EMS_HeatPump.version;
|
||||||
} else if (device_type == EMS_DEVICE_TYPE_MIXING) {
|
} else if (device_type == EMS_DEVICE_TYPE_MIXING) {
|
||||||
enabled = ems_getMixingDeviceEnabled();
|
enabled = ems_getMixingDeviceEnabled();
|
||||||
device_id = EMS_Mixing.device_id;
|
device_id = EMS_MixingModule.device_id;
|
||||||
product_id = EMS_Mixing.product_id;
|
product_id = EMS_MixingModule.product_id;
|
||||||
device_desc_p = EMS_Mixing.device_desc_p;
|
device_desc_p = EMS_MixingModule.device_desc_p;
|
||||||
version = EMS_Mixing.version;
|
version = EMS_MixingModule.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
|
|||||||
13
src/ems.h
13
src/ems.h
@@ -345,7 +345,7 @@ typedef struct {
|
|||||||
uint8_t pumpMod;
|
uint8_t pumpMod;
|
||||||
uint8_t valveStatus;
|
uint8_t valveStatus;
|
||||||
uint8_t flowSetTemp;
|
uint8_t flowSetTemp;
|
||||||
} _EMS_Mixing_HC;
|
} _EMS_MixingModule_HC;
|
||||||
|
|
||||||
// Mixing Module per WWC
|
// Mixing Module per WWC
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -354,7 +354,7 @@ typedef struct {
|
|||||||
uint16_t flowTemp;
|
uint16_t flowTemp;
|
||||||
uint8_t pumpMod;
|
uint8_t pumpMod;
|
||||||
uint8_t tempStatus;
|
uint8_t tempStatus;
|
||||||
} _EMS_Mixing_WWC;
|
} _EMS_MixingModule_WWC;
|
||||||
|
|
||||||
// Mixer data
|
// Mixer data
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -363,10 +363,9 @@ typedef struct {
|
|||||||
const char * device_desc_p;
|
const char * device_desc_p;
|
||||||
uint8_t product_id;
|
uint8_t product_id;
|
||||||
char version[10];
|
char version[10];
|
||||||
bool detected;
|
_EMS_MixingModule_HC hc[EMS_THERMOSTAT_MAXHC]; // array for the 4 heating circuits
|
||||||
_EMS_Mixing_HC hc[EMS_THERMOSTAT_MAXHC]; // array for the 4 heating circuits
|
_EMS_MixingModule_WWC wwc[EMS_THERMOSTAT_MAXWWC]; // array for the 2 ww circuits
|
||||||
_EMS_Mixing_WWC wwc[EMS_THERMOSTAT_MAXWWC]; // array for the 2 ww circuits
|
} _EMS_MixingModule;
|
||||||
} _EMS_Mixing;
|
|
||||||
|
|
||||||
// Solar Module - SM10/SM100/SM200/ISM1
|
// Solar Module - SM10/SM100/SM200/ISM1
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -496,6 +495,6 @@ extern _EMS_Boiler EMS_Boiler;
|
|||||||
extern _EMS_Thermostat EMS_Thermostat;
|
extern _EMS_Thermostat EMS_Thermostat;
|
||||||
extern _EMS_SolarModule EMS_SolarModule;
|
extern _EMS_SolarModule EMS_SolarModule;
|
||||||
extern _EMS_HeatPump EMS_HeatPump;
|
extern _EMS_HeatPump EMS_HeatPump;
|
||||||
extern _EMS_Mixing EMS_Mixing;
|
extern _EMS_MixingModule EMS_MixingModule;
|
||||||
|
|
||||||
extern std::list<_Detected_Device> Devices;
|
extern std::list<_Detected_Device> Devices;
|
||||||
|
|||||||
Reference in New Issue
Block a user