добавляет HALightColorTemperatureBrightness
This commit is contained in:
parent
5ac3add676
commit
41d3f59207
@ -3,12 +3,13 @@
|
|||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <IRremoteESP8266.h>
|
#include <IRremoteESP8266.h>
|
||||||
#include <IRsend.h>
|
#include <IRsend.h>
|
||||||
#include <HALightBrightness.hpp>
|
#include <HALightColorTemperatureBrightness.hpp>
|
||||||
|
|
||||||
class IRLight: public HALightBrightnessController {
|
class IRLight: public HALightColorTemperatureBrightnessController {
|
||||||
private:
|
private:
|
||||||
bool state;
|
bool state;
|
||||||
short brightness;
|
short brightness;
|
||||||
|
byte color_temp;
|
||||||
|
|
||||||
IRsend *irsend;
|
IRsend *irsend;
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ private:
|
|||||||
680, 470, 580, 1620, 630, 470, 630, 1570, 630, 520, 580, 520,
|
680, 470, 580, 1620, 630, 470, 630, 1570, 630, 520, 580, 520,
|
||||||
630, 1570, 680, 1520, 730, 1520, 680};
|
630, 1570, 680, 1520, 730, 1520, 680};
|
||||||
|
|
||||||
const uint16_t RDCentralButton[67] = {
|
const uint16_t RDButtonCenter[67] = {
|
||||||
9030, 4320, 680, 470, 630, 470, 680, 420, 680, 470, 630, 470,
|
9030, 4320, 680, 470, 630, 470, 680, 420, 680, 470, 630, 470,
|
||||||
680, 420, 680, 470, 630, 1570, 680, 1520, 680, 1520, 680, 1520,
|
680, 420, 680, 470, 630, 1570, 680, 1520, 680, 1520, 680, 1520,
|
||||||
730, 1520, 680, 1520, 680, 1520, 680, 1570, 680, 420, 680, 1520,
|
730, 1520, 680, 1520, 680, 1520, 680, 1570, 680, 420, 680, 1520,
|
||||||
@ -51,9 +52,13 @@ private:
|
|||||||
630, 470, 630, 1570, 680, 470, 630, 470, 630, 470, 680, 470,
|
630, 470, 630, 1570, 680, 470, 630, 470, 630, 470, 680, 470,
|
||||||
630, 1570, 630, 1570, 680, 1570, 630};
|
630, 1570, 630, 1570, 680, 1570, 630};
|
||||||
|
|
||||||
|
const uint16_t RDButtonA[67] = {8980,4370, 630,470, 680,470, 630,470, 630,470, 630,520, 630,470, 630,470, 630,1620, 630,1570, 630,1620, 580,1570, 630,1620, 630,1570, 630,1570, 630,1570, 680,470, 630,1570, 630,1570, 630,1620, 630,470, 630,470, 630,470, 680,470, 630,470, 630,470, 680,470, 630,470, 630,1570, 630,1620, 630,1570, 630,1570, 630,1570, 630};
|
||||||
|
|
||||||
|
const uint16_t RDButtonB[67] = {9030,4320, 630,520, 580,520, 630,470, 630,470, 680,470, 580,520, 630,470, 680,1570, 630,1570, 630,1570, 630,1570, 630,1620, 580,1620, 630,1570, 630,1620, 580,520, 580,520, 630,470, 680,470, 630,1570, 630,470, 630,520, 580,520, 630,470, 630,1620, 630,1570, 630,1570, 630,470, 680,1570, 630,1570, 630,1570, 630,1570, 680};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IRLight(int pin);
|
explicit IRLight(int pin);
|
||||||
IRLight(IRsend *irsend);
|
explicit IRLight(IRsend *irsend);
|
||||||
|
|
||||||
void setState(bool state);
|
void setState(bool state);
|
||||||
bool getState();
|
bool getState();
|
||||||
@ -63,6 +68,9 @@ public:
|
|||||||
void setBrightness(int brightness);
|
void setBrightness(int brightness);
|
||||||
int getBrightness();
|
int getBrightness();
|
||||||
|
|
||||||
|
void setColorTemperature(int color);
|
||||||
|
int getColorTemperature();
|
||||||
|
|
||||||
void brightnessUp();
|
void brightnessUp();
|
||||||
void brightnessDown();
|
void brightnessDown();
|
||||||
int getBrightnessScale();
|
int getBrightnessScale();
|
||||||
|
@ -18,6 +18,12 @@ JSON_DOCUMENT_TYPE HALight::createConfigJSON() {
|
|||||||
doc["stat_t"] = "~/state";
|
doc["stat_t"] = "~/state";
|
||||||
doc["schema"] = "json";
|
doc["schema"] = "json";
|
||||||
|
|
||||||
|
patchConfigJSON(doc);
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_DOCUMENT_TYPE HALight::patchConfigJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,10 +36,16 @@ JSON_DOCUMENT_TYPE HALight::createStateJSON() {
|
|||||||
doc["state"] = "OFF";
|
doc["state"] = "OFF";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patchStateJSON(doc);
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HALight::innerHanlder(JSON_DOCUMENT_TYPE &doc) {
|
JSON_DOCUMENT_TYPE HALight::patchStateJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HALight::innerHandler(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
if (strcmp(doc["state"], "ON") == 0) {
|
if (strcmp(doc["state"], "ON") == 0) {
|
||||||
light->setState(true);
|
light->setState(true);
|
||||||
} else {
|
} else {
|
||||||
@ -65,7 +77,7 @@ void HALight::handle(char *topic, byte *payload, unsigned int length) {
|
|||||||
JSON_DOCUMENT_TYPE doc;
|
JSON_DOCUMENT_TYPE doc;
|
||||||
deserializeJson(doc, (const byte *)payload, length);
|
deserializeJson(doc, (const byte *)payload, length);
|
||||||
|
|
||||||
innerHanlder(doc);
|
innerHandler(doc);
|
||||||
|
|
||||||
sendState();
|
sendState();
|
||||||
}
|
}
|
@ -16,13 +16,15 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual JSON_DOCUMENT_TYPE createConfigJSON();
|
virtual JSON_DOCUMENT_TYPE createConfigJSON();
|
||||||
|
virtual JSON_DOCUMENT_TYPE patchConfigJSON(JSON_DOCUMENT_TYPE &doc);
|
||||||
virtual JSON_DOCUMENT_TYPE createStateJSON();
|
virtual JSON_DOCUMENT_TYPE createStateJSON();
|
||||||
virtual void innerHanlder(JSON_DOCUMENT_TYPE &doc);
|
virtual JSON_DOCUMENT_TYPE patchStateJSON(JSON_DOCUMENT_TYPE &doc);
|
||||||
|
virtual void innerHandler(const JSON_DOCUMENT_TYPE &doc);
|
||||||
HALight(PubSubClient &client, const char *name, const char *unique_id);
|
HALight(PubSubClient &client, const char *name, const char *unique_id);
|
||||||
public:
|
public:
|
||||||
HALight(PubSubClient &client, const char *name, const char *unique_id,
|
HALight(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
HALightController &baseLight);
|
HALightController &baseLight);
|
||||||
void handle(char *topic, byte *payload, unsigned int length);
|
void handle(char *topic, byte *payload, unsigned int length) override;
|
||||||
void sendConfig();
|
void sendConfig() override;
|
||||||
void sendState();
|
void sendState() override;
|
||||||
};
|
};
|
@ -3,35 +3,28 @@
|
|||||||
|
|
||||||
HALightBrightness::HALightBrightness(PubSubClient &client, const char *name, const char *unique_id,
|
HALightBrightness::HALightBrightness(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
HALightBrightnessController &baseLight)
|
HALightBrightnessController &baseLight)
|
||||||
: HALight(client, "light", name, baseLight),
|
: HALight(client, name, unique_id, baseLight), light(&baseLight) {}
|
||||||
light(&baseLight) {}
|
|
||||||
|
|
||||||
|
|
||||||
JSON_DOCUMENT_TYPE HALightBrightness::createConfigJSON() {
|
JSON_DOCUMENT_TYPE HALightBrightness::patchConfigJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
JSON_DOCUMENT_TYPE doc = HALight::createConfigJSON();
|
|
||||||
|
|
||||||
doc["brightness"] = true;
|
doc["brightness"] = true;
|
||||||
doc["brightness_scale"] = light->getBrightnessScale();
|
doc["brightness_scale"] = light->getBrightnessScale();
|
||||||
// doc["color_mode"] = true;
|
|
||||||
// doc["supported_color_modes"] =
|
|
||||||
|
|
||||||
// JSON_DOCUMENT_TYPE doc;
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_DOCUMENT_TYPE HALightBrightness::createStateJSON() {
|
JSON_DOCUMENT_TYPE HALightBrightness::patchStateJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
JSON_DOCUMENT_TYPE doc = HALight::createStateJSON();
|
|
||||||
|
|
||||||
doc["brightness"] = light->getBrightness();
|
doc["brightness"] = light->getBrightness();
|
||||||
|
|
||||||
// JSON_DOCUMENT_TYPE doc;
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HALightBrightness::innerHanlder(JSON_DOCUMENT_TYPE &doc) {
|
void HALightBrightness::handleBrightness(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
if (doc.containsKey("brightness")) {
|
if (doc.containsKey("brightness")) {
|
||||||
light->setBrightness(doc["brightness"]);
|
light->setBrightness(doc["brightness"]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HALightBrightness::innerHandler(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
handleBrightness(doc);
|
||||||
delay(50);
|
delay(50);
|
||||||
HALight::innerHanlder(doc);
|
HALight::innerHandler(doc);
|
||||||
}
|
}
|
@ -2,23 +2,25 @@
|
|||||||
|
|
||||||
#include <HALight.hpp>
|
#include <HALight.hpp>
|
||||||
|
|
||||||
class HALightBrightnessController: public HALightController {
|
class HALightBrightnessController: public virtual HALightController {
|
||||||
public:
|
public:
|
||||||
virtual void setBrightness(int value) = 0;
|
virtual void setBrightness(int value) = 0;
|
||||||
virtual int getBrightness() = 0;
|
virtual int getBrightness() = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual int getBrightnessScale() = 0;
|
virtual int getBrightnessScale() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HALightBrightness : public HALight {
|
class HALightBrightness : public virtual HALight {
|
||||||
private:
|
private:
|
||||||
HALightBrightnessController *light;
|
HALightBrightnessController *light;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
JSON_DOCUMENT_TYPE createConfigJSON() override;
|
virtual JSON_DOCUMENT_TYPE patchConfigJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
JSON_DOCUMENT_TYPE createStateJSON() override;
|
virtual JSON_DOCUMENT_TYPE patchStateJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
void innerHanlder(JSON_DOCUMENT_TYPE &doc) override;
|
virtual void innerHandler(const JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
|
||||||
|
void handleBrightness(const JSON_DOCUMENT_TYPE &doc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HALightBrightness(PubSubClient &client, const char *name, const char *unique_id,
|
HALightBrightness(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
HALightBrightnessController &baseLight);
|
HALightBrightnessController &baseLight);
|
||||||
|
28
lib/HomeAssistantDevices/HALightColorTemperature.cpp
Normal file
28
lib/HomeAssistantDevices/HALightColorTemperature.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <HALightColorTemperature.hpp>
|
||||||
|
|
||||||
|
HALightColorTemperature::HALightColorTemperature(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
|
HALightColorTemperatureController &baseLight)
|
||||||
|
: HALight(client, "light", name, baseLight),
|
||||||
|
light(&baseLight) {}
|
||||||
|
|
||||||
|
JSON_DOCUMENT_TYPE HALightColorTemperature::patchConfigJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
doc["color_temp"] = true;
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_DOCUMENT_TYPE HALightColorTemperature::patchStateJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
doc["color_temp"] = light->getColorTemperature();
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HALightColorTemperature::handleColorTemperature(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
if (doc.containsKey("color_temp")) {
|
||||||
|
light->setColorTemperature(doc["color_temp"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HALightColorTemperature::innerHandler(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
handleColorTemperature(doc);
|
||||||
|
delay(50);
|
||||||
|
HALight::innerHandler(doc);
|
||||||
|
}
|
26
lib/HomeAssistantDevices/HALightColorTemperature.hpp
Normal file
26
lib/HomeAssistantDevices/HALightColorTemperature.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <HALight.hpp>
|
||||||
|
|
||||||
|
class HALightColorTemperatureController: public virtual HALightController {
|
||||||
|
public:
|
||||||
|
virtual void setColorTemperature(int value) = 0;
|
||||||
|
virtual int getColorTemperature() = 0;
|
||||||
|
|
||||||
|
virtual int getBrightnessScale() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HALightColorTemperature : public virtual HALight {
|
||||||
|
private:
|
||||||
|
HALightColorTemperatureController *light;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual JSON_DOCUMENT_TYPE patchConfigJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
virtual JSON_DOCUMENT_TYPE patchStateJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
virtual void innerHandler(const JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
|
||||||
|
void handleColorTemperature(const JSON_DOCUMENT_TYPE &doc);
|
||||||
|
public:
|
||||||
|
HALightColorTemperature(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
|
HALightColorTemperatureController &baseLight);
|
||||||
|
};
|
@ -0,0 +1,34 @@
|
|||||||
|
#include <HALightColorTemperatureBrightness.hpp>
|
||||||
|
|
||||||
|
HALightColorTemperatureBrightness::HALightColorTemperatureBrightness(
|
||||||
|
PubSubClient &client,
|
||||||
|
const char *name,
|
||||||
|
const char *unique_id,
|
||||||
|
HALightColorTemperatureBrightnessController &baseLight
|
||||||
|
) :
|
||||||
|
HALightBrightness(client, name, unique_id, baseLight),
|
||||||
|
HALightColorTemperature(client, name, unique_id, baseLight),
|
||||||
|
HALight(client, name, unique_id, baseLight),
|
||||||
|
light(&baseLight)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_DOCUMENT_TYPE HALightColorTemperatureBrightness::patchConfigJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
HALightBrightness::patchConfigJSON(doc);
|
||||||
|
HALightColorTemperature::patchConfigJSON(doc);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON_DOCUMENT_TYPE HALightColorTemperatureBrightness::patchStateJSON(JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
HALightBrightness::patchStateJSON(doc);
|
||||||
|
HALightColorTemperature::patchStateJSON(doc);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HALightColorTemperatureBrightness::innerHandler(const JSON_DOCUMENT_TYPE &doc) {
|
||||||
|
handleBrightness(doc);
|
||||||
|
delay(50);
|
||||||
|
handleColorTemperature(doc);
|
||||||
|
delay(50);
|
||||||
|
HALight::innerHandler(doc);
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <HALightBrightness.hpp>
|
||||||
|
#include <HALightColorTemperature.hpp>
|
||||||
|
|
||||||
|
class HALightColorTemperatureBrightnessController:
|
||||||
|
public HALightBrightnessController,
|
||||||
|
public HALightColorTemperatureController
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class HALightColorTemperatureBrightness :
|
||||||
|
public HALightBrightness,
|
||||||
|
public HALightColorTemperature
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HALightColorTemperatureBrightnessController *light;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
JSON_DOCUMENT_TYPE patchConfigJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
JSON_DOCUMENT_TYPE patchStateJSON(JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
virtual void innerHandler(const JSON_DOCUMENT_TYPE &doc) override;
|
||||||
|
public:
|
||||||
|
HALightColorTemperatureBrightness(PubSubClient &client, const char *name, const char *unique_id,
|
||||||
|
HALightColorTemperatureBrightnessController &baseLight);
|
||||||
|
};
|
@ -1,4 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <HALight.hpp>
|
#include <HALight.hpp>
|
||||||
#include <HALightBrightness.hpp>
|
#include <HALightBrightness.hpp>
|
||||||
|
#include <HALightColorTemperature.hpp>
|
||||||
|
#include <HALightColorTemperatureBrightness.hpp>
|
@ -42,6 +42,35 @@ void IRLight::setBrightness(int newBrightness) {
|
|||||||
brightness = newBrightness;
|
brightness = newBrightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRLight::setColorTemperature(int color) {
|
||||||
|
if (color < 208) {
|
||||||
|
color_temp = 2;
|
||||||
|
brightness = 14;
|
||||||
|
irsend->sendRaw(RDButtonB, 67, 38);
|
||||||
|
} else if (color < 294) {
|
||||||
|
color_temp = 1;
|
||||||
|
brightness = 14;
|
||||||
|
irsend->sendRaw(RDButtonCenter, 67, 38);
|
||||||
|
} else {
|
||||||
|
color_temp = 0;
|
||||||
|
brightness = 14;
|
||||||
|
irsend->sendRaw(RDButtonA, 67, 38);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int IRLight::getColorTemperature() {
|
||||||
|
switch (color_temp)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return 370;
|
||||||
|
case 1:
|
||||||
|
return 262;
|
||||||
|
case 2:
|
||||||
|
return 154;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void IRLight::brightnessUp() {
|
void IRLight::brightnessUp() {
|
||||||
if (brightness < getBrightnessScale()) {
|
if (brightness < getBrightnessScale()) {
|
||||||
brightness++;
|
brightness++;
|
||||||
@ -58,8 +87,9 @@ void IRLight::brightnessDown() {
|
|||||||
|
|
||||||
void IRLight::begin() {
|
void IRLight::begin() {
|
||||||
irsend->begin();
|
irsend->begin();
|
||||||
irsend->sendRaw(RDCentralButton, 67, 38);
|
|
||||||
brightness = 14;
|
brightness = 14;
|
||||||
|
color_temp = 1;
|
||||||
|
irsend->sendRaw(RDButtonCenter, 67, 38);
|
||||||
delay(250);
|
delay(250);
|
||||||
off();
|
off();
|
||||||
}
|
}
|
||||||
|
15
src/main.cpp
15
src/main.cpp
@ -55,8 +55,9 @@ PubSubClient client(espClient);
|
|||||||
DHT dht(DHTPIN, DHTTYPE);
|
DHT dht(DHTPIN, DHTTYPE);
|
||||||
|
|
||||||
IRLight irlight(4);
|
IRLight irlight(4);
|
||||||
HALightBrightness halight(client, "light", "l-1", irlight);
|
HALightColorTemperatureBrightness halight(client, "light", "l-1", irlight);
|
||||||
|
|
||||||
|
void setup_devices();
|
||||||
void setup_wifi();
|
void setup_wifi();
|
||||||
void setup_time();
|
void setup_time();
|
||||||
void setup_mqtt();
|
void setup_mqtt();
|
||||||
@ -76,9 +77,7 @@ void setup()
|
|||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
irlight.begin();
|
setup_devices();
|
||||||
dht.begin();
|
|
||||||
|
|
||||||
setup_wifi();
|
setup_wifi();
|
||||||
setup_time();
|
setup_time();
|
||||||
setup_mqtt();
|
setup_mqtt();
|
||||||
@ -110,6 +109,12 @@ void loop()
|
|||||||
delay(100);
|
delay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup_devices()
|
||||||
|
{
|
||||||
|
irlight.begin();
|
||||||
|
dht.begin();
|
||||||
|
}
|
||||||
|
|
||||||
void setup_wifi()
|
void setup_wifi()
|
||||||
{
|
{
|
||||||
delay(10);
|
delay(10);
|
||||||
@ -192,8 +197,6 @@ void reconnect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int unused = 0;
|
|
||||||
|
|
||||||
void mqtt_callback(char *topic, byte *payload, unsigned int length)
|
void mqtt_callback(char *topic, byte *payload, unsigned int length)
|
||||||
{
|
{
|
||||||
Serial.print("Message arrived [");
|
Serial.print("Message arrived [");
|
||||||
|
Loading…
Reference in New Issue
Block a user