mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-31 04:19:15 +03:00
Compare commits
11 Commits
ver4stable
...
2.3.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad440eef94 | ||
|
|
5ab6d13ae6 | ||
|
|
970136bb75 | ||
|
|
0de1df8625 | ||
|
|
708eb5f67e | ||
|
|
83d1531267 | ||
|
|
be5bd3ede4 | ||
|
|
e79be004b9 | ||
|
|
3135e5658f | ||
|
|
48ddb1a505 | ||
|
|
01a419d987 |
55
.github/workflows/build_iotm.yml
vendored
55
.github/workflows/build_iotm.yml
vendored
@@ -1,55 +0,0 @@
|
||||
env:
|
||||
BOARDS: '["esp8266_4mb", "esp8266_16mb", "esp32_4mb3f", "esp32c3m_4mb", "esp32s2_4mb", "esp32s3_16mb"]'
|
||||
|
||||
name: Build Firmware
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
generate-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set_matrix.outputs.json }}
|
||||
steps:
|
||||
- name: Prepare matrix JSON Object
|
||||
id: set_matrix
|
||||
uses: nickofthyme/object-remap@v2.0.0
|
||||
with:
|
||||
__case: kebab
|
||||
board: ${{ env.BOARDS }}
|
||||
|
||||
build:
|
||||
needs: [ generate-matrix ]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'ver4dev'
|
||||
- name: Run PrepareProject.py -b ${{ matrix.board }}
|
||||
run: python3 ./PrepareProject.py -b ${{ matrix.board }}
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install platformio
|
||||
- name: Run PlatformIO
|
||||
if: always()
|
||||
run: platformio run
|
||||
- name: Build FS
|
||||
if: always()
|
||||
run: platformio run -t buildfs --disable-auto-clean
|
||||
- name: Rearrange Artifacts
|
||||
run: |
|
||||
mkdir -p artifacts/${{ matrix.board }}
|
||||
find .pio/build/${{ matrix.board }} -name "*.bin" -exec mv {} artifacts/${{ matrix.board }} \;
|
||||
working-directory: ${{ github.workspace }}
|
||||
- name: Attach artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ github.run_number }}
|
||||
path: artifacts/${{ matrix.board }}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
.pio
|
||||
.vscode
|
||||
10
.vscode/extensions.json
vendored
10
.vscode/extensions.json
vendored
@@ -1,10 +0,0 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
BIN
CH341SER_WIN_3.5.ZIP
Normal file
BIN
CH341SER_WIN_3.5.ZIP
Normal file
Binary file not shown.
599
Cmd.ino
Normal file
599
Cmd.ino
Normal file
@@ -0,0 +1,599 @@
|
||||
void CMD_init() {
|
||||
|
||||
sCmd.addCommand("button", button);
|
||||
sCmd.addCommand("buttonSet", buttonSet);
|
||||
sCmd.addCommand("buttonChange", buttonChange);
|
||||
|
||||
sCmd.addCommand("pinSet", pinSet);
|
||||
sCmd.addCommand("pinChange", pinChange);
|
||||
|
||||
sCmd.addCommand("pwm", pwm);
|
||||
sCmd.addCommand("pwmSet", pwmSet);
|
||||
|
||||
sCmd.addCommand("switch", switch_);
|
||||
|
||||
#ifdef analog_enable
|
||||
sCmd.addCommand("analog", analog);
|
||||
#endif
|
||||
#ifdef level_enable
|
||||
sCmd.addCommand("level", level);
|
||||
#endif
|
||||
#ifdef dallas_enable
|
||||
sCmd.addCommand("dallas", dallas);
|
||||
#endif
|
||||
#ifdef dht_enable
|
||||
sCmd.addCommand("dhtT", dhtT);
|
||||
sCmd.addCommand("dhtH", dhtH);
|
||||
sCmd.addCommand("dhtPerception", dhtP);
|
||||
sCmd.addCommand("dhtComfort", dhtC);
|
||||
sCmd.addCommand("dhtDewpoint", dhtD);
|
||||
#endif
|
||||
|
||||
#ifdef bmp_enable
|
||||
sCmd.addCommand("bmp280T", bmp280T);
|
||||
sCmd.addCommand("bmp280P", bmp280P);
|
||||
#endif
|
||||
|
||||
#ifdef bme_enable
|
||||
sCmd.addCommand("bme280T", bme280T);
|
||||
sCmd.addCommand("bme280P", bme280P);
|
||||
sCmd.addCommand("bme280H", bme280H);
|
||||
sCmd.addCommand("bme280A", bme280A);
|
||||
#endif
|
||||
|
||||
#ifdef stepper_enable
|
||||
sCmd.addCommand("stepper", stepper);
|
||||
sCmd.addCommand("stepperSet", stepperSet);
|
||||
#endif
|
||||
|
||||
#ifdef servo_enable
|
||||
sCmd.addCommand("servo", servo_);
|
||||
sCmd.addCommand("servoSet", servoSet);
|
||||
#endif
|
||||
|
||||
#ifdef serial_enable
|
||||
sCmd.addCommand("serialBegin", serialBegin);
|
||||
sCmd.addCommand("serialWrite", serialWrite);
|
||||
#endif
|
||||
|
||||
#ifdef logging_enable
|
||||
sCmd.addCommand("logging", logging);
|
||||
#endif
|
||||
|
||||
sCmd.addCommand("inputDigit", inputDigit);
|
||||
sCmd.addCommand("digitSet", digitSet);
|
||||
|
||||
sCmd.addCommand("inputTime", inputTime);
|
||||
sCmd.addCommand("timeSet", timeSet);
|
||||
|
||||
sCmd.addCommand("timerStart", timerStart);
|
||||
sCmd.addCommand("timerStop", timerStop);
|
||||
|
||||
sCmd.addCommand("text", text);
|
||||
sCmd.addCommand("textSet", textSet);
|
||||
|
||||
sCmd.addCommand("mqtt", mqttOrderSend);
|
||||
sCmd.addCommand("http", httpOrderSend);
|
||||
|
||||
#ifdef push_enable
|
||||
sCmd.addCommand("push", pushControl);
|
||||
#endif
|
||||
|
||||
sCmd.addCommand("update", update_firmware);
|
||||
sCmd.addCommand("firmware", firmware);
|
||||
|
||||
|
||||
handle_time_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================================================
|
||||
//==========================================Модуль кнопок===================================================
|
||||
void button() {
|
||||
|
||||
String button_number = sCmd.next();
|
||||
String button_param = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
jsonWriteStr(configOptionJson, "button_param" + button_number, button_param);
|
||||
jsonWriteStr(configLiveJson, "button" + button_number, start_state);
|
||||
|
||||
if (isDigitStr (button_param)) {
|
||||
pinMode(button_param.toInt(), OUTPUT);
|
||||
digitalWrite(button_param.toInt(), start_state.toInt());
|
||||
}
|
||||
|
||||
if (button_param == "scen") {
|
||||
jsonWriteStr(configSetupJson, "scen", start_state);
|
||||
Scenario_init();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (button_param.indexOf("line") != -1) {
|
||||
String str = button_param;
|
||||
while (str.length() != 0) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker (str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = start_state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
createWidget (widget_name, page_name, page_number, "widgets/widget.toggle.json", "button" + button_number);
|
||||
}
|
||||
|
||||
void buttonSet() {
|
||||
|
||||
String button_number = sCmd.next();
|
||||
String button_state = sCmd.next();
|
||||
String button_param = jsonReadStr(configOptionJson, "button_param" + button_number);
|
||||
|
||||
if (button_param != "na" || button_param != "scen" || button_param.indexOf("line") != -1) {
|
||||
digitalWrite(button_param.toInt(), button_state.toInt());
|
||||
}
|
||||
|
||||
if (button_param == "scen") {
|
||||
jsonWriteStr(configSetupJson, "scen", button_state);
|
||||
Scenario_init();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (button_param.indexOf("line") != -1) {
|
||||
String str = button_param;
|
||||
while (str.length() != 0) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker (str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = button_state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
|
||||
eventGen ("button", button_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "button" + button_number, button_state);
|
||||
sendSTATUS("button" + button_number, button_state);
|
||||
}
|
||||
|
||||
void buttonChange() {
|
||||
String button_number = sCmd.next();
|
||||
String current_state = jsonReadStr(configLiveJson, "button" + button_number);
|
||||
if (current_state == "1") {
|
||||
current_state = "0";
|
||||
} else if (current_state == "0") {
|
||||
current_state = "1";
|
||||
}
|
||||
order_loop += "buttonSet " + button_number + " " + current_state + ",";
|
||||
jsonWriteStr(configLiveJson, "button" + button_number, current_state);
|
||||
sendSTATUS("button" + button_number, current_state);
|
||||
}
|
||||
|
||||
void pinSet() {
|
||||
String pin_number = sCmd.next();
|
||||
String pin_state = sCmd.next();
|
||||
pinMode(pin_number.toInt(), OUTPUT);
|
||||
digitalWrite(pin_number.toInt(), pin_state.toInt());
|
||||
}
|
||||
|
||||
void pinChange() {
|
||||
String pin_number = sCmd.next();
|
||||
pinMode(pin_number.toInt(), OUTPUT);
|
||||
digitalWrite(pin_number.toInt(), !digitalRead(pin_number.toInt()));
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль управления ШИМ===================================================
|
||||
void pwm() {
|
||||
|
||||
static boolean flag = true;
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_pin = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
|
||||
uint8_t pwm_pin_int = pwm_pin.toInt();
|
||||
jsonWriteStr(configOptionJson, "pwm_pin" + pwm_number, pwm_pin);
|
||||
pinMode(pwm_pin_int, INPUT);
|
||||
analogWrite(pwm_pin_int, start_state.toInt());
|
||||
//analogWriteFreq(32000);
|
||||
jsonWriteStr(configLiveJson, "pwm" + pwm_number, start_state);
|
||||
|
||||
createWidget (widget_name, page_name, page_number, "widgets/widget.range.json", "pwm" + pwm_number);
|
||||
}
|
||||
|
||||
void pwmSet() {
|
||||
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_state = sCmd.next();
|
||||
int pwm_state_int = pwm_state.toInt();
|
||||
|
||||
int pin = jsonReadInt(configOptionJson, "pwm_pin" + pwm_number);
|
||||
analogWrite(pin, pwm_state_int);
|
||||
|
||||
eventGen ("pwm", pwm_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "pwm" + pwm_number, pwm_state);
|
||||
sendSTATUS("pwm" + pwm_number, pwm_state);
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль физической кнопки================================================
|
||||
void switch_ () {
|
||||
|
||||
String switch_number = sCmd.next();
|
||||
String switch_pin = sCmd.next();
|
||||
String switch_delay = sCmd.next();
|
||||
|
||||
buttons[switch_number.toInt()].attach(switch_pin.toInt());
|
||||
buttons[switch_number.toInt()].interval(switch_delay.toInt());
|
||||
but[switch_number.toInt()] = true;
|
||||
}
|
||||
|
||||
void handleButton() {
|
||||
|
||||
static uint8_t switch_number = 1;
|
||||
|
||||
if (but[switch_number]) {
|
||||
buttons[switch_number].update();
|
||||
if (buttons[switch_number].fell()) {
|
||||
|
||||
eventGen ("switch", String(switch_number));
|
||||
|
||||
jsonWriteStr(configLiveJson, "switch" + String(switch_number), "1");
|
||||
}
|
||||
if (buttons[switch_number].rose()) {
|
||||
|
||||
eventGen ("switch", String(switch_number));
|
||||
|
||||
jsonWriteStr(configLiveJson, "switch" + String(switch_number), "0");
|
||||
}
|
||||
}
|
||||
switch_number++;
|
||||
if (switch_number == NUM_BUTTONS) switch_number = 0;
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода цифры=================================================================
|
||||
void inputDigit() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(5);
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "digit" + number, start_state);
|
||||
createWidget (widget_name, page_name, page_number, "widgets/widget.inputNum.json", "digit" + number);
|
||||
}
|
||||
void digitSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "digit" + number, value);
|
||||
sendSTATUS("digit" + number, value);
|
||||
}
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода времени===============================================================
|
||||
void inputTime() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(4);
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "time" + number, start_state);
|
||||
createWidget (widget_name, page_name, page_number, "widgets/widget.inputTime.json", "time" + number);
|
||||
}
|
||||
void timeSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "time" + number, value);
|
||||
sendSTATUS("time" + number, value);
|
||||
}
|
||||
|
||||
void handle_time_init() {
|
||||
ts.add(TIME, 1000, [&](void*) {
|
||||
|
||||
String tmp = GetTime();
|
||||
jsonWriteStr(configLiveJson, "time", tmp);
|
||||
tmp.replace(":", "-");
|
||||
jsonWriteStr(configLiveJson, "timenow", tmp);
|
||||
eventGen ("timenow", "");
|
||||
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление текстового виджета============================================================
|
||||
void text() {
|
||||
|
||||
String number = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
createWidget (widget_name, page_name, page_number, "widgets/widget.anyData.json", "text" + number);
|
||||
}
|
||||
|
||||
|
||||
void textSet() {
|
||||
|
||||
String number = sCmd.next();
|
||||
String text = sCmd.next();
|
||||
text.replace("_", " ");
|
||||
|
||||
if (text.indexOf("-time") >= 0) {
|
||||
text.replace("-time", "");
|
||||
text.replace("#", " ");
|
||||
String time = GetTime();
|
||||
time.replace(":", ".");
|
||||
text = text + " " + GetDataDigital() + " " + time;
|
||||
}
|
||||
|
||||
jsonWriteStr(configLiveJson, "text" + number, text);
|
||||
sendSTATUS("text" + number, text);
|
||||
}
|
||||
//=====================================================================================================================================
|
||||
//=========================================Модуль шагового мотора======================================================================
|
||||
#ifdef stepper_enable
|
||||
//stepper 1 12 13
|
||||
void stepper() {
|
||||
String stepper_number = sCmd.next();
|
||||
String pin_step = sCmd.next();
|
||||
String pin_dir = sCmd.next();
|
||||
|
||||
jsonWriteStr(configOptionJson, "stepper" + stepper_number, pin_step + " " + pin_dir);
|
||||
pinMode(pin_step.toInt(), OUTPUT);
|
||||
pinMode(pin_dir.toInt(), OUTPUT);
|
||||
}
|
||||
|
||||
//stepperSet 1 100 5
|
||||
void stepperSet() {
|
||||
String stepper_number = sCmd.next();
|
||||
String steps = sCmd.next();
|
||||
jsonWriteStr(configOptionJson, "steps" + stepper_number, steps);
|
||||
String stepper_speed = sCmd.next();
|
||||
String pin_step = selectToMarker (jsonReadStr(configOptionJson, "stepper" + stepper_number), " ");
|
||||
String pin_dir = deleteBeforeDelimiter (jsonReadStr(configOptionJson, "stepper" + stepper_number), " ");
|
||||
Serial.println(pin_step);
|
||||
Serial.println(pin_dir);
|
||||
if (steps.toInt() > 0) digitalWrite(pin_dir.toInt(), HIGH);
|
||||
if (steps.toInt() < 0) digitalWrite(pin_dir.toInt(), LOW);
|
||||
if (stepper_number == "1") {
|
||||
ts.add(STEPPER1, stepper_speed.toInt(), [&](void*) {
|
||||
int steps_int = abs(jsonReadInt(configOptionJson, "steps1") * 2);
|
||||
static int count;
|
||||
count++;
|
||||
String pin_step = selectToMarker (jsonReadStr(configOptionJson, "stepper1"), " ");
|
||||
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
|
||||
yield();
|
||||
if (count > steps_int) {
|
||||
digitalWrite(pin_step.toInt(), LOW);
|
||||
ts.remove(STEPPER1);
|
||||
count = 0;
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
if (stepper_number == "2") {
|
||||
ts.add(STEPPER2, stepper_speed.toInt(), [&](void*) {
|
||||
int steps_int = abs(jsonReadInt(configOptionJson, "steps2") * 2);
|
||||
static int count;
|
||||
count++;
|
||||
String pin_step = selectToMarker (jsonReadStr(configOptionJson, "stepper2"), " ");
|
||||
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
|
||||
yield();
|
||||
if (count > steps_int) {
|
||||
digitalWrite(pin_step.toInt(), LOW);
|
||||
ts.remove(STEPPER2);
|
||||
count = 0;
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//====================================================================================================================================================
|
||||
//=================================================================Сервоприводы=======================================================================
|
||||
#ifdef servo_enable
|
||||
//servo 1 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
|
||||
void servo_() {
|
||||
String servo_number = sCmd.next();
|
||||
String servo_pin = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
int start_state_int = start_state.toInt();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
|
||||
String min_value = sCmd.next();
|
||||
String max_value = sCmd.next();
|
||||
|
||||
String min_deg = sCmd.next();
|
||||
String max_deg = sCmd.next();
|
||||
|
||||
String page_number = sCmd.next();
|
||||
|
||||
jsonWriteStr(configOptionJson, "servo_pin" + servo_number, servo_pin);
|
||||
start_state_int = map(start_state_int, min_value.toInt(), max_value.toInt(), min_deg.toInt(), max_deg.toInt());
|
||||
|
||||
if (servo_number == "1") {
|
||||
#ifdef ESP8266
|
||||
myServo1.attach(servo_pin.toInt());
|
||||
myServo1.write(start_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo1.attach(servo_pin.toInt(), 500, 2400);
|
||||
myServo1.write(start_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (servo_number == "2") {
|
||||
#ifdef ESP8266
|
||||
myServo2.attach(servo_pin.toInt());
|
||||
myServo2.write(start_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo2.attach(servo_pin.toInt(), 500, 2400);
|
||||
myServo2.write(start_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
jsonWriteStr(configOptionJson, "s_min_val" + servo_number, min_value);
|
||||
jsonWriteStr(configOptionJson, "s_max_val" + servo_number, max_value);
|
||||
jsonWriteStr(configOptionJson, "s_min_deg" + servo_number, min_deg);
|
||||
jsonWriteStr(configOptionJson, "s_max_deg" + servo_number, max_deg);
|
||||
|
||||
jsonWriteStr(configLiveJson, "servo" + servo_number, start_state);
|
||||
|
||||
createWidgetParam (widget_name, page_name, page_number, "widgets/widget.range.json", "servo" + servo_number, "min", min_value, "max", max_value, "k", "1");
|
||||
}
|
||||
|
||||
void servoSet() {
|
||||
String servo_number = sCmd.next();
|
||||
String servo_state = sCmd.next();
|
||||
int servo_state_int = servo_state.toInt();
|
||||
|
||||
int pin = jsonReadInt(configOptionJson, "servo_pin" + servo_number);
|
||||
|
||||
servo_state_int = map(servo_state_int,
|
||||
jsonReadInt(configOptionJson, "s_min_val" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_max_val" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_min_deg" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_max_deg" + servo_number));
|
||||
|
||||
if (servo_number == "1") {
|
||||
#ifdef ESP8266
|
||||
myServo1.write(servo_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo1.write(servo_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (servo_number == "2") {
|
||||
#ifdef ESP8266
|
||||
myServo2.write(servo_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo2.write(servo_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Serial.println(servo_state_int);
|
||||
|
||||
eventGen ("servo", servo_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "servo" + servo_number, servo_state);
|
||||
sendSTATUS("servo" + servo_number, servo_state);
|
||||
}
|
||||
#endif
|
||||
//====================================================================================================================================================
|
||||
//===================================================================================serial===========================================================
|
||||
#ifdef serial_enable
|
||||
void serialBegin() {
|
||||
//String s_speed = sCmd.next();
|
||||
//String rxPin = sCmd.next();
|
||||
//String txPin = sCmd.next();
|
||||
//SoftwareSerial mySerial(rxPin.toInt(), txPin.toInt());
|
||||
//mySerial.begin(s_speed.toInt());
|
||||
}
|
||||
|
||||
void serialWrite() {
|
||||
//String text = sCmd.next();
|
||||
//mySerial.println(text);
|
||||
}
|
||||
#endif
|
||||
//====================================================================================================================================================
|
||||
//=================================================Глобальные команды удаленного управления===========================================================
|
||||
|
||||
void mqttOrderSend() {
|
||||
|
||||
String id = sCmd.next();
|
||||
String order = sCmd.next();
|
||||
|
||||
String all_line = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + id + "/order";
|
||||
//Serial.print(all_line);
|
||||
//Serial.print("->");
|
||||
//Serial.println(order);
|
||||
int send_status = client_mqtt.publish (all_line.c_str(), order.c_str(), false);
|
||||
}
|
||||
|
||||
void httpOrderSend() {
|
||||
|
||||
String ip = sCmd.next();
|
||||
String order = sCmd.next();
|
||||
order.replace("_", "%20");
|
||||
String url = "http://" + ip + "/cmd?command=" + order;
|
||||
getURL(url);
|
||||
}
|
||||
|
||||
void update_firmware() {
|
||||
upgrade = true;
|
||||
}
|
||||
|
||||
void firmware() {
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "firm1", firmware_version);
|
||||
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "firm1");
|
||||
}
|
||||
|
||||
//==============================================================================================================================
|
||||
//============================выполнение команд (в лупе) по очереди из строки order=============================================
|
||||
void handleCMD_loop() {
|
||||
|
||||
if (order_loop != "") {
|
||||
|
||||
String tmp = selectToMarker(order_loop, ","); //выделяем из страки order первую команду rel 5 1,
|
||||
sCmd.readStr(tmp); //выполняем первую команду
|
||||
Serial.println("[ORDER] => " + order_loop);
|
||||
order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем выполненную команду
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================================================================================
|
||||
//=======================================================================================================================================
|
||||
void txtExecution(String file) {
|
||||
|
||||
String command_all = readFile(file, 2048) + "\r\n";
|
||||
|
||||
command_all.replace("\r\n", "\n");
|
||||
command_all.replace("\r", "\n");
|
||||
|
||||
while (command_all.length() != 0) {
|
||||
|
||||
String tmp = selectToMarker (command_all, "\n");
|
||||
sCmd.readStr(tmp);
|
||||
command_all = deleteBeforeDelimiter(command_all, "\n");
|
||||
}
|
||||
command_all = "";
|
||||
}
|
||||
|
||||
void stringExecution(String str) {
|
||||
|
||||
str = str + "\r\n";
|
||||
|
||||
str.replace("\r\n", "\n");
|
||||
str.replace("\r", "\n");
|
||||
|
||||
while (str.length() != 0) {
|
||||
|
||||
String tmp = selectToMarker (str, "\n");
|
||||
sCmd.readStr(tmp);
|
||||
|
||||
str = deleteBeforeDelimiter(str, "\n");
|
||||
}
|
||||
}
|
||||
BIN
ESP32FS.7z
Normal file
BIN
ESP32FS.7z
Normal file
Binary file not shown.
BIN
ESP8266FS.7z
Normal file
BIN
ESP8266FS.7z
Normal file
Binary file not shown.
38
FS.ino
Normal file
38
FS.ino
Normal file
@@ -0,0 +1,38 @@
|
||||
void File_system_init() {
|
||||
|
||||
Serial.begin(115200);
|
||||
//Serial.setDebugOutput(true);
|
||||
Serial.println("--------------started----------------");
|
||||
//--------------------------------------------------------------
|
||||
SPIFFS.begin();
|
||||
configSetupJson = readFile("config.json", 4096);
|
||||
configSetupJson.replace(" ", "");
|
||||
configSetupJson.replace("\r\n", "");
|
||||
Serial.println(configSetupJson);
|
||||
//jsonWriteStr(configLiveJson, "name", jsonReadStr(configSetupJson, "name"));
|
||||
//jsonWriteStr(configLiveJson, "lang", jsonReadStr(configSetupJson, "lang"));
|
||||
|
||||
|
||||
#ifdef ESP32
|
||||
uint32_t chipID_u = ESP.getEfuseMac();
|
||||
chipID = String(chipID_u);
|
||||
jsonWriteStr(configSetupJson, "chipID", chipID);
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
chipID = String( ESP.getChipId() ) + "-" + String(ESP.getFlashChipId());
|
||||
jsonWriteStr(configSetupJson, "chipID", chipID);
|
||||
Serial.setDebugOutput(0);
|
||||
#endif
|
||||
|
||||
jsonWriteStr(configSetupJson, "firmware_version", firmware_version);
|
||||
|
||||
prex = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipID;
|
||||
Serial.println(chipID);
|
||||
|
||||
}
|
||||
|
||||
void get_esp_info() {
|
||||
|
||||
|
||||
}
|
||||
99
Init.ino
Normal file
99
Init.ino
Normal file
@@ -0,0 +1,99 @@
|
||||
void All_init() {
|
||||
Device_init();
|
||||
Scenario_init();
|
||||
Timer_countdown_init();
|
||||
}
|
||||
|
||||
void Device_init() {
|
||||
|
||||
logging_value_names_list = "";
|
||||
enter_to_logging_counter = LOG1 - 1;
|
||||
|
||||
analog_value_names_list = "";
|
||||
enter_to_analog_counter = 0;
|
||||
|
||||
level_value_name = "";
|
||||
|
||||
dhtT_value_name = "";
|
||||
dhtH_value_name = "";
|
||||
|
||||
bmp280T_value_name = "";
|
||||
bmp280P_value_name = "";
|
||||
|
||||
bme280T_value_name = "";
|
||||
bme280P_value_name = "";
|
||||
bme280H_value_name = "";
|
||||
bme280A_value_name = "";
|
||||
|
||||
int array_sz = sizeof(sensors_reading_map) / sizeof(sensors_reading_map[0]);
|
||||
|
||||
for (int i = 0; i <= array_sz; i++) {
|
||||
sensors_reading_map[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = LOG1; i <= LOG5; i++) {
|
||||
ts.remove(i);
|
||||
}
|
||||
|
||||
#ifdef layout_in_ram
|
||||
all_widgets = "";
|
||||
#else
|
||||
SPIFFS.remove("/layout.txt");
|
||||
#endif
|
||||
|
||||
txtExecution("firmware.c.txt");
|
||||
//outcoming_date();
|
||||
}
|
||||
//-------------------------------сценарии-----------------------------------------------------
|
||||
|
||||
void Scenario_init() {
|
||||
if (jsonReadStr(configSetupJson, "scen") == "1") {
|
||||
scenario = readFile("firmware.s.txt", 2048);
|
||||
}
|
||||
}
|
||||
|
||||
void uptime_init() {
|
||||
ts.add(UPTIME, 5000, [&](void*) {
|
||||
handle_uptime();
|
||||
}, nullptr, true);
|
||||
ts.add(STATISTICS, statistics_update, [&](void*) {
|
||||
handle_statistics();
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
void handle_uptime() {
|
||||
if (myUpTime.check()) {
|
||||
jsonWriteStr(configSetupJson, "uptime", uptime_as_string());
|
||||
}
|
||||
}
|
||||
|
||||
void handle_statistics() {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
String urls = "http://backup.privet.lv/visitors/?";
|
||||
//-----------------------------------------------------------------
|
||||
urls += WiFi.macAddress().c_str();
|
||||
urls += "&";
|
||||
//-----------------------------------------------------------------
|
||||
#ifdef ESP8266
|
||||
urls += "iot-manager_esp8266";
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
urls += "iot-manager_esp32";
|
||||
#endif
|
||||
urls += "&";
|
||||
//-----------------------------------------------------------------
|
||||
#ifdef ESP8266
|
||||
urls += ESP.getResetReason();
|
||||
//Serial.println(ESP.getResetReason());
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
urls += "Power on";
|
||||
#endif
|
||||
urls += "&";
|
||||
//-----------------------------------------------------------------
|
||||
urls += "ver: " + firmware_version;
|
||||
//-----------------------------------------------------------------
|
||||
String stat = getURL(urls);
|
||||
//Serial.println(stat);
|
||||
}
|
||||
}
|
||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Dmitry Borisenko
|
||||
|
||||
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.
|
||||
153
Logging.ino
Normal file
153
Logging.ino
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifdef logging_enable
|
||||
//===============================================Логирование============================================================
|
||||
//logging temp1 1 10 Температура Датчики 2
|
||||
void logging() {
|
||||
String value_name = sCmd.next();
|
||||
String period_min = sCmd.next();
|
||||
String maxCount = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
logging_value_names_list += value_name + ",";
|
||||
enter_to_logging_counter++; //считаем количество входов в эту функцию
|
||||
jsonWriteStr(configOptionJson, value_name + "_c", maxCount); //создаем в файловой системе переменную количества точек на графике с отметкой _c что значит count
|
||||
createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", value_name + "_ch", maxCount); //создаем график в приложении с топиком _ch /prefix/3234045-1589487/value_name_ch
|
||||
if (enter_to_logging_counter == LOG1) {
|
||||
ts.add(LOG1, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
String tmp_buf_1 = selectFromMarkerToMarker(logging_value_names_list, ",", 0);
|
||||
deleteOldDate("log." + tmp_buf_1 + ".txt", jsonReadInt(configOptionJson, tmp_buf_1 + "_c"), jsonReadStr(configLiveJson, tmp_buf_1));
|
||||
Serial.println("[i] LOGGING for sensor '" + tmp_buf_1 + "' done");
|
||||
}, nullptr, false);
|
||||
}
|
||||
if (enter_to_logging_counter == LOG2) {
|
||||
ts.add(LOG2, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
String tmp_buf_2 = selectFromMarkerToMarker(logging_value_names_list, ",", 1);
|
||||
deleteOldDate("log." + tmp_buf_2 + ".txt", jsonReadInt(configOptionJson, tmp_buf_2 + "_c"), jsonReadStr(configLiveJson, tmp_buf_2));
|
||||
Serial.println("[i] LOGGING for sensor '" + tmp_buf_2 + "' done");
|
||||
}, nullptr, false);
|
||||
}
|
||||
if (enter_to_logging_counter == LOG3) {
|
||||
ts.add(LOG3, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
String tmp_buf_3 = selectFromMarkerToMarker(logging_value_names_list, ",", 2);
|
||||
deleteOldDate("log." + tmp_buf_3 + ".txt", jsonReadInt(configOptionJson, tmp_buf_3 + "_c"), jsonReadStr(configLiveJson, tmp_buf_3));
|
||||
Serial.println("[i] LOGGING for sensor '" + tmp_buf_3 + "' done");
|
||||
}, nullptr, false);
|
||||
}
|
||||
if (enter_to_logging_counter == LOG4) {
|
||||
ts.add(LOG4, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
String tmp_buf_4 = selectFromMarkerToMarker(logging_value_names_list, ",", 3);
|
||||
deleteOldDate("log." + tmp_buf_4 + ".txt", jsonReadInt(configOptionJson, tmp_buf_4 + "_c"), jsonReadStr(configLiveJson, tmp_buf_4));
|
||||
Serial.println("[i] LOGGING for sensor '" + tmp_buf_4 + "' done");
|
||||
}, nullptr, false);
|
||||
}
|
||||
if (enter_to_logging_counter == LOG5) {
|
||||
ts.add(LOG5, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
String tmp_buf_5 = selectFromMarkerToMarker(logging_value_names_list, ",", 4);
|
||||
deleteOldDate("log." + tmp_buf_5 + ".txt", jsonReadInt(configOptionJson, tmp_buf_5 + "_c"), jsonReadStr(configLiveJson, tmp_buf_5));
|
||||
Serial.println("[i] LOGGING for sensor '" + tmp_buf_5 + "' done");
|
||||
}, nullptr, false);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================Удаление стрых данных и запись новых==================================================================
|
||||
void deleteOldDate(String file, int seted_number_of_lines, String date_to_add) {
|
||||
String log_date = readFile(file, 5000);
|
||||
int current_number_of_lines = count(log_date, "\r\n");
|
||||
Serial.println("=====> [i] in log file " + file + " " + current_number_of_lines + " lines");
|
||||
|
||||
if (current_number_of_lines > seted_number_of_lines + 1) {
|
||||
SPIFFS.remove("/" + file);
|
||||
current_number_of_lines = 0;
|
||||
}
|
||||
if (current_number_of_lines == 0) {
|
||||
SPIFFS.remove("/" + file);
|
||||
current_number_of_lines = 0;
|
||||
}
|
||||
if (current_number_of_lines > seted_number_of_lines) {
|
||||
log_date = deleteBeforeDelimiter(log_date, "\r\n");
|
||||
if (GetTimeUnix() != "failed") {
|
||||
log_date += GetTimeUnix() + " " + date_to_add + "\r\n";
|
||||
writeFile(file, log_date);
|
||||
}
|
||||
} else {
|
||||
if (GetTimeUnix() != "failed") {
|
||||
addFile(file, GetTimeUnix() + " " + date_to_add);
|
||||
}
|
||||
}
|
||||
log_date = "";
|
||||
}
|
||||
|
||||
//=========================================Выбор какие данные отправлять==================================================================
|
||||
void choose_log_date_and_send() {
|
||||
String all_line = logging_value_names_list;
|
||||
while (all_line.length() != 0) {
|
||||
String tmp = selectToMarker (all_line, ",");
|
||||
sendLogData("log." + tmp + ".txt", tmp + "_ch");
|
||||
all_line = deleteBeforeDelimiter(all_line, ",");
|
||||
}
|
||||
all_line = "";
|
||||
}
|
||||
//=========================================Отправка данных===================================================================================
|
||||
void sendLogData(String file, String topic) {
|
||||
String log_date = readFile(file, 5000);
|
||||
if (log_date != "Failed") {
|
||||
log_date.replace("\r\n", "\n");
|
||||
log_date.replace("\r", "\n");
|
||||
String buf = "{}";
|
||||
String json_array;
|
||||
String unix_time;
|
||||
String value;
|
||||
while (log_date.length() != 0) {
|
||||
String tmp = selectToMarker (log_date, "\n");
|
||||
log_date = deleteBeforeDelimiter(log_date, "\n");
|
||||
unix_time = selectToMarker (tmp, " ");
|
||||
jsonWriteInt(buf, "x", unix_time.toInt());
|
||||
value = deleteBeforeDelimiter(tmp, " ");
|
||||
jsonWriteFloat(buf, "y1", value.toFloat());
|
||||
if (log_date.length() < 3) {
|
||||
json_array += buf;
|
||||
} else {
|
||||
json_array += buf + ",";
|
||||
}
|
||||
buf = "{}";
|
||||
}
|
||||
unix_time = "";
|
||||
value = "";
|
||||
log_date = "";
|
||||
json_array = "{\"status\":[" + json_array + "]}";
|
||||
Serial.println(json_array);
|
||||
sendCHART(topic, json_array);
|
||||
json_array = "";
|
||||
getMemoryLoad("[i] after send log date");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//----------------------------------------------
|
||||
File configFile = SPIFFS.open("/" + file, "r");
|
||||
if (!configFile) {
|
||||
return;
|
||||
}
|
||||
configFile.seek(0, SeekSet); //поставим курсор в начало файла
|
||||
while (configFile.position() != configFile.size()) {
|
||||
String tmp = configFile.readStringUntil('\r\n');
|
||||
String unix_time = selectToMarker (tmp, " ");
|
||||
String value = deleteBeforeDelimiter(tmp, " ");
|
||||
String final_line = "{\"status\":{\"x\":" + unix_time + ",\"y1\":" + value + "}}";
|
||||
//Serial.println(final_line);
|
||||
sendCHART(topic, final_line);
|
||||
}
|
||||
getMemoryLoad("[i] after send log date");
|
||||
*/
|
||||
//=========================================Очистка данных===================================================================================
|
||||
void clean_log_date() {
|
||||
String all_line = logging_value_names_list;
|
||||
while (all_line.length() != 0) {
|
||||
String tmp = selectToMarker (all_line, ",");
|
||||
SPIFFS.remove("/log." + tmp + ".txt");
|
||||
all_line = deleteBeforeDelimiter(all_line, ",");
|
||||
}
|
||||
all_line = "";
|
||||
}
|
||||
#endif
|
||||
@@ -1,293 +0,0 @@
|
||||
# PrepareProject.py - инструмент для подготовки проекта к компиляции.
|
||||
# Необходимо вызвать при изменении персональных настроек или состава модулей.
|
||||
#
|
||||
# При отсутствии файла с персональными настройками, myProfile.json будет создан автоматически
|
||||
# python PrepareProject.py
|
||||
#
|
||||
# Если myProfile.json уже существует, можно запустить PrepareProject.py с параметром -u или --update для обновления списка модулей.
|
||||
# Данная функция будет полезна для разработчиков при добавлении модуля в папку src/modules
|
||||
# python PrepareProject.py --update
|
||||
# python PrepareProject.py -u
|
||||
#
|
||||
# Возможно использовать несколько вариантов персональных настроек и уточнять имя файла при запуске с использованием параметра -p или -profile
|
||||
# python PrepareProject.py --profile <ИмяФайла>
|
||||
# python PrepareProject.py -p <ИмяФайла>
|
||||
#
|
||||
# Используя параметры -b или --board <board_name> можно уточнить для какой платы нужно подготовить проект
|
||||
#
|
||||
# поддерживаемые контроллеры (профили):
|
||||
# esp8266_4mb
|
||||
# esp8266_16mb
|
||||
# esp32_4mb
|
||||
# esp32cam_4mb
|
||||
# esp32_16mb
|
||||
# esp32s2_4mb
|
||||
# esp8266_1mb
|
||||
# esp8266_1mb_ota
|
||||
# esp8285_1mb
|
||||
# esp8285_1mb_ota
|
||||
# esp8266_2mb
|
||||
# esp8266_2mb_ota
|
||||
|
||||
|
||||
import configparser
|
||||
import os, json, sys, getopt
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
|
||||
config = configparser.ConfigParser() # создаём объекта парсера INI
|
||||
|
||||
def printHelp():
|
||||
print('''Usage:
|
||||
PrepareProject.py
|
||||
-p --profile <file.json_in_root_folder>
|
||||
-u --update
|
||||
-h --help
|
||||
-b --board <board_name>''')
|
||||
with open('myProfile.json', "r", encoding='utf-8') as read_file:
|
||||
profJson = json.load(read_file)
|
||||
print ('')
|
||||
print ('Choose a board from the list:')
|
||||
# print(profJson['projectProp']['platformio']['comments_default_envs'])
|
||||
print (' ', end='')
|
||||
cnt = 0
|
||||
for envs in profJson['projectProp']['platformio']['envs']:
|
||||
if cnt == 5:
|
||||
cnt = 0
|
||||
print('')
|
||||
print(' ', end='')
|
||||
print(envs['name'] + ', ', end='')
|
||||
cnt = cnt + 1
|
||||
|
||||
|
||||
def updateModulesInProfile(profJson):
|
||||
profJson["modules"] = {}
|
||||
for root,d_names,f_names in os.walk("src/modules"):
|
||||
for fname in f_names:
|
||||
if fname == "modinfo.json":
|
||||
with open(os.path.join(root, fname), "r", encoding='utf-8') as read_file:
|
||||
modinfoJson = json.load(read_file)
|
||||
# проверяем есть ли уже узловой элемент и если нет, то создаем
|
||||
if not modinfoJson['menuSection'] in profJson["modules"]:
|
||||
listFromFirstElement = {modinfoJson['menuSection']: []}
|
||||
listFromFirstElement.update(profJson["modules"])
|
||||
profJson["modules"] = listFromFirstElement
|
||||
# добавляем информацию о модуле в узловой элемент
|
||||
profJson["modules"][modinfoJson['menuSection']].append({
|
||||
'path': os.path.normpath(root).replace("\\", "/"),
|
||||
'active': modinfoJson['defActive']
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
update = False # признак необходимости обновить список модулей
|
||||
profile = 'myProfile.json' # имя профиля. Будет заменено из консоли, если указано при старте
|
||||
selectDevice = '' # имя платы для которой хотим собрать, если её указали к командной строке -b <board>
|
||||
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, 'hp:ub:', ['help', 'profile=', 'update', 'board='])
|
||||
except getopt.GetoptError:
|
||||
print('Ошибка обработки параметров!')
|
||||
printHelp()
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
printHelp()
|
||||
sys.exit()
|
||||
elif opt in ("-p", "--profile"):
|
||||
print('Загрузка профиля из файла:' + arg)
|
||||
profile = arg
|
||||
elif opt in ("-u", "--update"):
|
||||
print('Создание новой конфигурации по исходным файлам!')
|
||||
update = True
|
||||
elif opt in ("-b", "--board"):
|
||||
print('Создание профиля для платы:' + arg)
|
||||
selectDevice = arg
|
||||
|
||||
if Path(profile).is_file():
|
||||
# подтягиваем уже существующий профиль
|
||||
with open(profile, "r", encoding='utf-8') as read_file:
|
||||
profJson = json.load(read_file)
|
||||
# если хотим обновить список модулей в существующем профиле
|
||||
if update:
|
||||
updateModulesInProfile(profJson)
|
||||
|
||||
# sortedListNames = sorted(profJson["modules"])
|
||||
# sortedModules = {}
|
||||
# for sortedModulName in sortedList:
|
||||
|
||||
# print(profJson)
|
||||
|
||||
with open(profile, "w", encoding='utf-8') as write_file:
|
||||
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
else:
|
||||
# если файла нет - создаем по образу настроек из проекта
|
||||
profJson = json.loads('{}')
|
||||
# копируем параметры IOTM из settings.json в новый профиль
|
||||
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
|
||||
profJson['iotmSettings'] = json.load(read_file)
|
||||
# устанавливаем параметры сборки
|
||||
profJson['projectProp'] = {
|
||||
'platformio': {
|
||||
'default_envs': 'esp8266_4mb'
|
||||
}
|
||||
}
|
||||
# загружаем список модулей для сборки
|
||||
updateModulesInProfile(profJson)
|
||||
# сохраняем новый профиль
|
||||
with open(profile, "w", encoding='utf-8') as write_file:
|
||||
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
deviceName = ''
|
||||
if selectDevice == '':
|
||||
# определяем какое устройство используется в профиле
|
||||
deviceName = profJson['projectProp']['platformio']['default_envs']
|
||||
else:
|
||||
for envs in profJson['projectProp']['platformio']['envs']:
|
||||
if envs['name'] == selectDevice:
|
||||
deviceName = selectDevice
|
||||
if deviceName == '':
|
||||
deviceName = profJson['projectProp']['platformio']['default_envs']
|
||||
print(f"\x1b[1;31;31m Board ", selectDevice, " not found in ",profile,"!!! Use ",deviceName," \x1b[0m")
|
||||
|
||||
# заполняем папку /data файлами прошивки в зависимости от устройства
|
||||
if deviceName == 'esp8266_1mb_ota' or deviceName == 'esp8285_1mb_ota' or deviceName == 'esp8266_2mb_ota':
|
||||
shutil.copytree("data_lite", "data_svelte", symlinks=False, ignore=None, ignore_dangling_symlinks=False, dirs_exist_ok=True)
|
||||
else:
|
||||
shutil.copytree("data_full", "data_svelte", symlinks=False, ignore=None, ignore_dangling_symlinks=False, dirs_exist_ok=True)
|
||||
|
||||
deviceType = 'esp32*'
|
||||
if not 'esp32' in deviceName:
|
||||
deviceType = 'esp82*'
|
||||
if 'bk72' in deviceName:
|
||||
deviceType = 'bk72*'
|
||||
# генерируем файлы проекта на основе подготовленного профиля
|
||||
# заполняем конфигурационный файл прошивки параметрами из профиля
|
||||
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
|
||||
iotmJson = json.load(read_file)
|
||||
for key, value in profJson['iotmSettings'].items():
|
||||
iotmJson[key] = value
|
||||
with open("data_svelte/settings.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(iotmJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
|
||||
# собираем меню прошивки из модулей
|
||||
# параллельно формируем список имен активных модулей
|
||||
# параллельно собираем необходимые активным модулям библиотеки для включения в компиляцию для текущего типа устройства (esp8266_4m, esp32_4mb, esp8266_1m, esp8266_1m_ota)
|
||||
activeModulesName = [] # список имен активных модулей
|
||||
allLibs = "" # подборка всех библиотек необходимых модулям для дальнейшей записи в конфигурацию platformio
|
||||
allDefs = "\n" # для каждого модуля создаем глобальный define
|
||||
itemsCount = 1
|
||||
includeDirs = "" # подборка путей ко всем модулям для дальнейшей записи в конфигурацию platformio
|
||||
itemsJson = json.loads('[{"name": "Выберите элемент", "num": 0}]')
|
||||
for section, modules in profJson['modules'].items():
|
||||
itemsJson.append({"header": section})
|
||||
for module in modules:
|
||||
if module['active']:
|
||||
with open(module['path'] + "/modinfo.json", "r", encoding='utf-8') as read_file:
|
||||
moduleJson = json.load(read_file)
|
||||
if 'moduleDefines' in moduleJson['about']:
|
||||
allDefs = allDefs + "\n".join("-D" + d for d in moduleJson['about']['moduleDefines'])
|
||||
if deviceName in moduleJson['usedLibs']: # проверяем поддерживает ли модуль текущее устройство
|
||||
if not 'exclude' in moduleJson['usedLibs'][deviceName]: # смотрим не нужно ли исключить данный модуль из указанной платы deviceName
|
||||
activeModulesName.append(moduleJson['about']['moduleName']) # запоминаем имена для использования на след шагах
|
||||
includeDirs = includeDirs + "\n+<" + module['path'].replace("src/", "") + ">" # запоминаем пути к модулям для компиляции
|
||||
for libPath in moduleJson['usedLibs'][deviceName]: # запоминаем библиотеки необходимые модулю для текущей платы
|
||||
allLibs = allLibs + "\n" + libPath
|
||||
for configItemsJson in moduleJson['configItem']:
|
||||
configItemsJson['num'] = itemsCount
|
||||
configItemsJson['name'] = str(itemsCount) + ". " + configItemsJson['name']
|
||||
itemsCount = itemsCount + 1
|
||||
configItemsJson['moduleName'] = moduleJson['about']['moduleName']
|
||||
itemsJson.append(configItemsJson)
|
||||
else: # В первую очередь ищем по имени deviceName, чтобы для данной платы можно было уточнить либы. Если не нашли плату по имени в usedLibs пробуем найти её по типу deviceType
|
||||
if deviceType in moduleJson['usedLibs']: # проверяем поддерживает ли модуль текущее устройство
|
||||
activeModulesName.append(moduleJson['about']['moduleName']) # запоминаем имена для использования на след шагах
|
||||
includeDirs = includeDirs + "\n+<" + module['path'].replace("src/", "") + ">" # запоминаем пути к модулям для компиляции
|
||||
for libPath in moduleJson['usedLibs'][deviceType]: # запоминаем библиотеки необходимые модулю для текущей платы
|
||||
allLibs = allLibs + "\n" + libPath
|
||||
for configItemsJson in moduleJson['configItem']:
|
||||
configItemsJson['num'] = itemsCount
|
||||
configItemsJson['name'] = str(itemsCount) + ". " + configItemsJson['name']
|
||||
itemsCount = itemsCount + 1
|
||||
itemsJson.append(configItemsJson)
|
||||
configItemsJson['moduleName'] = moduleJson['about']['moduleName']
|
||||
|
||||
with open("data_svelte/items.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(itemsJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
# учитываем вызовы модулей в API.cpp
|
||||
allAPI_head = ""
|
||||
allAPI_exec = ""
|
||||
for activModuleName in activeModulesName:
|
||||
allAPI_head = allAPI_head + "\nvoid* getAPI_" + activModuleName + "(String subtype, String params);"
|
||||
allAPI_exec = allAPI_exec + "\nif ((tmpAPI = getAPI_" + activModuleName + "(subtype, params)) != nullptr) foundAPI = tmpAPI;"
|
||||
apicpp = '#include "ESPConfiguration.h"\n'
|
||||
apicpp = apicpp + allAPI_head
|
||||
apicpp = apicpp + '\n\nvoid* getAPI(String subtype, String params) {\nvoid* tmpAPI; void* foundAPI = nullptr;'
|
||||
apicpp = apicpp + allAPI_exec
|
||||
apicpp = apicpp + '\nreturn foundAPI;\n}'
|
||||
with open('src/modules/API.cpp', 'w') as f:
|
||||
f.write(apicpp)
|
||||
|
||||
# корректируем параметры platformio
|
||||
# собираем пути всех отключенных модулей для исключения их из процесса компиляции
|
||||
# excludeDirs = ""
|
||||
# for root,d_names,f_names in os.walk("src\\modules"):
|
||||
# for fname in f_names:
|
||||
# if fname == "modinfo.json":
|
||||
# with open(root + "\\" + fname, "r", encoding='utf-8') as read_file:
|
||||
# modinfoJson = json.load(read_file)
|
||||
# if not modinfoJson['about']['moduleName'] in activeModulesName:
|
||||
# excludeDirs = excludeDirs + "\n-<" + root.replace("src\\", "") + ">"
|
||||
|
||||
# фиксируем изменения в platformio.ini
|
||||
config.clear()
|
||||
config.read("platformio.ini")
|
||||
config["env:" + deviceName + "_fromitems"]["lib_deps"] = allLibs
|
||||
config["env:" + deviceName + "_fromitems"]["build_src_filter"] = includeDirs
|
||||
config["env:" + deviceName + "_fromitems"]["build_flags"] = allDefs
|
||||
config["platformio"]["default_envs"] = deviceName
|
||||
if "${env:" + deviceName + "_fromitems.build_flags}" not in config["env:" + deviceName]["build_flags"]:
|
||||
config["env:" + deviceName]["build_flags"] += "\n${env:" + deviceName + "_fromitems.build_flags}"
|
||||
# config["platformio"]["data_dir"] = profJson['projectProp']['platformio']['data_dir']
|
||||
with open("platformio.ini", 'w') as configFile:
|
||||
config.write(configFile)
|
||||
|
||||
|
||||
# сохраняем часть применяемого профиля в папку data_svelte для загрузки на контроллер и дальнейшего переиспользования
|
||||
print(f"Saving profile {profile} in /data_svelte/flashProfile.json")
|
||||
shortProfJson = json.loads('{}')
|
||||
shortProfJson['projectProp'] = {
|
||||
'platformio': {
|
||||
'default_envs': deviceName
|
||||
}
|
||||
}
|
||||
shortProfJson['modules'] = profJson['modules']
|
||||
with open("data_svelte/flashProfile.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(shortProfJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
# import ctypes # An included library with Python install.
|
||||
# if update:
|
||||
# ctypes.windll.user32.MessageBoxW(0, "Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
|
||||
# else:
|
||||
# ctypes.windll.user32.MessageBoxW(0, "Профиль " + profile + " применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
|
||||
|
||||
if update:
|
||||
shutil.copy(profile, "compilerProfile.json")
|
||||
print(f"\x1b[1;31;42m Profile modules " + profile + " updated, profile applied, you can run compilation and firmware.\x1b[0m")
|
||||
|
||||
else:
|
||||
print(f"\x1b[1;31;42m Profile ", profile, " applied, you can run compilation and firmware.\x1b[0m")
|
||||
|
||||
# print(f"\x1b[1;32;41m Операция завершена. \x1b[0m")
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# подготавливаем папку для локального сервера обновлений
|
||||
# для этого компилируем проект и получаем бинарные файлы:
|
||||
# firmware.bin, littlefs.bin, partitions.bin и ver.json
|
||||
|
||||
import shutil
|
||||
import configparser
|
||||
import os, json, sys, getopt
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def copyFileIfExist(fileName, deviceName):
|
||||
srcFilePath = ".pio/build/" + deviceName + "/" + fileName
|
||||
dstFilePath = "iotm/" + deviceName + "/400/" + fileName
|
||||
if Path(srcFilePath).is_file():
|
||||
print("Ok...... \"" + srcFilePath + "\" на месте!")
|
||||
Path(dstFilePath).parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(srcFilePath, dstFilePath)
|
||||
return True
|
||||
else:
|
||||
print("Error...... \"" + srcFilePath + "\" НЕ существует!")
|
||||
return False
|
||||
|
||||
|
||||
config = configparser.ConfigParser() # создаём объекта парсера INI
|
||||
config.read("platformio.ini")
|
||||
deviceName = config["platformio"]["default_envs"]
|
||||
|
||||
homeDir = os.path.expanduser('~')
|
||||
os.system(homeDir + "/.platformio/penv/Scripts/pio run")
|
||||
os.system(homeDir + "/.platformio/penv/Scripts/pio run -t buildfs --disable-auto-clean")
|
||||
|
||||
if copyFileIfExist("firmware.bin", deviceName) and copyFileIfExist("littlefs.bin", deviceName):
|
||||
copyFileIfExist("partitions.bin", deviceName)
|
||||
versionsJson = json.loads('{"' + deviceName + '": {"0": "400"}}')
|
||||
with open("iotm/ver.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(versionsJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
print(f"\x1b[1;31;42m Сервер для обновления 'по воздуху' для " + deviceName + " подготовлен. Не забудьте установить расширение Live Server, запустить его и прописать в ESP IP вашего компьютера. Подробнее смотрите в WIKI: https://iotmanager.org/wiki.\x1b[0m")
|
||||
40
README.md
40
README.md
@@ -1,15 +1,37 @@
|
||||
# IoTManager
|
||||
# esp32-esp8266_iot-manager_modules_firmware
|
||||
|
||||
This is a smart home based on esp8266 and esp32 microcontrollers. These microcontrollers gained their popularity due to their low cost. Each such microcontroller is able to connect to your home wifi router. They can be purchased at any robotics store or on aliexpress, there are also ready-made devices based on them. This microcontroller has a certain number of pins on which digital signals are generated. Various peripheral devices can be connected to it: sensors, relays, stepper motors, servo drives, etc.
|
||||
It is based on esp8266 and esp32 automation system. Each module has a web interface for its initial configuration. The modules are managed using the "iot manager" application. This application is released for both android and ios platform. The application connects to a MQTT broker, you can add several brokers and switch between them. All modules also connect to same broker. All esp8266 esp32 are combined and appear in the application as widgets.
|
||||
|
||||
Our firmware allows you to receive data from all these devices and manage them. The iot manager app available for ios and android is used to display the data. In order to connect devices and the application, a special mqtt server is needed, in other words, an mqtt broker. All devices are first connected to a wifi router, and then to this mqtt broker, the application is also connected to it. As a result, through the application you can manage devices from anywhere in the world, monitor sensor readings, build graphs and much more. Broker mqtt can be used in the cloud, such as wqtt.ru, or your own, raised, for example, on a single-board computer raspberry pi. There is also a second way to manage devices, it works even when you do not have the Internet - control through a web browser. All your devices will be available on one page. Both methods, through the application or through the web, work simultaneously with full mutual synchronization.
|
||||
There are two configuration options in the web interface of the modules:
|
||||
|
||||
To achieve your goal, you only need three things:
|
||||
1. Select a ready-made preset.
|
||||
|
||||
1. Buy an esp microcontroller
|
||||
2. Download the app
|
||||
3. Get a cloud broker
|
||||
The following presets are available:
|
||||
|
||||
- On off relay
|
||||
- On off relay according to the schedule specified in the application
|
||||
- On off the relay after a period of time specified in the application
|
||||
- On off relay groups on different devices with one button in the application
|
||||
- Light switch module
|
||||
- PWM controlled by the slider in the application
|
||||
- Reading and logging analog input into graph with scaling function
|
||||
- Reading and logging in the graph of the following sensors:
|
||||
|
||||
DHT22, DHT33, DHT44, AM2302, RHT03
|
||||
DS18B20
|
||||
JSN-SR04T, HC-SR04, HY-SRF05
|
||||
BME280 BMP280 and other i2c sensors
|
||||
|
||||
-ds18b20 termostat controlled from application with graph (you can use any sensor for termostat any other supported).
|
||||
|
||||
2. Configure with special scripts. A simple programming language was invented which can very flexibly configure the module.
|
||||
|
||||
People who do not know how to program can use ready-made presets (option 1), and people who want to play with the system can use scripts (option 2).
|
||||
|
||||
Scenarios:
|
||||
|
||||
The web interface has the ability to configure Scenarios. An event occurs on one esp, and a reaction to this event can setup to occurs on another.
|
||||
|
||||
Logging of sensors data in this project made with out any server. All data for graf storring in esp flash. You can look any time your sensor history for 2 - 3 days or week in mobile app in graf. And for this option needed only esp.
|
||||
|
||||
If remote control and the application are not needed, then the last step can be omitted.
|
||||
|
||||
The logic of each device is configured using scripts. They are needed in order to teach the device to carry out your invented algorithms. You can assign any reaction to any action. The temperature has risen - the device will turn off the heater. Humidity has fallen and the level in the tank is more than 10% - the device will start watering, if not, it will send you a telegram notification that there is not enough water. These are just a few examples. Scenarios are created by you, and their flexibility will allow you to fulfill your every desire.
|
||||
|
||||
94
Scenario.ino
Normal file
94
Scenario.ino
Normal file
@@ -0,0 +1,94 @@
|
||||
void handleScenario() {
|
||||
|
||||
if (jsonReadStr(configSetupJson, "scen") == "1") {
|
||||
if ((jsonReadStr(configOptionJson, "scenario_status") != "")) {
|
||||
int i = 0;
|
||||
String str = scenario; //читаем переменную с сценариями (то что из файла на странице)
|
||||
str += "\n";
|
||||
str.replace("\r\n", "\n");
|
||||
str.replace("\r", "\n");
|
||||
while (str.length() != 0) {
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
String tmp = selectToMarker (str, "end"); //выделяем первый сценарий из файла вместе с командами
|
||||
if (tmp == "") return;
|
||||
i++;
|
||||
|
||||
if (scenario_line_status[i] == 1) {
|
||||
//Serial.println(i);
|
||||
String condition = selectToMarker (tmp, "\n"); //выделяем первую строку самого сценария button1 = 1 (условие)
|
||||
String param_name = selectFromMarkerToMarker(condition, " " , 0);
|
||||
String order = jsonReadStr(configOptionJson, "scenario_status"); //читаем весь файл событий
|
||||
String param = selectToMarker (order, ","); //читаем первое событие из файла событий
|
||||
if (param_name == param) { //если поступившее событие равно событию заданному buttonSet1 в файле начинаем его обработку
|
||||
|
||||
String sign = selectFromMarkerToMarker(condition, " " , 1); //читаем знак (=)
|
||||
String value = selectFromMarkerToMarker(condition, " " , 2); //читаем значение (1)
|
||||
if (value.indexOf("digit") != -1) {
|
||||
// value = add_set(value);
|
||||
value = jsonReadStr(configLiveJson, value);
|
||||
}
|
||||
if (value.indexOf("time") != -1) {
|
||||
// value = add_set(value);
|
||||
value = jsonReadStr(configLiveJson, value);
|
||||
}
|
||||
boolean flag = false; //если одно из значений совпало то только тогда начинаем выполнять комнады
|
||||
if (sign == "=") {
|
||||
if (jsonReadStr(configLiveJson, param_name) == value) flag = true;
|
||||
}
|
||||
if (sign == "!=") {
|
||||
if (jsonReadStr(configLiveJson, param_name) != value) flag = true;
|
||||
}
|
||||
if (sign == "<") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() < value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() > value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">=") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() >= value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == "<=") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() <= value.toInt()) flag = true;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
tmp = deleteBeforeDelimiter(tmp, "\n"); //удаляем строку самого сценария оставляя только команды
|
||||
stringExecution(tmp); //выполняем все команды
|
||||
|
||||
Serial.println("[SCENARIO] '" + condition + "'");
|
||||
//Serial.println(" " + tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
str = deleteBeforeDelimiter(str, "end\n"); //удаляем первый сценарий
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
String tmp2 = jsonReadStr(configOptionJson, "scenario_status"); //читаем файл событий
|
||||
tmp2 = deleteBeforeDelimiter(tmp2, ","); //удаляем выполненное событие
|
||||
jsonWriteStr(configOptionJson, "scenario_status", tmp2); //записываем обновленный файл событий
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eventGen (String event_name, String number) { //событие выглядит как имя плюс set плюс номер: button+Set+1
|
||||
|
||||
if (jsonReadStr(configSetupJson, "scen") == "1") {
|
||||
String tmp = jsonReadStr(configOptionJson, "scenario_status") ; //генерирование события
|
||||
//Serial.println(event_name);
|
||||
jsonWriteStr(configOptionJson, "scenario_status", tmp + event_name + number + ",");
|
||||
}
|
||||
}
|
||||
|
||||
String add_set(String param_name) {
|
||||
String num1 = param_name.substring(param_name.length() - 1);
|
||||
String num2 = param_name.substring(param_name.length() - 2, param_name.length() - 1);
|
||||
if (isDigitStr(num1) && isDigitStr(num2)) {
|
||||
param_name = param_name.substring(0, param_name.length() - 2) + "Set" + num2 + num1;
|
||||
} else {
|
||||
if (isDigitStr(num1)) {
|
||||
param_name = param_name.substring(0, param_name.length() - 1) + "Set" + num1;
|
||||
}
|
||||
}
|
||||
return param_name;
|
||||
}
|
||||
556
Sensors.ino
Normal file
556
Sensors.ino
Normal file
@@ -0,0 +1,556 @@
|
||||
void sensors_init() {
|
||||
ts.add(SENSORS, 1000, [&](void*) {
|
||||
static int counter;
|
||||
counter++;
|
||||
|
||||
#ifdef level_enable
|
||||
if (sensors_reading_map[0] == 1) level_reading();
|
||||
#endif
|
||||
|
||||
if (counter > 10) {
|
||||
counter = 0;
|
||||
|
||||
#ifdef analog_enable
|
||||
if (sensors_reading_map[1] == 1) analog_reading1();
|
||||
if (sensors_reading_map[2] == 1) analog_reading2();
|
||||
#endif
|
||||
|
||||
#ifdef dallas_enable
|
||||
if (sensors_reading_map[3] == 1) dallas_reading();
|
||||
#endif
|
||||
|
||||
#ifdef dht_enable
|
||||
if (sensors_reading_map[4] == 1) dhtT_reading();
|
||||
if (sensors_reading_map[5] == 1) dhtH_reading();
|
||||
if (sensors_reading_map[6] == 1) dhtP_reading();
|
||||
if (sensors_reading_map[7] == 1) dhtC_reading();
|
||||
if (sensors_reading_map[8] == 1) dhtD_reading();
|
||||
#endif
|
||||
|
||||
#ifdef bmp_enable
|
||||
if (sensors_reading_map[9] == 1) bmp280T_rading();
|
||||
if (sensors_reading_map[10] == 1) bmp280P_reading();
|
||||
#endif
|
||||
|
||||
#ifdef bme_enable
|
||||
if (sensors_reading_map[11] == 1) bme280T_reading();
|
||||
if (sensors_reading_map[12] == 1) bme280P_reading();
|
||||
if (sensors_reading_map[13] == 1) bme280H_reading();
|
||||
if (sensors_reading_map[14] == 1) bme280A_reading();
|
||||
#endif
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль измерения уровня в баке==================================================================
|
||||
#ifdef level_enable
|
||||
//level L 14 12 Вода#в#баке,#% Датчики fill-gauge 125 20 1
|
||||
void level() {
|
||||
String value_name = sCmd.next();
|
||||
String trig = sCmd.next();
|
||||
String echo = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String empty_level = sCmd.next();
|
||||
String full_level = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
level_value_name = value_name;
|
||||
jsonWriteStr(configOptionJson, "e_lev", empty_level);
|
||||
jsonWriteStr(configOptionJson, "f_lev", full_level);
|
||||
jsonWriteStr(configOptionJson, "trig", trig);
|
||||
jsonWriteStr(configOptionJson, "echo", echo);
|
||||
pinMode(trig.toInt(), OUTPUT);
|
||||
pinMode(echo.toInt(), INPUT);
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
sensors_reading_map[0] = 1;
|
||||
}
|
||||
|
||||
void level_reading() {
|
||||
long duration_;
|
||||
int distance_cm;
|
||||
int level;
|
||||
static int counter;
|
||||
int trig = jsonReadInt(configOptionJson, "trig");
|
||||
int echo = jsonReadInt(configOptionJson, "echo");
|
||||
digitalWrite(trig, LOW);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(trig, HIGH);
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(trig, LOW);
|
||||
duration_ = pulseIn(echo, HIGH, 30000); // 3000 µs = 50cm // 30000 µs = 5 m
|
||||
distance_cm = duration_ / 29 / 2;
|
||||
distance_cm = medianFilter.filtered(distance_cm);//отсечение промахов медианным фильтром
|
||||
counter++;
|
||||
if (counter > tank_level_times_to_send) {
|
||||
counter = 0;
|
||||
level = map(distance_cm,
|
||||
jsonReadInt(configOptionJson, "e_lev"),
|
||||
jsonReadInt(configOptionJson, "f_lev"), 0, 100);
|
||||
jsonWriteInt(configLiveJson, level_value_name, level);
|
||||
eventGen (level_value_name, "");
|
||||
sendSTATUS(level_value_name, String(level));
|
||||
Serial.println("[i] sensor '" + level_value_name + "' data: " + String(level));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль аналогового сенсора======================================================================
|
||||
#ifdef analog_enable
|
||||
//analog adc 0 Аналоговый#вход,#% Датчики any-data 1 1023 1 100 1
|
||||
void analog() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String analog_start = sCmd.next();
|
||||
String analog_end = sCmd.next();
|
||||
String analog_start_out = sCmd.next();
|
||||
String analog_end_out = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
analog_value_names_list += value_name + ",";
|
||||
enter_to_analog_counter++;
|
||||
jsonWriteStr(configOptionJson, value_name + "_st", analog_start);
|
||||
jsonWriteStr(configOptionJson, value_name + "_end", analog_end);
|
||||
jsonWriteStr(configOptionJson, value_name + "_st_out", analog_start_out);
|
||||
jsonWriteStr(configOptionJson, value_name + "_end_out", analog_end_out);
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
if (enter_to_analog_counter == 1) {
|
||||
sensors_reading_map[1] = 1;
|
||||
}
|
||||
if (enter_to_analog_counter == 2) {
|
||||
sensors_reading_map[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void analog_reading1() {
|
||||
String value_name = selectFromMarkerToMarker(analog_value_names_list, ",", 0);
|
||||
#ifdef ESP32
|
||||
int analog_in = analogRead(34);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
int analog_in = analogRead(A0);
|
||||
#endif
|
||||
int analog = map(analog_in,
|
||||
jsonReadInt(configOptionJson, value_name + "_st") ,
|
||||
jsonReadInt(configOptionJson, value_name + "_end"),
|
||||
jsonReadInt(configOptionJson, value_name + "_st_out"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end_out"));
|
||||
jsonWriteInt(configLiveJson, value_name, analog);
|
||||
eventGen (value_name, "");
|
||||
sendSTATUS(value_name, String(analog));
|
||||
Serial.println("[i] sensor '" + value_name + "' data: " + String(analog));
|
||||
}
|
||||
|
||||
void analog_reading2() {
|
||||
String value_name = selectFromMarkerToMarker(analog_value_names_list, ",", 1);
|
||||
#ifdef ESP32
|
||||
int analog_in = analogRead(35);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
int analog_in = analogRead(A0);
|
||||
#endif
|
||||
int analog = map(analog_in,
|
||||
jsonReadInt(configOptionJson, value_name + "_st") ,
|
||||
jsonReadInt(configOptionJson, value_name + "_end"),
|
||||
jsonReadInt(configOptionJson, value_name + "_st_out"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end_out"));
|
||||
jsonWriteInt(configLiveJson, value_name, analog);
|
||||
eventGen (value_name, "");
|
||||
sendSTATUS(value_name, String(analog));
|
||||
Serial.println("[i] sensor '" + value_name + "' data: " + String(analog));
|
||||
}
|
||||
#endif
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль температурного сенсора ds18b20===========================================================
|
||||
#ifdef dallas_enable
|
||||
void dallas() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
oneWire = new OneWire((uint8_t) pin.toInt());
|
||||
sensors.setOneWire(oneWire);
|
||||
sensors.begin();
|
||||
sensors.setResolution(12);
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, "dallas");
|
||||
sensors_reading_map[3] = 1;
|
||||
}
|
||||
|
||||
void dallas_reading() {
|
||||
float temp = 0;
|
||||
sensors.requestTemperatures();
|
||||
temp = sensors.getTempCByIndex(0);
|
||||
jsonWriteStr(configLiveJson, "dallas", String(temp));
|
||||
eventGen ("dallas", "");
|
||||
sendSTATUS("dallas", String(temp));
|
||||
Serial.println("[i] sensor 'dallas' send date " + String(temp));
|
||||
}
|
||||
#endif
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль сенсоров DHT=============================================================================
|
||||
#ifdef dht_enable
|
||||
//dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1
|
||||
void dhtT() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String sensor_type = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
dhtT_value_name = value_name;
|
||||
if (sensor_type == "dht11") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT11);
|
||||
}
|
||||
if (sensor_type == "dht22") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT22);
|
||||
}
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
sensors_reading_map[4] = 1;
|
||||
}
|
||||
|
||||
void dhtT_reading() {
|
||||
float value = 0;
|
||||
static int counter;
|
||||
if (dht.getStatus() != 0 && counter < 5) {
|
||||
sendSTATUS(dhtT_value_name, String(dht.getStatusString()));
|
||||
counter++;
|
||||
} else {
|
||||
counter = 0;
|
||||
value = dht.getTemperature();
|
||||
if (String(value) != "nan") {
|
||||
eventGen (dhtT_value_name, "");
|
||||
jsonWriteStr(configLiveJson, dhtT_value_name, String(value));
|
||||
sendSTATUS(dhtT_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + dhtT_value_name + "' data: " + String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//dhtH h 2 dht11 Влажность#DHT,#t°C Датчики any-data 1
|
||||
void dhtH() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String sensor_type = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
dhtH_value_name = value_name;
|
||||
if (sensor_type == "dht11") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT11);
|
||||
}
|
||||
if (sensor_type == "dht22") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT22);
|
||||
}
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
sensors_reading_map[5] = 1;
|
||||
}
|
||||
|
||||
void dhtH_reading() {
|
||||
float value = 0;
|
||||
static int counter;
|
||||
if (dht.getStatus() != 0 && counter < 5) {
|
||||
sendSTATUS(dhtH_value_name, String(dht.getStatusString()));
|
||||
counter++;
|
||||
} else {
|
||||
counter = 0;
|
||||
value = dht.getHumidity();
|
||||
if (String(value) != "nan") {
|
||||
eventGen (dhtH_value_name, "");
|
||||
jsonWriteStr(configLiveJson, dhtH_value_name, String(value));
|
||||
sendSTATUS(dhtH_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + dhtH_value_name + "' data: " + String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//dhtPerception Восприятие: Датчики 4
|
||||
void dhtP() {
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtPerception");
|
||||
sensors_reading_map[6] = 1;
|
||||
}
|
||||
|
||||
void dhtP_reading() {
|
||||
byte value;
|
||||
if (dht.getStatus() != 0) {
|
||||
sendSTATUS("dhtPerception", String(dht.getStatusString()));
|
||||
} else {
|
||||
value = dht.computePerception(jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
|
||||
String final_line = perception(value);
|
||||
jsonWriteStr(configLiveJson, "dhtPerception", final_line);
|
||||
eventGen ("dhtPerception", "");
|
||||
sendSTATUS("dhtPerception", final_line);
|
||||
if (client_mqtt.connected()) {
|
||||
Serial.println("[i] sensor 'dhtPerception' data: " + final_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String perception(byte value) {
|
||||
if (value == 0) return "Сухой воздух";
|
||||
if (value == 1) return "Комфортно";
|
||||
if (value == 2) return "Уютно";
|
||||
if (value == 3) return "Хорошо";
|
||||
if (value == 4) return "Неудобно";
|
||||
if (value == 5) return "Довольно неудобно";
|
||||
if (value == 6) return "Очень неудобно";
|
||||
if (value == 7) return "Сильно неудобно, полный звиздец";
|
||||
}
|
||||
|
||||
//dhtComfort Степень#комфорта: Датчики 3
|
||||
void dhtC() {
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtComfort");
|
||||
sensors_reading_map[7] = 1;
|
||||
}
|
||||
|
||||
void dhtC_reading() {
|
||||
float value;
|
||||
ComfortState cf;
|
||||
if (dht.getStatus() != 0) {
|
||||
sendSTATUS("dhtComfort", String(dht.getStatusString()));
|
||||
} else {
|
||||
value = dht.getComfortRatio(cf, jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
|
||||
String final_line = get_comfort_status(cf);
|
||||
jsonWriteStr(configLiveJson, "dhtComfort", final_line);
|
||||
eventGen ("dhtComfort", "");
|
||||
sendSTATUS("dhtComfort", final_line);
|
||||
Serial.println("[i] sensor 'dhtComfort' send date " + final_line);
|
||||
}
|
||||
}
|
||||
|
||||
String get_comfort_status(ComfortState cf) {
|
||||
String comfortStatus;
|
||||
switch (cf) {
|
||||
case Comfort_OK:
|
||||
comfortStatus = "Отлично";
|
||||
break;
|
||||
case Comfort_TooHot:
|
||||
comfortStatus = "Очень жарко";
|
||||
break;
|
||||
case Comfort_TooCold:
|
||||
comfortStatus = "Очень холодно";
|
||||
break;
|
||||
case Comfort_TooDry:
|
||||
comfortStatus = "Очень сухо";
|
||||
break;
|
||||
case Comfort_TooHumid:
|
||||
comfortStatus = "Очень влажно";
|
||||
break;
|
||||
case Comfort_HotAndHumid:
|
||||
comfortStatus = "Жарко и влажно";
|
||||
break;
|
||||
case Comfort_HotAndDry:
|
||||
comfortStatus = "Жарко и сухо";
|
||||
break;
|
||||
case Comfort_ColdAndHumid:
|
||||
comfortStatus = "Холодно и влажно";
|
||||
break;
|
||||
case Comfort_ColdAndDry:
|
||||
comfortStatus = "Холодно и сухо";
|
||||
break;
|
||||
default:
|
||||
comfortStatus = "Неизвестно";
|
||||
break;
|
||||
};
|
||||
return comfortStatus;
|
||||
}
|
||||
|
||||
|
||||
//dhtDewpoint Точка#росы: Датчики 5
|
||||
void dhtD() {
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtDewpoint");
|
||||
sensors_reading_map[8] = 1;
|
||||
}
|
||||
|
||||
void dhtD_reading() {
|
||||
float value;
|
||||
if (dht.getStatus() != 0) {
|
||||
sendSTATUS("dhtDewpoint", String(dht.getStatusString()));
|
||||
} else {
|
||||
value = dht.computeDewPoint(jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
|
||||
jsonWriteInt(configLiveJson, "dhtDewpoint", value);
|
||||
eventGen ("dhtDewpoint", "");
|
||||
sendSTATUS("dhtDewpoint", String(value));
|
||||
Serial.println("[i] sensor 'dhtDewpoint' data: " + String(value));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//=========================================i2c bus esp8266 scl-4 sda-5 ====================================================================
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль сенсоров bmp280==========================================================================
|
||||
#ifdef bmp_enable
|
||||
//bmp280T temp1 0x76 Температура#bmp280 Датчики any-data 1
|
||||
void bmp280T() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bmp280T_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bmp.begin(hexStringToUint8(address));
|
||||
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
|
||||
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
|
||||
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
|
||||
Adafruit_BMP280::FILTER_X16, /* Filtering. */
|
||||
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
|
||||
//bmp_temp->printSensorDetails();
|
||||
sensors_reading_map[9] = 1;
|
||||
}
|
||||
|
||||
void bmp280T_rading() {
|
||||
float value = 0;
|
||||
sensors_event_t temp_event, pressure_event;
|
||||
bmp_temp->getEvent(&temp_event);
|
||||
value = temp_event.temperature;
|
||||
jsonWriteStr(configLiveJson, bmp280T_value_name, String(value));
|
||||
eventGen(bmp280T_value_name, "");
|
||||
sendSTATUS(bmp280T_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bmp280T_value_name + "' data: " + String(value));
|
||||
}
|
||||
|
||||
//bmp280P press1 0x76 Давление#bmp280 Датчики any-data 2
|
||||
void bmp280P() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bmp280P_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bmp.begin(hexStringToUint8(address));
|
||||
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
|
||||
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
|
||||
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
|
||||
Adafruit_BMP280::FILTER_X16, /* Filtering. */
|
||||
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
|
||||
//bmp_temp->printSensorDetails();
|
||||
sensors_reading_map[10] = 1;
|
||||
}
|
||||
|
||||
void bmp280P_reading() {
|
||||
float value = 0;
|
||||
sensors_event_t temp_event, pressure_event;
|
||||
bmp_pressure->getEvent(&pressure_event);
|
||||
value = pressure_event.pressure;
|
||||
value = value / 1.333224;
|
||||
jsonWriteStr(configLiveJson, bmp280P_value_name, String(value));
|
||||
eventGen(bmp280P_value_name, "");
|
||||
sendSTATUS(bmp280P_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bmp280P_value_name + "' data: " + String(value));
|
||||
}
|
||||
#endif
|
||||
//=========================================================================================================================================
|
||||
//=============================================Модуль сенсоров bme280======================================================================
|
||||
#ifdef bme_enable
|
||||
//bme280T temp1 0x76 Температура#bmp280 Датчики any-data 1
|
||||
void bme280T() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bme280T_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bme.begin(hexStringToUint8(address));
|
||||
sensors_reading_map[11] = 1;
|
||||
}
|
||||
|
||||
void bme280T_reading() {
|
||||
float value = 0;
|
||||
value = bme.readTemperature();
|
||||
jsonWriteStr(configLiveJson, bme280T_value_name, String(value));
|
||||
eventGen(bme280T_value_name, "");
|
||||
sendSTATUS(bme280T_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bme280T_value_name + "' data: " + String(value));
|
||||
}
|
||||
|
||||
//bme280P pres1 0x76 Давление#bmp280 Датчики any-data 1
|
||||
void bme280P() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bme280P_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bme.begin(hexStringToUint8(address));
|
||||
sensors_reading_map[12] = 1;
|
||||
}
|
||||
|
||||
void bme280P_reading() {
|
||||
float value = 0;
|
||||
value = bme.readPressure();
|
||||
value = value / 1.333224;
|
||||
jsonWriteStr(configLiveJson, bme280P_value_name, String(value));
|
||||
eventGen(bme280P_value_name, "");
|
||||
sendSTATUS(bme280P_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bme280P_value_name + "' data: " + String(value));
|
||||
}
|
||||
|
||||
//bme280H hum1 0x76 Влажность#bmp280 Датчики any-data 1
|
||||
void bme280H() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bme280H_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bme.begin(hexStringToUint8(address));
|
||||
sensors_reading_map[13] = 1;
|
||||
}
|
||||
|
||||
void bme280H_reading() {
|
||||
float value = 0;
|
||||
value = bme.readHumidity();
|
||||
jsonWriteStr(configLiveJson, bme280H_value_name, String(value));
|
||||
eventGen(bme280H_value_name, "");
|
||||
sendSTATUS(bme280H_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bme280H_value_name + "' data: " + String(value));
|
||||
}
|
||||
|
||||
//bme280A altit1 0x76 Высота#bmp280 Датчики any-data 1
|
||||
void bme280A() {
|
||||
String value_name = sCmd.next();
|
||||
String address = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
bme280A_value_name = value_name;
|
||||
choose_widget_and_create(widget_name, page_name, page_number, type, value_name);
|
||||
bme.begin(hexStringToUint8(address));
|
||||
sensors_reading_map[14] = 1;
|
||||
}
|
||||
|
||||
void bme280A_reading() {
|
||||
float value = 0;
|
||||
value = bme.readAltitude(1013.25);
|
||||
jsonWriteStr(configLiveJson, bme280A_value_name, String(value));
|
||||
eventGen(bme280A_value_name, "");
|
||||
sendSTATUS(bme280A_value_name, String(value));
|
||||
Serial.println("[i] sensor '" + bme280A_value_name + "' data: " + String(value));
|
||||
}
|
||||
#endif
|
||||
87
Ticker_for_TickerScheduler/Ticker/Ticker.cpp
Normal file
87
Ticker_for_TickerScheduler/Ticker/Ticker.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Ticker.cpp - esp8266 library that calls functions periodically
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
|
||||
static const int ONCE = 0;
|
||||
static const int REPEAT = 1;
|
||||
|
||||
#include "Ticker.h"
|
||||
|
||||
Ticker::Ticker()
|
||||
: _timer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Ticker::~Ticker()
|
||||
{
|
||||
detach();
|
||||
}
|
||||
|
||||
void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg)
|
||||
{
|
||||
if (_timer)
|
||||
{
|
||||
os_timer_disarm(_timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_timer = new ETSTimer;
|
||||
}
|
||||
|
||||
os_timer_setfn(_timer, reinterpret_cast<ETSTimerFunc*>(callback), reinterpret_cast<void*>(arg));
|
||||
os_timer_arm(_timer, milliseconds, (repeat)?REPEAT:ONCE);
|
||||
}
|
||||
|
||||
void Ticker::detach()
|
||||
{
|
||||
if (!_timer)
|
||||
return;
|
||||
|
||||
os_timer_disarm(_timer);
|
||||
delete _timer;
|
||||
_timer = nullptr;
|
||||
_callback_function = nullptr;
|
||||
}
|
||||
|
||||
bool Ticker::active() const
|
||||
{
|
||||
return (bool)_timer;
|
||||
}
|
||||
|
||||
void Ticker::_static_callback(void* arg)
|
||||
{
|
||||
Ticker* _this = (Ticker*)arg;
|
||||
if (_this == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_this->_callback_function)
|
||||
{
|
||||
_this->_callback_function();
|
||||
}
|
||||
}
|
||||
136
Ticker_for_TickerScheduler/Ticker/Ticker.h
Normal file
136
Ticker_for_TickerScheduler/Ticker/Ticker.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Ticker.h - esp8266 library that calls functions periodically
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef TICKER_H
|
||||
#define TICKER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <functional>
|
||||
#include <Schedule.h>
|
||||
|
||||
extern "C" {
|
||||
typedef struct _ETSTIMER_ ETSTimer;
|
||||
}
|
||||
|
||||
class Ticker
|
||||
{
|
||||
public:
|
||||
Ticker();
|
||||
~Ticker();
|
||||
typedef void (*callback_t)(void);
|
||||
typedef void (*callback_with_arg_t)(void*);
|
||||
typedef std::function<void(void)> callback_function_t;
|
||||
|
||||
void attach_scheduled(float seconds, callback_function_t callback)
|
||||
{
|
||||
attach(seconds,std::bind(schedule_function, callback));
|
||||
}
|
||||
|
||||
void attach(float seconds, callback_function_t callback)
|
||||
{
|
||||
_callback_function = callback;
|
||||
attach(seconds, _static_callback, (void*)this);
|
||||
}
|
||||
|
||||
void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
|
||||
{
|
||||
attach_ms(milliseconds, std::bind(schedule_function, callback));
|
||||
}
|
||||
|
||||
void attach_ms(uint32_t milliseconds, callback_function_t callback)
|
||||
{
|
||||
_callback_function = callback;
|
||||
attach_ms(milliseconds, _static_callback, (void*)this);
|
||||
}
|
||||
|
||||
template<typename TArg>
|
||||
void attach(float seconds, void (*callback)(TArg), TArg arg)
|
||||
{
|
||||
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes");
|
||||
// C-cast serves two purposes:
|
||||
// static_cast for smaller integer types,
|
||||
// reinterpret_cast + const_cast for pointer types
|
||||
uint32_t arg32 = (uint32_t)arg;
|
||||
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
|
||||
}
|
||||
|
||||
template<typename TArg>
|
||||
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
|
||||
{
|
||||
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes");
|
||||
uint32_t arg32 = (uint32_t)arg;
|
||||
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
|
||||
}
|
||||
|
||||
void once_scheduled(float seconds, callback_function_t callback)
|
||||
{
|
||||
once(seconds, std::bind(schedule_function, callback));
|
||||
}
|
||||
|
||||
void once(float seconds, callback_function_t callback)
|
||||
{
|
||||
_callback_function = callback;
|
||||
once(seconds, _static_callback, (void*)this);
|
||||
}
|
||||
|
||||
void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
|
||||
{
|
||||
once_ms(milliseconds, std::bind(schedule_function, callback));
|
||||
}
|
||||
|
||||
void once_ms(uint32_t milliseconds, callback_function_t callback)
|
||||
{
|
||||
_callback_function = callback;
|
||||
once_ms(milliseconds, _static_callback, (void*)this);
|
||||
}
|
||||
|
||||
template<typename TArg>
|
||||
void once(float seconds, void (*callback)(TArg), TArg arg)
|
||||
{
|
||||
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes");
|
||||
uint32_t arg32 = (uint32_t)(arg);
|
||||
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
|
||||
}
|
||||
|
||||
template<typename TArg>
|
||||
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
|
||||
{
|
||||
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes");
|
||||
uint32_t arg32 = (uint32_t)(arg);
|
||||
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
|
||||
}
|
||||
|
||||
void detach();
|
||||
bool active() const;
|
||||
|
||||
protected:
|
||||
void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg);
|
||||
static void _static_callback (void* arg);
|
||||
|
||||
protected:
|
||||
ETSTimer* _timer;
|
||||
callback_function_t _callback_function = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif//TICKER_H
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Basic Ticker usage
|
||||
|
||||
Ticker is an object that will call a given function with a certain period.
|
||||
Each Ticker calls one function. You can have as many Tickers as you like,
|
||||
memory being the only limitation.
|
||||
|
||||
A function may be attached to a ticker and detached from the ticker.
|
||||
There are two variants of the attach function: attach and attach_ms.
|
||||
The first one takes period in seconds, the second one in milliseconds.
|
||||
|
||||
The built-in LED will be blinking.
|
||||
*/
|
||||
|
||||
#include <Ticker.h>
|
||||
|
||||
Ticker flipper;
|
||||
|
||||
int count = 0;
|
||||
|
||||
void flip() {
|
||||
int state = digitalRead(LED_BUILTIN); // get the current state of GPIO1 pin
|
||||
digitalWrite(LED_BUILTIN, !state); // set pin to the opposite state
|
||||
|
||||
++count;
|
||||
// when the counter reaches a certain value, start blinking like crazy
|
||||
if (count == 20) {
|
||||
flipper.attach(0.1, flip);
|
||||
}
|
||||
// when the counter reaches yet another value, stop blinking
|
||||
else if (count == 120) {
|
||||
flipper.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
||||
// flip the pin every 0.3s
|
||||
flipper.attach(0.3, flip);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "Arduino.h"
|
||||
#include "Ticker.h"
|
||||
|
||||
#define LED1 2
|
||||
#define LED2 4
|
||||
#define LED3 12
|
||||
#define LED4 14
|
||||
#define LED5 15
|
||||
|
||||
|
||||
class ExampleClass {
|
||||
public:
|
||||
ExampleClass(int pin, int duration) : _pin(pin), _duration(duration) {
|
||||
pinMode(_pin, OUTPUT);
|
||||
_myTicker.attach_ms(_duration, std::bind(&ExampleClass::classBlink, this));
|
||||
}
|
||||
~ExampleClass() {};
|
||||
|
||||
int _pin, _duration;
|
||||
Ticker _myTicker;
|
||||
|
||||
void classBlink() {
|
||||
digitalWrite(_pin, !digitalRead(_pin));
|
||||
}
|
||||
};
|
||||
|
||||
void staticBlink() {
|
||||
digitalWrite(LED2, !digitalRead(LED2));
|
||||
}
|
||||
|
||||
void scheduledBlink() {
|
||||
digitalWrite(LED3, !digitalRead(LED2));
|
||||
}
|
||||
|
||||
void parameterBlink(int p) {
|
||||
digitalWrite(p, !digitalRead(p));
|
||||
}
|
||||
|
||||
Ticker staticTicker;
|
||||
Ticker scheduledTicker;
|
||||
Ticker parameterTicker;
|
||||
Ticker lambdaTicker;
|
||||
|
||||
ExampleClass example(LED1, 100);
|
||||
|
||||
|
||||
void setup() {
|
||||
pinMode(LED2, OUTPUT);
|
||||
staticTicker.attach_ms(100, staticBlink);
|
||||
|
||||
pinMode(LED3, OUTPUT);
|
||||
scheduledTicker.attach_ms_scheduled(100, scheduledBlink);
|
||||
|
||||
pinMode(LED4, OUTPUT);
|
||||
parameterTicker.attach_ms(100, std::bind(parameterBlink, LED4));
|
||||
|
||||
pinMode(LED5, OUTPUT);
|
||||
lambdaTicker.attach_ms(100, []() {
|
||||
digitalWrite(LED5, !digitalRead(LED5));
|
||||
});
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Passing paramters to Ticker callbacks
|
||||
|
||||
Apart from void(void) functions, the Ticker library supports
|
||||
functions taking one argument. This argument's size has to be less or
|
||||
equal to 4 bytes (so char, short, int, float, void*, char* types will do).
|
||||
|
||||
This sample runs two tickers that both call one callback function,
|
||||
but with different arguments.
|
||||
|
||||
The built-in LED will be pulsing.
|
||||
*/
|
||||
|
||||
#include <Ticker.h>
|
||||
|
||||
Ticker tickerSetHigh;
|
||||
Ticker tickerSetLow;
|
||||
|
||||
void setPin(int state) {
|
||||
digitalWrite(LED_BUILTIN, state);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(1, LOW);
|
||||
|
||||
// every 25 ms, call setPin(0)
|
||||
tickerSetLow.attach_ms(25, setPin, 0);
|
||||
|
||||
// every 26 ms, call setPin(1)
|
||||
tickerSetHigh.attach_ms(26, setPin, 1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
29
Ticker_for_TickerScheduler/Ticker/keywords.txt
Normal file
29
Ticker_for_TickerScheduler/Ticker/keywords.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Wire
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
attach KEYWORD2
|
||||
attach_ms KEYWORD2
|
||||
once KEYWORD2
|
||||
once_ms KEYWORD2
|
||||
detach KEYWORD2
|
||||
active KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
Ticker KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
10
Ticker_for_TickerScheduler/Ticker/library.properties
Normal file
10
Ticker_for_TickerScheduler/Ticker/library.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=Ticker
|
||||
version=1.0
|
||||
author=Ivan Grokhtokov <ivan@esp8266.com>
|
||||
maintainer=Ivan Grokhtokov <ivan@esp8266.com>
|
||||
sentence=Allows to call functions with a given interval.
|
||||
paragraph=
|
||||
category=Timing
|
||||
url=
|
||||
architectures=esp8266
|
||||
dot_a_linkage=true
|
||||
131
Time.ino
Normal file
131
Time.ino
Normal file
@@ -0,0 +1,131 @@
|
||||
void Time_Init() {
|
||||
ts.add(TIME_SYNC, 30000, [&](void*) {
|
||||
time_check();
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
void time_check() {
|
||||
if (GetTimeUnix() == "failed") {
|
||||
Serial.println("[i] Time is not synchronized, start synchronization");
|
||||
reconfigTime();
|
||||
}
|
||||
}
|
||||
|
||||
void reconfigTime() {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
String ntp = jsonReadStr(configSetupJson, "ntp");
|
||||
configTime(0, 0, ntp.c_str());
|
||||
int i = 0;
|
||||
Serial.println("[i] Awaiting for time ");
|
||||
#ifdef ESP32
|
||||
struct tm timeinfo;
|
||||
while (!getLocalTime(&timeinfo) && i <= 4) {
|
||||
Serial.print(".");
|
||||
i++;
|
||||
delay(1000);
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
//while (!time(nullptr) && i < 4) {
|
||||
// Serial.print(".");
|
||||
// i++;
|
||||
delay(2000);
|
||||
//}
|
||||
#endif
|
||||
if (GetTimeUnix() != "failed") {
|
||||
Serial.print("[V] Time synchronized = ");
|
||||
Serial.print(GetDataDigital());
|
||||
Serial.print(" ");
|
||||
Serial.println(GetTime());
|
||||
} else {
|
||||
Serial.println("[E] Time server or internet connection error, will try again in 30 sec");
|
||||
}
|
||||
} else {
|
||||
Serial.println("[E] Get time impossible, no wifi connection");
|
||||
}
|
||||
}
|
||||
|
||||
//Получаем время в формате linux gmt
|
||||
String GetTimeUnix() {
|
||||
time_t now = time(nullptr);
|
||||
if (now < 30000) {
|
||||
return "failed";
|
||||
} else {
|
||||
return String(now);
|
||||
}
|
||||
}
|
||||
// Получение текущего времени
|
||||
String GetTime() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
|
||||
now = now + zone;
|
||||
String Time = ""; // Строка для результатов времени
|
||||
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
int i = Time.indexOf(":"); //Ишем позицию первого символа :
|
||||
Time = Time.substring(i - 2, i + 6); // Выделяем из строки 2 символа перед символом : и 6 символов после
|
||||
return Time; // Возврашаем полученное время
|
||||
}
|
||||
|
||||
String GetTimeWOsec() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
|
||||
now = now + zone;
|
||||
String Time = ""; // Строка для результатов времени
|
||||
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
int i = Time.indexOf(":"); //Ишем позицию первого символа :
|
||||
Time = Time.substring(i - 2, i + 3); // Выделяем из строки 2 символа перед символом : и 6 символов после
|
||||
return Time; // Возврашаем полученное время
|
||||
}
|
||||
|
||||
// Получение даты
|
||||
String GetDate() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
|
||||
now = now + zone;
|
||||
String Data = ""; // Строка для результатов времени
|
||||
Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
Data.replace("\n", "");
|
||||
uint8_t i = Data.lastIndexOf(" "); //Ишем позицию последнего символа пробел
|
||||
String Time = Data.substring(i - 8, i + 1); // Выделяем время и пробел
|
||||
Data.replace(Time, ""); // Удаляем из строки 8 символов времени и пробел
|
||||
return Data; // Возврашаем полученную дату
|
||||
}
|
||||
|
||||
String GetDataDigital() {
|
||||
String date = GetDate();
|
||||
|
||||
date = deleteBeforeDelimiter(date, " ");
|
||||
|
||||
date.replace("Jan", "01");
|
||||
date.replace("Feb", "02");
|
||||
date.replace("Mar", "03");
|
||||
date.replace("Apr", "04");
|
||||
date.replace("May", "05");
|
||||
date.replace("Jun", "06");
|
||||
date.replace("Jul", "07");
|
||||
date.replace("Aug", "08");
|
||||
date.replace("Sep", "09");
|
||||
date.replace("Oct", "10");
|
||||
date.replace("Nov", "11");
|
||||
date.replace("Dec", "12");
|
||||
|
||||
String month = date.substring(0, 2);
|
||||
String day = date.substring(3, 5);
|
||||
String year = date.substring(8, 10);
|
||||
|
||||
String out = day;
|
||||
out += ".";
|
||||
out += month;
|
||||
out += ".";
|
||||
out += year;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int timeToMin(String Time) {
|
||||
//"00:00:00" время в секунды
|
||||
long min = selectToMarker(Time, ":").toInt() * 60; //общее количество секунд в полных часах
|
||||
Time = deleteBeforeDelimiter (Time, ":"); // Теперь здесь минуты секунды
|
||||
min += selectToMarker(Time, ":").toInt(); // Добавим секунды из полных минут
|
||||
return min;
|
||||
}
|
||||
89
Timers.ino
Normal file
89
Timers.ino
Normal file
@@ -0,0 +1,89 @@
|
||||
//================================================================================================================
|
||||
//=========================================Таймеры=================================================================
|
||||
void Timer_countdown_init() {
|
||||
|
||||
ts.add(TIMER_COUNTDOWN, 1000, [&](void*) {
|
||||
|
||||
String old_line = jsonReadStr(configOptionJson, "timers");
|
||||
if (old_line != "") {
|
||||
//Serial.println(old_line);
|
||||
int i = 0;
|
||||
do {
|
||||
String timer = selectFromMarkerToMarker(old_line, "," , i);
|
||||
Serial.print("timer no " + String (i) + ": ");
|
||||
Serial.println(timer);
|
||||
if (timer == "not found" || timer == "") return;
|
||||
int number = selectToMarker (timer, ":").toInt();
|
||||
int time = readTimer(number);
|
||||
if (time == 0) {
|
||||
delTimer (String (number));
|
||||
jsonWriteStr(configLiveJson, "timer" + String(number), "0");
|
||||
eventGen ("timer", String(number));
|
||||
} else {
|
||||
time--;
|
||||
addTimer(String (number), String (time));
|
||||
}
|
||||
i++;
|
||||
} while (i <= 9);
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
void timerStart() {
|
||||
String number = sCmd.next();
|
||||
String period_of_time = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
if (period_of_time.indexOf("digit") != -1) {
|
||||
//period_of_time = add_set(period_of_time);
|
||||
period_of_time = jsonReadStr(configLiveJson, period_of_time);
|
||||
}
|
||||
if (type == "sec") period_of_time = period_of_time;
|
||||
if (type == "min") period_of_time = String(period_of_time.toInt() * 60);
|
||||
if (type == "hours") period_of_time = String(period_of_time.toInt() * 60 * 60);
|
||||
addTimer(number, period_of_time);
|
||||
jsonWriteStr(configLiveJson, "timer" + number, "1");
|
||||
}
|
||||
void addTimer(String number, String time) {
|
||||
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
|
||||
String new_timer = number + ":" + time;
|
||||
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо заменить
|
||||
if (psn1 != -1) { //если он есть
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
String timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо заменить
|
||||
///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке)
|
||||
tmp.replace(timer + ",", "");
|
||||
tmp += new_timer + ",";
|
||||
} else { //если его нет
|
||||
tmp += new_timer + ",";
|
||||
}
|
||||
jsonWriteStr(configOptionJson, "timers", tmp);
|
||||
//Serial.println("ura");
|
||||
}
|
||||
|
||||
void timerStop() {
|
||||
String number = sCmd.next();
|
||||
delTimer(number);
|
||||
}
|
||||
|
||||
void delTimer (String number) {
|
||||
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
|
||||
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо удалить
|
||||
if (psn1 != -1) { //если он есть
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
String timer = tmp.substring(psn1, psn2) + ","; //1:60, выделяем таймер который надо удалить
|
||||
tmp.replace(timer, ""); //удаляем таймер
|
||||
jsonWriteStr(configOptionJson, "timers", tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int readTimer(int number) {
|
||||
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
|
||||
int psn1 = tmp.indexOf(String(number) + ":"); //0 ищем позицию таймера который надо прочитать
|
||||
String timer;
|
||||
if (psn1 != -1) { //если он есть
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо прочитать
|
||||
timer = deleteBeforeDelimiter(timer, ":");
|
||||
}
|
||||
return timer.toInt();
|
||||
}
|
||||
234
Upgrade.ino
Normal file
234
Upgrade.ino
Normal file
@@ -0,0 +1,234 @@
|
||||
void initUpgrade() {
|
||||
#ifdef ESP8266
|
||||
if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt");
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt");
|
||||
#endif
|
||||
jsonWriteStr(configSetupJson, "last_version", last_version);
|
||||
Serial.print("[i] Last firmware version: ");
|
||||
Serial.println(last_version);
|
||||
}
|
||||
|
||||
void do_upgrade_url() {
|
||||
if (upgrade_url) {
|
||||
upgrade_url = false;
|
||||
#ifdef ESP32
|
||||
last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt");
|
||||
#endif
|
||||
jsonWriteStr(configSetupJson, "last_version", last_version);
|
||||
}
|
||||
}
|
||||
|
||||
void upgrade_firmware() {
|
||||
|
||||
String scenario_for_update;
|
||||
String config_for_update;
|
||||
String configSetup_for_update;
|
||||
scenario_for_update = readFile("firmware.s.txt", 4000);
|
||||
config_for_update = readFile("firmware.c.txt", 4000);
|
||||
configSetup_for_update = configSetupJson;
|
||||
|
||||
Serial.println("Start upgrade SPIFFS, please wait...");
|
||||
|
||||
WiFiClient client_for_upgrade;
|
||||
|
||||
#ifdef ESP32
|
||||
httpUpdate.rebootOnUpdate(false);
|
||||
t_httpUpdate_return ret = httpUpdate.updateSpiffs(client_for_upgrade, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
ESPhttpUpdate.rebootOnUpdate(false);
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(client_for_upgrade, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
|
||||
#endif
|
||||
|
||||
if (ret == HTTP_UPDATE_OK) {
|
||||
|
||||
writeFile("firmware.s.txt", scenario_for_update);
|
||||
writeFile("firmware.c.txt", config_for_update);
|
||||
writeFile("config.json", configSetup_for_update);
|
||||
saveConfig();
|
||||
|
||||
Serial.println("SPIFFS upgrade done!");
|
||||
Serial.println("Start upgrade BUILD, please wait...");
|
||||
|
||||
#ifdef ESP32
|
||||
//httpUpdate.rebootOnUpdate(true);
|
||||
t_httpUpdate_return ret = httpUpdate.update(client_for_upgrade, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
//ESPhttpUpdate.rebootOnUpdate(true);
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.update(client_for_upgrade, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
|
||||
#endif
|
||||
|
||||
if (ret == HTTP_UPDATE_OK) {
|
||||
|
||||
Serial.println("BUILD upgrade done!");
|
||||
Serial.println("Restart ESP....");
|
||||
ESP.restart();
|
||||
} else {
|
||||
Serial.println("!!!!BUILD upgrade ERROR");
|
||||
}
|
||||
} else {
|
||||
Serial.println("!!!!SPIFFS upgrade ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
void do_upgrade() {
|
||||
if (upgrade) {
|
||||
upgrade = false;
|
||||
upgrade_firmware();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void upgrade_status(t_httpUpdate_return set) {
|
||||
switch (set) {
|
||||
case HTTP_UPDATE_FAILED:
|
||||
Serial.printf("UPDATE_FAILED Error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
|
||||
break;
|
||||
|
||||
case HTTP_UPDATE_NO_UPDATES:
|
||||
Serial.println("NO_UPDATES");
|
||||
break;
|
||||
|
||||
case HTTP_UPDATE_OK:
|
||||
Serial.println("HTTP_UPDATE_OK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// ----------------------- Обновление с сайта
|
||||
void webUpgrade() {
|
||||
|
||||
#ifdef ESP8266
|
||||
String spiffsData = "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin";
|
||||
String buildData = "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.ino.bin";
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
String spiffsData = "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin";
|
||||
String buildData = "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin";
|
||||
#endif
|
||||
|
||||
if (spiffsData != "") { // Если нужно прошить FS
|
||||
String scenario_for_update;
|
||||
String config_for_update;
|
||||
String configSetup_for_update;
|
||||
Serial.println(spiffsData);
|
||||
scenario_for_update = readFile("firmware.s.txt", 2048);
|
||||
config_for_update = readFile("config.all.txt", 2048);
|
||||
configSetup_for_update = configSetup;
|
||||
ESPhttpUpdate.rebootOnUpdate(false); // Отключим перезагрузку после обновления
|
||||
updateHTTP(spiffsData, true);
|
||||
writeFile("firmware.s.txt", scenario_for_update);
|
||||
writeFile("config.all.txt", config_for_update);
|
||||
writeFile("config.json", configSetup_for_update);
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (buildData != "") { // Если нужно прошить build
|
||||
Serial.println(buildData);
|
||||
ESPhttpUpdate.rebootOnUpdate(true); // Включим перезагрузку после обновления
|
||||
updateHTTP(buildData, false);
|
||||
}
|
||||
}
|
||||
// ------------------ Обновление по url
|
||||
void updateHTTP(String url, boolean mode) {
|
||||
if (url == "") return;
|
||||
ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW);
|
||||
if (mode) {
|
||||
Serial.println("Update Spiffs...");
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(url);
|
||||
UpdateStatus(ret , "Spiffs");
|
||||
} else {
|
||||
Serial.println("Update Build...");
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.update(url);
|
||||
UpdateStatus(ret , "build");
|
||||
}
|
||||
}
|
||||
void UpdateStatus(t_httpUpdate_return set, String mode) {
|
||||
|
||||
switch (set) {
|
||||
|
||||
case HTTP_UPDATE_FAILED:
|
||||
Serial.println(mode + "_FAILED");
|
||||
var = "{}";
|
||||
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_FAILED");
|
||||
jsonWriteStr(var, "class", "pop-up");
|
||||
//request->send(200, "text/text", var);
|
||||
break;
|
||||
|
||||
case HTTP_UPDATE_NO_UPDATES:
|
||||
Serial.println(mode + "_NO_UPDATES");
|
||||
var = "{}";
|
||||
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_NO_UPDATES");
|
||||
jsonWriteStr(var, "class", "pop-up");
|
||||
//request->send(200, "text/text", var);
|
||||
break;
|
||||
|
||||
case HTTP_UPDATE_OK:
|
||||
Serial.println(mode + "_UPDATE_OK");
|
||||
var = "{}";
|
||||
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_UPDATE_OK");
|
||||
jsonWriteStr(var, "class", "pop-up");
|
||||
//request->send(200, "text/text", var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
352
Web.ino
Normal file
352
Web.ino
Normal file
@@ -0,0 +1,352 @@
|
||||
void web_init() {
|
||||
server.on("/set", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
String value;
|
||||
//============================device settings=====================================
|
||||
if (request->hasArg("preset")) {
|
||||
//--------------------------------------------------------------------------------
|
||||
String value;
|
||||
value = request->getParam("preset")->value();
|
||||
if (value == "1") {
|
||||
writeFile("firmware.c.txt", readFile("configs/1-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/1-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "2") {
|
||||
writeFile("firmware.c.txt", readFile("configs/2-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/2-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "3") {
|
||||
writeFile("firmware.c.txt", readFile("configs/3-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/3-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "4") {
|
||||
writeFile("firmware.c.txt", readFile("configs/4-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/4-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "5") {
|
||||
writeFile("firmware.c.txt", readFile("configs/5-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/5-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "6") {
|
||||
writeFile("firmware.c.txt", readFile("configs/6-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/6-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "7") {
|
||||
writeFile("firmware.c.txt", readFile("configs/7-relay.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/7-relay.s.txt", 2048));
|
||||
}
|
||||
if (value == "8") {
|
||||
writeFile("firmware.c.txt", readFile("configs/8-pwm.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/8-pwm.s.txt", 2048));
|
||||
}
|
||||
if (value == "9") {
|
||||
writeFile("firmware.c.txt", readFile("configs/9-dht11.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/9-dht11.s.txt", 2048));
|
||||
}
|
||||
if (value == "10") {
|
||||
writeFile("firmware.c.txt", readFile("configs/10-dht22.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/10-dht22.s.txt", 2048));
|
||||
}
|
||||
if (value == "11") {
|
||||
writeFile("firmware.c.txt", readFile("configs/11-analog.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/11-analog.s.txt", 2048));
|
||||
}
|
||||
if (value == "12") {
|
||||
writeFile("firmware.c.txt", readFile("configs/12-bmp280.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/12-bmp280.s.txt", 2048));
|
||||
}
|
||||
if (value == "13") {
|
||||
writeFile("firmware.c.txt", readFile("configs/13-bme280.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/13-bme280.s.txt", 2048));
|
||||
}
|
||||
if (value == "14") {
|
||||
writeFile("firmware.c.txt", readFile("configs/14-dallas.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/14-dallas.s.txt", 2048));
|
||||
}
|
||||
if (value == "15") {
|
||||
writeFile("firmware.c.txt", readFile("configs/15-termostat.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/15-termostat.s.txt", 2048));
|
||||
}
|
||||
if (value == "16") {
|
||||
writeFile("firmware.c.txt", readFile("configs/16-level.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/16-level.s.txt", 2048));
|
||||
}
|
||||
if (value == "17") {
|
||||
writeFile("firmware.c.txt", readFile("configs/17-moution.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/17-moution.s.txt", 2048));
|
||||
}
|
||||
if (value == "18") {
|
||||
writeFile("firmware.c.txt", readFile("configs/18-moution.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/18-moution.s.txt", 2048));
|
||||
}
|
||||
if (value == "19") {
|
||||
writeFile("firmware.c.txt", readFile("configs/19-stepper.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/19-stepper.s.txt", 2048));
|
||||
}
|
||||
if (value == "20") {
|
||||
writeFile("firmware.c.txt", readFile("configs/20-servo.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/20-servo.s.txt", 2048));
|
||||
}
|
||||
if (value == "21") {
|
||||
writeFile("firmware.c.txt", readFile("configs/firmware.c.txt", 2048));
|
||||
writeFile("firmware.s.txt", readFile("configs/firmware.s.txt", 2048));
|
||||
}
|
||||
Device_init();
|
||||
Scenario_init();
|
||||
request->redirect("/?set.device");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("devinit")) {
|
||||
Device_init();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("scen")) {
|
||||
value = request->getParam("scen")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "scen", value);
|
||||
saveConfig();
|
||||
Scenario_init();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "scen", value);
|
||||
saveConfig();
|
||||
Scenario_init();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("sceninit")) {
|
||||
Scenario_init();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
#ifdef logging_enable
|
||||
if (request->hasArg("cleanlog")) {
|
||||
clean_log_date();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
#endif
|
||||
//==============================udp settings=============================================
|
||||
if (request->hasArg("udponoff")) {
|
||||
value = request->getParam("udponoff")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "udponoff", value);
|
||||
saveConfig();
|
||||
Scenario_init();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "udponoff", value);
|
||||
saveConfig();
|
||||
Scenario_init();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("updatelist")) {
|
||||
SPIFFS.remove("/dev.csv");
|
||||
addFile("dev.csv", "device id;device name;ip address");
|
||||
request->redirect("/?set.udp");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("updatepage")) {
|
||||
request->redirect("/?set.udp");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("devname")) {
|
||||
jsonWriteStr(configSetupJson, "name", request->getParam("devname")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//==============================wifi settings=============================================
|
||||
if (request->hasArg("routerssid")) {
|
||||
jsonWriteStr(configSetupJson, "routerssid", request->getParam("routerssid")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("routerpass")) {
|
||||
jsonWriteStr(configSetupJson, "routerpass", request->getParam("routerpass")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("apssid")) {
|
||||
jsonWriteStr(configSetupJson, "apssid", request->getParam("apssid")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("appass")) {
|
||||
jsonWriteStr(configSetupJson, "appass", request->getParam("appass")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("weblogin")) {
|
||||
jsonWriteStr(configSetupJson, "weblogin", request->getParam("weblogin")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("webpass")) {
|
||||
jsonWriteStr(configSetupJson, "webpass", request->getParam("webpass")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("timezone")) {
|
||||
jsonWriteStr(configSetupJson, "timezone", request->getParam("timezone")->value());
|
||||
saveConfig();
|
||||
reconfigTime();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("ntp")) {
|
||||
jsonWriteStr(configSetupJson, "ntp", request->getParam("ntp")->value());
|
||||
saveConfig();
|
||||
reconfigTime();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("device")) {
|
||||
if (request->getParam("device")->value() == "ok") ESP.restart();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("blink")) {
|
||||
value = request->getParam("blink")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "blink", value);
|
||||
saveConfig();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "blink", value);
|
||||
saveConfig();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//==============================mqtt settings=============================================
|
||||
if (request->hasArg("mqttServer")) {
|
||||
jsonWriteStr(configSetupJson, "mqttServer", request->getParam("mqttServer")->value());
|
||||
saveConfig();
|
||||
mqtt_connection = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPort")) {
|
||||
int port = (request->getParam("mqttPort")->value()).toInt();
|
||||
jsonWriteInt(configSetupJson, "mqttPort", port);
|
||||
saveConfig();
|
||||
mqtt_connection = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPrefix")) {
|
||||
jsonWriteStr(configSetupJson, "mqttPrefix", request->getParam("mqttPrefix")->value());
|
||||
saveConfig();
|
||||
mqtt_connection = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttUser")) {
|
||||
jsonWriteStr(configSetupJson, "mqttUser", request->getParam("mqttUser")->value());
|
||||
saveConfig();
|
||||
mqtt_connection = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPass")) {
|
||||
jsonWriteStr(configSetupJson, "mqttPass", request->getParam("mqttPass")->value());
|
||||
saveConfig();
|
||||
mqtt_connection = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("mqttsend")) {
|
||||
mqtt_send_settings_to_udp = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("mqttcheck")) {
|
||||
String tmp = "{}";
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>" + stateMQTT());
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
request->send(200, "text/text", tmp);
|
||||
}
|
||||
//==============================push settings=============================================
|
||||
#ifdef push_enable
|
||||
if (request->hasArg("pushingboxid")) {
|
||||
jsonWriteStr(configSetupJson, "pushingboxid", request->getParam("pushingboxid")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
#endif
|
||||
//==============================utilities settings=============================================
|
||||
if (request->hasArg("itoc")) {
|
||||
i2c_scanning = true;
|
||||
request->redirect("/?set.utilities");
|
||||
}
|
||||
});
|
||||
//==============================upgrade settings=============================================
|
||||
server.on("/check", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
upgrade_url = true;
|
||||
Serial.print("[i] Last firmware version: ");
|
||||
Serial.println(last_version);
|
||||
String tmp = "{}";
|
||||
int case_of_update;
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) last_version = "nowifi";
|
||||
if (!mb_4_of_memory) last_version = "less";
|
||||
|
||||
if (last_version == firmware_version) case_of_update = 1;
|
||||
if (last_version != firmware_version) case_of_update = 2;
|
||||
if (last_version == "error") case_of_update = 3;
|
||||
if (last_version == "") case_of_update = 4;
|
||||
if (last_version == "less") case_of_update = 5;
|
||||
if (last_version == "nowifi") case_of_update = 6;
|
||||
if (last_version == "notsupported") case_of_update = 7;
|
||||
|
||||
switch (case_of_update) {
|
||||
case 1: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Последняя версия прошивки уже установлена.");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Имеется новая версия прошивки<a href=\"#\" class=\"btn btn-block btn-danger\" onclick=\"send_request(this, '/upgrade');setTimeout(function(){ location.href='/'; }, 120000);html('my-block','<span class=loader></span>Идет обновление прошивки, после обновления страница перезагрузится автоматически...')\">Установить</a>");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Ошибка... Cервер не найден. Попробуйте позже...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Нажмите на кнопку \"обновить прошивку\" повторно...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Обновление по воздуху не поддерживается, модуль имеет меньше 4 мб памяти...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Устройство не подключено к роутеру...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Обновление на новую версию возможно только через usb...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
}
|
||||
request->send(200, "text/text", tmp);
|
||||
});
|
||||
|
||||
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
upgrade = true;
|
||||
String tmp = "{}";
|
||||
request->send(200, "text/text", "ok");
|
||||
});
|
||||
}
|
||||
232
Web_server.ino
Normal file
232
Web_server.ino
Normal file
@@ -0,0 +1,232 @@
|
||||
void Web_server_init() {
|
||||
/*********************************************************************************
|
||||
***************************************OTA****************************************
|
||||
*********************************************************************************/
|
||||
#ifdef OTA_enable
|
||||
ArduinoOTA.onStart([]() {
|
||||
events.send("Update Start", "ota");
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
events.send("Update End", "ota");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
char p[32];
|
||||
sprintf(p, "Progress: %u%%\n", (progress / (total / 100)));
|
||||
events.send(p, "ota");
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
if (error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
|
||||
else if (error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
|
||||
else if (error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
|
||||
else if (error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
|
||||
else if (error == OTA_END_ERROR) events.send("End Failed", "ota");
|
||||
});
|
||||
ArduinoOTA.setHostname(hostName);
|
||||
ArduinoOTA.begin();
|
||||
#endif
|
||||
/*********************************************************************************
|
||||
**************************************MDNS****************************************
|
||||
*********************************************************************************/
|
||||
#ifdef MDNS_enable
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
#endif
|
||||
//SPIFFS.begin();
|
||||
/*********************************************************************************
|
||||
**************************************WS******************************************
|
||||
*********************************************************************************/
|
||||
#ifdef WS_enable
|
||||
ws.onEvent(onWsEvent);
|
||||
server.addHandler(&ws);
|
||||
|
||||
events.onConnect([](AsyncEventSourceClient * client) {
|
||||
//!!!client->send("hello!", NULL, millis(), 1000);
|
||||
});
|
||||
|
||||
server.addHandler(&events);
|
||||
#endif
|
||||
/*********************************************************************************
|
||||
**************************************WEB****************************************
|
||||
*********************************************************************************/
|
||||
#ifdef ESP32
|
||||
server.addHandler(new SPIFFSEditor(SPIFFS, jsonReadStr(configSetupJson, "web_login").c_str(), jsonReadStr(configSetupJson, "web_pass").c_str()));
|
||||
#elif defined(ESP8266)
|
||||
server.addHandler(new SPIFFSEditor(jsonReadStr(configSetupJson, "web_login").c_str(), jsonReadStr(configSetupJson, "web_pass").c_str()));
|
||||
#endif
|
||||
|
||||
/* server.on("/heap", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "text/plain", String(ESP.getFreeHeap()));
|
||||
});*/
|
||||
|
||||
server.serveStatic("/css/", SPIFFS, "/css/").setCacheControl("max-age=31536000");
|
||||
server.serveStatic("/js/", SPIFFS, "/js/").setCacheControl("max-age=31536000");
|
||||
server.serveStatic("/favicon.ico", SPIFFS, "/favicon.ico").setCacheControl("max-age=31536000");
|
||||
server.serveStatic("/icon.jpeg", SPIFFS, "/icon.jpeg").setCacheControl("max-age=31536000");
|
||||
|
||||
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm")
|
||||
.setAuthentication(jsonReadStr(configSetupJson, "web_login").c_str(), jsonReadStr(configSetupJson, "web_pass").c_str());
|
||||
|
||||
server.onNotFound([](AsyncWebServerRequest * request) {
|
||||
Serial.printf("NOT_FOUND: ");
|
||||
if (request->method() == HTTP_GET)
|
||||
Serial.printf("GET");
|
||||
else if (request->method() == HTTP_POST)
|
||||
Serial.printf("POST");
|
||||
else if (request->method() == HTTP_DELETE)
|
||||
Serial.printf("DELETE");
|
||||
else if (request->method() == HTTP_PUT)
|
||||
Serial.printf("PUT");
|
||||
else if (request->method() == HTTP_PATCH)
|
||||
Serial.printf("PATCH");
|
||||
else if (request->method() == HTTP_HEAD)
|
||||
Serial.printf("HEAD");
|
||||
else if (request->method() == HTTP_OPTIONS)
|
||||
Serial.printf("OPTIONS");
|
||||
else
|
||||
Serial.printf("UNKNOWN");
|
||||
Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str());
|
||||
|
||||
if (request->contentLength()) {
|
||||
Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str());
|
||||
Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength());
|
||||
}
|
||||
|
||||
int headers = request->headers();
|
||||
int i;
|
||||
for (i = 0; i < headers; i++) {
|
||||
AsyncWebHeader* h = request->getHeader(i);
|
||||
Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||
}
|
||||
|
||||
int params = request->params();
|
||||
for (i = 0; i < params; i++) {
|
||||
AsyncWebParameter* p = request->getParam(i);
|
||||
if (p->isFile()) {
|
||||
Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
|
||||
} else if (p->isPost()) {
|
||||
Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||
} else {
|
||||
Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
request->send(404);
|
||||
});
|
||||
|
||||
|
||||
server.onFileUpload([](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!index)
|
||||
Serial.printf("UploadStart: %s\n", filename.c_str());
|
||||
Serial.printf("%s", (const char*)data);
|
||||
if (final)
|
||||
Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index + len);
|
||||
});
|
||||
|
||||
|
||||
server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
|
||||
if (!index)
|
||||
Serial.printf("BodyStart: %u\n", total);
|
||||
Serial.printf("%s", (const char*)data);
|
||||
if (index + len == total)
|
||||
Serial.printf("BodyEnd: %u\n", total);
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
// --------------------Выдаем данные configJson //config.live.json - динамические данные
|
||||
server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", configLiveJson);
|
||||
});
|
||||
// --------------------Выдаем данные optionJson //config.option.json - данные не являющиеся событиями
|
||||
server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", configOptionJson);
|
||||
});
|
||||
// -------------------Выдаем данные configSetup //config.setup.json - для хранения постоянных данных
|
||||
server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", configSetupJson);
|
||||
});
|
||||
|
||||
// ------------------Выполнение команды из запроса
|
||||
//http://192.168.88.45/cmd?command=rel%201%201
|
||||
server.on("/cmd", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
String com = request->getParam("command")->value();
|
||||
Serial.println(com);
|
||||
order_loop += com + ",";
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
}
|
||||
/*********************************************************************************************************************************
|
||||
*********************************************************WS**********************************************************************
|
||||
********************************************************************************************************************************/
|
||||
#ifdef WS_enable
|
||||
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
if (type == WS_EVT_CONNECT) {
|
||||
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
|
||||
client->printf(json.c_str(), client->id());
|
||||
//client->ping();
|
||||
} else if (type == WS_EVT_DISCONNECT) {
|
||||
Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id());
|
||||
} else if (type == WS_EVT_ERROR) {
|
||||
Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
|
||||
} else if (type == WS_EVT_PONG) {
|
||||
Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char*)data : "");
|
||||
} else if (type == WS_EVT_DATA) {
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
String msg = "";
|
||||
if (info->final && info->index == 0 && info->len == len) {
|
||||
//the whole message is in a single frame and we got all of it's data
|
||||
Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len);
|
||||
|
||||
if (info->opcode == WS_TEXT) {
|
||||
for (size_t i = 0; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for (size_t i = 0; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n", msg.c_str());
|
||||
|
||||
if (info->opcode == WS_TEXT)
|
||||
client->text("{}");
|
||||
else
|
||||
client->binary("{}");
|
||||
} else {
|
||||
//message is comprised of multiple frames or the frame is split into multiple packets
|
||||
if (info->index == 0) {
|
||||
if (info->num == 0)
|
||||
Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
|
||||
Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
}
|
||||
|
||||
Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len);
|
||||
|
||||
if (info->opcode == WS_TEXT) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n", msg.c_str());
|
||||
|
||||
if ((info->index + len) == info->len) {
|
||||
Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
if (info->final) {
|
||||
Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
|
||||
if (info->message_opcode == WS_TEXT)
|
||||
client->text("I got your text message");
|
||||
else
|
||||
client->binary("I got your binary message");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
162
WiFi.ino
Normal file
162
WiFi.ino
Normal file
@@ -0,0 +1,162 @@
|
||||
void ROUTER_Connecting() {
|
||||
|
||||
led_blink("slow");
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
byte tries = 20;
|
||||
String _ssid = jsonReadStr(configSetupJson, "routerssid");
|
||||
String _password = jsonReadStr(configSetupJson, "routerpass");
|
||||
//WiFi.persistent(false);
|
||||
|
||||
if (_ssid == "" && _password == "") {
|
||||
WiFi.begin();
|
||||
}
|
||||
else {
|
||||
WiFi.begin(_ssid.c_str(), _password.c_str());
|
||||
Serial.print("ssid: ");
|
||||
Serial.println(_ssid);
|
||||
}
|
||||
// Делаем проверку подключения до тех пор пока счетчик tries
|
||||
// не станет равен нулю или не получим подключение
|
||||
while (--tries && WiFi.status() != WL_CONNECTED) {
|
||||
if (WiFi.status() == WL_CONNECT_FAILED) {
|
||||
Serial.println("[E] password is not correct");
|
||||
tries = 1;
|
||||
jsonWriteInt(configOptionJson, "pass_status", 1);
|
||||
}
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
// Если не удалось подключиться запускаем в режиме AP
|
||||
Serial.println("");
|
||||
// WiFi.disconnect(true);
|
||||
StartAPMode();
|
||||
|
||||
}
|
||||
else {
|
||||
// Иначе удалось подключиться отправляем сообщение
|
||||
// о подключении и выводим адрес IP
|
||||
Serial.println("");
|
||||
Serial.println("[V] WiFi connected");
|
||||
Serial.print("[V] IP address: http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println("");
|
||||
jsonWriteStr(configSetupJson, "ip", WiFi.localIP().toString());
|
||||
led_blink("off");
|
||||
//add_dev_in_list("dev.txt", chipID, WiFi.localIP().toString());
|
||||
MQTT_init();
|
||||
}
|
||||
}
|
||||
|
||||
bool StartAPMode() {
|
||||
Serial.println("WiFi up AP");
|
||||
WiFi.disconnect();
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
String _ssidAP = jsonReadStr(configSetupJson, "apssid");
|
||||
String _passwordAP = jsonReadStr(configSetupJson, "appass");
|
||||
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
|
||||
IPAddress myIP = WiFi.softAPIP();
|
||||
led_blink("on");
|
||||
Serial.print("AP IP address: ");
|
||||
Serial.println(myIP);
|
||||
jsonWriteStr(configSetupJson, "ip", myIP.toString());
|
||||
|
||||
//if (jsonReadInt(configOptionJson, "pass_status") != 1) {
|
||||
ts.add(ROUTER_SEARCHING, 10 * 1000, [&](void*) {
|
||||
Serial.println("->try find router");
|
||||
if (RouterFind(jsonReadStr(configSetupJson, "routerssid"))) {
|
||||
ts.remove(ROUTER_SEARCHING);
|
||||
WiFi.scanDelete();
|
||||
ROUTER_Connecting();
|
||||
}
|
||||
}, nullptr, true);
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
boolean RouterFind(String ssid) {
|
||||
int n = WiFi.scanComplete ();
|
||||
Serial.println("n = " + String(n));
|
||||
if (n == -2) { //Сканирование не было запущено, запускаем
|
||||
Serial.println("[WIFI][i] scanning has not been triggered, starting scanning");
|
||||
WiFi.scanNetworks (true, false); //async, show_hidden
|
||||
return false;
|
||||
}
|
||||
if (n == -1) { //Сканирование все еще выполняется
|
||||
Serial.println("[WIFI][i] scanning still in progress");
|
||||
return false;
|
||||
}
|
||||
if (n == 0) { //ни одна сеть не найдена
|
||||
Serial.println("[WIFI][i] no any wifi sations, starting scanning");
|
||||
WiFi.scanNetworks (true, false);
|
||||
return false;
|
||||
}
|
||||
if (n > 0) {
|
||||
for (int i = 0; i <= n; i++) {
|
||||
if (WiFi.SSID (i) == ssid) {
|
||||
WiFi.scanDelete();
|
||||
return true;
|
||||
} else {
|
||||
Serial.print(i);
|
||||
Serial.print(")");
|
||||
//Serial.print(ssid);
|
||||
//Serial.print("<=>");
|
||||
if (i == n) {
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.println("; ");
|
||||
} else {
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.println("; ");
|
||||
}
|
||||
}
|
||||
}
|
||||
WiFi.scanDelete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
String scanWIFI() {
|
||||
uint8_t n = WiFi.scanNetworks();
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonObject& json = jsonBuffer.createObject();
|
||||
JsonArray& networks = json.createNestedArray("networks");
|
||||
for (uint8_t i = 0; i < n; i++) {
|
||||
JsonObject& data = networks.createNestedObject();
|
||||
String ssidMy = WiFi.SSID(i);
|
||||
data["routerssid"] = ssidMy;
|
||||
data["pass"] = (WiFi.encryptionType(i) == ENC_TYPE_NONE) ? "" : "*";
|
||||
int8_t dbm = WiFi.RSSI(i);
|
||||
data["dbm"] = dbm;
|
||||
if (ssidMy == jsonReadStr(configSetupJson, "routerssid")) {
|
||||
jsonWriteStr(configLiveJson, "dbm", dbm);
|
||||
}
|
||||
}
|
||||
String root;
|
||||
json.printTo(root);
|
||||
return root;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
{
|
||||
"type":"wifi",
|
||||
"title":"{{LangWiFi1}}",
|
||||
"name":"routerssid",
|
||||
"state":"{{ssid}}",
|
||||
"pattern":".{1,}"
|
||||
},
|
||||
{
|
||||
"type":"routerpass",
|
||||
"title":"{{LangPass}}",
|
||||
"name":"routerpass",
|
||||
"state":"{{ssidPass}}",
|
||||
"pattern":".{8,}"
|
||||
},
|
||||
*/
|
||||
88
Widgets.ino
Normal file
88
Widgets.ino
Normal file
@@ -0,0 +1,88 @@
|
||||
//======================================================================================================================
|
||||
//===============================================Создание виджетов=======================================================
|
||||
void createWidget (String widget_name, String page_name, String page_number, String file, String topic) {
|
||||
|
||||
String widget;
|
||||
widget = readFile(file, 1024);
|
||||
|
||||
if (widget == "Failed") return;
|
||||
if (widget == "Large") return;
|
||||
|
||||
widget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
jsonWriteStr(widget, "page", page_name);
|
||||
jsonWriteStr(widget, "order", page_number);
|
||||
jsonWriteStr(widget, "descr", widget_name);
|
||||
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
||||
|
||||
#ifdef layout_in_ram
|
||||
all_widgets += widget + "\r\n";
|
||||
#else
|
||||
addFile("layout.txt", widget);
|
||||
#endif
|
||||
widget = "";
|
||||
}
|
||||
|
||||
void createWidgetParam (String widget_name, String page_name, String page_number, String file, String topic, String name1, String param1, String name2, String param2, String name3, String param3) {
|
||||
|
||||
String widget;
|
||||
widget = readFile(file, 1024);
|
||||
|
||||
if (widget == "Failed") return;
|
||||
if (widget == "Large") return;
|
||||
|
||||
widget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
jsonWriteStr(widget, "page", page_name);
|
||||
jsonWriteStr(widget, "order", page_number);
|
||||
jsonWriteStr(widget, "descr", widget_name);
|
||||
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
||||
|
||||
if (name1 != "") jsonWriteStr(widget, name1, param1);
|
||||
if (name2 != "") jsonWriteStr(widget, name2, param2);
|
||||
if (name3 != "") jsonWriteStr(widget, name3, param3);
|
||||
|
||||
#ifdef layout_in_ram
|
||||
all_widgets += widget + "\r\n";
|
||||
#else
|
||||
addFile("layout.txt", widget);
|
||||
#endif
|
||||
widget = "";
|
||||
}
|
||||
|
||||
void createChart (String widget_name, String page_name, String page_number, String file, String topic, String maxCount) {
|
||||
|
||||
String widget;
|
||||
widget = readFile(file, 1024);
|
||||
|
||||
if (widget == "Failed") return;
|
||||
if (widget == "Large") return;
|
||||
|
||||
widget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
jsonWriteStr(widget, "page", page_name);
|
||||
jsonWriteStr(widget, "order", page_number);
|
||||
//jsonWriteStr(widget, "descr", widget_name);
|
||||
jsonWriteStr(widget, "series", widget_name);
|
||||
jsonWriteStr(widget, "maxCount", maxCount);
|
||||
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
||||
|
||||
#ifdef layout_in_ram
|
||||
all_widgets += widget + "\r\n";
|
||||
#else
|
||||
addFile("layout.txt", widget);
|
||||
#endif
|
||||
widget = "";
|
||||
}
|
||||
|
||||
void choose_widget_and_create(String widget_name, String page_name, String page_number, String type, String topik) {
|
||||
|
||||
if (type == "any-data") createWidget (widget_name, page_name, page_number, "widgets/widget.anyData.json", topik);
|
||||
if (type == "progress-line") createWidget (widget_name, page_name, page_number, "widgets/widget.progLine.json", topik);
|
||||
if (type == "progress-round") createWidget (widget_name, page_name, page_number, "widgets/widget.progRound.json", topik);
|
||||
if (type == "fill-gauge") createWidget (widget_name, page_name, page_number, "widgets/widget.fillGauge.json", topik);
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
33
bus.ino
Normal file
33
bus.ino
Normal file
@@ -0,0 +1,33 @@
|
||||
void do_i2c_scanning() {
|
||||
if (i2c_scanning) {
|
||||
i2c_scanning = false;
|
||||
String tmp = i2c_scan();
|
||||
if (tmp == "error") {
|
||||
tmp = i2c_scan();
|
||||
Serial.println(tmp);
|
||||
jsonWriteStr(configLiveJson, "i2c", tmp);
|
||||
} else {
|
||||
Serial.println(tmp);
|
||||
jsonWriteStr(configLiveJson, "i2c", tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String i2c_scan() {
|
||||
String out;
|
||||
byte count = 0;
|
||||
Wire.begin();
|
||||
for (byte i = 8; i < 120; i++) {
|
||||
Wire.beginTransmission(i);
|
||||
if (Wire.endTransmission() == 0) {
|
||||
count++;
|
||||
out += String(count) + ". 0x" + String(i, HEX) + "; ";
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
return "error";
|
||||
} else {
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -1,515 +0,0 @@
|
||||
{
|
||||
"iotmSettings": {
|
||||
"name": "IoTmanagerVer4",
|
||||
"apssid": "IoTmanager",
|
||||
"appass": "",
|
||||
"routerssid": "iot",
|
||||
"routerpass": "hostel3333",
|
||||
"timezone": 2,
|
||||
"ntp": "pool.ntp.org",
|
||||
"weblogin": "admin",
|
||||
"webpass": "admin",
|
||||
"mqttServer": "",
|
||||
"mqttPort": 8021,
|
||||
"mqttPrefix": "/risenew",
|
||||
"mqttUser": "rise",
|
||||
"mqttPass": "3hostel3",
|
||||
"serverip": "http://iotmanager.org",
|
||||
"log": 0,
|
||||
"mqttin": 0,
|
||||
"pinSCL": 0,
|
||||
"pinSDA": 0,
|
||||
"i2cFreq": 100000,
|
||||
"wg": "group1"
|
||||
},
|
||||
"projectProp": {
|
||||
"platformio": {
|
||||
"default_envs": "esp8266_4mb",
|
||||
"comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32cam_4mb or esp32s2_4mb or esp32_4mb3f or esp32s3_16mb or esp32c3m_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota",
|
||||
"envs": [
|
||||
{
|
||||
"name": "esp8266_4mb",
|
||||
"firmware": "0x00000",
|
||||
"littlefs": "0x300000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_16mb",
|
||||
"firmware": "0x00000",
|
||||
"littlefs": "0x200000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x290000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_4mb3f",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32cam_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_16mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x910000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_1mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000bb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_1mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000eb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_2mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x00100000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_2mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x001c0000"
|
||||
},
|
||||
{
|
||||
"name": "esp8285_1mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000bb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8285_1mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000eb000"
|
||||
},
|
||||
{
|
||||
"name": "esp32s2_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x290000"
|
||||
},
|
||||
{
|
||||
"name": "esp32c3m_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32s3_16mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x910000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"virtual_elments": [
|
||||
{
|
||||
"path": "src/modules/virtual/Benchmark",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Cron",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/GoogleSheet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Loging",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/LogingDaily",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Math",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/owmWeather",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Ping",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Timer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Variable",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/VButton",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Weather",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"sensors": [
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8591",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/A02Distance",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Acs712",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ads1115",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AhtXX",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AnalogAdc",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BH_1750",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BL0937",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part1",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bme280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bmp280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Dht1122",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds18b20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/DS2401",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Emon",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/EnergyMon485",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExampleModule",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExternalMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/FreqMeter",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/GY21",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hdc1080",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx710",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx711",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Impulse",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina219",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina226",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/IoTWiegand",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ld2410",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Max6675",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Mhz19",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/MQgas",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ntc",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t_v2",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RCswitch",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RTC",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/S8",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Scd40",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sds011",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sgp30",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht30",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sonar",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/UART",
|
||||
"active": true
|
||||
}
|
||||
],
|
||||
"executive_devices": [
|
||||
{
|
||||
"path": "src/modules/exec/AnalogBtn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/BrokerMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonIn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonOut",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Buzzer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Enconder",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/EspCam",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Ftp",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/HttpGet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/IoTServo",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23008",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23017",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mp3",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Multitouch",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/MySensors",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8574",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm32",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm8266",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SDcard",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SIM800",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SmartBoiler",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SysExt",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/TelegramLT",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram_v2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Thermostat",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds2423",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"screens": [
|
||||
{
|
||||
"path": "src/modules/display/DwinI",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Lcd2004",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Nextion",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/NextionUpload",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled128",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled64",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Smi2_m",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/TM16XX",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Ws2812b",
|
||||
"active": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
2
data/.exclude.files
Normal file
2
data/.exclude.files
Normal file
@@ -0,0 +1,2 @@
|
||||
/*.js.gz
|
||||
/.exclude.files
|
||||
21
data/config.json
Normal file
21
data/config.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "IoTmanager",
|
||||
"chipID": "",
|
||||
"apssid": "IoTmanager",
|
||||
"appass": "",
|
||||
"routerssid": "rise",
|
||||
"routerpass": "hostel3333",
|
||||
"timezone": 2,
|
||||
"ntp": "pool.ntp.org",
|
||||
"mqttServer": "91.204.228.124",
|
||||
"mqttPort": 1883,
|
||||
"mqttPrefix": "/rise",
|
||||
"mqttUser": "test",
|
||||
"mqttPass": "test",
|
||||
"scen": "1",
|
||||
"pushingboxid": "v7C133E426B0C69E",
|
||||
"weblogin": "admin",
|
||||
"webpass": "admin",
|
||||
"udponoff": "1",
|
||||
"blink":"1"
|
||||
}
|
||||
3
data/configs/1-relay.c.txt
Normal file
3
data/configs/1-relay.c.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
button 1 5 Включить#реле Реле 0 1
|
||||
|
||||
//это простая кнопка номер 1 управляющая пином 5 имеющая начальное состояние 0
|
||||
1
data/configs/1-relay.s.txt
Normal file
1
data/configs/1-relay.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
7
data/configs/10-dht22.c.txt
Normal file
7
data/configs/10-dht22.c.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
dhtT t 2 dht22 Температура#DHT,#t°C Датчики any-data 1
|
||||
dhtH h 2 dht22 Влажность#DHT,#t°C Датчики any-data 2
|
||||
dhtComfort Степень#комфорта: Датчики 3
|
||||
dhtPerception Восприятие: Датчики 4
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
logging t 1 50 Температура Датчики 6
|
||||
logging h 1 50 Влажность Датчики 7
|
||||
1
data/configs/10-dht22.s.txt
Normal file
1
data/configs/10-dht22.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
8
data/configs/11-analog.c.txt
Normal file
8
data/configs/11-analog.c.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
analog adc 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1
|
||||
logging adc 5 100 Аналоговый#вход Датчики 2
|
||||
|
||||
//если датчик углекислого газа выдает напряжение от 1 вольта до 2 вольт, то значит
|
||||
//значение чтения аналогового входа будут примерно равным
|
||||
//при 1 вольте - 310, а при 2 вольтах - 620 (считаем по пропорции)
|
||||
//данная строка переведет диапазон 310-620 в диапазон 1-100 и отобразит в приложении
|
||||
//варианты отображения: any-data, progress-round, progress-line, fill-gauge
|
||||
1
data/configs/11-analog.s.txt
Normal file
1
data/configs/11-analog.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
6
data/configs/12-bmp280.c.txt
Normal file
6
data/configs/12-bmp280.c.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
bmp280T temp1 0x76 Температура#bmp280 Датчики any-data 1
|
||||
bmp280P press1 0x76 Давление#bmp280 Датчики any-data 2
|
||||
logging temp1 1 100 Температура Датчики 3
|
||||
logging press1 1 100 Давление Датчики 4
|
||||
|
||||
//Чтение и логгирование датчика bmp280. Датчик подключается к шине i2c (esp8266 - gpio 5, 4)
|
||||
1
data/configs/12-bmp280.s.txt
Normal file
1
data/configs/12-bmp280.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
9
data/configs/13-bme280.c.txt
Normal file
9
data/configs/13-bme280.c.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
bme280T temp1 0x76 Температура#bmp280 Датчики any-data 1
|
||||
bme280P pres1 0x76 Давление#bmp280 Датчики any-data 2
|
||||
bme280H hum1 0x76 Влажность#bmp280 Датчики any-data 3
|
||||
bme280A altit1 0x76 Высота#bmp280 Датчики any-data 4
|
||||
logging temp1 1 100 Температура Датчики 5
|
||||
logging press1 1 100 Давление Датчики 6
|
||||
logging hum1 1 100 Влажность Датчики 7
|
||||
|
||||
//Чтение и логгирование датчика bme280. Датчик подключается к шине i2c (esp8266 - gpio 5, 4)
|
||||
1
data/configs/13-bme280.s.txt
Normal file
1
data/configs/13-bme280.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
5
data/configs/14-dallas.c.txt
Normal file
5
data/configs/14-dallas.c.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
dallas 2 Водонагреватель,#t°C Датчики any-data 1
|
||||
logging dallas 1 100 Температура Датчики 2
|
||||
|
||||
//2 - номер пина датчика
|
||||
//варианты отображения: any-data, progress-round, progress-line, fill-gauge
|
||||
1
data/configs/14-dallas.s.txt
Normal file
1
data/configs/14-dallas.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
12
data/configs/15-termostat.c.txt
Normal file
12
data/configs/15-termostat.c.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
dallas 2 Водонагреватель,#t°C Термостат any-data 1
|
||||
logging dallas 5 100 Температура Термостат 2
|
||||
inputDigit digit1 При#скольки#выключить? Термостат 40 3
|
||||
inputDigit digit2 При#скольки#включить? Термостат 20 4
|
||||
button 1 5 Нагреватель Термостат 0 5
|
||||
button 2 line1,line2, Автоматический#режим Термостат 1 6
|
||||
|
||||
//2 - номер пина датчика
|
||||
//5 - номер пина реле
|
||||
//это термостат который будет держать температуру между двумя
|
||||
//установленными в приложении значениями, так же можно выключить
|
||||
//автоматический режим, и тогда нагреватель будет управляться в ручную
|
||||
6
data/configs/15-termostat.s.txt
Normal file
6
data/configs/15-termostat.s.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
dallas > digit1
|
||||
buttonSet 1 0
|
||||
end
|
||||
dallas < digit2
|
||||
buttonSet 1 1
|
||||
end
|
||||
11
data/configs/16-level.c.txt
Normal file
11
data/configs/16-level.c.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
level lev 14 12 Вода#в#баке,#% Датчики fill-gauge 125 20 1
|
||||
inputDigit digit1 При#скольки#выключить? Датчики 95 2
|
||||
inputDigit digit2 При#скольки#включить? Датчики 10 3
|
||||
button 1 5 Насос Датчики 0 4
|
||||
button 2 line1,line2, Автоматический#режим Датчики 1 5
|
||||
logging lev 1 100 Вода#в#баке Датчики 6
|
||||
|
||||
//125 - это расстояние от датчика до дна бака в сантиметрах
|
||||
//20 - это расстояние от датчика до поверхности воды когда бак полный в сантиметрах
|
||||
//вывод данных будет в процентах заполнения бака
|
||||
//варианты отображения: any-data, progress-round, progress-line, fill-gauge
|
||||
6
data/configs/16-level.s.txt
Normal file
6
data/configs/16-level.s.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
lev > digit1
|
||||
buttonSet 1 0
|
||||
end
|
||||
lev < digit2
|
||||
buttonSet 1 1
|
||||
end
|
||||
11
data/configs/17-moution.c.txt
Normal file
11
data/configs/17-moution.c.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
button 1 5 Прихожая Освещение 0 1
|
||||
inputDigit digit1 Задержка#выключения Освещение 30 2
|
||||
switch 1 0 10
|
||||
|
||||
//0 - номер пина датчика движения
|
||||
//5 - номер пина реле
|
||||
//при срабатывании датчика движения включится реле и обратный таймер на 30 сек
|
||||
//если движение не будет обнаружено повтороно в течении 30 секунд - свет выключится
|
||||
//если движение повторится в течении 30 секунд то таймер продлится опять на 30 сек
|
||||
//свет выключится только в том случае если в комнате все замрет на 30 сек
|
||||
//задержку выключения можно будет настраивать в приложении
|
||||
7
data/configs/17-moution.s.txt
Normal file
7
data/configs/17-moution.s.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
switch1 = 1
|
||||
timerStart 1 digit1 sec
|
||||
buttonSet 1 1
|
||||
end
|
||||
timer1 = 0
|
||||
buttonSet 1 0
|
||||
end
|
||||
12
data/configs/18-moution.c.txt
Normal file
12
data/configs/18-moution.c.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
switch 1 0 20
|
||||
text 1 Вход: Охрана 1
|
||||
textSet 1 не#обнаружено-time
|
||||
button 1 na Сбросить Охрана 0 2
|
||||
button 2 line3, Включить#push Охрана 1 3
|
||||
|
||||
//0 - номер пина датчика
|
||||
//при срабатывании датчика движения устройство пошлет пуш и в приложении будет
|
||||
//написано в текстовом поле, что движение было обнаружено
|
||||
//так же будет зафиксирован момент времени срабатывания датчика
|
||||
//в приложении можно отключать отправку пуш сообщений на тот случай если дома хозяин
|
||||
//перевести датчик снова в режим ожидания движения можно нажав кнопку сброса в приложении
|
||||
10
data/configs/18-moution.s.txt
Normal file
10
data/configs/18-moution.s.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
switch1 = 1
|
||||
textSet 1 обнаружено#движение-time
|
||||
end
|
||||
button1 = 1
|
||||
textSet 1 не#обнаружено-time
|
||||
buttonSet 1 0
|
||||
end
|
||||
switch1 = 1
|
||||
push Внимание обнаружено#движение!
|
||||
end
|
||||
17
data/configs/19-stepper.c.txt
Normal file
17
data/configs/19-stepper.c.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
stepper 1 12 4
|
||||
stepper 2 13 5
|
||||
button 1 na Открыть#штору#1 Шторы 0 1
|
||||
button 2 na Открыть#штору#2 Шторы 0 2
|
||||
|
||||
//для подключения необходим драйвер шагового двигателя A4988
|
||||
|
||||
//stepper 1 12 4 шаговый двигатель с параметрами: 1 - номер шагового двигателя,
|
||||
//12 - номер пина количества шагов, 4 - номер пина направления
|
||||
|
||||
//stepper 2 13 5 шаговый двигатель с параметрами: 2 - номер шагового двигателя,
|
||||
//13 - номер пина количества шагов, 5 - номер пина направления
|
||||
|
||||
//stepperSet 1 200 5 - прокрутить шаговик номер 1 на 200 шагов по часовой стрелке
|
||||
//с задержкой между шагами 5 милисекунд (чем меньше задержка тем больше скорость)
|
||||
//если поставить -200 то будет вращаться против часовой стрелки
|
||||
//можно подключить не более двух шаговиков
|
||||
12
data/configs/19-stepper.s.txt
Normal file
12
data/configs/19-stepper.s.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
button1 = 1
|
||||
stepperSet 1 200 1
|
||||
end
|
||||
button1 = 0
|
||||
stepperSet 1 -200 1
|
||||
end
|
||||
button2 = 1
|
||||
stepperSet 2 200 1
|
||||
end
|
||||
button2 = 0
|
||||
stepperSet 2 -200 1
|
||||
end
|
||||
6
data/configs/2-relay.c.txt
Normal file
6
data/configs/2-relay.c.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1
|
||||
inputTime time2 Во#сколько#выключить? Таймеры 20-35-00 2
|
||||
button 1 5 Кнопка#(по#таймеру) Таймеры 0 3
|
||||
|
||||
//время в приложение необходимо вводить в строгом формате: ЧЧ-ММ-СС
|
||||
//можно создавать любое количество таймеров, копируя строку inputTime...
|
||||
6
data/configs/2-relay.s.txt
Normal file
6
data/configs/2-relay.s.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
timenow = time1
|
||||
buttonSet 1 1
|
||||
end
|
||||
timenow = time2
|
||||
buttonSet 1 0
|
||||
end
|
||||
17
data/configs/20-servo.c.txt
Normal file
17
data/configs/20-servo.c.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
servo 1 12 50 Мой#сервопривод Сервоприводы 0 100 0 180 1
|
||||
servo 2 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
|
||||
button 1 na Открыть1 Сервоприводы 0 3
|
||||
button 2 na Открыть2 Сервоприводы 0 4
|
||||
|
||||
//Можно создавать не более двух сервоприводов на одном устройстве.
|
||||
//1 - номер привода
|
||||
//12 - номер пина
|
||||
//50 - начальное значение в процентах
|
||||
|
||||
//0 - 100 диапазон ползунка
|
||||
//0 - 180 диапазон угла
|
||||
|
||||
//Представим ситуацию когда есть некая заслонка и при угле в 30 градусов она закрыта,
|
||||
//а при угле в 90 градусов открыта. В этом случае необходимо написать
|
||||
//0 100 30 90 и тогда поставив ползунок в 0 % серва встанет в положение 30 градусов,
|
||||
//а если поставить ползунок в 100 % серва встанет в положение 90 градусов.
|
||||
12
data/configs/20-servo.s.txt
Normal file
12
data/configs/20-servo.s.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
button1 = 1
|
||||
servoSet 1 100
|
||||
end
|
||||
button1 = 0
|
||||
servoSet 1 0
|
||||
end
|
||||
button2 = 1
|
||||
servoSet 2 100
|
||||
end
|
||||
button2 = 0
|
||||
servoSet 2 0
|
||||
end
|
||||
4
data/configs/3-relay.c.txt
Normal file
4
data/configs/3-relay.c.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
button 1 5 Вкл#на#время Таймеры 0 1
|
||||
inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2
|
||||
|
||||
//в сценариях можно поменять на sec, min или hours если нужны другие размерности времени
|
||||
6
data/configs/3-relay.s.txt
Normal file
6
data/configs/3-relay.s.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
button1 = 1
|
||||
timerStart 1 digit1 sec
|
||||
end
|
||||
timer1 = 0
|
||||
buttonSet 1 0
|
||||
end
|
||||
3
data/configs/4-relay.c.txt
Normal file
3
data/configs/4-relay.c.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
button 1 na Включить#все Освещение 0 1
|
||||
|
||||
//при нажатии на эту кнопку пины номер 5 и 13 поведут себя как установленно в сценариях
|
||||
8
data/configs/4-relay.s.txt
Normal file
8
data/configs/4-relay.s.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
button1 = 1
|
||||
pinSet 5 1
|
||||
pinSet 13 0
|
||||
end
|
||||
button1 = 0
|
||||
pinSet 5 0
|
||||
pinSet 13 1
|
||||
end
|
||||
4
data/configs/5-relay.c.txt
Normal file
4
data/configs/5-relay.c.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
button 1 13 Включить#реле Реле 0 1
|
||||
switch 1 0 10
|
||||
|
||||
//можно управлять реле на пине 13 кнопкой на пине 0 или кнопкой в приложении
|
||||
3
data/configs/5-relay.s.txt
Normal file
3
data/configs/5-relay.s.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
switch1 = 1
|
||||
buttonChange 1
|
||||
end
|
||||
6
data/configs/6-relay.c.txt
Normal file
6
data/configs/6-relay.c.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
button 1 5 Включить#все Реле 0 1
|
||||
|
||||
|
||||
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
|
||||
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
|
||||
//того esp, кнопка на этом девайсе будет выключать другие устройства по воздуху
|
||||
8
data/configs/6-relay.s.txt
Normal file
8
data/configs/6-relay.s.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
button1 = 1
|
||||
mqtt 3233662-1589485 buttonSet_1_1
|
||||
mqtt 2233662-1589486 buttonSet_1_1
|
||||
end
|
||||
button1 = 0
|
||||
mqtt 3233662-1589485 buttonSet_1_0
|
||||
mqtt 2233662-1589486 buttonSet_1_0
|
||||
end
|
||||
6
data/configs/7-relay.c.txt
Normal file
6
data/configs/7-relay.c.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
switch 1 0 10
|
||||
|
||||
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
|
||||
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
|
||||
//того esp, к данному модулю нужно подключить кнопку к пину 0 и тогда
|
||||
//один девайс будет управлять другим по воздуху
|
||||
4
data/configs/7-relay.s.txt
Normal file
4
data/configs/7-relay.s.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
switch1 = 1
|
||||
mqtt 3233662-1589485 buttonChange_1
|
||||
mqtt 2233662-1589486 buttonChange_1
|
||||
end
|
||||
6
data/configs/8-pwm.c.txt
Normal file
6
data/configs/8-pwm.c.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 1
|
||||
pwm 2 4 Яркость#ванная: Реле 510 2
|
||||
|
||||
//в приложении появятся ползунки, соответствующее значение pwm
|
||||
//будет установленно на пинах 3 и 4
|
||||
//1023 и 510 это начальные значения после загрузки модуля
|
||||
1
data/configs/8-pwm.s.txt
Normal file
1
data/configs/8-pwm.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
7
data/configs/9-dht11.c.txt
Normal file
7
data/configs/9-dht11.c.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1
|
||||
dhtH h 2 dht11 Влажность#DHT,#t°C Датчики any-data 2
|
||||
dhtComfort Степень#комфорта: Датчики 3
|
||||
dhtPerception Восприятие: Датчики 4
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
logging t 1 50 Температура Датчики 6
|
||||
logging h 1 50 Влажность Датчики 7
|
||||
1
data/configs/9-dht11.s.txt
Normal file
1
data/configs/9-dht11.s.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
12
data/configs/firmware.c.txt
Normal file
12
data/configs/firmware.c.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
button 1 na Включить#все Реле 0 1
|
||||
button 2 13 Прихожая Реле 0 2
|
||||
button 3 14 Кухня Реле 0 3
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 4
|
||||
pwm 2 4 Яркость#ванная: Реле 510 5
|
||||
analog adc 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6
|
||||
logging adc 1 100 Аналоговый#вход Датчики 7
|
||||
|
||||
//Это демо конфигурация. В ней показано как связать кнопки c помощью сценариев
|
||||
//Кнопка номер 1 связана с кнопкой 2, 3 и с pwm 2
|
||||
//Так же продемонстрированна система логгирования данных строкой logging
|
||||
//1 - это интервал между точками в минутах, 100 это количество точек
|
||||
13
data/configs/firmware.s.txt
Normal file
13
data/configs/firmware.s.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
button1 = 1
|
||||
buttonSet 2 1
|
||||
buttonSet 3 1
|
||||
pwmSet 2 1024
|
||||
end
|
||||
button1 = 0
|
||||
buttonSet 2 0
|
||||
buttonSet 3 0
|
||||
pwmSet 2 0
|
||||
end
|
||||
adc > 50
|
||||
buttonSet 2 1
|
||||
end
|
||||
BIN
data/css/build.css.gz
Normal file
BIN
data/css/build.css.gz
Normal file
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
12
data/firmware.c.txt
Normal file
12
data/firmware.c.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
button 1 na Включить#все Реле 0 1
|
||||
button 2 13 Прихожая Реле 0 2
|
||||
button 3 14 Кухня Реле 0 3
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 4
|
||||
pwm 2 4 Яркость#ванная: Реле 510 5
|
||||
analog adc 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6
|
||||
logging adc 1 100 Аналоговый#вход Датчики 7
|
||||
|
||||
//Это демо конфигурация. В ней показано как связать кнопки c помощью сценариев
|
||||
//Кнопка номер 1 связана с кнопкой 2, 3 и с pwm 2
|
||||
//Так же продемонстрированна система логгирования данных строкой logging
|
||||
//1 - это интервал между точками в минутах, 100 это количество точек
|
||||
13
data/firmware.s.txt
Normal file
13
data/firmware.s.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
button1 = 1
|
||||
buttonSet 2 1
|
||||
buttonSet 3 1
|
||||
pwmSet 2 1024
|
||||
end
|
||||
button1 = 0
|
||||
buttonSet 2 0
|
||||
buttonSet 3 0
|
||||
pwmSet 2 0
|
||||
end
|
||||
adc > 50
|
||||
buttonSet 2 1
|
||||
end
|
||||
BIN
data/icon.jpeg
Normal file
BIN
data/icon.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
data/index.htm.gz
Normal file
BIN
data/index.htm.gz
Normal file
Binary file not shown.
69
data/index.json
Normal file
69
data/index.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.live.json",
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"title": "Главная",
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"class": "alert alert-light",
|
||||
"title": "<center><img src='/icon.jpeg' alt='IoT Manager'></center>"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация устройства",
|
||||
"action": "/?set.device",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Список других устройств в сети",
|
||||
"action": "/?set.udp",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация WIFI",
|
||||
"action": "/?set.wifi",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация MQTT",
|
||||
"action": "/?set.mqtt",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация push",
|
||||
"action": "/?set.push",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Утилиты",
|
||||
"action": "/?set.utilities",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Скачать приложение IoT Manager для android",
|
||||
"action": "https://play.google.com/store/apps/details?id=ru.esp8266.iotmanager",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Скачать приложение IoT Manager для iphone",
|
||||
"action": "https://apps.apple.com/ru/app/iot-manager/id1155934877",
|
||||
"class": "btn btn-block btn-default"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
data/js/build.chart.js.gz
Normal file
BIN
data/js/build.chart.js.gz
Normal file
Binary file not shown.
BIN
data/js/function.js.gz
Normal file
BIN
data/js/function.js.gz
Normal file
Binary file not shown.
39
data/lang/lang.ru.json
Normal file
39
data/lang/lang.ru.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"SetDevConf": "Конфигурация устройства",
|
||||
"SetDevPreset": "Выберите из списка подходящий пресет кофигурации",
|
||||
|
||||
"ButSave":"Сохранить",
|
||||
"ButMainPage":"Главная",
|
||||
|
||||
|
||||
"SetUDPList": "Список других устройств в сети:",
|
||||
"SetUDPWarn1": "После нажатия на кнопку <b>переформировать список устройств</b> ждите примерно минуту, а затем обновите страницу и список появится вновь",
|
||||
|
||||
"SetUDPUpdateList":"Переформировать список устройств",
|
||||
"SetUDPUpdatePage":"Обновить страницу",
|
||||
"SetUDPNameOfDev":"Имя этого устройства:",
|
||||
"SetUDPDateExchange":"Включить обмен данными между устройствами",
|
||||
"SetUDPWarn2":"Если обмен данными включен, то устройства будут обмениваться широковещательными пакетами udp для формирования списка устройств и для осуществления посылки настроек mqtt. Данный обмен создает дополнительную нагрузку на wifi сеть.",
|
||||
|
||||
"SetWiFiNameOfDev":"Имя устройства:",
|
||||
"SetWiFiRouterConnect":"Подключение к WiFi роутеру:",
|
||||
"SetWiFiAccessPoint":"Точка доступа:",
|
||||
"SetWiFiWeb":"Логин и пароль web interface:",
|
||||
"SetWiFiTimeZone":"Временная зона:",
|
||||
"SetWiFiNTP":"Сервер NTP:",
|
||||
"SetWiFiWarn1":"Имя устройства должно состоять из английских букв и иметь длинну от 6 до 12 символов",
|
||||
"SetWiFiWarn2":"После того как вы введете логин пароль от вашего wifi роутера необходимо нажать кнопку сохранить, а затем обязательно нажать кнопку <b>перезагрузить устройство</b> внизу этой страницы",
|
||||
"SetWiFiWarn3":"Устройство постоянно сканирует сеть на наличие wifi. Если роутер отключен, то устройство автоматически перейдет в режим точки доступа. Когда wifi появится устройство автоматически подключится к роутеру снова, и выключит точку доступа",
|
||||
"SetWiFiWarn4":"После изменения поля <b>NTP сервер</b> необходимо перезагрузить устройство",
|
||||
"SetWiFiWarn5":"Светодиод статуса подключения показывает четыре состояния подключения: <br><b>1. мигает редко</b> - идет подключение к wifi <br><b>2. мигает часто</b> - идет подключение к серверу mqtt <br><b>3. горит постоянно</b> - модуль в режиме точки доступа, <br><b>4. не горит</b> - модуль подключен к wifi и к mqtt. <br>Светодиод подключен к gpio2. Если галочка стоит - то использовать этот пин нельзя",
|
||||
|
||||
"SetMQTTServerName":"Имя сервера:",
|
||||
"SetMQTTPort":"Номер порта:",
|
||||
"SetMQTTPrefix":"Префикс:",
|
||||
"SetMQTTUserName":"Имя пользователя:",
|
||||
"SetMQTTPassword":"Пароль:",
|
||||
|
||||
"SetMQTTSendSettings":"Отправить настройки MQTT с этого устройства на все остальные",
|
||||
"SetMQTTWarn1":"Обратите внимание что поле префикс может состоять только из одного слова и одного разделителя: <b>/prefix</b>, вариант вида: <b>/prefix1/prefix2</b> работать не будет. После изменения поля prefix необходимо перезагрузить устройство",
|
||||
"SetMQTTWarn2":"Прежде чем нажимать на кнопку <b>Отправить настройки MQTT</b> сохрание их, если Вы их меняли. Настройки получат и перезапишут все устройства в локальной сети"
|
||||
}
|
||||
143
data/set.device.json
Normal file
143
data/set.device.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json",
|
||||
"/config.option.json",
|
||||
"/config.live.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"class": "col-sm-offset-1 col-sm-10",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Device ID: {{chipID}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "IP address: {{ip}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Time: {{time}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Uptime: {{uptime}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Build version: {{firmware_version}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "SPIFFS version: 2.3.3"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "dropdown",
|
||||
"name": "help-url",
|
||||
"class": "btn btn-default",
|
||||
"style": "display:inline",
|
||||
"title": {
|
||||
"#": "{{SetDevPreset}}<span class=\"caret\"></span>",
|
||||
"/set?preset=1": "1.Вкл. выкл. локального реле",
|
||||
"/set?preset=2": "2.Вкл. выкл. локального реле в определенное время",
|
||||
"/set?preset=3": "3.Вкл. выкл. локального реле на определенный период времени",
|
||||
"/set?preset=4": "4.Вкл. выкл. нескольких локальных реле кнопкой в приложении",
|
||||
"/set?preset=5": "5.Вкл. выкл. локального реле физической кнопкой и кнопкой в приложении параллельно (для выключателя света)",
|
||||
"/set?preset=6": "6.Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
|
||||
"/set?preset=7": "7.Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
|
||||
"/set?preset=8": "8.Широтно импульсная модуляция",
|
||||
"/set?preset=9": "9.Сенсор DHT11 (темп, влажность) и логгирование",
|
||||
"/set?preset=10": "10.Сенсор DHT22, DHT33, DHT44, AM2302, RHT03 (темп, влажность) и логгирование",
|
||||
"/set?preset=11": "11.Аналоговый сенсор и логгирование",
|
||||
"/set?preset=12": "12.Cенсор bmp280 (темп, давление) и логгирование",
|
||||
"/set?preset=13": "13.Cенсор bme280 (темп, давление, влажность, высота) и логгирование",
|
||||
"/set?preset=14": "12.Сенсор DS18B20 (темп) и логгирование",
|
||||
"/set?preset=15": "13.Термостат на DS18B20 с переключением в ручной режим и логгированием",
|
||||
"/set?preset=16": "14.Котроль уровня в баке (датчик расстояния) на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 и логгирование",
|
||||
"/set?preset=17": "15.Датчик движения включающий свет",
|
||||
"/set?preset=18": "16.Охранный датчик движения",
|
||||
"/set?preset=19": "17.Система управления шаговыми двигателями на основе драйвера A4988 (открытие закрытие штор)",
|
||||
"/set?preset=20": "18.Система управления сервоприводами",
|
||||
"/set?preset=21": "Настройки по умолчанию"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "{{SetDevConf}}"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"state": "firmware.c.txt",
|
||||
"style": "width:100%;height:350px",
|
||||
"title": "Сохранить",
|
||||
"action": "/set?devinit",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Сценарии"
|
||||
},
|
||||
{
|
||||
"type": "checkbox",
|
||||
"name": "scen",
|
||||
"title": "Включить сценарии",
|
||||
"action": "/set?scen=[[scen]]",
|
||||
"state": "{{scen}}"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"state": "firmware.s.txt",
|
||||
"style": "width:100%;height:350px",
|
||||
"title": "Сохранить",
|
||||
"action": "/set?sceninit",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Инструкция к системе автоматизации",
|
||||
"action": "https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/wiki/Instruction",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Очистить логи сенсоров",
|
||||
"action": "/set?cleanlog",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"name": "my-block",
|
||||
"style": "position:fixed;top:50%;left:50%;width:400px;margin-left:-200px;text-align:center;",
|
||||
"class": "hidden"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Обновить прошивку устройства",
|
||||
"action": "/check",
|
||||
"response": "[[my-block]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
}
|
||||
]
|
||||
}
|
||||
133
data/set.mqtt.json
Normal file
133
data/set.mqtt.json
Normal file
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{SetMQTTServerName}}",
|
||||
"style": "width:60%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "mqttServer-arg",
|
||||
"state": "{{mqttServer}}",
|
||||
"style": "width:40%;float:right"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{SetMQTTPort}}",
|
||||
"style": "width:60%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "mqttPort-arg",
|
||||
"state": "{{mqttPort}}",
|
||||
"style": "width:40%;float:right"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{SetMQTTPrefix}}",
|
||||
"style": "width:60%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "mqttPrefix-arg",
|
||||
"state": "{{mqttPrefix}}",
|
||||
"style": "width:40%;float:right"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{SetMQTTUserName}}",
|
||||
"style": "width:60%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "mqttUser-arg",
|
||||
"state": "{{mqttUser}}",
|
||||
"style": "width:40%;float:right"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{SetMQTTPassword}}",
|
||||
"style": "width:60%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "mqttPass-arg",
|
||||
"state": "{{mqttPass}}",
|
||||
"style": "width:40%;float:right"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"name": "my-block",
|
||||
"style": "position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
|
||||
"class": "hidden"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"style": "width:100%;float:left;",
|
||||
"action": "set?mqttServer=[[mqttServer-arg]]&mqttPort=[[mqttPort-arg]]&mqttPrefix=[[mqttPrefix-arg]]&mqttUser=[[mqttUser-arg]]&mqttPass=[[mqttPass-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"style": "width:100%;float:left;",
|
||||
"title": "{{SetMQTTSendSettings}}",
|
||||
"action": "set?mqttsend",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "button",
|
||||
"style": "width:100%;float:left;",
|
||||
"title": "Проверить соединение с MQTT",
|
||||
"action": "set?mqttcheck",
|
||||
"response": "[[my-block]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"style": "width:100%;float:left;",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetMQTTWarn1}}</p></font></div>"
|
||||
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"style": "width:100%;float:left;",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetMQTTWarn2}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"style": "width:100%;float:left;",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-danger"
|
||||
}
|
||||
]
|
||||
}
|
||||
51
data/set.push.json
Normal file
51
data/set.push.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"style": "width:60%;float:left;",
|
||||
"title": "Device id:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "push-arg",
|
||||
"style": "width:40%;float:right",
|
||||
"state": "{{pushingboxid}}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "set?pushingboxid=[[push-arg]]",
|
||||
"class": "btn btn-block btn-default",
|
||||
"style": "width:100%;display:inline"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-danger"
|
||||
}
|
||||
]
|
||||
}
|
||||
96
data/set.udp.json
Normal file
96
data/set.udp.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"title": "Главная",
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetUDPList}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "csv",
|
||||
"title": [
|
||||
"html",
|
||||
"html",
|
||||
"html"
|
||||
],
|
||||
"state": "dev.csv",
|
||||
"style": "width:100%;",
|
||||
"class": "nan"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{SetUDPUpdateList}}",
|
||||
"action": "/set?updatelist",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{SetUDPUpdatePage}}",
|
||||
"action": "/set?updatepage",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetUDPWarn1}}</p></font></div>",
|
||||
"style": "width:100%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetUDPNameOfDev}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "{{SetUDPNameOfDev}}",
|
||||
"name": "devname-arg",
|
||||
"state": "{{name}}",
|
||||
"pattern": "[A-Za-z0-9]{6,12}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "/set?devname=[[devname-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "checkbox",
|
||||
"name": "udponoff",
|
||||
"title": "{{SetUDPDateExchange}}",
|
||||
"action": "/set?udponoff=[[udponoff]]",
|
||||
"state": "{{udponoff}}"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetUDPWarn2}}</p></font></div>"
|
||||
}
|
||||
]
|
||||
}
|
||||
39
data/set.utilities.json
Normal file
39
data/set.utilities.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.live.json",
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"title": "Главная",
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "Сканирование адресов шины i2c"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{i2c}}"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Сканировать",
|
||||
"action": "/set?itoc",
|
||||
"class": "btn btn-block btn-default"
|
||||
}
|
||||
]
|
||||
}
|
||||
185
data/set.wifi.json
Normal file
185
data/set.wifi.json
Normal file
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json"
|
||||
],
|
||||
"title": "Конфигурация",
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{name}}",
|
||||
"class": "alert-default"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "{{ButMainPage}}",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetWiFiNameOfDev}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "{{SetWiFiNameOfDev}}",
|
||||
"name": "devname-arg",
|
||||
"state": "{{name}}",
|
||||
"pattern": "[A-Za-z0-9]{6,12}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "set?devname=[[devname-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn1}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetWiFiRouterConnect}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "routerssid-arg",
|
||||
"state": "{{routerssid}}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "",
|
||||
"name": "routerpass-arg",
|
||||
"state": "{{routerpass}}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"class": "btn btn-block btn-default",
|
||||
"action": "set?routerssid=[[routerssid-arg]]&routerpass=[[routerpass-arg]]"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn2}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "checkbox",
|
||||
"name": "blink",
|
||||
"title": "Включить светодиод статуса подключения",
|
||||
"action": "/set?blink=[[blink]]",
|
||||
"state": "{{blink}}"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn5}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetWiFiAccessPoint}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "apssid-arg",
|
||||
"state": "{{apssid}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "",
|
||||
"name": "appass-arg",
|
||||
"state": "{{appass}}",
|
||||
"pattern": ".{8,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "set?apssid=[[apssid-arg]]&appass=[[appass-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn3}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetWiFiWeb}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "Логин",
|
||||
"name": "weblogin-arg",
|
||||
"state": "{{weblogin}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "Пароль",
|
||||
"name": "webpass-arg",
|
||||
"state": "{{webpass}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "set?weblogin=[[weblogin-arg]]&webpass=[[webpass-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h3",
|
||||
"title": "{{SetWiFiTimeZone}}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "timezone-arg",
|
||||
"state": "{{timezone}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name": "ntp-arg",
|
||||
"state": "{{ntp}}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "{{ButSave}}",
|
||||
"action": "set?timezone=[[timezone-arg]]&ntp=[[ntp-arg]]",
|
||||
"class": "btn btn-block btn-default"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn4}}</p></font></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/set?device=ok');}",
|
||||
"class": "btn btn-block btn-danger"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
data/sync.ffs_db
Normal file
BIN
data/sync.ffs_db
Normal file
Binary file not shown.
7
data/widgets/outstanding/widget.select.json
Normal file
7
data/widgets/outstanding/widget.select.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"widget" : "select",
|
||||
"size" : "small",
|
||||
"fill" : "outline",
|
||||
"options" : "["Zero item", "First item", "Second item"]",
|
||||
"status" : 2
|
||||
}
|
||||
5
data/widgets/widget.anyData.json
Normal file
5
data/widgets/widget.anyData.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"widget" : "anydata",
|
||||
"after" : "",
|
||||
"icon" : ""
|
||||
}
|
||||
5
data/widgets/widget.chart.json
Normal file
5
data/widgets/widget.chart.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"widget": "chart",
|
||||
"series": "Temperature, °C",
|
||||
"dateFormat": "HH:mm"
|
||||
}
|
||||
7
data/widgets/widget.fillGauge.json
Normal file
7
data/widgets/widget.fillGauge.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"widget": "fillgauge",
|
||||
"circleColor": "#00FFFF",
|
||||
"textColor": "#FFFFFF",
|
||||
"waveTextColor": "#000000",
|
||||
"waveColor": "#00FFFF"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user