cleaned user settings function
This commit is contained in:
114
src/IRbaby.cpp
114
src/IRbaby.cpp
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
* Copyright (c) 2020-2022 IRbaby-IRext
|
||||||
*
|
*
|
||||||
* Author: Strawmanbobi and Caffreyfans
|
* Author: Strawmanbobi and Caffreyfans
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@@ -23,31 +23,24 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Ticker.h>
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <LittleFS.h>
|
||||||
|
#include <Ticker.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "IRbabyIR.h"
|
#include "IRbabyIR.h"
|
||||||
#include "IRbabyOTA.h"
|
#include "IRbabyAlink.h"
|
||||||
|
|
||||||
#if defined USE_IRBABY_MQTT
|
|
||||||
#include "IRbabyMQTT.h"
|
|
||||||
#else
|
|
||||||
#include "IRbabyAlink.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "IRbabyMsgHandler.h"
|
|
||||||
#include "IRbabyGlobal.h"
|
|
||||||
#include "IRbabyUserSettings.h"
|
|
||||||
#include "IRbabyHttp.h"
|
#include "IRbabyHttp.h"
|
||||||
|
#include "IRbabyGlobal.h"
|
||||||
#include "IRbabyIRIS.h"
|
#include "IRbabyIRIS.h"
|
||||||
#include "IRbabyRF.h"
|
#include "IRbabySerial.h"
|
||||||
|
#include "IRbabyUserSettings.h"
|
||||||
|
|
||||||
#include "IRbaby.h"
|
#include "IRbaby.h"
|
||||||
|
|
||||||
#define CREDENTIAL_INIT_RETRY_MAX (3)
|
#define CREDENTIAL_INIT_RETRY_MAX (3)
|
||||||
|
|
||||||
|
// external variable declarations
|
||||||
extern char iris_server_address[];
|
extern char iris_server_address[];
|
||||||
extern char iris_credential_token[];
|
extern char iris_credential_token[];
|
||||||
|
|
||||||
@@ -55,25 +48,22 @@ extern String g_product_key;
|
|||||||
extern String g_device_name;
|
extern String g_device_name;
|
||||||
extern String g_device_secret;
|
extern String g_device_secret;
|
||||||
|
|
||||||
|
|
||||||
|
// public variable definitions
|
||||||
int credential_init_retry = 0;
|
int credential_init_retry = 0;
|
||||||
|
|
||||||
|
|
||||||
void uploadIP(); // device info upload to devicehive
|
|
||||||
void IRAM_ATTR resetHandle(); // interrupt handle
|
|
||||||
|
|
||||||
#if defined USE_IRBABY_MQTT
|
// private variable definitions
|
||||||
Ticker mqttCheckTask; // MQTT check timer
|
static Ticker alinkCheckTask; // Aliyun IoT MQTT check timer
|
||||||
#else
|
static Ticker disableIRTask; // disable IR receive
|
||||||
Ticker alinkCheckTask; // Aliyun IoT MQTT check timer
|
static Ticker disableRFTask; // disable RF receive
|
||||||
#endif
|
static Ticker saveDataTask; // save data
|
||||||
|
|
||||||
Ticker disableIRTask; // disable IR receive
|
// private function declarations
|
||||||
Ticker disableRFTask; // disable RF receive
|
static void wifiReset();
|
||||||
Ticker saveDataTask; // save data
|
|
||||||
|
|
||||||
// LSOC DAS2 related tasks
|
|
||||||
Ticker lsocHeartBeatTask; // lsoc heart beat sync
|
|
||||||
|
|
||||||
|
// public function definitions
|
||||||
void setup() {
|
void setup() {
|
||||||
if (LOG_DEBUG || LOG_ERROR || LOG_INFO) {
|
if (LOG_DEBUG || LOG_ERROR || LOG_INFO) {
|
||||||
Serial.begin(BAUD_RATE);
|
Serial.begin(BAUD_RATE);
|
||||||
@@ -82,7 +72,7 @@ void setup() {
|
|||||||
pinMode(RESET_PIN, INPUT_PULLUP);
|
pinMode(RESET_PIN, INPUT_PULLUP);
|
||||||
pinMode(0, OUTPUT);
|
pinMode(0, OUTPUT);
|
||||||
digitalWrite(0, LOW);
|
digitalWrite(0, LOW);
|
||||||
attachInterrupt(digitalPinToInterrupt(RESET_PIN), resetHandle, ONLOW);
|
attachInterrupt(digitalPinToInterrupt(RESET_PIN), factoryReset, ONLOW);
|
||||||
|
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
@@ -97,13 +87,11 @@ void setup() {
|
|||||||
INFOLN("== IRIS Kit [1.2.7] Powered by IRBaby ==");
|
INFOLN("== IRIS Kit [1.2.7] Powered by IRBaby ==");
|
||||||
|
|
||||||
// custom parameter for iris credentials
|
// custom parameter for iris credentials
|
||||||
|
WiFiManagerParameter server_address("server", "Server", "", URL_SHORT_MAX);
|
||||||
WiFiManagerParameter server_address("server", "Server", "http://192.168.2.31:8081", URL_SHORT_MAX);
|
|
||||||
WiFiManagerParameter credential_token("credential", "Credential", "", CREDENTIAL_MAX);
|
WiFiManagerParameter credential_token("credential", "Credential", "", CREDENTIAL_MAX);
|
||||||
|
|
||||||
wifi_manager.addParameter(&server_address);
|
wifi_manager.addParameter(&server_address);
|
||||||
wifi_manager.addParameter(&credential_token);
|
wifi_manager.addParameter(&credential_token);
|
||||||
|
|
||||||
wifi_manager.autoConnect();
|
wifi_manager.autoConnect();
|
||||||
|
|
||||||
memset(iris_server_address, 0, URL_SHORT_MAX);
|
memset(iris_server_address, 0, URL_SHORT_MAX);
|
||||||
@@ -113,10 +101,10 @@ void setup() {
|
|||||||
strcpy(iris_credential_token, credential_token.getValue());
|
strcpy(iris_credential_token, credential_token.getValue());
|
||||||
|
|
||||||
INFOF("Wifi Connected, IRIS server = %s, credential token = %s\n",
|
INFOF("Wifi Connected, IRIS server = %s, credential token = %s\n",
|
||||||
iris_server_address, iris_credential_token);
|
iris_server_address, iris_credential_token);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(WiFi.status()== WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
if (0 == fetchIrisCredential(iris_credential_token,
|
if (0 == fetchIrisCredential(iris_credential_token,
|
||||||
g_product_key,
|
g_product_key,
|
||||||
g_device_name,
|
g_device_name,
|
||||||
@@ -127,67 +115,27 @@ void setup() {
|
|||||||
credential_init_retry++;
|
credential_init_retry++;
|
||||||
if (credential_init_retry >= CREDENTIAL_INIT_RETRY_MAX) {
|
if (credential_init_retry >= CREDENTIAL_INIT_RETRY_MAX) {
|
||||||
ERRORLN("retried fetch credential for 3 times, reset WiFi");
|
ERRORLN("retried fetch credential for 3 times, reset WiFi");
|
||||||
wifiReset();
|
factoryReset();
|
||||||
}
|
}
|
||||||
delay(1000);
|
delay(1000);
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
INFOF("credential get : %s\n", iris_credential_token);
|
INFOF("credential get : %s\n", iris_credential_token);
|
||||||
|
|
||||||
settingsLoad(); // load user settings form fs
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
connectToAliyunIoT();
|
connectToAliyunIoT();
|
||||||
#ifdef USE_RF
|
|
||||||
initRF(); // RF init
|
|
||||||
#endif
|
|
||||||
loadIRPin(ConfigData["pin"]["ir_send"], ConfigData["pin"]["ir_receive"]);
|
loadIRPin(ConfigData["pin"]["ir_send"], ConfigData["pin"]["ir_receive"]);
|
||||||
|
|
||||||
#if defined USE_IRBABY_MQTT
|
|
||||||
mqttCheckTask.attach_scheduled(MQTT_CHECK_INTERVALS, mqttCheck);
|
|
||||||
#else
|
|
||||||
alinkCheckTask.attach_scheduled(MQTT_CHECK_INTERVALS, checkAlinkMQTT);
|
alinkCheckTask.attach_scheduled(MQTT_CHECK_INTERVALS, checkAlinkMQTT);
|
||||||
#endif
|
|
||||||
disableIRTask.attach_scheduled(DISABLE_SIGNAL_INTERVALS, disableIR);
|
disableIRTask.attach_scheduled(DISABLE_SIGNAL_INTERVALS, disableIR);
|
||||||
disableRFTask.attach_scheduled(DISABLE_SIGNAL_INTERVALS, disableRF);
|
|
||||||
saveDataTask.attach_scheduled(SAVE_DATA_INTERVALS, settingsSave);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wifiReset() {
|
|
||||||
WiFi.disconnect();
|
|
||||||
ESP.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
/* IR receive */
|
|
||||||
recvIR();
|
recvIR();
|
||||||
#ifdef USE_RF
|
|
||||||
/* RF receive */
|
|
||||||
recvRF();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* UDP receive and handle */
|
|
||||||
char *msg = udpRecive();
|
|
||||||
if (msg) {
|
|
||||||
udp_msg_doc.clear();
|
|
||||||
DeserializationError error = deserializeJson(udp_msg_doc, msg);
|
|
||||||
if (error) {
|
|
||||||
ERRORLN("Failed to parse udp message");
|
|
||||||
}
|
|
||||||
msgHandle(&udp_msg_doc, MsgType::udp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined USE_IRBABY_MQTT
|
|
||||||
/* MQTT loop */
|
|
||||||
mqttLoop();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetHandle() {
|
void factoryReset() {
|
||||||
static unsigned long last_interrupt_time = millis();
|
static unsigned long last_interrupt_time = millis();
|
||||||
unsigned long interrupt_time = millis();
|
unsigned long interrupt_time = millis();
|
||||||
static unsigned long start_time = millis();
|
static unsigned long start_time = millis();
|
||||||
@@ -197,6 +145,16 @@ void resetHandle() {
|
|||||||
}
|
}
|
||||||
last_interrupt_time = interrupt_time;
|
last_interrupt_time = interrupt_time;
|
||||||
if (end_time - start_time > 3000) {
|
if (end_time - start_time > 3000) {
|
||||||
settingsClear();
|
factoryReset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// private function defitions
|
||||||
|
static void wifiReset() {
|
||||||
|
DEBUGLN("\nReset settings");
|
||||||
|
wifi_manager.resetSettings();
|
||||||
|
LittleFS.format();
|
||||||
|
ESP.reset();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
* Copyright (c) 2020-2022 IRbaby-IRext
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
@@ -24,6 +24,6 @@
|
|||||||
#ifndef IRBABY_H
|
#ifndef IRBABY_H
|
||||||
#define IRBABY_H
|
#define IRBABY_H
|
||||||
|
|
||||||
void wifiReset();
|
void IRAM_ATTR factoryReset();
|
||||||
|
|
||||||
#endif // IRBABY_H
|
#endif // IRBABY_H
|
||||||
@@ -52,10 +52,11 @@ static void sendIrisKitHeartBeat();
|
|||||||
void connectToAliyunIoT() {
|
void connectToAliyunIoT() {
|
||||||
INFOF("Try connecting to Aliyun IoT : %s, %s, %s, %s\n",
|
INFOF("Try connecting to Aliyun IoT : %s, %s, %s, %s\n",
|
||||||
g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(), g_region_id.c_str());
|
g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(), g_region_id.c_str());
|
||||||
iot.begin(wifi_client, g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(), g_region_id.c_str());
|
iot.begin(wifi_client, g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(),
|
||||||
|
g_region_id.c_str());
|
||||||
INFOLN("Aliyun IoT connect done");
|
INFOLN("Aliyun IoT connect done");
|
||||||
snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream",
|
snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream",
|
||||||
g_product_key.c_str(), g_device_name.c_str());
|
g_product_key.c_str(), g_device_name.c_str());
|
||||||
registerCallback();
|
registerCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ void checkAlinkMQTT() {
|
|||||||
}
|
}
|
||||||
if (iot_retry >= IOT_RETRY_MAX) {
|
if (iot_retry >= IOT_RETRY_MAX) {
|
||||||
ERRORLN("Alink could not established, something went wrong, reset...");
|
ERRORLN("Alink could not established, something went wrong, reset...");
|
||||||
wifiReset();
|
factoryReset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
* Copyright (c) 2020-2022 IRbaby-IRext
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
|
|
||||||
#include "IRbabyHttp.h"
|
#include "IRbabyHttp.h"
|
||||||
|
|
||||||
#define FETCH_CREDENTIAL_SUFFIX "/irext-collect/credentials/fetch_credential"
|
#define FETCH_CREDENTIAL_SUFFIX "/irext-collect/credentials/fetch_credential"
|
||||||
|
#define LOAD_ALIOT_ACCOUNT_SUFFIX "/irext-collect/aliot/load_account"
|
||||||
#define DOWNLOAD_PREFIX "http://irext-debug.oss-cn-hangzhou.aliyuncs.com/irda_"
|
#define DOWNLOAD_PREFIX "http://irext-debug.oss-cn-hangzhou.aliyuncs.com/irda_"
|
||||||
#define DOWNLOAD_SUFFIX ".bin"
|
#define DOWNLOAD_SUFFIX ".bin"
|
||||||
|
|
||||||
@@ -52,13 +53,13 @@ int fetchIrisCredential(String credential_token,
|
|||||||
String& device_secret) {
|
String& device_secret) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
String device_sn("IRbaby_");
|
String device_id("IRbaby_");
|
||||||
String fetch_credential_url(iris_server_address);
|
String fetch_credential_url(iris_server_address);
|
||||||
HTTPClient http_client;
|
HTTPClient http_client;
|
||||||
int tsi = 0;
|
int tsi = 0;
|
||||||
int response_code = 0;
|
int response_code = 0;
|
||||||
fetch_credential_url.concat(String(FETCH_CREDENTIAL_SUFFIX));
|
fetch_credential_url.concat(String(FETCH_CREDENTIAL_SUFFIX));
|
||||||
device_sn.concat(String(ESP.getChipId(), HEX));
|
device_id.concat(String(ESP.getChipId(), HEX));
|
||||||
|
|
||||||
INFOF("fetch credential URL = %s\n", fetch_credential_url.c_str());
|
INFOF("fetch credential URL = %s\n", fetch_credential_url.c_str());
|
||||||
if (credential_token.isEmpty()) {
|
if (credential_token.isEmpty()) {
|
||||||
@@ -76,7 +77,7 @@ int fetchIrisCredential(String credential_token,
|
|||||||
http_client.begin(wifi_client, fetch_credential_url);
|
http_client.begin(wifi_client, fetch_credential_url);
|
||||||
http_client.addHeader("Content-Type", "application/json");
|
http_client.addHeader("Content-Type", "application/json");
|
||||||
http_request_doc.clear();
|
http_request_doc.clear();
|
||||||
http_request_doc["endpointSN"] = device_sn;
|
http_request_doc["deviceID"] = device_id;
|
||||||
http_request_doc["credentialToken"] = credential_token;
|
http_request_doc["credentialToken"] = credential_token;
|
||||||
String request_data = "";
|
String request_data = "";
|
||||||
serializeJson(http_request_doc, request_data);
|
serializeJson(http_request_doc, request_data);
|
||||||
@@ -91,7 +92,7 @@ int fetchIrisCredential(String credential_token,
|
|||||||
String ds = http_response_doc["entity"];
|
String ds = http_response_doc["entity"];
|
||||||
device_secret = ds;
|
device_secret = ds;
|
||||||
INFOF("HTTP response deserialized, PK = %s, DN = %s, DS = %s\n",
|
INFOF("HTTP response deserialized, PK = %s, DN = %s, DS = %s\n",
|
||||||
product_key.c_str(), device_name.c_str(), device_secret.c_str());
|
product_key.c_str(), device_name.c_str(), device_secret.c_str());
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,6 @@ int fetchIrisCredential(String credential_token,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void downLoadFile(String file, String path) {
|
void downLoadFile(String file, String path) {
|
||||||
HTTPClient http_client;
|
HTTPClient http_client;
|
||||||
String download_url = DOWNLOAD_PREFIX + file + DOWNLOAD_SUFFIX;
|
String download_url = DOWNLOAD_PREFIX + file + DOWNLOAD_SUFFIX;
|
||||||
|
|||||||
@@ -1,266 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <LittleFS.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
#include "IRbabyMsgHandler.h"
|
|
||||||
#include "IRbabySerial.h"
|
|
||||||
#include "IRbabyUserSettings.h"
|
|
||||||
#include "ESP8266WiFi.h"
|
|
||||||
#include "IRbabyIR.h"
|
|
||||||
#include "IRbabyOTA.h"
|
|
||||||
#include "IRbabyRF.h"
|
|
||||||
#include "IRbabyGlobal.h"
|
|
||||||
#include "IRbabyha.h"
|
|
||||||
|
|
||||||
#include "ir_ac_control.h"
|
|
||||||
|
|
||||||
bool msgHandle(StaticJsonDocument<1024> *p_recv_msg_doc, MsgType msg_type) {
|
|
||||||
if (LOG_DEBUG) {
|
|
||||||
serializeJsonPretty(*p_recv_msg_doc, Serial);
|
|
||||||
Serial.println();
|
|
||||||
}
|
|
||||||
JsonObject obj = p_recv_msg_doc->as<JsonObject>();
|
|
||||||
String cmd = obj["cmd"];
|
|
||||||
JsonObject params = obj["params"];
|
|
||||||
send_msg_doc.clear();
|
|
||||||
|
|
||||||
if (cmd.equalsIgnoreCase("query")) {
|
|
||||||
String type = params["type"];
|
|
||||||
if (type.equals("discovery")) {
|
|
||||||
String chip_id = String(ESP.getChipId(), HEX);
|
|
||||||
chip_id.toUpperCase();
|
|
||||||
send_msg_doc["cmd"] = "query_discovery";
|
|
||||||
send_msg_doc["params"]["ip"] = WiFi.localIP().toString();
|
|
||||||
send_msg_doc["params"]["mac"] = chip_id;
|
|
||||||
|
|
||||||
if (ConfigData.containsKey("mqtt")) {
|
|
||||||
send_msg_doc["params"]["mqtt"] = ConfigData["mqtt"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigData.containsKey("pin")) {
|
|
||||||
send_msg_doc["params"]["pin"] = ConfigData["pin"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigData.containsKey("version")) {
|
|
||||||
send_msg_doc["params"]["version"] = ConfigData["version"];
|
|
||||||
}
|
|
||||||
|
|
||||||
String ip = obj["params"]["ip"];
|
|
||||||
// remote_ip.fromString(ip);
|
|
||||||
// sendUDP(&send_msg_doc, remote_ip);
|
|
||||||
} else if (type.equals("info")) {
|
|
||||||
String free_mem = String(ESP.getFreeHeap() / 1024) + "KB";
|
|
||||||
String chip_id = String(ESP.getChipId(), HEX);
|
|
||||||
chip_id.toUpperCase();
|
|
||||||
String cpu_freq = String(ESP.getCpuFreqMHz()) + "MHz";
|
|
||||||
String flash_speed = String(ESP.getFlashChipSpeed() / 1000000);
|
|
||||||
String flash_size = String(ESP.getFlashChipSize() / 1024) + "KB";
|
|
||||||
String sketch_size = String(ESP.getSketchSize() / 1024) + "KB";
|
|
||||||
String reset_reason = ESP.getResetReason();
|
|
||||||
String sketch_space = String(ESP.getFreeSketchSpace() / 1024) + "KB";
|
|
||||||
FSInfo fsinfo;
|
|
||||||
LittleFS.info(fsinfo);
|
|
||||||
String fs_total_bytes = String(fsinfo.totalBytes / 1024) + "KB";
|
|
||||||
String fs_used_bytes = String(fsinfo.usedBytes / 1024) + "KB";
|
|
||||||
send_msg_doc["cmd"] = "query_info";
|
|
||||||
send_msg_doc["params"]["free_mem"] = free_mem;
|
|
||||||
send_msg_doc["params"]["chip_id"] = chip_id;
|
|
||||||
send_msg_doc["params"]["cpu_freq"] = cpu_freq;
|
|
||||||
send_msg_doc["params"]["flash_speed"] = flash_speed;
|
|
||||||
send_msg_doc["params"]["flash_size"] = flash_size;
|
|
||||||
send_msg_doc["params"]["reset_reason"] = reset_reason;
|
|
||||||
send_msg_doc["params"]["sketch_space"] = sketch_space;
|
|
||||||
send_msg_doc["params"]["fs_total_bytes"] = fs_total_bytes;
|
|
||||||
send_msg_doc["params"]["fs_used_bytes"] = fs_used_bytes;
|
|
||||||
send_msg_doc["params"]["version_name"] = FIRMWARE_VERSION;
|
|
||||||
send_msg_doc["params"]["version_code"] = VERSION_CODE;
|
|
||||||
// returnUDP(&send_msg_doc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd.equalsIgnoreCase("send")) {
|
|
||||||
String signal = params["signal"];
|
|
||||||
String type = params["type"];
|
|
||||||
|
|
||||||
if (signal.equalsIgnoreCase("ir")) {
|
|
||||||
if (type.equalsIgnoreCase("status")) {
|
|
||||||
String file = params["file"];
|
|
||||||
JsonObject statusJson = params[type];
|
|
||||||
t_remote_ac_status ac_status;
|
|
||||||
ac_status.ac_power = t_ac_power((int)statusJson["power"]);
|
|
||||||
ac_status.ac_temp = t_ac_temperature((int)statusJson["temperature"]);
|
|
||||||
ac_status.ac_mode = t_ac_mode((int)statusJson["mode"]);
|
|
||||||
ac_status.ac_swing = t_ac_swing((int)statusJson["swing"]);
|
|
||||||
ac_status.ac_wind_speed = t_ac_wind_speed((int)statusJson["speed"]);
|
|
||||||
ac_status.ac_display = 1;
|
|
||||||
ac_status.ac_timer = 0;
|
|
||||||
ac_status.ac_sleep = 0;
|
|
||||||
sendStatus(file, ac_status);
|
|
||||||
returnACStatus(file, ac_status);
|
|
||||||
} else if (type.equalsIgnoreCase("file")) {
|
|
||||||
String file = params["file"];
|
|
||||||
sendIR(file);
|
|
||||||
} else if (type.equalsIgnoreCase("key")) {
|
|
||||||
String file = params["file"];
|
|
||||||
} else if (type.equalsIgnoreCase("data")) {
|
|
||||||
} else if (type.equalsIgnoreCase("local")) {
|
|
||||||
String file = params["file"];
|
|
||||||
JsonObject localobj = params[type];
|
|
||||||
if (!ACStatus.containsKey(file)) {
|
|
||||||
initAC(file);
|
|
||||||
}
|
|
||||||
t_remote_ac_status ac_status = getACState(file);
|
|
||||||
if (localobj.containsKey("mode")) {
|
|
||||||
String mode = localobj["mode"];
|
|
||||||
if (mode.equalsIgnoreCase("off"))
|
|
||||||
ac_status.ac_power = AC_POWER_OFF;
|
|
||||||
else
|
|
||||||
ac_status.ac_power = AC_POWER_ON;
|
|
||||||
|
|
||||||
if (mode.equalsIgnoreCase("cool"))
|
|
||||||
ac_status.ac_mode = AC_MODE_COOL;
|
|
||||||
else if (mode.equalsIgnoreCase("heat"))
|
|
||||||
ac_status.ac_mode = AC_MODE_HEAT;
|
|
||||||
else if (mode.equalsIgnoreCase("auto"))
|
|
||||||
ac_status.ac_mode = AC_MODE_AUTO;
|
|
||||||
else if (mode.equalsIgnoreCase("fan") || mode.equalsIgnoreCase("fan_only"))
|
|
||||||
ac_status.ac_mode = AC_MODE_FAN;
|
|
||||||
else if (mode.equalsIgnoreCase("dry"))
|
|
||||||
ac_status.ac_mode = AC_MODE_DRY;
|
|
||||||
} else if (localobj.containsKey("temperature")) {
|
|
||||||
String temperature = localobj["temperature"];
|
|
||||||
ac_status.ac_temp = (t_ac_temperature)(temperature.toInt() - 16);
|
|
||||||
} else if (localobj.containsKey("fan")) {
|
|
||||||
String fan = localobj["fan"];
|
|
||||||
if (fan.equalsIgnoreCase("auto"))
|
|
||||||
ac_status.ac_wind_speed = AC_WS_AUTO;
|
|
||||||
else if (fan.equalsIgnoreCase("low"))
|
|
||||||
ac_status.ac_wind_speed = AC_WS_LOW;
|
|
||||||
else if (fan.equalsIgnoreCase("medium"))
|
|
||||||
ac_status.ac_wind_speed = AC_WS_MEDIUM;
|
|
||||||
else if (fan.equalsIgnoreCase("high"))
|
|
||||||
ac_status.ac_wind_speed = AC_WS_HIGH;
|
|
||||||
} else if (localobj.containsKey("swing")) {
|
|
||||||
String swing = localobj["swing"];
|
|
||||||
if (swing.equalsIgnoreCase("on"))
|
|
||||||
ac_status.ac_swing = AC_SWING_ON;
|
|
||||||
else if (swing.equalsIgnoreCase("off"))
|
|
||||||
ac_status.ac_swing = AC_SWING_OFF;
|
|
||||||
}
|
|
||||||
sendStatus(file, ac_status);
|
|
||||||
returnACStatus(file, ac_status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef USE_RF
|
|
||||||
else if (signal.equalsIgnoreCase("rf315")) {
|
|
||||||
RFTYPE rf_type;
|
|
||||||
|
|
||||||
rf_type = RF315;
|
|
||||||
if (type.equalsIgnoreCase("data")) {
|
|
||||||
unsigned long code = params["code"];
|
|
||||||
unsigned int length = params["length"];
|
|
||||||
sendRFData(code, length, rf_type);
|
|
||||||
} else if (type.equalsIgnoreCase("file")) {
|
|
||||||
String file = params["file"];
|
|
||||||
sendRFFile(file);
|
|
||||||
}
|
|
||||||
} else if (signal.equalsIgnoreCase("rf433")) {
|
|
||||||
RFTYPE rf_type;
|
|
||||||
if (type.equalsIgnoreCase("data")) {
|
|
||||||
rf_type = RF433;
|
|
||||||
unsigned long code = params["code"];
|
|
||||||
unsigned int length = params["length"];
|
|
||||||
sendRFData(code, length, rf_type);
|
|
||||||
} else if (type.equalsIgnoreCase("file")) {
|
|
||||||
String file = params["file"];
|
|
||||||
sendRFFile(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd.equalsIgnoreCase("set")) {
|
|
||||||
String type = params["type"];
|
|
||||||
if (type.equals("update")) {
|
|
||||||
String url = params["url"];
|
|
||||||
otaUpdate(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (type.equals("record")) {
|
|
||||||
String ip = params["ip"];
|
|
||||||
// remote_ip.fromString(ip);
|
|
||||||
DEBUGLN("start record");
|
|
||||||
enableIR();
|
|
||||||
enableRF();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (type.equals("disable_record")) {
|
|
||||||
DEBUGLN("disable record");
|
|
||||||
disableRF();
|
|
||||||
disableIR();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (type.equals("save_signal")) {
|
|
||||||
String file_name = params["file"];
|
|
||||||
String signal = params["signal"];
|
|
||||||
if (signal.equals("IR"))
|
|
||||||
saveIR(file_name);
|
|
||||||
else
|
|
||||||
saveRF(file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (type.equals("reset"))
|
|
||||||
settingsClear();
|
|
||||||
|
|
||||||
else if (type.equals("config")) {
|
|
||||||
if (params.containsKey("mqtt")) {
|
|
||||||
ConfigData["mqtt"]["host"] = params["mqtt"]["host"];
|
|
||||||
ConfigData["mqtt"]["port"] = params["mqtt"]["port"];
|
|
||||||
ConfigData["mqtt"]["user"] = params["mqtt"]["user"];
|
|
||||||
ConfigData["mqtt"]["password"] = params["mqtt"]["password"];
|
|
||||||
}
|
|
||||||
if (params.containsKey("pin")) {
|
|
||||||
ConfigData["pin"]["ir_send"] = params["pin"]["ir_send"];
|
|
||||||
ConfigData["pin"]["ir_receive"] = params["pin"]["ir_receive"];
|
|
||||||
}
|
|
||||||
send_msg_doc["cmd"] = "return";
|
|
||||||
send_msg_doc["params"]["message"] = "set success";
|
|
||||||
// returnUDP(&send_msg_doc);
|
|
||||||
settingsSave();
|
|
||||||
loadIRPin(ConfigData["pin"]["ir_send"], ConfigData["pin"]["ir_receive"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (type.equals("device")) {
|
|
||||||
DEBUGLN("Register Device")
|
|
||||||
String file = params["file"];
|
|
||||||
int device_type = (int)params["device_type"];
|
|
||||||
bool exist = params["exist"];
|
|
||||||
if (device_type == 1)
|
|
||||||
registAC(file, exist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IREASY_MSG_HANDLE_H
|
|
||||||
#define IREASY_MSG_HANDLE_H
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
typedef enum msgtype {
|
|
||||||
mqtt,
|
|
||||||
udp
|
|
||||||
} MsgType;
|
|
||||||
|
|
||||||
bool msgHandle(StaticJsonDocument<1024> *p_recv_msg_doc, MsgType msg_type);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "IRbabyOTA.h"
|
|
||||||
#include <ESP8266HTTPClient.h>
|
|
||||||
#include <ESP8266httpUpdate.h>
|
|
||||||
#include <ESP8266WiFi.h>
|
|
||||||
|
|
||||||
void update_started() {
|
|
||||||
DEBUGLN("CALLBACK: HTTP update process started");
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_finished() {
|
|
||||||
DEBUGLN("CALLBACK: HTTP update process finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_progress(int cur, int total) {
|
|
||||||
DEBUGF("CALLBACK: HTTP update process at %d of %d bytes...\n", cur, total);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_error(int err) {
|
|
||||||
DEBUGF("CALLBACK: HTTP update fatal error code %d\n", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
void versionCheck() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void otaUpdate(String url) {
|
|
||||||
|
|
||||||
WiFiClient client;
|
|
||||||
// Add optional callback notifiers
|
|
||||||
ESPhttpUpdate.onStart(update_started);
|
|
||||||
ESPhttpUpdate.onEnd(update_finished);
|
|
||||||
ESPhttpUpdate.onProgress(update_progress);
|
|
||||||
ESPhttpUpdate.onError(update_error);
|
|
||||||
|
|
||||||
t_httpUpdate_return ret = ESPhttpUpdate.update(client, url);
|
|
||||||
|
|
||||||
switch (ret) {
|
|
||||||
case HTTP_UPDATE_FAILED:
|
|
||||||
DEBUGF("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(),
|
|
||||||
ESPhttpUpdate.getLastErrorString().c_str());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HTTP_UPDATE_NO_UPDATES:
|
|
||||||
DEBUGLN("HTTP_UPDATE_NO_UPDATES");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HTTP_UPDATE_OK:
|
|
||||||
DEBUGLN("HTTP_UPDATE_OK");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IREASY_OTA_H
|
|
||||||
#define IREASY_OTA_H
|
|
||||||
|
|
||||||
#include "IRbabySerial.h"
|
|
||||||
|
|
||||||
void otaUpdate(String url);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
162
src/IRbabyRF.cpp
162
src/IRbabyRF.cpp
@@ -1,162 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "IRbabyRF.h"
|
|
||||||
#include <LittleFS.h>
|
|
||||||
#include "IRbabySerial.h"
|
|
||||||
#include "IRbabyGlobal.h"
|
|
||||||
#include "defines.h"
|
|
||||||
#include <Ticker.h>
|
|
||||||
RCSwitch rf315;
|
|
||||||
RCSwitch rf433;
|
|
||||||
|
|
||||||
#define FILE_PRE "/rf/"
|
|
||||||
unsigned long code_tmp;
|
|
||||||
unsigned int length_tmp;
|
|
||||||
RFTYPE rf_type_tmp;
|
|
||||||
|
|
||||||
Ticker change_rf_ticker; // change receiver
|
|
||||||
RFTYPE rf_receiver;
|
|
||||||
bool rf_record;
|
|
||||||
|
|
||||||
static void changeReceiver(void) {
|
|
||||||
static bool flag = false;
|
|
||||||
flag = !flag;
|
|
||||||
rf_receiver = flag ? RF315 : RF433;
|
|
||||||
}
|
|
||||||
void sendRFData(unsigned long code, unsigned int length, RFTYPE type) {
|
|
||||||
if (type == RF315) {
|
|
||||||
rf315.send(code, length);
|
|
||||||
} else if (type == RF433) {
|
|
||||||
rf433.send(code, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendRFFile(String file_name) {
|
|
||||||
File cache;
|
|
||||||
unsigned long code;
|
|
||||||
unsigned int length;
|
|
||||||
RFTYPE rf_type;
|
|
||||||
String file_path = FILE_PRE + file_name;
|
|
||||||
if (file_name.equals("test")) {
|
|
||||||
code = code_tmp;
|
|
||||||
length = length_tmp;
|
|
||||||
rf_type = rf_type_tmp;
|
|
||||||
} else if (LittleFS.exists(file_path)) {
|
|
||||||
cache = LittleFS.open(file_path, "r");
|
|
||||||
if (!cache) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cache.readBytes((char *)&rf_type, sizeof(rf_type_tmp));
|
|
||||||
cache.readBytes((char *)&code, sizeof(code));
|
|
||||||
cache.readBytes((char *)&length, sizeof(length));
|
|
||||||
DEBUGF("type = %d\n", rf_type);
|
|
||||||
DEBUGF("code = %ld\n", code);
|
|
||||||
DEBUGF("length = %d\n", length);
|
|
||||||
cache.close();
|
|
||||||
} else {
|
|
||||||
ERRORF("%s file not exists\n", file_name.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch (rf_type) {
|
|
||||||
case RF315:
|
|
||||||
|
|
||||||
rf315.send(code, length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RF433:
|
|
||||||
rf433.send(code, length);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void recvRF(void) {
|
|
||||||
if (rf_record) {
|
|
||||||
if (rf_receiver == RF433) {
|
|
||||||
rf433.enableReceive(R_433);
|
|
||||||
rf315.disableReceive();
|
|
||||||
} else {
|
|
||||||
rf315.enableReceive(R_315);
|
|
||||||
rf433.disableReceive();
|
|
||||||
}
|
|
||||||
delay(100);
|
|
||||||
if (rf_receiver == RF433 && rf433.available()) {
|
|
||||||
code_tmp = rf433.getReceivedValue();
|
|
||||||
length_tmp = rf433.getReceivedBitlength();
|
|
||||||
rf_type_tmp = RF433;
|
|
||||||
rf433.resetAvailable();
|
|
||||||
send_msg_doc.clear();
|
|
||||||
send_msg_doc["cmd"] = "record_rt";
|
|
||||||
send_msg_doc["params"]["signal"] = "RF433";
|
|
||||||
send_msg_doc["params"]["value"] = String(code_tmp);
|
|
||||||
// sendUDP(&send_msg_doc, remote_ip);
|
|
||||||
serializeJsonPretty(send_msg_doc, Serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (rf_receiver == RF315 && rf315.available()) {
|
|
||||||
code_tmp = rf315.getReceivedValue();
|
|
||||||
length_tmp = rf315.getReceivedBitlength();
|
|
||||||
rf_type_tmp = RF315;
|
|
||||||
rf315.resetAvailable();
|
|
||||||
send_msg_doc.clear();
|
|
||||||
send_msg_doc["cmd"] = "record_rt";
|
|
||||||
send_msg_doc["params"]["signal"] = "RF315";
|
|
||||||
send_msg_doc["params"]["value"] = String(code_tmp);
|
|
||||||
// sendUDP(&send_msg_doc, remote_ip);
|
|
||||||
serializeJsonPretty(send_msg_doc, Serial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRF(String file_name) {
|
|
||||||
String save_path = FILE_PRE + file_name;
|
|
||||||
File cache = LittleFS.open(save_path, "w");
|
|
||||||
if (!cache) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cache.write((char *)&rf_type_tmp, sizeof(rf_type_tmp));
|
|
||||||
cache.write((char *)&code_tmp, sizeof(code_tmp));
|
|
||||||
cache.write((char *)&length_tmp, sizeof(length_tmp));
|
|
||||||
cache.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disableRF(void) {
|
|
||||||
rf_record = false;
|
|
||||||
rf315.disableReceive();
|
|
||||||
rf433.disableReceive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void enableRF(void) {
|
|
||||||
rf_record = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initRF(void) {
|
|
||||||
rf_record = false;
|
|
||||||
rf315.enableTransmit(T_315);
|
|
||||||
rf433.enableTransmit(T_433);
|
|
||||||
change_rf_ticker.attach_ms_scheduled(100, changeReceiver);
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IRBABYRF_H
|
|
||||||
#define IRBABYRF_H
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include "RCSwitch.h"
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
RF315,
|
|
||||||
RF433
|
|
||||||
} RFTYPE;
|
|
||||||
|
|
||||||
void initRF(void);
|
|
||||||
bool sendRFFile(String file_name);
|
|
||||||
void sendRFData(unsigned long code, unsigned int length, RFTYPE type);
|
|
||||||
void recvRF(void);
|
|
||||||
void disableRF(void);
|
|
||||||
void enableRF(void);
|
|
||||||
bool saveRF(String file_name);
|
|
||||||
|
|
||||||
extern RCSwitch rf315;
|
|
||||||
extern RCSwitch rf433;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
* Copyright (c) 2020-2022 IRbaby-IRext
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
@@ -30,24 +30,24 @@
|
|||||||
// generic COM debug
|
// generic COM debug
|
||||||
|
|
||||||
#define DEBUGLN(...) \
|
#define DEBUGLN(...) \
|
||||||
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.println(__VA_ARGS__);}}
|
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.println(__VA_ARGS__);}}
|
||||||
#define DEBUGF(...) \
|
#define DEBUGF(...) \
|
||||||
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.printf(__VA_ARGS__);}}
|
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.printf(__VA_ARGS__);}}
|
||||||
#define DEBUG(...) \
|
#define DEBUG(...) \
|
||||||
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.print(__VA_ARGS__);}}
|
{if (LOG_DEBUG) { Serial.printf("DEBUG:\t"); Serial.print(__VA_ARGS__);}}
|
||||||
|
|
||||||
#define INFOLN(...) \
|
#define INFOLN(...) \
|
||||||
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.println(__VA_ARGS__);}}
|
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.println(__VA_ARGS__);}}
|
||||||
#define INFOF(...) \
|
#define INFOF(...) \
|
||||||
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.printf(__VA_ARGS__);}}
|
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.printf(__VA_ARGS__);}}
|
||||||
#define INFO(...) \
|
#define INFO(...) \
|
||||||
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.print(__VA_ARGS__);}}
|
{if (LOG_INFO) { Serial.printf("INFO:\t"); Serial.print(__VA_ARGS__);}}
|
||||||
|
|
||||||
#define ERRORLN(...) \
|
#define ERRORLN(...) \
|
||||||
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.println(__VA_ARGS__);}}
|
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.println(__VA_ARGS__);}}
|
||||||
#define ERRORF(...) \
|
#define ERRORF(...) \
|
||||||
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.printf(__VA_ARGS__);}}
|
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.printf(__VA_ARGS__);}}
|
||||||
#define ERROR(...) \
|
#define ERROR(...) \
|
||||||
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.print(__VA_ARGS__);}}
|
{if (LOG_ERROR) { Serial.printf("ERROR:\t"); Serial.print(__VA_ARGS__);}}
|
||||||
|
|
||||||
#endif // IREASY_SERIAL_H
|
#endif // IREASY_SERIAL_H
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020-2022 IRbaby-IRext
|
* Copyright (c) 2020-2022 IRbaby-IRext
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
* copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
@@ -22,19 +22,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
#include <WiFiManager.h>
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include "IRbabyGlobal.h"
|
||||||
|
#include "IRbabySerial.h"
|
||||||
|
#include "IRbabyIR.h"
|
||||||
|
|
||||||
#include "IRbabyUserSettings.h"
|
#include "IRbabyUserSettings.h"
|
||||||
#include "IRbabySerial.h"
|
|
||||||
#include "WiFiManager.h"
|
|
||||||
#include "IRbabyGlobal.h"
|
|
||||||
#include "IRbabyIR.h"
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
StaticJsonDocument<1024> ConfigData;
|
StaticJsonDocument<1024> ConfigData;
|
||||||
StaticJsonDocument<1024> ACStatus;
|
StaticJsonDocument<1024> ACStatus;
|
||||||
|
|
||||||
bool settingsSave()
|
bool saveSettings() {
|
||||||
{
|
|
||||||
DEBUGLN("Save Config");
|
DEBUGLN("Save Config");
|
||||||
File cache = LittleFS.open("/config", "w");
|
File cache = LittleFS.open("/config", "w");
|
||||||
if (!cache || (serializeJson(ConfigData, cache) == 0)) {
|
if (!cache || (serializeJson(ConfigData, cache) == 0)) {
|
||||||
@@ -44,36 +44,30 @@ bool settingsSave()
|
|||||||
}
|
}
|
||||||
cache.close();
|
cache.close();
|
||||||
cache = LittleFS.open("/acstatus", "w");
|
cache = LittleFS.open("/acstatus", "w");
|
||||||
if (!cache || (serializeJson(ACStatus, cache) == 0))
|
if (!cache || (serializeJson(ACStatus, cache) == 0)) {
|
||||||
{
|
|
||||||
ERRORLN("ERROR: Failed to save acstatus file");
|
ERRORLN("ERROR: Failed to save acstatus file");
|
||||||
cache.close();
|
cache.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cache.close();
|
cache.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool settingsLoad()
|
bool loadSettings() {
|
||||||
{
|
|
||||||
LittleFS.begin();
|
LittleFS.begin();
|
||||||
int ret = false;
|
int ret = false;
|
||||||
FSInfo64 info;
|
FSInfo64 info;
|
||||||
LittleFS.info64(info);
|
LittleFS.info64(info);
|
||||||
DEBUGF("fs total bytes = %llu\n", info.totalBytes);
|
DEBUGF("fs total bytes = %llu\n", info.totalBytes);
|
||||||
if (LittleFS.exists("/config"))
|
if (LittleFS.exists("/config")) {
|
||||||
{
|
|
||||||
File cache = LittleFS.open("/config", "r");
|
File cache = LittleFS.open("/config", "r");
|
||||||
if (!cache)
|
if (!cache) {
|
||||||
{
|
|
||||||
ERRORLN("Failed to read config file");
|
ERRORLN("Failed to read config file");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (cache.size() > 0)
|
if (cache.size() > 0) {
|
||||||
{
|
|
||||||
DeserializationError error = deserializeJson(ConfigData, cache);
|
DeserializationError error = deserializeJson(ConfigData, cache);
|
||||||
if (error)
|
if (error) {
|
||||||
{
|
|
||||||
ERRORLN("Failed to load config settings");
|
ERRORLN("Failed to load config settings");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -106,16 +100,7 @@ bool settingsLoad()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void settingsClear()
|
bool saveACStatus(String file, t_remote_ac_status status) {
|
||||||
{
|
|
||||||
DEBUGLN("\nReset settings");
|
|
||||||
wifi_manager.resetSettings();
|
|
||||||
LittleFS.format();
|
|
||||||
ESP.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveACStatus(String file, t_remote_ac_status status)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
ACStatus[file]["power"] = (int)status.ac_power;
|
ACStatus[file]["power"] = (int)status.ac_power;
|
||||||
ACStatus[file]["temperature"] = (int)status.ac_temp;
|
ACStatus[file]["temperature"] = (int)status.ac_temp;
|
||||||
@@ -125,8 +110,7 @@ bool saveACStatus(String file, t_remote_ac_status status)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_remote_ac_status getACState(String file)
|
t_remote_ac_status getACStatus(String file) {
|
||||||
{
|
|
||||||
t_remote_ac_status status;
|
t_remote_ac_status status;
|
||||||
int power = (int)ACStatus[file]["power"];
|
int power = (int)ACStatus[file]["power"];
|
||||||
int temperature = (int)ACStatus[file]["temperature"];
|
int temperature = (int)ACStatus[file]["temperature"];
|
||||||
|
|||||||
@@ -25,19 +25,17 @@
|
|||||||
#define IRBABY_USER_SETTINGS_H
|
#define IRBABY_USER_SETTINGS_H
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
#include "ir_ac_control.h"
|
#include "ir_ac_control.h"
|
||||||
|
|
||||||
/* save settings */
|
/* save settings */
|
||||||
bool settingsSave();
|
bool saveSettings();
|
||||||
|
|
||||||
/* clear settings */
|
|
||||||
void settingsClear();
|
|
||||||
|
|
||||||
/* load settings */
|
/* load settings */
|
||||||
bool settingsLoad();
|
bool loadSettings();
|
||||||
|
|
||||||
bool saveACStatus(String, t_remote_ac_status);
|
bool saveACStatus(String file, t_remote_ac_status status);
|
||||||
t_remote_ac_status getACState(String file);
|
t_remote_ac_status getACStatus(String file);
|
||||||
|
|
||||||
extern StaticJsonDocument<1024> ConfigData;
|
extern StaticJsonDocument<1024> ConfigData;
|
||||||
extern StaticJsonDocument<1024> ACStatus;
|
extern StaticJsonDocument<1024> ACStatus;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef IRBABYHA_H
|
#ifndef IRBABY_HA_H
|
||||||
#define IRBABYHA_H
|
#define IRBABY_HA_H
|
||||||
|
|
||||||
#include <WString.h>
|
#include <WString.h>
|
||||||
#include "ir_ac_control.h"
|
#include "ir_ac_control.h"
|
||||||
@@ -31,4 +31,4 @@ void returnACStatus(String filename, t_remote_ac_status ac_status);
|
|||||||
|
|
||||||
void registAC(String filename, bool flag);
|
void registAC(String filename, bool flag);
|
||||||
|
|
||||||
#endif
|
#endif // IRBABY_HA_H
|
||||||
Reference in New Issue
Block a user