mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' into development
This commit is contained in:
commit
0288a2da15
33
README.md
33
README.md
|
@ -15,7 +15,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
|
|||
### Development
|
||||
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
|
||||
|
||||
Current version is **6.0.0c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
|
||||
Current version is **6.1.1b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for release information and [sonoff/_changelog.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_changelog.ino) for change information.
|
||||
|
||||
### Disclaimer
|
||||
:warning: **DANGER OF ELECTROCUTION** :warning:
|
||||
|
@ -39,7 +39,7 @@ If you want to compile Sonoff-Tasmota yourself keep in mind the following:
|
|||
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
|
||||
- After reboot select config menu again or use commands ```GPIOs``` and ```GPIO``` to change GPIO with desired sensor.
|
||||
|
||||
### Migration Instructions
|
||||
### Migration Information
|
||||
See [wiki migration path](https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path) for instructions how to migrate to a major version. Pay attention to the following version breaks due to dynamic settings updates:
|
||||
|
||||
1. Migrate to **Sonoff-Tasmota 3.9.x**
|
||||
|
@ -134,34 +134,34 @@ Different firmware images are released based on Features and Sensors selection g
|
|||
| USE_ADS1115 | - | - | - | - | x |
|
||||
| USE_ADS1115_I2CDEV | - | - | - | - | - |
|
||||
| USE_INA219 | - | - | - | - | x |
|
||||
| USE_APDS9960 | - | - | - | - | - |
|
||||
| USE_MGS | - | - | - | - | x |
|
||||
| USE_SPI | - | - | - | - | - |
|
||||
| USE_MHZ19 | x | x | - | x | x |
|
||||
| USE_SENSEAIR | x | x | - | x | x |
|
||||
| USE_PMS5003 | x | x | - | x | x |
|
||||
| USE_SENSEAIR | x | - | - | x | x |
|
||||
| USE_PMS5003 | x | - | - | x | x |
|
||||
| USE_NOVA_SDS | x | - | - | x | x |
|
||||
| USE_PZEM004T | x | x | - | x | x |
|
||||
| USE_PZEM004T | x | - | - | x | x |
|
||||
| USE_SERIAL_BRIDGE | x | - | - | x | x |
|
||||
| USE_SDM120 | x | - | - | - | x |
|
||||
| USE_SDM630 | x | - | - | - | x |
|
||||
| USE_SDM120 | - | - | - | - | x |
|
||||
| USE_SDM630 | - | - | - | - | x |
|
||||
| USE_IR_REMOTE | x | x | - | x | x |
|
||||
| USE_IR_HVAC | - | - | - | - | x |
|
||||
| USE_IR_RECEIVE | x | - | - | x | x |
|
||||
| USE_WS2812 | x | x | - | x | x |
|
||||
| USE_WS2812_DMA | - | - | - | - | - |
|
||||
| USE_ARILUX_RF | x | x | - | x | x |
|
||||
| USE_ARILUX_RF | x | - | - | x | x |
|
||||
| USE_SR04 | x | - | - | x | x |
|
||||
| USE_TM1638 | - | - | - | - | - |
|
||||
| USE_RF_FLASH | x | - | - | x | x |
|
||||
|
||||
#### Typical File Size
|
||||
#### Typical file size
|
||||
|
||||
| ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors |
|
||||
|-----------------------------|--------|---------|---------|------|------------|
|
||||
| ESP/Arduino lib v2.3.0 | 529k | 490k | 429k | 538k | 554k |
|
||||
| ESP/Arduino lib v2.4.0 | 534k | 498k | 436k | 542k | 558k |
|
||||
| ESP/Arduino lib v2.4.1 | 536k | 501k | 439k | 545k | 560k |
|
||||
| ESP/Arduino lib v2.3.0 | 538k | 490k | 407k | 548k | 562k |
|
||||
| ESP/Arduino lib v2.4.0 | 543k | 498k | 414k | 553k | 565k |
|
||||
| ESP/Arduino lib v2.4.1 | 544k | 500k | 416k | 555k | 567k |
|
||||
|
||||
See [Tasmota ESP/Arduino library version related issues](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips#20180523---relation-tasmota-and-esp8266arduino-core-version) for more information.
|
||||
|
||||
### Contribute
|
||||
You can contribute to Sonoff-Tasmota by
|
||||
|
@ -176,13 +176,14 @@ You can contribute to Sonoff-Tasmota by
|
|||
#### Libraries Used
|
||||
Libraries used with Sonoff-Tasmota are:
|
||||
- [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)
|
||||
- [Adafruit BME680](https://github.com/adafruit/Adafruit_BME680)
|
||||
- [Adafruit Sensor](https://github.com/adafruit/Adafruit_Sensor)
|
||||
- [Adafruit SGP30](https://github.com/adafruit/Adafruit_SGP30)
|
||||
- [ArduinoJson](https://arduinojson.org/)
|
||||
- [Bosch BME680](https://github.com/BoschSensortec/BME680_driver)
|
||||
- [C2 Programmer](http://app.cear.ufpb.br/~lucas.hartmann/tag/efm8bb1/)
|
||||
- [Esp8266MqttClient](https://github.com/tuanpmt/ESP8266MQTTClient)
|
||||
- [esp-knx-ip](https://github.com/envy/esp-knx-ip)
|
||||
- [esp-mqtt-arduino](https://github.com/i-n-g-o/esp-mqtt-arduino)
|
||||
- [ESPAsyncUDP](https://github.com/me-no-dev/ESPAsyncUDP)
|
||||
- [I2Cdevlib](https://github.com/jrowberg/i2cdevlib)
|
||||
- [IRremoteEsp8266](https://github.com/markszabo/IRremoteESP8266)
|
||||
- [JobaTsl2561](https://github.com/joba-1/Joba_Tsl2561)
|
||||
|
|
|
@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
|
|||
|
||||
#include <Tsl2561Util.h>
|
||||
|
||||
// to mimic Serial.printf() of esp8266 core for other platforms
|
||||
char *format( const char *fmt, ... ) {
|
||||
static char buf[128];
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, arg);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
va_end(arg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Tsl2561 Tsl(Wire);
|
||||
uint8_t id;
|
||||
|
||||
|
@ -35,31 +46,30 @@ void setup() {
|
|||
}
|
||||
|
||||
void loop() {
|
||||
uint16_t scaledFull = ~0, scaledIr = ~0;
|
||||
uint32_t full = ~0, ir = ~0, milliLux = ~0;
|
||||
uint16_t scaledFull = 0xffff, scaledIr = 0xffff;
|
||||
uint32_t full = 0xffffffff, ir = 0xffffffff, milliLux = 0xffffffff;
|
||||
bool gain = false;
|
||||
Tsl2561::exposure_t exposure = Tsl2561::EXP_OFF;
|
||||
|
||||
if( Tsl2561Util::autoGain(Tsl, gain, exposure, scaledFull, scaledIr) ) {
|
||||
if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) {
|
||||
if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id)) ) {
|
||||
Serial.printf("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, full: %5u, ir: %5u, gain: %d, exp: %d, lux: %5u.%03u\n",
|
||||
Tsl.address(), id, scaledFull, scaledIr, full, ir, gain, exposure, milliLux/1000, milliLux%1000);
|
||||
if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id), 5) ) {
|
||||
Serial.print(format("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, full: %7lu, ir: %7lu, gain: %d, exp: %d, lux: %5lu.%03lu\n",
|
||||
Tsl.address(), id, scaledFull, scaledIr, (unsigned long)full, (unsigned long)ir, gain, exposure, (unsigned long)milliLux/1000, (unsigned long)milliLux%1000));
|
||||
}
|
||||
else {
|
||||
Serial.printf("Tsl2561Util::milliLux(full=%u, ir=%u) error\n", full, ir);
|
||||
Serial.print(format("Tsl2561Util::milliLux(full=%lu, ir=%lu) error\n", (unsigned long)full, (unsigned long)ir));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.printf("Tsl2561Util::normalizedLuminosity(gain=%u, exposure=%u, sfull=%u, sir=%u, full=%u, ir=%u) error\n",
|
||||
gain, exposure, scaledFull, scaledIr, full, ir);
|
||||
Serial.print(format("Tsl2561Util::normalizedLuminosity(gain=%u, exposure=%u, sfull=%u, sir=%u, full=%lu, ir=%lu) error\n",
|
||||
gain, exposure, scaledFull, scaledIr, (unsigned long)full, (unsigned long)ir));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.printf("Tsl2561Util::autoGain(gain=%u, exposure=%u, sfull=%u, sir=%u) error\n",
|
||||
gain, exposure, scaledFull, scaledIr);
|
||||
Serial.print(format("Tsl2561Util::autoGain(gain=%u, exposure=%u, sfull=%u, sir=%u) error\n",
|
||||
gain, exposure, scaledFull, scaledIr));
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
|
@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
|
|||
|
||||
#include <Tsl2561.h>
|
||||
|
||||
// to mimic Serial.printf() of esp8266 core for other platforms
|
||||
char *format( const char *fmt, ... ) {
|
||||
static char buf[128];
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, arg);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
va_end(arg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Tsl2561 Tsl(Wire);
|
||||
|
||||
void setup() {
|
||||
|
@ -44,7 +55,7 @@ void loop() {
|
|||
Tsl.fullLuminosity(full);
|
||||
Tsl.irLuminosity(ir);
|
||||
|
||||
Serial.printf("Tsl2561 at 0x%02x(id=0x%02x) luminosity is %5u (full) and %5u (ir)\n", Tsl.address(), id, full, ir);
|
||||
Serial.print(format("Tsl2561 at 0x%02x(id=0x%02x) luminosity is %5u (full) and %5u (ir)\n", Tsl.address(), id, full, ir));
|
||||
|
||||
Tsl.off();
|
||||
}
|
|
@ -22,11 +22,22 @@ This file is part of the Joba_Tsl2561 Library.
|
|||
|
||||
#include <Tsl2561.h>
|
||||
|
||||
// to mimic Serial.printf() of esp8266 core for other platforms
|
||||
char *format( const char *fmt, ... ) {
|
||||
static char buf[128];
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, arg);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
va_end(arg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Tsl2561 Tsl(Wire);
|
||||
|
||||
void showError( Tsl2561 &tsl ) {
|
||||
Tsl2561::status_t status = tsl.status();
|
||||
Serial.printf("Error was %u: ", status);
|
||||
Serial.print(format("Error was %u: ", status));
|
||||
switch( status ) {
|
||||
case Tsl2561::ERR_OK: Serial.println("None"); break;
|
||||
case Tsl2561::ERR_RW: Serial.println("Read/Write"); break;
|
||||
|
@ -40,7 +51,7 @@ void showError( Tsl2561 &tsl ) {
|
|||
void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
|
||||
if( tsl.on() ) {
|
||||
uint32_t start = millis();
|
||||
Serial.printf("Chip powered on at %u\n", start);
|
||||
Serial.print(format("Chip powered on at %lu\n", (unsigned long)start));
|
||||
|
||||
bool chipGain;
|
||||
Tsl2561::exposure_t chipExp;
|
||||
|
@ -58,7 +69,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
|
|||
bool check = true;
|
||||
if( change ) {
|
||||
if( tsl.setSensitivity(newGain, newExp) ) {
|
||||
Serial.printf("New gain = %d, exposure = 0x%02x\n", newGain, newExp);
|
||||
Serial.print(format("New gain = %d, exposure = 0x%02x\n", newGain, newExp));
|
||||
}
|
||||
else {
|
||||
check = false;
|
||||
|
@ -69,6 +80,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
|
|||
|
||||
if( check ) {
|
||||
uint16_t ir, full = 0;
|
||||
|
||||
while( !full && millis() - start < 1000 ) {
|
||||
if( !tsl.fullLuminosity(full) ) {
|
||||
Serial.print("Check full luminosity failed. ");
|
||||
|
@ -89,7 +101,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
|
|||
Serial.println("No luminosity reading after 1s. Too dark?");
|
||||
}
|
||||
else {
|
||||
Serial.printf("Got luminosity after %d ms. Full spectrum is %d and IR only is %d\n", millis() - start, full, ir);
|
||||
Serial.print(format("Got luminosity after %lu ms. Full spectrum is %u and IR only is %u\n", (unsigned long)millis() - start, full, ir));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +119,7 @@ void testSensitivity( Tsl2561 &tsl, bool newGain, Tsl2561::exposure_t newExp ) {
|
|||
bool testPackage( Tsl2561 &tsl ) {
|
||||
uint8_t id;
|
||||
if( tsl.id(id) ) {
|
||||
Serial.printf("Chip has type %02x and revision %x\n", Tsl2561::type(id), Tsl2561::revision(id) );
|
||||
Serial.print(format("Chip has type %02x and revision %x\n", Tsl2561::type(id), Tsl2561::revision(id)));
|
||||
if( Tsl2561::packageT_FN_CL(id) ) {
|
||||
Serial.println("Chip is a T, FN or CL type package");
|
||||
}
|
||||
|
@ -128,7 +140,7 @@ bool testPackage( Tsl2561 &tsl ) {
|
|||
|
||||
void test( Tsl2561 &tsl ) {
|
||||
bool ok = tsl.available();
|
||||
Serial.printf("\nTesting Tsl2561 at address %02x: %sfound\n", tsl.address(), ok ? "" : "NOT ");
|
||||
Serial.print(format("\nTesting Tsl2561 at address %02x: %sfound\n", tsl.address(), ok ? "" : "NOT "));
|
||||
if( ok ) {
|
||||
if( testPackage(tsl) ) {
|
||||
testSensitivity(tsl, Tsl2561::GAIN_OFF, Tsl2561::EXP_402);
|
||||
|
@ -160,4 +172,3 @@ void loop() {
|
|||
Serial.println("\nNext test in 5s\n");
|
||||
delay(5000);
|
||||
}
|
||||
|
|
@ -21,6 +21,17 @@ This file is part of the Joba_Tsl2561 Library.
|
|||
|
||||
#include <Tsl2561Util.h>
|
||||
|
||||
// to mimic Serial.printf() of esp8266 core for other platforms
|
||||
char *format( const char *fmt, ... ) {
|
||||
static char buf[128];
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, arg);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
va_end(arg);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Tsl2561::address_t addr[] = { Tsl2561::ADDR_GND, Tsl2561::ADDR_FLOAT, Tsl2561::ADDR_VDD };
|
||||
Tsl2561 Tsl(Wire);
|
||||
|
||||
|
@ -58,18 +69,19 @@ void loop() {
|
|||
Tsl.fullLuminosity(scaledFull);
|
||||
Tsl.irLuminosity(scaledIr);
|
||||
|
||||
Serial.printf("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, gain: %d, exp: %d", addr[i], id, scaledFull, scaledIr, gain, exposure);
|
||||
Serial.print(format("Tsl2561 addr: 0x%02x, id: 0x%02x, sfull: %5u, sir: %5u, gain: %d, exp: %d",
|
||||
addr[i], id, scaledFull, scaledIr, gain, exposure));
|
||||
|
||||
if( Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr) ) {
|
||||
if( Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id)) ) {
|
||||
Serial.printf(", full: %5u, ir: %5u, lux: %5u.%03u\n", full, ir, milliLux/1000, milliLux%1000);
|
||||
Serial.print(format(", full: %5lu, ir: %5lu, lux: %5lu.%03lu\n", (unsigned long)full, (unsigned long)ir, (unsigned long)milliLux/1000, (unsigned long)milliLux%1000));
|
||||
}
|
||||
else {
|
||||
Serial.printf(", full: %5u, ir: %5u: Tsl2561Util::milliLux() error\n", full, ir);
|
||||
Serial.print(format(", full: %5lu, ir: %5lu: Tsl2561Util::milliLux() error\n", (unsigned long)full, (unsigned long)ir));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.printf(", full: %5u, ir: %5u: Tsl2561Util::normalizedLuminosity() error\n", full, ir);
|
||||
Serial.print(format(", full: %5lu, ir: %5lu: Tsl2561Util::normalizedLuminosity() error\n", (unsigned long)full, (unsigned long)ir));
|
||||
}
|
||||
|
||||
Tsl.off();
|
||||
|
@ -84,4 +96,3 @@ void loop() {
|
|||
|
||||
delay(5000);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Example config for flashing nodemcuv2 boards via linux serial port
|
||||
;
|
||||
; Adapt (e.g. platform, board, port) to your environment as needed.
|
||||
; Then call platformio.sh to copy the file to all examples.
|
||||
; Now cd to the example directory (e.g. Autogain/) and do "pio run"
|
||||
; to build it or directly upload with "pio run --target upload".
|
||||
; Watch the serial output of your sketch with "pio device monitor".
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
|
||||
[platformio]
|
||||
src_dir = .
|
||||
lib_dir = ../..
|
||||
|
||||
; uncomment one, if you want to build only one
|
||||
; env_default = nodemcuv2
|
||||
; env_default = nano328
|
||||
|
||||
[env:nodemcuv2]
|
||||
; TSL <-> ESP8266
|
||||
; ------------
|
||||
; GND <-> GND
|
||||
; VCC <-> 3V
|
||||
; SCL <-> D1
|
||||
; SDA <-> D2
|
||||
platform = espressif8266
|
||||
board = nodemcuv2
|
||||
framework = arduino
|
||||
build_flags = -Wall
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
upload_speed = 230400
|
||||
upload_resetmethod = nodemcu
|
||||
;usually upload port is autodetected
|
||||
;upload_port = /dev/ttyUSB[1-9]
|
||||
|
||||
|
||||
[env:nano328]
|
||||
; TSL <-> NANO
|
||||
; ------------
|
||||
; GND <-> GND
|
||||
; VCC <-> 3V3
|
||||
; SCL <-> A5
|
||||
; SDA <-> A4
|
||||
platform = atmelavr
|
||||
board = nanoatmega328
|
||||
framework = arduino
|
||||
build_flags = -Wall
|
||||
|
||||
monitor_speed = 115200
|
||||
;upload_port = /dev/ttyUSB[1-9]
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Create platformio.ini templates for all examples, if missing.
|
||||
# Start this script from within the examples directory.
|
||||
|
||||
for d in *; do
|
||||
if [ -d "$d" -a -f "$d/$d.ino" -a ! -e "$d/platformio.ini" ]
|
||||
then
|
||||
cp -av platformio.ini "$d/"
|
||||
fi
|
||||
done
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
This directory is intended for the project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link to executable file.
|
||||
|
||||
The source code of each library should be placed in separate directory, like
|
||||
"lib/private_lib/[here are source files]".
|
||||
|
||||
For example, see how can be organized `Foo` and `Bar` libraries:
|
||||
|
||||
|--lib
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |- readme.txt --> THIS FILE
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Then in `src/main.c` you should use:
|
||||
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
// rest H/C/CPP code
|
||||
|
||||
PlatformIO will find your libraries automatically, configure preprocessor's
|
||||
include paths and build them.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- http://docs.platformio.org/page/librarymanager/ldf.html
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Joba_Tsl2561",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.7",
|
||||
"keywords": "twowire, i2c, bus, sensor, luminosity, illuminance, lux",
|
||||
"description": "Arduino Library for ams (taos) luminance chip Tsl2561 with autogain",
|
||||
"repository":
|
|
@ -1,5 +1,5 @@
|
|||
name=Joba Tsl2561 Library
|
||||
version=2.0.1
|
||||
version=2.0.7
|
||||
author=joba-1
|
||||
maintainer=joba-1 <joban123.psn@gmail.com>
|
||||
sentence=IoT library for using the Tsl2561 luminosity sensor
|
|
@ -0,0 +1,58 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Example config for flashing nodemcuv2 boards via linux serial port
|
||||
;
|
||||
; Adapt (e.g. platform, board, port) to your environment as needed.
|
||||
; Then call platformio.sh to copy the file to all examples.
|
||||
; Now cd to the example directory (e.g. Autogain/) and do "pio run"
|
||||
; to build it or directly upload with "pio run --target upload".
|
||||
; Watch the serial output of your sketch with "pio device monitor".
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
|
||||
[platformio]
|
||||
; uncomment one, if you want to build only one
|
||||
; env_default = nodemcuv2
|
||||
; env_default = nano328
|
||||
|
||||
|
||||
[env:nodemcuv2]
|
||||
; TSL <-> ESP8266
|
||||
; ------------
|
||||
; GND <-> GND
|
||||
; VCC <-> 3V
|
||||
; SCL <-> D1
|
||||
; SDA <-> D2
|
||||
platform = espressif8266
|
||||
board = nodemcuv2
|
||||
framework = arduino
|
||||
build_flags = -Wall
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
upload_speed = 230400
|
||||
upload_resetmethod = nodemcu
|
||||
;usually upload port is autodetected
|
||||
;upload_port = /dev/ttyUSB[1-9]
|
||||
|
||||
|
||||
[env:nano328]
|
||||
; TSL <-> NANO
|
||||
; ------------
|
||||
; GND <-> GND
|
||||
; VCC <-> 3V3
|
||||
; SCL <-> A5
|
||||
; SDA <-> A4
|
||||
platform = atmelavr
|
||||
board = nanoatmega328
|
||||
framework = arduino
|
||||
build_flags = -Wall
|
||||
|
||||
monitor_speed = 115200
|
|
@ -29,7 +29,7 @@ bool Tsl2561::available() {
|
|||
|
||||
bool Tsl2561::begin( address_t addr ) {
|
||||
_addr = addr;
|
||||
return available();
|
||||
return available();
|
||||
}
|
||||
|
||||
bool Tsl2561::begin() {
|
||||
|
@ -48,24 +48,30 @@ bool Tsl2561::begin() {
|
|||
bool Tsl2561::readByte( register_t reg, uint8_t &val ) {
|
||||
_wire.beginTransmission(_addr);
|
||||
_wire.write(reg | CONTROL_CMD);
|
||||
if( _wire.endTransmission(false) == ERR_OK ) {
|
||||
if( _wire.requestFrom(_addr, 1) ) {
|
||||
if( (_status = static_cast<status_t>(_wire.endTransmission(false))) == ERR_OK ) {
|
||||
if( _wire.requestFrom(_addr, 1) == 1 ) {
|
||||
val = static_cast<uint8_t>(_wire.read());
|
||||
}
|
||||
else {
|
||||
_status = ERR_RW;
|
||||
}
|
||||
}
|
||||
return (_status = static_cast<status_t>(_wire.endTransmission())) == ERR_OK;
|
||||
return _status == ERR_OK;
|
||||
}
|
||||
|
||||
bool Tsl2561::readWord( register_t reg, uint16_t &val ) {
|
||||
_wire.beginTransmission(_addr);
|
||||
_wire.write(reg | CONTROL_CMD);
|
||||
if( _wire.endTransmission(false) == ERR_OK ) {
|
||||
if( _wire.requestFrom(_addr, 2) ) {
|
||||
val = (uint16_t)_wire.read() & 0xff;
|
||||
val |= ((uint16_t)_wire.read() & 0xff) << 8;
|
||||
if( (_status = static_cast<status_t>(_wire.endTransmission(false))) == ERR_OK ) {
|
||||
if( _wire.requestFrom(_addr, 2) == 2 ) {
|
||||
val = static_cast<uint16_t>(_wire.read()) & 0xff;
|
||||
val |= (static_cast<uint16_t>(_wire.read()) & 0xff) << 8;
|
||||
}
|
||||
else {
|
||||
_status = ERR_RW;
|
||||
}
|
||||
}
|
||||
return (_status = static_cast<status_t>(_wire.endTransmission())) == ERR_OK;
|
||||
return _status == ERR_OK;
|
||||
}
|
||||
|
||||
bool Tsl2561::writeByte( register_t reg, uint8_t val ) {
|
|
@ -39,22 +39,22 @@ bool normalizedLuminosity( bool gain, Tsl2561::exposure_t exposure, uint32_t &fu
|
|||
|
||||
switch( exposure ) {
|
||||
case Tsl2561::EXP_14:
|
||||
full = (scaledFull >= 5047/4*3) ? ~0 : ((full + 5) * 322) / 11;
|
||||
ir = (scaledIr >= 5047/4*3) ? ~0 : ((ir + 5) * 322) / 11;
|
||||
full = (scaledFull >= 5047/4*3) ? 0xffffffff : ((full + 5) * 322) / 11;
|
||||
ir = (scaledIr >= 5047/4*3) ? 0xffffffff : ((ir + 5) * 322) / 11;
|
||||
break;
|
||||
case Tsl2561::EXP_101:
|
||||
full = (scaledFull >= 37177/4*3) ? ~0 : ((full + 40) * 322) / 81;
|
||||
ir = (scaledIr >= 37177/4*3) ? ~0 : ((ir + 40) * 322) / 81;
|
||||
full = (scaledFull >= 37177/4*3) ? 0xffffffff : ((full + 40) * 322) / 81;
|
||||
ir = (scaledIr >= 37177/4*3) ? 0xffffffff : ((ir + 40) * 322) / 81;
|
||||
break;
|
||||
case Tsl2561::EXP_402:
|
||||
if( scaledFull >= 65535/4*3 ) full = ~0;
|
||||
if( scaledIr >= 65535/4*3 ) ir = ~0;
|
||||
if( scaledFull >= 65535/4*3 ) full = 0xffffffff;
|
||||
if( scaledIr >= 65535/4*3 ) ir = 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return full != ~0U && ir != ~0U;
|
||||
return full != 0xffffffff && ir != 0xffffffff;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -72,9 +72,9 @@ uint16_t getLimit( Tsl2561::exposure_t exposure ) {
|
|||
// Wait for one measurement interval plus some empirically tested extra millis
|
||||
void waitNext( Tsl2561::exposure_t exposure ) {
|
||||
switch( exposure ) {
|
||||
case Tsl2561::EXP_14: delay(16); break;
|
||||
case Tsl2561::EXP_101: delay(103); break;
|
||||
default: delay(408); break;
|
||||
case Tsl2561::EXP_14: delay(Tsl2561Util::DELAY_EXP_14); break;
|
||||
case Tsl2561::EXP_101: delay(Tsl2561Util::DELAY_EXP_101); break;
|
||||
default: delay(Tsl2561Util::DELAY_EXP_402); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
|
|||
|
||||
// get current sensitivity
|
||||
if( !tsl.getSensitivity(gain, exposure) ) {
|
||||
return false;
|
||||
return false; // I2C error
|
||||
}
|
||||
|
||||
// find index of current sensitivity
|
||||
|
@ -111,11 +111,13 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
|
|||
}
|
||||
|
||||
// in a loop wait for next sample, get values and adjust sensitivity if needed
|
||||
uint8_t retryOnSaturated = 10;
|
||||
|
||||
while( true ) {
|
||||
waitNext(exposure);
|
||||
|
||||
if( !tsl.fullLuminosity(full) || !tsl.irLuminosity(ir) ) {
|
||||
return false;
|
||||
return false; // I2C error
|
||||
}
|
||||
|
||||
uint16_t limit = getLimit(exposure);
|
||||
|
@ -126,13 +128,15 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
|
|||
if( (full < 1000 && ++curr < sizeof(sensitivity)/sizeof(sensitivity[0]))
|
||||
|| (full > limit && curr-- > 0) ) {
|
||||
if( !tsl.setSensitivity(sensitivity[curr].gain, sensitivity[curr].exposure) ) {
|
||||
return false;
|
||||
return false; // I2C error
|
||||
}
|
||||
gain = sensitivity[curr].gain;
|
||||
exposure = sensitivity[curr].exposure;
|
||||
}
|
||||
else {
|
||||
return true; // saturated, but best we can do
|
||||
if( ++curr > 0 && retryOnSaturated-- == 0 ) {
|
||||
return true; // saturated, but best we can do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,16 +145,32 @@ bool autoGain( Tsl2561 &tsl, bool &gain, Tsl2561::exposure_t &exposure, uint16_t
|
|||
bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir ) {
|
||||
// assume linear gradient 0% at 25°C to +20% at 70°C
|
||||
if( centiCelsius >= -3000 && centiCelsius <= 7000 ) {
|
||||
full -= (full * (centiCelsius - 2500) * 20) / (100 * (7000 - 2500));
|
||||
ir -= (ir * (centiCelsius - 2500) * 20) / (100 * (7000 - 2500));
|
||||
full -= (full * (centiCelsius - 2500)) / (5 * (7000 - 2500));
|
||||
ir -= (ir * (centiCelsius - 2500)) / (5 * (7000 - 2500));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Round num after valid digits
|
||||
uint32_t significance( uint32_t num, uint8_t digits ) {
|
||||
uint8_t len = 1;
|
||||
uint32_t n = num;
|
||||
while( n /= 10 ) {
|
||||
len++;
|
||||
}
|
||||
|
||||
uint32_t e10 = 1;
|
||||
while( len-- > digits ) {
|
||||
e10 *= 10;
|
||||
}
|
||||
|
||||
return ((num + e10 / 2) / e10) * e10;
|
||||
}
|
||||
|
||||
// Calculate lux from raw luminosity values
|
||||
bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType ) {
|
||||
bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType, uint8_t digits ) {
|
||||
if( !full ) {
|
||||
mLux = 0;
|
||||
return true;
|
||||
|
@ -187,6 +207,8 @@ bool milliLux( uint32_t full, uint32_t ir, uint32_t &mLux, bool csType ) {
|
|||
mLux /= 400 * 16 / 193; // 33 = counts/lux (cpl)
|
||||
}
|
||||
|
||||
mLux = significance(mLux, digits); // only the first 4 digits seem to make sense.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -24,6 +24,14 @@ This file is part of the Joba_Tsl2561 Library.
|
|||
|
||||
namespace Tsl2561Util {
|
||||
|
||||
// Some chips may need higher values.
|
||||
// Tweak here if autogain does not return valid results.
|
||||
typedef enum {
|
||||
DELAY_EXP_14 = 20, // Max. delay in ms after
|
||||
DELAY_EXP_101 = 110, // starting a measurement until
|
||||
DELAY_EXP_402 = 430 // the first values arrive.
|
||||
} delay_t;
|
||||
|
||||
// delay until next sample is available
|
||||
void waitNext( Tsl2561::exposure_t exposure );
|
||||
|
||||
|
@ -40,9 +48,11 @@ namespace Tsl2561Util {
|
|||
// adjust luminosity according to sensor temperature (max +/-20% from 25°C)
|
||||
bool compensateTemperature( int16_t centiCelsius, uint32_t &full, uint32_t &ir );
|
||||
|
||||
// calculate lux from normalized (and optionally temperature adjusted) luminosity
|
||||
bool milliLux( uint32_t full, uint32_t ir, uint32_t &milliLux, bool csType = false );
|
||||
// helper function to round after significant digits (~4 digits for Tsl2561)
|
||||
uint32_t significance( uint32_t value, uint8_t digits );
|
||||
|
||||
// calculate lux from normalized (and optionally temperature adjusted) luminosity
|
||||
bool milliLux( uint32_t full, uint32_t ir, uint32_t &milliLux, bool csType = false, uint8_t digits = 4 );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -39,7 +39,7 @@ platform = espressif8266@1.5.0
|
|||
; *** Esp8266 core for Arduino version 2.4.0
|
||||
;platform = espressif8266@1.6.0
|
||||
; *** Esp8266 core for Arduino version 2.4.1
|
||||
;platform = espressif8266@1.7.0
|
||||
;platform = espressif8266@1.7.3
|
||||
; *** Esp8266 core for Arduino version latest beta
|
||||
;platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||
; *** Esp8266 core for Arduino current version
|
||||
|
@ -62,8 +62,7 @@ build_flags =
|
|||
monitor_speed = 115200
|
||||
|
||||
; *** Upload Serial reset method for Wemos and NodeMCU
|
||||
;upload_speed = 115200
|
||||
upload_speed = 512000
|
||||
upload_speed = 115200
|
||||
upload_resetmethod = nodemcu
|
||||
upload_port = COM5
|
||||
; *** Fix Esp/Arduino core 2.4.x induced Tasmota unused floating point includes
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -215,6 +215,7 @@
|
|||
#define D_WCFG_3_WPSCONFIG "WPSConfig"
|
||||
#define D_WCFG_4_RETRY "Retry"
|
||||
#define D_WCFG_5_WAIT "Wait"
|
||||
#define D_WCFG_6_SERIAL "Serial"
|
||||
#define D_CMND_FRIENDLYNAME "FriendlyName"
|
||||
#define D_CMND_SWITCHMODE "SwitchMode"
|
||||
#define D_CMND_TELEPERIOD "TelePeriod"
|
||||
|
@ -471,6 +472,7 @@ const char S_JSON_COMMAND_INDEX_NVALUE_ACTIVE_NVALUE[] PROGMEM = "{\"%s%d\":\"%d
|
|||
const char S_JSON_SENSOR_INDEX_NVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":%d}";
|
||||
const char S_JSON_SENSOR_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_SENSOR "%d\":\"%s\"}";
|
||||
|
||||
const char JSON_SNS_TEMP[] PROGMEM = "%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}";
|
||||
const char JSON_SNS_TEMPHUM[] PROGMEM = "%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}";
|
||||
|
||||
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";
|
||||
|
@ -498,7 +500,8 @@ const char kWifiConfig[MAX_WIFI_OPTION][WCFG_MAX_STRING_LENGTH] PROGMEM = {
|
|||
D_WCFG_2_WIFIMANAGER,
|
||||
D_WCFG_3_WPSCONFIG,
|
||||
D_WCFG_4_RETRY,
|
||||
D_WCFG_5_WAIT };
|
||||
D_WCFG_5_WAIT,
|
||||
D_WCFG_6_SERIAL };
|
||||
const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
|
||||
D_CMND,
|
||||
D_STAT,
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Подтвърдете рестартирането"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Конфигурация на модула"
|
||||
#define D_CONFIGURE_MCP230XX "Конфигурация на MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Конфигурация на WiFi"
|
||||
#define D_CONFIGURE_MQTT "Конфигурация на MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Конфигурация на Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Potvrzení restartu"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Nastavení modulu"
|
||||
#define D_CONFIGURE_MCP230XX "Nastavení MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Nastavení WiFi"
|
||||
#define D_CONFIGURE_MQTT "Nastavení MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Nastavení Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Wirklich neustarten?"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Gerät konfigurieren"
|
||||
#define D_CONFIGURE_MCP230XX "MCP230xx konfigurieren"
|
||||
#define D_CONFIGURE_WIFI "WLAN konfigurieren"
|
||||
#define D_CONFIGURE_MQTT "MQTT konfigurieren"
|
||||
#define D_CONFIGURE_DOMOTICZ "Domoticz konfigurieren"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Επιβεβαίωση Επανεκκίνησης"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Ρύθμιση Module"
|
||||
#define D_CONFIGURE_MCP230XX "Ρύθμιση MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Ρύθμιση WiFi"
|
||||
#define D_CONFIGURE_MQTT "Ρύθμιση MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Ρύθμιση Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Confirm Restart"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configure Module"
|
||||
#define D_CONFIGURE_MCP230XX "Configure MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configure WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configure MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configure Domoticz"
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
#define D_PROGRAM_SIZE "Tamaño Programa"
|
||||
#define D_PROJECT "Proyecto"
|
||||
#define D_RECEIVED "Recibido"
|
||||
#define D_RESTART "Reinicio"
|
||||
#define D_RESTART "Reiniciar"
|
||||
#define D_RESTARTING "Reiniciando"
|
||||
#define D_RESTART_REASON "Causa Reinicio"
|
||||
#define D_RESTORE "Restauración"
|
||||
|
@ -168,7 +168,7 @@
|
|||
#define D_WEB_SERVER "Servidor Web"
|
||||
|
||||
// sonoff.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "Precaución, esta versión no salva los cambios"
|
||||
#define D_WARNING_MINIMAL_VERSION "Cuidado, esta versión no guarda los cambios"
|
||||
#define D_LEVEL_10 "level 1-0"
|
||||
#define D_LEVEL_01 "level 0-1"
|
||||
#define D_SERIAL_LOGGING_DISABLED "Log serial deshabilitado"
|
||||
|
@ -188,12 +188,12 @@
|
|||
#define D_PATCH_ISSUE_2186 "Patch issue 2186"
|
||||
#define D_CONNECTING_TO_AP "Connectando a AP"
|
||||
#define D_IN_MODE "en modo"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Falló Conección, Dirección IP no recibida"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Falló Conección, AP no pudo ser contactado"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Falló Conección, clave de AP incorrecta"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Falló Conección, timeout de AP"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Falló Conexión, Dirección IP no recibida"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Falló Conexión, AP no pudo ser contactado"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Falló Conexión, clave de AP incorrecta"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Falló Conexión, timeout de AP"
|
||||
#define D_ATTEMPTING_CONNECTION "Intentando conectar..."
|
||||
#define D_CHECKING_CONNECTION "Probando conección..."
|
||||
#define D_CHECKING_CONNECTION "Probando conexión..."
|
||||
#define D_QUERY_DONE "Consulta lista. Servicio MQTT encontrado"
|
||||
#define D_MQTT_SERVICE_FOUND "Servicio MQTT encontrado en"
|
||||
#define D_FOUND_AT "encontrado en"
|
||||
|
@ -211,22 +211,23 @@
|
|||
#define D_WITH_IP_ADDRESS "con dirección IP"
|
||||
#define D_WEBSERVER_STOPPED "Servidor web detenido"
|
||||
#define D_FILE_NOT_FOUND "Archivo No Encontrado"
|
||||
#define D_REDIRECTED "Redireccinado al portal captivo"
|
||||
#define D_REDIRECTED "Redireccionado al portal captivo"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager como AccessPoint y Estación"
|
||||
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager como AccessPoint"
|
||||
#define D_TRYING_TO_CONNECT "Intentado conectar dispositivo a la red"
|
||||
|
||||
#define D_RESTART_IN "Reinicio en"
|
||||
#define D_SECONDS "segundos"
|
||||
#define D_DEVICE_WILL_RESTART "El dispositivo se reiniciará en pocos segundos"
|
||||
#define D_DEVICE_WILL_RESTART "El dispositivo se reiniciará en unos segundos"
|
||||
#define D_BUTTON_TOGGLE "Alternar ON/OFF"
|
||||
#define D_CONFIGURATION "Configuración"
|
||||
#define D_INFORMATION "Información"
|
||||
#define D_FIRMWARE_UPGRADE "Actualización Firmware"
|
||||
#define D_FIRMWARE_UPGRADE "Actualizar Firmware"
|
||||
#define D_CONSOLE "Consola"
|
||||
#define D_CONFIRM_RESTART "Confirmar Reinicio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configuración del Módulo"
|
||||
#define D_CONFIGURE_MCP230XX "Configuración MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configuración WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configuración MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configuración Domoticz"
|
||||
|
@ -239,7 +240,7 @@
|
|||
#define D_MAIN_MENU "Menú Principal"
|
||||
|
||||
#define D_MODULE_PARAMETERS "Parámetros del módulo"
|
||||
#define D_MODULE_TYPE "Tipo módulo"
|
||||
#define D_MODULE_TYPE "Tipo de módulo"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "Serial In"
|
||||
#define D_SERIAL_OUT "Serial Out"
|
||||
|
@ -250,7 +251,7 @@
|
|||
#define D_NO_NETWORKS_FOUND "Ninguna red encontrada"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Recargar página para buscar nuevamente"
|
||||
#define D_DUPLICATE_ACCESSPOINT "AccessPoint duplicado"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorado debido a baja calidad"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorado por baja calidad"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
#define D_WPA_PSK "WPA PSK"
|
||||
|
@ -268,7 +269,7 @@
|
|||
#define D_SERIAL_LOG_LEVEL "Nivel de log Serial"
|
||||
#define D_WEB_LOG_LEVEL "Nivel de log Web"
|
||||
#define D_SYS_LOG_LEVEL "Nivel de Syslog"
|
||||
#define D_MORE_DEBUG "Mas Debug"
|
||||
#define D_MORE_DEBUG "Más Debug"
|
||||
#define D_SYSLOG_HOST "Host del Syslog"
|
||||
#define D_SYSLOG_PORT "Puerto del Syslog"
|
||||
#define D_TELEMETRY_PERIOD "Período de Telemetría"
|
||||
|
@ -287,7 +288,7 @@
|
|||
#define D_CONFIGURATION_RESET "Configuración restablecida"
|
||||
|
||||
#define D_PROGRAM_VERSION "Versión del Programa"
|
||||
#define D_BUILD_DATE_AND_TIME "Fecha y Hora de la Compilación"
|
||||
#define D_BUILD_DATE_AND_TIME "Fecha y Hora de Compilación"
|
||||
#define D_CORE_AND_SDK_VERSION "Versión Core/SDK"
|
||||
#define D_FLASH_WRITE_COUNT "Contador de escritura en Flash"
|
||||
#define D_MAC_ADDRESS "Dirección MAC"
|
||||
|
@ -333,16 +334,16 @@
|
|||
|
||||
// xdrv_01_mqtt.ino
|
||||
#define D_FINGERPRINT "Verificar TLS fingerprint..."
|
||||
#define D_TLS_CONNECT_FAILED_TO "Falló Conección TLS a"
|
||||
#define D_TLS_CONNECT_FAILED_TO "Falló Conexión TLS a"
|
||||
#define D_RETRY_IN "Reintentando"
|
||||
#define D_VERIFIED "Verificado Fingerprint"
|
||||
#define D_INSECURE "Conección insegura por Fingerprint no válido"
|
||||
#define D_CONNECT_FAILED_TO "Falló Conección a"
|
||||
#define D_INSECURE "Conexión insegura por Fingerprint inválido"
|
||||
#define D_CONNECT_FAILED_TO "Falló Conexión a"
|
||||
|
||||
// xplg_wemohue.ino
|
||||
#define D_MULTICAST_DISABLED "Multicast deshabilitado"
|
||||
#define D_MULTICAST_REJOINED "Multicast (re)conectado"
|
||||
#define D_MULTICAST_JOIN_FAILED "Conección Multicast fallida"
|
||||
#define D_MULTICAST_JOIN_FAILED "Conexión Multicast fallida"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "Falla al enviar respuesta"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Confirmer redémarrage"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configuration du Module"
|
||||
#define D_CONFIGURE_MCP230XX "Configuration MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configuration WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configuration MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configuration Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Újraindítás megerősítése"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Eszköz konfiguráció"
|
||||
#define D_CONFIGURE_MCP230XX "MCP230xx konfiguráció"
|
||||
#define D_CONFIGURE_WIFI "WiFi konfiguráció"
|
||||
#define D_CONFIGURE_MQTT "MQTT konfiguráció"
|
||||
#define D_CONFIGURE_DOMOTICZ "Domoticz konfiguráció"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Conferma Riavvio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configurazione Modulo"
|
||||
#define D_CONFIGURE_MCP230XX "Configurazione MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configurazione WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configurazione MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configurazione Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Bevestig herstart"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configureer Module"
|
||||
#define D_CONFIGURE_MCP230XX "Configureer MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configureer WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configureer MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configureer Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Potwierdź restart"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Konfiguruj moduł"
|
||||
#define D_CONFIGURE_MCP230XX "Konfiguruj MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Konfiguruj WiFi"
|
||||
#define D_CONFIGURE_MQTT "Konfiguruj MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Konfiguruj Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Confirmar o reinicio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configurar Módulo"
|
||||
#define D_CONFIGURE_MCP230XX "Configurar MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configurar WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configurar MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configurar Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Confirmar o reinicio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configurar Módulo"
|
||||
#define D_CONFIGURE_MCP230XX "Configurar MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Configurar WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configurar MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configurar Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Подтвердить перезагрузку"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Конфигурация Модуля"
|
||||
#define D_CONFIGURE_MCP230XX "Конфигурация MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Конфигурация WiFi"
|
||||
#define D_CONFIGURE_MQTT "Конфигурация MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Конфигурация Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "Підтвердити перезавантаження"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Конфігурація модуля"
|
||||
#define D_CONFIGURE_MCP230XX "Конфігурація MCP230xx"
|
||||
#define D_CONFIGURE_WIFI "Конфігурація WiFi"
|
||||
#define D_CONFIGURE_MQTT "Конфігурація MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Конфігурація Domoticz"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "确认重启"
|
||||
|
||||
#define D_CONFIGURE_MODULE "模块设置"
|
||||
#define D_CONFIGURE_MCP230XX "MCP230xx设置"
|
||||
#define D_CONFIGURE_WIFI "WiFi设置"
|
||||
#define D_CONFIGURE_MQTT "MQTT设置"
|
||||
#define D_CONFIGURE_DOMOTICZ "Domoticz设置"
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
#define D_CONFIRM_RESTART "確認重啟"
|
||||
|
||||
#define D_CONFIGURE_MODULE "模塊設置"
|
||||
#define D_CONFIGURE_MCP230XX "MCP230xx設置"
|
||||
#define D_CONFIGURE_WIFI "WiFi設置"
|
||||
#define D_CONFIGURE_MQTT "MQTT設置"
|
||||
#define D_CONFIGURE_DOMOTICZ "Domoticz設置"
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
uint32_t rf_receive_decimal : 1; // bit 28 (v6.0.0a)
|
||||
uint32_t ir_receive_decimal : 1; // bit 29 (v6.0.0a)
|
||||
uint32_t hass_light : 1; // bit 30 (v6.0.0b)
|
||||
uint32_t spare31 : 1;
|
||||
uint32_t global_state : 1; // bit 31 (v6.1.0)
|
||||
};
|
||||
} SysBitfield;
|
||||
|
||||
|
@ -394,6 +394,20 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
};
|
||||
} RulesBitfield;
|
||||
|
||||
typedef union {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t wifi_down : 1;
|
||||
uint8_t mqtt_down : 1;
|
||||
uint8_t spare02 : 1;
|
||||
uint8_t spare03 : 1;
|
||||
uint8_t spare04 : 1;
|
||||
uint8_t spare05 : 1;
|
||||
uint8_t spare06 : 1;
|
||||
uint8_t spare07 : 1;
|
||||
};
|
||||
} StateBitfield;
|
||||
|
||||
// See issue https://github.com/esp8266/Arduino/issues/2913
|
||||
#ifdef USE_ADC_VCC
|
||||
ADC_MODE(ADC_VCC); // Set ADC input for Power Supply Voltage usage
|
||||
|
|
|
@ -95,6 +95,8 @@ typedef unsigned long power_t; // Power (Relay) type
|
|||
#define LOGSZ 512 // Max number of characters in log
|
||||
#define MIN_MESSZ 893 // Min number of characters in MQTT message
|
||||
|
||||
#define SENSOR_MAX_MISS 5 // Max number of missed sensor reads before deciding it's offline
|
||||
|
||||
#ifdef USE_MQTT_TLS
|
||||
#define WEB_LOG_SIZE 2000 // Max number of characters in weblog
|
||||
#else
|
||||
|
@ -109,11 +111,15 @@ typedef unsigned long power_t; // Power (Relay) type
|
|||
#define SERIAL_POLLING 100 // Serial receive polling in ms
|
||||
#define MAX_STATUS 11 // Max number of status lines
|
||||
|
||||
#define NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
|
||||
|
||||
/*
|
||||
// Removed from esp8266 core since 20171105
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
*/
|
||||
#define tmin(a,b) ((a)<(b)?(a):(b))
|
||||
#define tmax(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
@ -167,7 +173,7 @@ enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME };
|
|||
|
||||
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||
|
||||
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, MAX_WIFI_OPTION};
|
||||
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, MAX_WIFI_OPTION};
|
||||
|
||||
enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION};
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||
====================================================*/
|
||||
|
||||
#define VERSION 0x06000003 // 6.0.0c
|
||||
#define VERSION 0x06010102 // 6.1.1b
|
||||
|
||||
// Location specific includes
|
||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
|
@ -161,6 +161,7 @@ uint8_t stop_flash_rotate = 0; // Allow flash configuration rotatio
|
|||
|
||||
int blinks = 201; // Number of LED blinks
|
||||
uint8_t blinkstate = 0; // LED state
|
||||
uint8_t blinkspeed = 1; // LED blink rate
|
||||
|
||||
uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit
|
||||
uint8_t lastbutton[MAX_KEYS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states
|
||||
|
@ -169,7 +170,7 @@ uint8_t multiwindow[MAX_KEYS] = { 0 }; // Max time between button presses t
|
|||
uint8_t multipress[MAX_KEYS] = { 0 }; // Number of button presses within multiwindow
|
||||
uint8_t lastwallswitch[MAX_SWITCHES]; // Last wall switch states
|
||||
uint8_t holdwallswitch[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold
|
||||
uint8_t virtualswitch[MAX_SWITCHES] = { 0 }; // Virtual switch states
|
||||
uint8_t virtualswitch[MAX_SWITCHES]; // Virtual switch states
|
||||
|
||||
mytmplt my_module; // Active copy of Module name and GPIOs
|
||||
uint8_t pin[GPIO_MAX]; // Possible pin configurations
|
||||
|
@ -184,6 +185,7 @@ uint8_t light_type = 0; // Light types
|
|||
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||
boolean mdns_begun = false;
|
||||
uint8_t ntp_force_sync = 0; // Force NTP sync
|
||||
StateBitfield global_state;
|
||||
RulesBitfield rules_flag;
|
||||
|
||||
char my_version[33]; // Composed version string
|
||||
|
@ -540,6 +542,53 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
mqtt_data[0] = '\0';
|
||||
MqttShowState();
|
||||
}
|
||||
else if (CMND_SLEEP == command_code) {
|
||||
if ((payload >= 0) && (payload < 251)) {
|
||||
if ((!Settings.sleep && payload) || (Settings.sleep && !payload)) restart_flag = 2;
|
||||
Settings.sleep = payload;
|
||||
sleep = payload;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_UNIT_NVALUE_UNIT, command, sleep, (Settings.flag.value_units) ? " " D_UNIT_MILLISECOND : "", Settings.sleep, (Settings.flag.value_units) ? " " D_UNIT_MILLISECOND : "");
|
||||
}
|
||||
else if ((CMND_UPGRADE == command_code) || (CMND_UPLOAD == command_code)) {
|
||||
// Check if the payload is numerically 1, and had no trailing chars.
|
||||
// e.g. "1foo" or "1.2.3" could fool us.
|
||||
// Check if the version we have been asked to upgrade to is higher than our current version.
|
||||
// We also need at least 3 chars to make a valid version number string.
|
||||
if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && NewerVersion(dataBuf))) {
|
||||
ota_state_flag = 3;
|
||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}", command, my_version, Settings.ota_url);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}", command, my_version, GetOtaUrl(stemp1, sizeof(stemp1)));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_ONE_OR_GT "\"}", command, my_version);
|
||||
}
|
||||
}
|
||||
else if (CMND_OTAURL == command_code) {
|
||||
if ((data_len > 0) && (data_len < sizeof(Settings.ota_url)))
|
||||
strlcpy(Settings.ota_url, (1 == payload) ? OTA_URL : dataBuf, sizeof(Settings.ota_url));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.ota_url);
|
||||
}
|
||||
else if (CMND_SERIALLOG == command_code) {
|
||||
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
||||
Settings.flag.mqtt_serial = 0;
|
||||
SetSeriallog(payload);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.seriallog_level, seriallog_level);
|
||||
}
|
||||
else if (CMND_RESTART == command_code) {
|
||||
switch (payload) {
|
||||
case 1:
|
||||
restart_flag = 2;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_RESTARTING);
|
||||
break;
|
||||
case 99:
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
|
||||
EspRestart();
|
||||
break;
|
||||
default:
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_ONE_TO_RESTART);
|
||||
}
|
||||
}
|
||||
else if ((CMND_POWERONSTATE == command_code) && (Settings.module != MOTOR)) {
|
||||
/* 0 = Keep relays off after power on
|
||||
* 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off
|
||||
|
@ -854,32 +903,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.pulse_counter_debounce);
|
||||
}
|
||||
else if (CMND_SLEEP == command_code) {
|
||||
if ((payload >= 0) && (payload < 251)) {
|
||||
if ((!Settings.sleep && payload) || (Settings.sleep && !payload)) restart_flag = 2;
|
||||
Settings.sleep = payload;
|
||||
sleep = payload;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_UNIT_NVALUE_UNIT, command, sleep, (Settings.flag.value_units) ? " " D_UNIT_MILLISECOND : "", Settings.sleep, (Settings.flag.value_units) ? " " D_UNIT_MILLISECOND : "");
|
||||
}
|
||||
else if ((CMND_UPGRADE == command_code) || (CMND_UPLOAD == command_code)) {
|
||||
// Check if the payload is numerically 1, and had no trailing chars.
|
||||
// e.g. "1foo" or "1.2.3" could fool us.
|
||||
// Check if the version we have been asked to upgrade to is higher than our current version.
|
||||
// We also need at least 3 chars to make a valid version number string.
|
||||
if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && NewerVersion(dataBuf))) {
|
||||
ota_state_flag = 3;
|
||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}", command, my_version, Settings.ota_url);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}", command, my_version, GetOtaUrl(stemp1, sizeof(stemp1)));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"%s\":\"" D_JSON_ONE_OR_GT "\"}", command, my_version);
|
||||
}
|
||||
}
|
||||
else if (CMND_OTAURL == command_code) {
|
||||
if ((data_len > 0) && (data_len < sizeof(Settings.ota_url)))
|
||||
strlcpy(Settings.ota_url, (1 == payload) ? OTA_URL : dataBuf, sizeof(Settings.ota_url));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.ota_url);
|
||||
}
|
||||
else if (CMND_BAUDRATE == command_code) {
|
||||
if (payload32 > 0) {
|
||||
payload32 /= 1200; // Make it a valid baudrate
|
||||
|
@ -917,13 +940,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.serial_delimiter);
|
||||
}
|
||||
else if (CMND_SERIALLOG == command_code) {
|
||||
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
||||
Settings.flag.mqtt_serial = 0;
|
||||
SetSeriallog(payload);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.seriallog_level, seriallog_level);
|
||||
}
|
||||
else if (CMND_SYSLOG == command_code) {
|
||||
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
||||
Settings.syslog_level = payload;
|
||||
|
@ -976,7 +992,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
else if ((CMND_SSID == command_code) && (index > 0) && (index <= 2)) {
|
||||
if ((data_len > 0) && (data_len < sizeof(Settings.sta_ssid[0]))) {
|
||||
strlcpy(Settings.sta_ssid[index -1], (1 == payload) ? (1 == index) ? STA_SSID1 : STA_SSID2 : dataBuf, sizeof(Settings.sta_ssid[0]));
|
||||
strlcpy(Settings.sta_ssid[index -1], (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? (1 == index) ? STA_SSID1 : STA_SSID2 : dataBuf, sizeof(Settings.sta_ssid[0]));
|
||||
Settings.sta_active = index -1;
|
||||
restart_flag = 2;
|
||||
}
|
||||
|
@ -984,7 +1000,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
else if ((CMND_PASSWORD == command_code) && (index > 0) && (index <= 2)) {
|
||||
if ((data_len > 0) && (data_len < sizeof(Settings.sta_pwd[0]))) {
|
||||
strlcpy(Settings.sta_pwd[index -1], (1 == payload) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0]));
|
||||
strlcpy(Settings.sta_pwd[index -1], (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0]));
|
||||
Settings.sta_active = index -1;
|
||||
restart_flag = 2;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.sta_pwd[index -1]);
|
||||
|
@ -1040,20 +1056,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_UNIT, command, Settings.tele_period, (Settings.flag.value_units) ? " " D_UNIT_SECOND : "");
|
||||
}
|
||||
else if (CMND_RESTART == command_code) {
|
||||
switch (payload) {
|
||||
case 1:
|
||||
restart_flag = 2;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_RESTARTING);
|
||||
break;
|
||||
case 99:
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
|
||||
EspRestart();
|
||||
break;
|
||||
default:
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_ONE_TO_RESTART);
|
||||
}
|
||||
}
|
||||
else if (CMND_RESET == command_code) {
|
||||
switch (payload) {
|
||||
case 1:
|
||||
|
@ -1721,7 +1723,7 @@ void SwitchHandler(byte mode)
|
|||
uint8_t switchflag;
|
||||
|
||||
for (byte i = 0; i < MAX_SWITCHES; i++) {
|
||||
if (pin[GPIO_SWT1 +i] < 99) {
|
||||
if ((pin[GPIO_SWT1 +i] < 99) || (mode)) {
|
||||
|
||||
if (holdwallswitch[i]) {
|
||||
holdwallswitch[i]--;
|
||||
|
@ -1802,6 +1804,7 @@ void SwitchHandler(byte mode)
|
|||
void StateLoop()
|
||||
{
|
||||
power_t power_now;
|
||||
uint8_t blinkinterval = 1;
|
||||
|
||||
state_loop_timer = millis() + (1000 / STATES);
|
||||
state++;
|
||||
|
@ -1879,27 +1882,38 @@ void StateLoop()
|
|||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
if (!(state % ((STATES/10)*2))) {
|
||||
if (!Settings.flag.global_state) { // Problem blinkyblinky enabled
|
||||
if (global_state.data) { // Any problem
|
||||
if (global_state.mqtt_down) { blinkinterval = 9; } // MQTT problem so blink every 2 seconds (slowest)
|
||||
if (global_state.wifi_down) { blinkinterval = 4; } // Wifi problem so blink every second (slow)
|
||||
blinks = 201; // Allow only a single blink in case the problem is solved
|
||||
}
|
||||
}
|
||||
if (blinks || restart_flag || ota_state_flag) {
|
||||
if (restart_flag || ota_state_flag) {
|
||||
blinkstate = 1; // Stay lit
|
||||
if (restart_flag || ota_state_flag) { // Overrule blinks and keep led lit
|
||||
blinkstate = 1; // Stay lit
|
||||
} else {
|
||||
blinkstate ^= 1; // Blink
|
||||
blinkspeed--;
|
||||
if (!blinkspeed) {
|
||||
blinkspeed = blinkinterval; // Set interval to 0.2 (default), 1 or 2 seconds
|
||||
blinkstate ^= 1; // Blink
|
||||
}
|
||||
}
|
||||
if ((!(Settings.ledstate &0x08)) && ((Settings.ledstate &0x06) || (blinks > 200) || (blinkstate))) {
|
||||
SetLedPower(blinkstate);
|
||||
// if ( (!Settings.flag.global_state && global_state.data) || ((!(Settings.ledstate &0x08)) && ((Settings.ledstate &0x06) || (blinks > 200) || (blinkstate))) ) {
|
||||
SetLedPower(blinkstate); // Set led on or off
|
||||
}
|
||||
if (!blinkstate) {
|
||||
blinks--;
|
||||
if (200 == blinks) blinks = 0;
|
||||
if (200 == blinks) blinks = 0; // Disable blink
|
||||
}
|
||||
} else {
|
||||
if (Settings.ledstate &1) {
|
||||
boolean tstate = power;
|
||||
if ((SONOFF_TOUCH == Settings.module) || (SONOFF_T11 == Settings.module) || (SONOFF_T12 == Settings.module) || (SONOFF_T13 == Settings.module)) {
|
||||
tstate = (!power) ? 1 : 0;
|
||||
}
|
||||
SetLedPower(tstate);
|
||||
}
|
||||
else if (Settings.ledstate &1) {
|
||||
boolean tstate = power;
|
||||
if ((SONOFF_TOUCH == Settings.module) || (SONOFF_T11 == Settings.module) || (SONOFF_T12 == Settings.module) || (SONOFF_T13 == Settings.module)) {
|
||||
tstate = (!power) ? 1 : 0; // As requested invert signal for Touch devices to find them in the dark
|
||||
}
|
||||
SetLedPower(tstate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2142,6 +2156,7 @@ void SerialInput()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Sonoff S31 and Sonoff Pow R2 4800 baud serial interface
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
@ -2152,7 +2167,7 @@ void SerialInput()
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_ENERGY_SENSOR
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
if (serial_in_byte > 127) { // binary data...
|
||||
|
@ -2364,10 +2379,13 @@ void GpioInit()
|
|||
}
|
||||
}
|
||||
for (byte i = 0; i < MAX_SWITCHES; i++) {
|
||||
lastwallswitch[i] = 1; // Init global to virtual switch state;
|
||||
if (pin[GPIO_SWT1 +i] < 99) {
|
||||
pinMode(pin[GPIO_SWT1 +i], (16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 :INPUT_PULLUP);
|
||||
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check
|
||||
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // Set global now so doesn't change the saved power state on first switch check
|
||||
|
||||
}
|
||||
virtualswitch[i] = lastwallswitch[i];
|
||||
}
|
||||
|
||||
#ifdef USE_WS2812
|
||||
|
|
|
@ -51,6 +51,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
#endif
|
||||
|
||||
#define USE_DHT // Default DHT11 sensor needs no external library
|
||||
#define USE_ENERGY_SENSOR // Use energy sensors
|
||||
|
||||
/*********************************************************************************************\
|
||||
* [sonoff-allsensors.bin]
|
||||
|
@ -58,6 +59,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_ALL_SENSORS
|
||||
|
||||
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
||||
#define USE_DS18x20 // For more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
|
||||
//#define USE_DS18x20_LEGACY // For more than one DS18x20 sensors with dynamic scan using library OneWire (+1k5 code)
|
||||
|
@ -65,16 +67,19 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
#define USE_SHT // Add I2C emulating code for SHT1X sensor (+1k4 code)
|
||||
#define USE_SHT3X // Add I2C code for SHT3x sensor (+0k6 code)
|
||||
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code)
|
||||
#define USE_LM75AD // Add I2C code for LM75AD sensor (+0k5 code)
|
||||
#define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code)
|
||||
#define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code)
|
||||
#define USE_BME680 // Add additional support for BME680 sensor using Bosch BME680 library (+4k code)
|
||||
#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code)
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code)
|
||||
#define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code)
|
||||
#define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code)
|
||||
//#define USE_SI1145 // Add I2C code for SI1145/46/47 sensor (+1k code)
|
||||
#define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code)
|
||||
//#define USE_ADS1115_I2CDEV // Add I2C code for ADS1115 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
|
||||
#define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
|
||||
#define USE_MGS // Add I2C code for Xadow and Grove Mutichannel Gas sensor using library Multichannel_Gas_Sensor (+10k code)
|
||||
//#define USE_APDS9960 // Add I2C code for APDS9960 Proximity Sensor. Disables SHT and VEML6070 (+4k7 code)
|
||||
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
|
||||
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
|
||||
#ifndef CO2_LOW
|
||||
|
@ -87,6 +92,8 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
|
||||
#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
#define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||
|
@ -105,36 +112,28 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_CLASSIC
|
||||
#ifdef USE_KNX
|
||||
#undef USE_KNX
|
||||
#endif
|
||||
#ifdef USE_TIMERS
|
||||
#undef USE_TIMERS
|
||||
#endif
|
||||
#ifdef USE_TIMERS_WEB
|
||||
#undef USE_TIMERS_WEB
|
||||
#endif
|
||||
#ifdef USE_SUNRISE
|
||||
#undef USE_SUNRISE
|
||||
#endif
|
||||
#ifdef USE_RULES
|
||||
#undef USE_RULES
|
||||
#endif
|
||||
#ifdef USE_SGP30
|
||||
#undef USE_SGP30
|
||||
#endif
|
||||
#ifdef USE_NOVA_SDS
|
||||
#undef USE_NOVA_SDS
|
||||
#endif
|
||||
#ifdef USE_IR_RECEIVE
|
||||
#undef USE_IR_RECEIVE
|
||||
#endif
|
||||
#ifdef USE_SERIAL_BRIDGE
|
||||
#undef USE_SERIAL_BRIDGE
|
||||
#endif
|
||||
#ifdef USE_SR04
|
||||
#undef USE_SR04
|
||||
#endif
|
||||
|
||||
#undef USE_KNX // Disable KNX IP Protocol Support
|
||||
#undef USE_TIMERS // Disable support for up to 16 timers
|
||||
#undef USE_TIMERS_WEB // Disable support for timer webpage
|
||||
#undef USE_SUNRISE // Disable support for Sunrise and sunset tools
|
||||
#undef USE_RULES // Disable support for rules
|
||||
#undef USE_LM75AD // Disable sensor
|
||||
#undef USE_BME680 // Disable sensor
|
||||
#undef USE_SGP30 // Disable sensor
|
||||
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
|
||||
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
|
||||
#undef USE_PZEM004T // Disable PZEM004T energy sensor
|
||||
#undef USE_IR_RECEIVE // Disable support for IR receiver
|
||||
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
|
||||
#undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter
|
||||
#undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter
|
||||
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
|
||||
#undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices
|
||||
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
|
||||
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
|
||||
#undef DEBUG_THEO // Disable debug code
|
||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||
#endif // USE_CLASSIC
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -143,12 +142,11 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_KNX_NO_EMULATION
|
||||
|
||||
#ifndef USE_KNX
|
||||
#define USE_KNX // Enable KNX IP Protocol Support (+23k code, +3k3 mem)
|
||||
#endif
|
||||
#ifdef USE_EMULATION
|
||||
#undef USE_EMULATION // Disable Belkin WeMo and Hue Bridge emulation for Alexa (-16k code, -2k mem)
|
||||
#endif
|
||||
#endif // USE_KNX_NO_EMULATION
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -166,96 +164,55 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
|||
\*********************************************************************************************/
|
||||
|
||||
#ifdef BE_MINIMAL
|
||||
#ifdef USE_MQTT_TLS
|
||||
#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set
|
||||
#endif
|
||||
#ifdef USE_DISCOVERY
|
||||
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
|
||||
#endif
|
||||
#ifdef USE_DOMOTICZ
|
||||
|
||||
#undef USE_ENERGY_SENSOR // Disable energy sensors
|
||||
#undef USE_ARDUINO_OTA // Disable support for Arduino OTA
|
||||
#undef USE_WPS // Disable support for WPS as initial wifi configuration tool
|
||||
#undef USE_SMARTCONFIG // Disable support for Wifi SmartConfig as initial wifi configuration tool
|
||||
#undef USE_DOMOTICZ // Disable Domoticz
|
||||
#endif
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
#undef USE_HOME_ASSISTANT // Disable Home Assistant
|
||||
#endif
|
||||
#ifdef USE_KNX
|
||||
#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set
|
||||
#undef USE_KNX // Disable KNX IP Protocol Support
|
||||
#endif
|
||||
//#ifdef USE_WEBSERVER
|
||||
//#undef USE_WEBSERVER // Disable Webserver
|
||||
//#endif
|
||||
#ifdef USE_EMULATION
|
||||
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
|
||||
#undef USE_EMULATION // Disable Wemo or Hue emulation
|
||||
#endif
|
||||
#ifdef USE_TIMERS
|
||||
#undef USE_TIMERS // Disable support for up to 16 timers
|
||||
#endif
|
||||
#ifdef USE_SUNRISE
|
||||
#undef USE_TIMERS_WEB // Disable support for timer webpage
|
||||
#undef USE_SUNRISE // Disable support for Sunrise and sunset tools
|
||||
#endif
|
||||
#ifdef USE_RULES
|
||||
#undef USE_RULES // Disable support for rules
|
||||
#endif
|
||||
#ifdef USE_DHT
|
||||
#undef USE_DHT // Disable internal DHT sensor
|
||||
#endif
|
||||
#ifdef USE_DS18x20
|
||||
#undef USE_DS18x20 // Disable DS18x20 sensor
|
||||
#endif
|
||||
#ifdef USE_DS18B20
|
||||
#undef USE_DS18x20_LEGACY // Disable DS18x20 sensor
|
||||
#undef USE_DS18B20 // Disable internal DS18B20 sensor
|
||||
#endif
|
||||
#ifdef USE_I2C
|
||||
#undef USE_I2C // Disable all I2C sensors and devices
|
||||
#endif
|
||||
#ifdef USE_SPI
|
||||
#undef USE_SPI // Disable all SPI devices
|
||||
#endif
|
||||
#ifdef USE_DISPLAY
|
||||
#undef USE_DISPLAY // Disable Display support
|
||||
#endif
|
||||
#ifdef USE_MHZ19
|
||||
#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor
|
||||
#endif
|
||||
#ifdef USE_SENSEAIR
|
||||
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
|
||||
#endif
|
||||
#ifdef USE_PMS5003
|
||||
#undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor
|
||||
#endif
|
||||
#ifdef USE_NOVA_SDS
|
||||
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
|
||||
#endif
|
||||
#ifdef USE_PZEM004T
|
||||
#undef USE_PZEM004T // Disable PZEM004T energy sensor
|
||||
#endif
|
||||
#ifdef USE_SERIAL_BRIDGE
|
||||
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
|
||||
#endif
|
||||
#ifdef USE_IR_REMOTE
|
||||
#undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter
|
||||
#undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter
|
||||
#undef USE_IR_REMOTE // Disable IR driver
|
||||
#endif
|
||||
#ifdef USE_WS2812
|
||||
#undef USE_WS2812 // Disable WS2812 Led string
|
||||
#endif
|
||||
#ifdef USE_ARILUX_RF
|
||||
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
|
||||
#endif
|
||||
#ifdef USE_SR04
|
||||
#undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices
|
||||
#endif
|
||||
#ifdef DEBUG_THEO
|
||||
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
|
||||
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
|
||||
#undef DEBUG_THEO // Disable debug code
|
||||
#endif
|
||||
#ifdef USE_DEBUG_DRIVER
|
||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||
#endif
|
||||
#endif // BE_MINIMAL
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Mandatory defines satisfying possible disabled defines
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifndef USE_WPS // See https://github.com/esp8266/Arduino/pull/4889
|
||||
#undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
|
||||
#endif
|
||||
|
||||
#ifndef SWITCH_MODE
|
||||
#define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state)
|
||||
#endif
|
||||
|
|
|
@ -735,6 +735,12 @@ void GetFeatures()
|
|||
#ifdef USE_KNX
|
||||
feature_drv1 |= 0x10000000; // xdrv_11_knx.ino
|
||||
#endif
|
||||
#ifdef USE_WPS
|
||||
feature_drv1 |= 0x20000000; // support.ino
|
||||
#endif
|
||||
#ifdef USE_SMARTCONFIG
|
||||
feature_drv1 |= 0x40000000; // support.ino
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
|
@ -954,42 +960,49 @@ boolean WifiWpsConfigDone(void)
|
|||
boolean WifiWpsConfigBegin(void)
|
||||
{
|
||||
wps_result = 99;
|
||||
if (!wifi_wps_disable()) {
|
||||
return false;
|
||||
}
|
||||
if (!wifi_wps_enable(WPS_TYPE_PBC)) {
|
||||
return false; // so far only WPS_TYPE_PBC is supported (SDK 2.0.0)
|
||||
}
|
||||
if (!wifi_set_wps_cb((wps_st_cb_t) &WifiWpsStatusCallback)) {
|
||||
return false;
|
||||
}
|
||||
if (!wifi_wps_start()) {
|
||||
return false;
|
||||
}
|
||||
if (!wifi_wps_disable()) { return false; }
|
||||
if (!wifi_wps_enable(WPS_TYPE_PBC)) { return false; } // so far only WPS_TYPE_PBC is supported (SDK 2.0.0)
|
||||
if (!wifi_set_wps_cb((wps_st_cb_t) &WifiWpsStatusCallback)) { return false; }
|
||||
if (!wifi_wps_start()) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiConfig(uint8_t type)
|
||||
{
|
||||
if (!wifi_config_type) {
|
||||
if (type >= WIFI_RETRY) { // WIFI_RETRY and WIFI_WAIT
|
||||
return;
|
||||
}
|
||||
if ((WIFI_RETRY == type) || (WIFI_WAIT == type)) { return; }
|
||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION)
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
WiFi.disconnect(); // Solve possible Wifi hangs
|
||||
WiFi.disconnect(); // Solve possible Wifi hangs
|
||||
wifi_config_type = type;
|
||||
|
||||
#ifndef USE_WPS
|
||||
if (WIFI_WPSCONFIG == wifi_config_type) { wifi_config_type = WIFI_MANAGER; }
|
||||
#endif // USE_WPS
|
||||
#ifndef USE_WEBSERVER
|
||||
if (WIFI_MANAGER == wifi_config_type) { wifi_config_type = WIFI_SMARTCONFIG; }
|
||||
#endif // USE_WEBSERVER
|
||||
#ifndef USE_SMARTCONFIG
|
||||
if (WIFI_SMARTCONFIG == wifi_config_type) { wifi_config_type = WIFI_SERIAL; }
|
||||
#endif // USE_SMARTCONFIG
|
||||
|
||||
wifi_config_counter = WIFI_CONFIG_SEC; // Allow up to WIFI_CONFIG_SECS seconds for phone to provide ssid/pswd
|
||||
wifi_counter = wifi_config_counter +5;
|
||||
blinks = 1999;
|
||||
if (WIFI_RESTART == wifi_config_type) {
|
||||
restart_flag = 2;
|
||||
}
|
||||
else if (WIFI_SERIAL == wifi_config_type) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_6_SERIAL " " D_ACTIVE_FOR_3_MINUTES));
|
||||
}
|
||||
#ifdef USE_SMARTCONFIG
|
||||
else if (WIFI_SMARTCONFIG == wifi_config_type) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_1_SMARTCONFIG " " D_ACTIVE_FOR_3_MINUTES));
|
||||
WiFi.beginSmartConfig();
|
||||
}
|
||||
#endif // USE_SMARTCONFIG
|
||||
#ifdef USE_WPS
|
||||
else if (WIFI_WPSCONFIG == wifi_config_type) {
|
||||
if (WifiWpsConfigBegin()) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_3_WPSCONFIG " " D_ACTIVE_FOR_3_MINUTES));
|
||||
|
@ -998,6 +1011,7 @@ void WifiConfig(uint8_t type)
|
|||
wifi_config_counter = 3;
|
||||
}
|
||||
}
|
||||
#endif // USE_WPS
|
||||
#ifdef USE_WEBSERVER
|
||||
else if (WIFI_MANAGER == wifi_config_type) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES));
|
||||
|
@ -1023,17 +1037,11 @@ void WifiBegin(uint8_t flag)
|
|||
WiFi.disconnect(true); // Delete SDK wifi config
|
||||
delay(200);
|
||||
WiFi.mode(WIFI_STA); // Disable AP mode
|
||||
if (Settings.sleep) {
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_4_1 // See https://github.com/arendst/Sonoff-Tasmota/issues/2559
|
||||
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
|
||||
#ifndef ARDUINO_ESP8266_RELEASE_2_4_1 // See https://github.com/arendst/Sonoff-Tasmota/issues/2559 - Sleep bug
|
||||
if (Settings.sleep) { WiFi.setSleepMode(WIFI_LIGHT_SLEEP); } // Allow light sleep during idle times
|
||||
#endif
|
||||
}
|
||||
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) {
|
||||
// WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||
// }
|
||||
if (!WiFi.getAutoConnect()) {
|
||||
WiFi.setAutoConnect(true);
|
||||
}
|
||||
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); }
|
||||
if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); }
|
||||
// WiFi.setAutoReconnect(true);
|
||||
switch (flag) {
|
||||
case 0: // AP1
|
||||
|
@ -1043,9 +1051,7 @@ void WifiBegin(uint8_t flag)
|
|||
case 2: // Toggle
|
||||
Settings.sta_active ^= 1;
|
||||
} // 3: Current AP
|
||||
if (0 == strlen(Settings.sta_ssid[1])) {
|
||||
Settings.sta_active = 0;
|
||||
}
|
||||
if ('\0' == Settings.sta_ssid[Settings.sta_active][0]) { Settings.sta_active ^= 1; } // Skip empty SSID
|
||||
if (Settings.ip_address[0]) {
|
||||
WiFi.config(Settings.ip_address[0], Settings.ip_address[1], Settings.ip_address[2], Settings.ip_address[3]); // Set static IP
|
||||
}
|
||||
|
@ -1059,6 +1065,7 @@ void WifiBegin(uint8_t flag)
|
|||
void WifiCheckIp()
|
||||
{
|
||||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
|
||||
global_state.wifi_down = 0;
|
||||
wifi_counter = WIFI_CHECK_SEC;
|
||||
wifi_retry = wifi_retry_init;
|
||||
AddLog_P((wifi_status != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, S_LOG_WIFI, PSTR(D_CONNECTED));
|
||||
|
@ -1070,6 +1077,8 @@ void WifiCheckIp()
|
|||
}
|
||||
wifi_status = WL_CONNECTED;
|
||||
} else {
|
||||
global_state.wifi_down = 1;
|
||||
uint8_t wifi_config_tool = Settings.sta_config;
|
||||
wifi_status = WiFi.status();
|
||||
switch (wifi_status) {
|
||||
case WL_CONNECTED:
|
||||
|
@ -1103,7 +1112,12 @@ void WifiCheckIp()
|
|||
if (!wifi_retry || ((wifi_retry_init / 2) == wifi_retry)) {
|
||||
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_TIMEOUT));
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_ATTEMPTING_CONNECTION));
|
||||
if (('\0' == Settings.sta_ssid[0][0]) && ('\0' == Settings.sta_ssid[1][0])) {
|
||||
wifi_config_tool = WIFI_CONFIG_NO_SSID; // Skip empty SSIDs and start Wifi config tool
|
||||
wifi_retry = 0;
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_ATTEMPTING_CONNECTION));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wifi_retry) {
|
||||
|
@ -1116,7 +1130,7 @@ void WifiCheckIp()
|
|||
wifi_counter = 1;
|
||||
wifi_retry--;
|
||||
} else {
|
||||
WifiConfig(Settings.sta_config);
|
||||
WifiConfig(wifi_config_tool);
|
||||
wifi_counter = 1;
|
||||
wifi_retry = wifi_retry_init;
|
||||
}
|
||||
|
@ -1127,6 +1141,7 @@ void WifiCheck(uint8_t param)
|
|||
{
|
||||
wifi_counter--;
|
||||
switch (param) {
|
||||
case WIFI_SERIAL:
|
||||
case WIFI_SMARTCONFIG:
|
||||
case WIFI_MANAGER:
|
||||
case WIFI_WPSCONFIG:
|
||||
|
@ -1137,12 +1152,16 @@ void WifiCheck(uint8_t param)
|
|||
wifi_config_counter--;
|
||||
wifi_counter = wifi_config_counter +5;
|
||||
if (wifi_config_counter) {
|
||||
#ifdef USE_SMARTCONFIG
|
||||
if ((WIFI_SMARTCONFIG == wifi_config_type) && WiFi.smartConfigDone()) {
|
||||
wifi_config_counter = 0;
|
||||
}
|
||||
#endif // USE_SMARTCONFIG
|
||||
#ifdef USE_WPS
|
||||
if ((WIFI_WPSCONFIG == wifi_config_type) && WifiWpsConfigDone()) {
|
||||
wifi_config_counter = 0;
|
||||
}
|
||||
#endif // USE_WPS
|
||||
if (!wifi_config_counter) {
|
||||
if (strlen(WiFi.SSID().c_str())) {
|
||||
strlcpy(Settings.sta_ssid[0], WiFi.SSID().c_str(), sizeof(Settings.sta_ssid[0]));
|
||||
|
@ -1156,10 +1175,10 @@ void WifiCheck(uint8_t param)
|
|||
}
|
||||
}
|
||||
if (!wifi_config_counter) {
|
||||
if (WIFI_SMARTCONFIG == wifi_config_type) {
|
||||
WiFi.stopSmartConfig();
|
||||
}
|
||||
SettingsSdkErase();
|
||||
#ifdef USE_SMARTCONFIG
|
||||
if (WIFI_SMARTCONFIG == wifi_config_type) { WiFi.stopSmartConfig(); }
|
||||
#endif // USE_SMARTCONFIG
|
||||
// SettingsSdkErase(); // Disabled v6.1.0b due to possible bad wifi connects
|
||||
restart_flag = 2;
|
||||
}
|
||||
} else {
|
||||
|
@ -1169,6 +1188,7 @@ void WifiCheck(uint8_t param)
|
|||
WifiCheckIp();
|
||||
}
|
||||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0) && !wifi_config_type) {
|
||||
global_state.wifi_down = 0;
|
||||
#ifdef BE_MINIMAL
|
||||
if (1 == RtcSettings.ota_loader) {
|
||||
RtcSettings.ota_loader = 0;
|
||||
|
@ -1194,9 +1214,7 @@ void WifiCheck(uint8_t param)
|
|||
StopWebserver();
|
||||
}
|
||||
#ifdef USE_EMULATION
|
||||
if (Settings.flag2.emulation) {
|
||||
UdpConnect();
|
||||
}
|
||||
if (Settings.flag2.emulation) { UdpConnect(); }
|
||||
#endif // USE_EMULATION
|
||||
#endif // USE_WEBSERVER
|
||||
#ifdef USE_KNX
|
||||
|
@ -1206,6 +1224,7 @@ void WifiCheck(uint8_t param)
|
|||
}
|
||||
#endif // USE_KNX
|
||||
} else {
|
||||
global_state.wifi_down = 1;
|
||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION)
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
|
@ -1225,9 +1244,7 @@ int WifiState()
|
|||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
|
||||
state = WIFI_RESTART;
|
||||
}
|
||||
if (wifi_config_type) {
|
||||
state = wifi_config_type;
|
||||
}
|
||||
if (wifi_config_type) { state = wifi_config_type; }
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -1240,6 +1257,8 @@ void WifiConnect()
|
|||
wifi_counter = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
// Enable from 6.0.0a until 6.1.0a - disabled due to possible cause of bad wifi connect on core 2.3.0
|
||||
void WifiDisconnect()
|
||||
{
|
||||
// Courtesy of EspEasy
|
||||
|
@ -1252,10 +1271,17 @@ void WifiDisconnect()
|
|||
|
||||
void EspRestart()
|
||||
{
|
||||
delay(100); // Allow time for message xfer
|
||||
// This results in exception 3 on restarts
|
||||
delay(100); // Allow time for message xfer - disabled v6.1.0b
|
||||
WifiDisconnect();
|
||||
ESP.restart();
|
||||
}
|
||||
*/
|
||||
|
||||
void EspRestart()
|
||||
{
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
#ifdef USE_DISCOVERY
|
||||
/*********************************************************************************************\
|
||||
|
@ -2076,6 +2102,12 @@ void AddLogSerial(byte loglevel)
|
|||
AddLogSerial(loglevel, (uint8_t*)serial_in_buffer, serial_in_byte_counter);
|
||||
}
|
||||
|
||||
void AddLogMissed(char *sensor, uint8_t misses)
|
||||
{
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("SNS: %s missed %d"), sensor, SENSOR_MAX_MISS - misses);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
\*********************************************************************************************/
|
||||
|
||||
// -- Master parameter control --------------------
|
||||
#define CFG_HOLDER 4617 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash
|
||||
#define CFG_HOLDER 4617 // [Reset 1] Change this value (max 32000) to load SECTION1 configuration parameters to flash
|
||||
|
||||
// -- Project -------------------------------------
|
||||
#define PROJECT "sonoff" // PROJECT is used as the default topic delimiter
|
||||
|
@ -63,8 +63,13 @@
|
|||
#define STA_PASS1 "" // [Password1] Wifi password
|
||||
#define STA_SSID2 "" // [Ssid2] Optional alternate AP Wifi SSID
|
||||
#define STA_PASS2 "" // [Password2] Optional alternate AP Wifi password
|
||||
#define WIFI_CONFIG_TOOL WIFI_WPSCONFIG // [WifiConfig] Default tool if wifi fails to connect
|
||||
// (WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT)
|
||||
#define WIFI_CONFIG_TOOL WIFI_WAIT // [WifiConfig] Default tool if wifi fails to connect
|
||||
// (WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL)
|
||||
#define WIFI_CONFIG_NO_SSID WIFI_WPSCONFIG // Default tool if wifi fails to connect and no SSID is configured
|
||||
// (WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_SERIAL)
|
||||
// *** NOTE: When WPS is disabled by USE_WPS below, WIFI_WPSCONFIG will execute WIFI_MANAGER ***
|
||||
// *** NOTE: When WIFI_MANAGER is disabled by USE_WEBSERVER below, WIFI_MANAGER will execute WIFI_SMARTCONFIG ***
|
||||
// *** NOTE: When WIFI_SMARTCONFIG is disabled by USE_SMARTCONFIG below, WIFI_SMARTCONFIG will execute WIFI_SERIAL ***
|
||||
|
||||
// -- Syslog --------------------------------------
|
||||
#define SYS_LOG_HOST "" // [LogHost] (Linux) syslog host
|
||||
|
@ -178,8 +183,6 @@
|
|||
* - Disable a feature by preceding it with //
|
||||
\*********************************************************************************************/
|
||||
|
||||
//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+13k code)
|
||||
|
||||
// -- Localization --------------------------------
|
||||
// If non selected the default en-GB will be used
|
||||
//#define MY_LANGUAGE bg-BG // Bulgarian in Bulgaria
|
||||
|
@ -200,6 +203,13 @@
|
|||
//#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China
|
||||
//#define MY_LANGUAGE zh-TW // Chinese (Traditional) in Taiwan
|
||||
|
||||
// -- Wifi Config tools ---------------------------
|
||||
//#define USE_WPS // Add support for WPS as initial wifi configuration tool (+33k code, 1k mem (5k mem with core v2.4.2+))
|
||||
//#define USE_SMARTCONFIG // Add support for Wifi SmartConfig as initial wifi configuration tool (+23k code, +0.6k mem)
|
||||
|
||||
// -- OTA -----------------------------------------
|
||||
//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+13k code)
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Select ONE of possible three MQTT library types below
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
@ -230,7 +240,7 @@
|
|||
//#define USE_KNX // Enable KNX IP Protocol Support (+23k code, +3k3 mem)
|
||||
|
||||
// -- HTTP ----------------------------------------
|
||||
#define USE_WEBSERVER // Enable web server and wifi manager (+66k code, +8k mem)
|
||||
#define USE_WEBSERVER // Enable web server and Wifi Manager (+66k code, +8k mem)
|
||||
#define WEB_PORT 80 // Web server Port for User and Admin mode
|
||||
#define WEB_USERNAME "admin" // Web server Admin mode user name
|
||||
#define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+16k code, +2k mem)
|
||||
|
@ -265,7 +275,7 @@
|
|||
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code)
|
||||
#define USE_LM75AD // Add I2C code for LM75AD sensor (+0k5 code)
|
||||
#define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code)
|
||||
// #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code)
|
||||
// #define USE_BME680 // Add additional support for BME680 sensor using Bosch BME680 library (+4k code)
|
||||
#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code)
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code)
|
||||
// #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code)
|
||||
|
@ -277,8 +287,13 @@
|
|||
// #define USE_MGS // Add I2C code for Xadow and Grove Mutichannel Gas sensor using library Multichannel_Gas_Sensor (+10k code)
|
||||
#define MGS_SENSOR_ADDR 0x04 // Default Mutichannel Gas sensor i2c address
|
||||
// #define USE_APDS9960 // Add I2C code for APDS9960 Proximity Sensor. Disables SHT and VEML6070 (+4k7 code)
|
||||
|
||||
// #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons
|
||||
|
||||
|
||||
// #define USE_MCP230xx // Add I2C code for MCP23008/MCP23017 for GP INPUT ONLY providing command Sensor29 for configuration (+2k2 code)
|
||||
// #define USE_MCP230xx_displaymain // Display pin status on Tasmota main page (+0k2 code)
|
||||
// #define USE_MCP230xx_webconfig // Enable web config button and form to Tasmota web interface (+2k1 code)
|
||||
|
||||
#endif // USE_I2C
|
||||
|
||||
// -- SPI sensors ---------------------------------
|
||||
|
@ -314,9 +329,9 @@
|
|||
|
||||
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
|
||||
|
||||
//#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
|
||||
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
|
||||
|
||||
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
|
||||
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code)
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Debug features are only supported in development branch
|
||||
|
|
|
@ -383,6 +383,7 @@ void MqttConnected()
|
|||
}
|
||||
mqtt_initial_connection_state = 0;
|
||||
rules_flag.mqtt_connected = 1;
|
||||
global_state.mqtt_down = 0;
|
||||
}
|
||||
|
||||
#ifdef USE_MQTT_TLS
|
||||
|
@ -443,6 +444,7 @@ void MqttReconnect()
|
|||
|
||||
mqtt_connected = false;
|
||||
mqtt_retry_counter = Settings.mqtt_retry;
|
||||
global_state.mqtt_down = 1;
|
||||
|
||||
#ifndef USE_MQTT_TLS
|
||||
#ifdef USE_DISCOVERY
|
||||
|
@ -512,13 +514,17 @@ void MqttCheck()
|
|||
{
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
if (!MqttIsConnected()) {
|
||||
global_state.mqtt_down = 1;
|
||||
if (!mqtt_retry_counter) {
|
||||
MqttReconnect();
|
||||
} else {
|
||||
mqtt_retry_counter--;
|
||||
}
|
||||
} else {
|
||||
global_state.mqtt_down = 0;
|
||||
}
|
||||
} else {
|
||||
global_state.mqtt_down = 0;
|
||||
if (mqtt_initial_connection_state) MqttReconnect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,6 +190,10 @@ const char HTTP_BTN_RSTRT[] PROGMEM =
|
|||
"<br/><form action='rb' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESTART "\");'><button class='button bred'>" D_RESTART "</button></form>";
|
||||
const char HTTP_BTN_MENU_MODULE[] PROGMEM =
|
||||
"<br/><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form>";
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_webconfig)
|
||||
const char HTTP_BTN_MCP230XX[] PROGMEM =
|
||||
"<br/><form action='mc' method='get'><button>" D_CONFIGURE_MCP230XX "</button></form>";
|
||||
#endif // USE_I2C and USE_MCP230xx and USE_MCP230xx_webconfig
|
||||
#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB)
|
||||
const char HTTP_BTN_MENU_TIMER[] PROGMEM =
|
||||
"<br/><form action='tm' method='get'><button>" D_CONFIGURE_TIMER "</button></form>";
|
||||
|
@ -367,8 +371,21 @@ void StartWebserver(int type, IPAddress ipweb)
|
|||
if (!WebServer) {
|
||||
WebServer = new ESP8266WebServer((HTTP_MANAGER==type) ? 80 : WEB_PORT);
|
||||
WebServer->on("/", HandleRoot);
|
||||
WebServer->on("/up", HandleUpgradeFirmware);
|
||||
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
||||
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
||||
WebServer->on("/cs", HandleConsole);
|
||||
WebServer->on("/ax", HandleAjaxConsoleRefresh);
|
||||
WebServer->on("/ay", HandleAjaxStatusRefresh);
|
||||
WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
WebServer->on("/cm", HandleHttpCommand);
|
||||
WebServer->on("/rb", HandleRestart);
|
||||
#ifndef BE_MINIMAL
|
||||
WebServer->on("/cn", HandleConfiguration);
|
||||
WebServer->on("/md", HandleModuleConfiguration);
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_webconfig)
|
||||
WebServer->on("/mc", HandleMCP230xxConfiguration);
|
||||
#endif // USE_I2C and USE_MCP230xx and USE_MCP230xx_webconfig
|
||||
#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB)
|
||||
WebServer->on("/tm", HandleTimerConfiguration);
|
||||
#endif // USE_TIMERS and USE_TIMERS_WEB
|
||||
|
@ -389,17 +406,7 @@ void StartWebserver(int type, IPAddress ipweb)
|
|||
WebServer->on("/sv", HandleSaveSettings);
|
||||
WebServer->on("/rs", HandleRestoreConfiguration);
|
||||
WebServer->on("/rt", HandleResetConfiguration);
|
||||
WebServer->on("/up", HandleUpgradeFirmware);
|
||||
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
|
||||
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
|
||||
WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest);
|
||||
WebServer->on("/cm", HandleHttpCommand);
|
||||
WebServer->on("/cs", HandleConsole);
|
||||
WebServer->on("/ax", HandleAjaxConsoleRefresh);
|
||||
WebServer->on("/ay", HandleAjaxStatusRefresh);
|
||||
WebServer->on("/in", HandleInformation);
|
||||
WebServer->on("/rb", HandleRestart);
|
||||
WebServer->on("/fwlink", HandleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
|
||||
#ifdef USE_EMULATION
|
||||
if (EMUL_WEMO == Settings.flag2.emulation) {
|
||||
WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
|
||||
|
@ -411,6 +418,8 @@ void StartWebserver(int type, IPAddress ipweb)
|
|||
WebServer->on("/description.xml", HandleUpnpSetupHue);
|
||||
}
|
||||
#endif // USE_EMULATION
|
||||
#endif // Not BE_MINIMAL
|
||||
WebServer->on("/fwlink", HandleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
|
||||
WebServer->onNotFound(HandleNotFound);
|
||||
}
|
||||
reset_web_log_flag = 0;
|
||||
|
@ -520,6 +529,7 @@ void HandleRoot()
|
|||
if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page.
|
||||
|
||||
if (HTTP_MANAGER == webserver_state) {
|
||||
#ifndef BE_MINIMAL
|
||||
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) {
|
||||
HandleWifiLogin();
|
||||
} else {
|
||||
|
@ -537,6 +547,7 @@ void HandleRoot()
|
|||
HandleWifiLogin();
|
||||
}
|
||||
}
|
||||
#endif // Not BE_MINIMAL
|
||||
} else {
|
||||
char stemp[10];
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
|
@ -672,6 +683,7 @@ boolean HttpUser()
|
|||
return status;
|
||||
}
|
||||
|
||||
#ifndef BE_MINIMAL
|
||||
void HandleConfiguration()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
|
@ -681,6 +693,11 @@ void HandleConfiguration()
|
|||
page.replace(F("{v}"), FPSTR(S_CONFIGURATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_BTN_MENU_MODULE);
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_webconfig)
|
||||
if (MCP230xx_Type()) { // Configuration button will only show if MCP23008/MCP23017 was detected on I2C
|
||||
page += FPSTR(HTTP_BTN_MCP230XX);
|
||||
}
|
||||
#endif // USE_I2C and USE_MCP230xx and USE_MCP230xx_webconfig
|
||||
#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB)
|
||||
#ifdef USE_RULES
|
||||
page += FPSTR(HTTP_BTN_MENU_TIMER);
|
||||
|
@ -1119,6 +1136,11 @@ void HandleSaveSettings()
|
|||
}
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
break;
|
||||
#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_webconfig)
|
||||
case 8:
|
||||
MCP230xx_SaveSettings();
|
||||
break;
|
||||
#endif // USE_I2C and USE_MCP230xx and USE_MCP230xx_webconfig
|
||||
case 6:
|
||||
WebGetArg("g99", tmp, sizeof(tmp));
|
||||
byte new_module = (!strlen(tmp)) ? MODULE : atoi(tmp);
|
||||
|
@ -1205,6 +1227,122 @@ void HandleRestoreConfiguration()
|
|||
upload_file_type = UPL_SETTINGS;
|
||||
}
|
||||
|
||||
void HandleInformation()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_INFORMATION);
|
||||
|
||||
char stopic[TOPSZ];
|
||||
|
||||
int freeMem = ESP.getFreeHeap();
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_INFORMATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
// page += F("<fieldset><legend><b> Information </b></legend>");
|
||||
|
||||
page += F("<style>td{padding:0px 5px;}</style>");
|
||||
page += F("<div id='i' name='i'></div>");
|
||||
|
||||
// Save 1k of code space replacing table html with javascript replace codes
|
||||
// }1 = </td></tr><tr><th>
|
||||
// }2 = </th><td>
|
||||
String func = FPSTR(HTTP_SCRIPT_INFO_BEGIN);
|
||||
func += F("<table style='width:100%'><tr><th>");
|
||||
func += F(D_PROGRAM_VERSION "}2"); func += my_version;
|
||||
func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime();
|
||||
func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion());
|
||||
func += F("}1" D_UPTIME "}2"); func += GetDateAndTime(DT_UPTIME);
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress());
|
||||
func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic;
|
||||
func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount);
|
||||
func += F("}1" D_RESTART_REASON "}2"); func += GetResetReason();
|
||||
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
if (SONOFF_IFAN02 == Settings.module) { maxfn = 1; }
|
||||
for (byte i = 0; i < maxfn; i++) {
|
||||
func += F("}1" D_FRIENDLY_NAME " "); func += i +1; func += F("}2"); func += Settings.friendlyname[i];
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_AP); func += String(Settings.sta_active +1);
|
||||
func += F(" " D_SSID " (" D_RSSI ")}2"); func += Settings.sta_ssid[Settings.sta_active]; func += F(" ("); func += WifiGetRssiAsQuality(WiFi.RSSI()); func += F("%)");
|
||||
func += F("}1" D_HOSTNAME "}2"); func += my_hostname;
|
||||
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
|
||||
func += F("}1" D_IP_ADDRESS "}2"); func += WiFi.localIP().toString();
|
||||
func += F("}1" D_GATEWAY "}2"); func += IPAddress(Settings.ip_address[1]).toString();
|
||||
func += F("}1" D_SUBNET_MASK "}2"); func += IPAddress(Settings.ip_address[2]).toString();
|
||||
func += F("}1" D_DNS_SERVER "}2"); func += IPAddress(Settings.ip_address[3]).toString();
|
||||
func += F("}1" D_MAC_ADDRESS "}2"); func += WiFi.macAddress();
|
||||
}
|
||||
if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {
|
||||
func += F("}1" D_AP " " D_IP_ADDRESS "}2"); func += WiFi.softAPIP().toString();
|
||||
func += F("}1" D_AP " " D_GATEWAY "}2"); func += WiFi.softAPIP().toString();
|
||||
func += F("}1" D_AP " " D_MAC_ADDRESS "}2"); func += WiFi.softAPmacAddress();
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
func += F("}1" D_MQTT_HOST "}2"); func += Settings.mqtt_host;
|
||||
func += F("}1" D_MQTT_PORT "}2"); func += String(Settings.mqtt_port);
|
||||
func += F("}1" D_MQTT_CLIENT " &<br/> " D_FALLBACK_TOPIC "}2"); func += mqtt_client;
|
||||
func += F("}1" D_MQTT_USER "}2"); func += Settings.mqtt_user;
|
||||
func += F("}1" D_MQTT_TOPIC "}2"); func += Settings.mqtt_topic;
|
||||
func += F("}1" D_MQTT_GROUP_TOPIC "}2"); func += Settings.mqtt_grptopic;
|
||||
GetTopic_P(stopic, CMND, mqtt_topic, "");
|
||||
func += F("}1" D_MQTT_FULL_TOPIC "}2"); func += stopic;
|
||||
|
||||
} else {
|
||||
func += F("}1" D_MQTT "}2" D_DISABLED);
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_EMULATION "}2");
|
||||
#ifdef USE_EMULATION
|
||||
if (EMUL_WEMO == Settings.flag2.emulation) {
|
||||
func += F(D_BELKIN_WEMO);
|
||||
}
|
||||
else if (EMUL_HUE == Settings.flag2.emulation) {
|
||||
func += F(D_HUE_BRIDGE);
|
||||
}
|
||||
else {
|
||||
func += F(D_NONE);
|
||||
}
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // USE_EMULATION
|
||||
|
||||
func += F("}1" D_MDNS_DISCOVERY "}2");
|
||||
#ifdef USE_DISCOVERY
|
||||
func += F(D_ENABLED);
|
||||
func += F("}1" D_MDNS_ADVERTISE "}2");
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
func += F(D_WEB_SERVER);
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_ESP_CHIP_ID "}2"); func += String(ESP.getChipId());
|
||||
func += F("}1" D_FLASH_CHIP_ID "}2"); func += String(ESP.getFlashChipId());
|
||||
func += F("}1" D_FLASH_CHIP_SIZE "}2"); func += String(ESP.getFlashChipRealSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_PROGRAM_FLASH_SIZE "}2"); func += String(ESP.getFlashChipSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_PROGRAM_SIZE "}2"); func += String(ESP.getSketchSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_FREE_PROGRAM_SPACE "}2"); func += String(ESP.getFreeSketchSpace() / 1024); func += F("kB");
|
||||
func += F("}1" D_FREE_MEMORY "}2"); func += String(freeMem / 1024); func += F("kB");
|
||||
func += F("</td></tr></table>");
|
||||
func += FPSTR(HTTP_SCRIPT_INFO_END);
|
||||
page.replace(F("</script>"), func);
|
||||
page.replace(F("<body>"), F("<body onload='i()'>"));
|
||||
|
||||
// page += F("</fieldset>");
|
||||
page += FPSTR(HTTP_BTN_MAIN);
|
||||
ShowPage(page);
|
||||
}
|
||||
#endif // Not BE_MINIMAL
|
||||
|
||||
void HandleUpgradeFirmware()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
|
@ -1629,121 +1767,6 @@ void HandleAjaxConsoleRefresh()
|
|||
WebServer->send(200, FPSTR(HDR_CTYPE_XML), message);
|
||||
}
|
||||
|
||||
void HandleInformation()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_INFORMATION);
|
||||
|
||||
char stopic[TOPSZ];
|
||||
|
||||
int freeMem = ESP.getFreeHeap();
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
page.replace(F("{v}"), FPSTR(S_INFORMATION));
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
// page += F("<fieldset><legend><b> Information </b></legend>");
|
||||
|
||||
page += F("<style>td{padding:0px 5px;}</style>");
|
||||
page += F("<div id='i' name='i'></div>");
|
||||
|
||||
// Save 1k of code space replacing table html with javascript replace codes
|
||||
// }1 = </td></tr><tr><th>
|
||||
// }2 = </th><td>
|
||||
String func = FPSTR(HTTP_SCRIPT_INFO_BEGIN);
|
||||
func += F("<table style='width:100%'><tr><th>");
|
||||
func += F(D_PROGRAM_VERSION "}2"); func += my_version;
|
||||
func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime();
|
||||
func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion());
|
||||
func += F("}1" D_UPTIME "}2"); func += GetDateAndTime(DT_UPTIME);
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress());
|
||||
func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic;
|
||||
func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount);
|
||||
func += F("}1" D_RESTART_REASON "}2"); func += GetResetReason();
|
||||
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||
if (SONOFF_IFAN02 == Settings.module) { maxfn = 1; }
|
||||
for (byte i = 0; i < maxfn; i++) {
|
||||
func += F("}1" D_FRIENDLY_NAME " "); func += i +1; func += F("}2"); func += Settings.friendlyname[i];
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_AP); func += String(Settings.sta_active +1);
|
||||
func += F(" " D_SSID " (" D_RSSI ")}2"); func += Settings.sta_ssid[Settings.sta_active]; func += F(" ("); func += WifiGetRssiAsQuality(WiFi.RSSI()); func += F("%)");
|
||||
func += F("}1" D_HOSTNAME "}2"); func += my_hostname;
|
||||
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
|
||||
func += F("}1" D_IP_ADDRESS "}2"); func += WiFi.localIP().toString();
|
||||
func += F("}1" D_GATEWAY "}2"); func += IPAddress(Settings.ip_address[1]).toString();
|
||||
func += F("}1" D_SUBNET_MASK "}2"); func += IPAddress(Settings.ip_address[2]).toString();
|
||||
func += F("}1" D_DNS_SERVER "}2"); func += IPAddress(Settings.ip_address[3]).toString();
|
||||
func += F("}1" D_MAC_ADDRESS "}2"); func += WiFi.macAddress();
|
||||
}
|
||||
if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {
|
||||
func += F("}1" D_AP " " D_IP_ADDRESS "}2"); func += WiFi.softAPIP().toString();
|
||||
func += F("}1" D_AP " " D_GATEWAY "}2"); func += WiFi.softAPIP().toString();
|
||||
func += F("}1" D_AP " " D_MAC_ADDRESS "}2"); func += WiFi.softAPmacAddress();
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
if (Settings.flag.mqtt_enabled) {
|
||||
func += F("}1" D_MQTT_HOST "}2"); func += Settings.mqtt_host;
|
||||
func += F("}1" D_MQTT_PORT "}2"); func += String(Settings.mqtt_port);
|
||||
func += F("}1" D_MQTT_CLIENT " &<br/> " D_FALLBACK_TOPIC "}2"); func += mqtt_client;
|
||||
func += F("}1" D_MQTT_USER "}2"); func += Settings.mqtt_user;
|
||||
func += F("}1" D_MQTT_TOPIC "}2"); func += Settings.mqtt_topic;
|
||||
func += F("}1" D_MQTT_GROUP_TOPIC "}2"); func += Settings.mqtt_grptopic;
|
||||
GetTopic_P(stopic, CMND, mqtt_topic, "");
|
||||
func += F("}1" D_MQTT_FULL_TOPIC "}2"); func += stopic;
|
||||
|
||||
} else {
|
||||
func += F("}1" D_MQTT "}2" D_DISABLED);
|
||||
}
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_EMULATION "}2");
|
||||
#ifdef USE_EMULATION
|
||||
if (EMUL_WEMO == Settings.flag2.emulation) {
|
||||
func += F(D_BELKIN_WEMO);
|
||||
}
|
||||
else if (EMUL_HUE == Settings.flag2.emulation) {
|
||||
func += F(D_HUE_BRIDGE);
|
||||
}
|
||||
else {
|
||||
func += F(D_NONE);
|
||||
}
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // USE_EMULATION
|
||||
|
||||
func += F("}1" D_MDNS_DISCOVERY "}2");
|
||||
#ifdef USE_DISCOVERY
|
||||
func += F(D_ENABLED);
|
||||
func += F("}1" D_MDNS_ADVERTISE "}2");
|
||||
#ifdef WEBSERVER_ADVERTISE
|
||||
func += F(D_WEB_SERVER);
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // WEBSERVER_ADVERTISE
|
||||
#else
|
||||
func += F(D_DISABLED);
|
||||
#endif // USE_DISCOVERY
|
||||
|
||||
func += F("}1}2 "); // Empty line
|
||||
func += F("}1" D_ESP_CHIP_ID "}2"); func += String(ESP.getChipId());
|
||||
func += F("}1" D_FLASH_CHIP_ID "}2"); func += String(ESP.getFlashChipId());
|
||||
func += F("}1" D_FLASH_CHIP_SIZE "}2"); func += String(ESP.getFlashChipRealSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_PROGRAM_FLASH_SIZE "}2"); func += String(ESP.getFlashChipSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_PROGRAM_SIZE "}2"); func += String(ESP.getSketchSize() / 1024); func += F("kB");
|
||||
func += F("}1" D_FREE_PROGRAM_SPACE "}2"); func += String(ESP.getFreeSketchSpace() / 1024); func += F("kB");
|
||||
func += F("}1" D_FREE_MEMORY "}2"); func += String(freeMem / 1024); func += F("kB");
|
||||
func += F("</td></tr></table>");
|
||||
func += FPSTR(HTTP_SCRIPT_INFO_END);
|
||||
page.replace(F("</script>"), func);
|
||||
page.replace(F("<body>"), F("<body onload='i()'>"));
|
||||
|
||||
// page += F("</fieldset>");
|
||||
page += FPSTR(HTTP_BTN_MAIN);
|
||||
ShowPage(page);
|
||||
}
|
||||
|
||||
void HandleRestart()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define USE_ENERGY_SENSOR
|
||||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
/*********************************************************************************************\
|
||||
* HLW8012 and PZEM004T - Energy
|
||||
|
@ -93,18 +91,18 @@ void EnergyUpdateToday()
|
|||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* HLW8012, BL0937 or HJL-01 - Energy (Sonoff Pow)
|
||||
* HLW8012, BL0937 or HJL-01 - Energy (Sonoff Pow, HuaFan, KMC70011, BlitzWolf)
|
||||
*
|
||||
* Based on Source: Shenzhen Heli Technology Co., Ltd
|
||||
\*********************************************************************************************/
|
||||
|
||||
// HLW8012 based (Sonoff Pow, KMC70011)
|
||||
// HLW8012 based (Sonoff Pow, KMC70011, HuaFan)
|
||||
#define HLW_PREF 10000 // 1000.0W
|
||||
#define HLW_UREF 2200 // 220.0V
|
||||
#define HLW_IREF 4545 // 4.545A
|
||||
#define HLW_SEL_VOLTAGE 1
|
||||
|
||||
// HJL-01 based (Homecube, BlitzWolf)
|
||||
// HJL-01 based (BlitzWolf, Homecube, Gosund)
|
||||
#define HJL_PREF 1362
|
||||
#define HJL_UREF 822
|
||||
#define HJL_IREF 3300
|
||||
|
|
|
@ -271,14 +271,17 @@ boolean DomoticzCommand()
|
|||
|
||||
boolean DomoticzSendKey(byte key, byte device, byte state, byte svalflg)
|
||||
{
|
||||
if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"),
|
||||
(key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off");
|
||||
MqttPublish(domoticz_in_topic);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
boolean result = 0;
|
||||
|
||||
if (device <= MAX_DOMOTICZ_IDX) {
|
||||
if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"),
|
||||
(key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off");
|
||||
MqttPublish(domoticz_in_topic);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
|
|
@ -253,7 +253,7 @@ bool RulesRuleMatch(byte rule_set, String &event, String &rule)
|
|||
}
|
||||
} else match = true;
|
||||
|
||||
if (Settings.flag.rules_once) {
|
||||
if (bitRead(Settings.rule_once, rule_set)) {
|
||||
if (match) { // Only allow match state changes
|
||||
if (!bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set])) {
|
||||
bitSet(rules_triggers[rule_set], rules_trigger_count[rule_set]);
|
||||
|
@ -557,44 +557,38 @@ boolean RulesCommand()
|
|||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mems[index -1]);
|
||||
}
|
||||
else if ((CMND_ADD == command_code) && (index > 0) && (index <= RULES_MAX_VARS)) {
|
||||
if ( XdrvMailbox.data_len > 0 ) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) + CharToDouble(XdrvMailbox.data);
|
||||
dtostrfd(tempvar,2,vars[index -1]);
|
||||
dtostrfd(tempvar, 2, vars[index -1]);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||
}
|
||||
else if ((CMND_SUB == command_code) && (index > 0) && (index <= RULES_MAX_VARS)) {
|
||||
if ( XdrvMailbox.data_len > 0 ){
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) - CharToDouble(XdrvMailbox.data);
|
||||
dtostrfd(tempvar,2,vars[index -1]);
|
||||
dtostrfd(tempvar, 2, vars[index -1]);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||
}
|
||||
else if ((CMND_MULT == command_code) && (index > 0) && (index <= RULES_MAX_VARS)) {
|
||||
if ( XdrvMailbox.data_len > 0 ){
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
double tempvar = CharToDouble(vars[index -1]) * CharToDouble(XdrvMailbox.data);
|
||||
dtostrfd(tempvar,2,vars[index -1]);
|
||||
dtostrfd(tempvar, 2, vars[index -1]);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||
}
|
||||
else if ((CMND_SCALE == command_code) && (index > 0) && (index <= RULES_MAX_VARS)) {
|
||||
if ( XdrvMailbox.data_len > 0 ) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
||||
double value = 0;
|
||||
double valueIN = 0;
|
||||
double fromLow = 0;
|
||||
double fromHigh = 0;
|
||||
double toLow = 0;
|
||||
double toHigh = 0;
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
|
||||
valueIN = CharToDouble(subStr(XdrvMailbox.data, ",", 1));
|
||||
fromLow = CharToDouble(subStr(XdrvMailbox.data, ",", 2));
|
||||
fromHigh = CharToDouble(subStr(XdrvMailbox.data, ",", 3));
|
||||
toLow = CharToDouble(subStr(XdrvMailbox.data, ",", 4));
|
||||
toHigh = CharToDouble(subStr(XdrvMailbox.data, ",", 5));
|
||||
|
||||
value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh);
|
||||
dtostrfd(value,2,vars[index -1]);
|
||||
double valueIN = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||
double fromLow = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
double fromHigh = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
double toLow = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 4));
|
||||
double toHigh = CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 5));
|
||||
double value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh);
|
||||
dtostrfd(value, 2, vars[index -1]);
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, vars[index -1]);
|
||||
|
@ -610,24 +604,23 @@ double map_double(double x, double in_min, double in_max, double out_min, double
|
|||
}
|
||||
|
||||
// Function to return a substring defined by a delimiter at an index
|
||||
char* subStr (char* str, const char *delim, int index) {
|
||||
char *act, *sub, *ptr;
|
||||
static char copy[10];
|
||||
char* subStr(char* dest, char* str, const char *delim, int index)
|
||||
{
|
||||
char *act;
|
||||
char *sub;
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
// Since strtok consumes the first arg, make a copy
|
||||
strcpy(copy, str);
|
||||
|
||||
for (i = 1, act = copy; i <= index; i++, act = NULL) {
|
||||
sub = strtok_r(act, delim, &ptr);
|
||||
if (sub == NULL) break;
|
||||
strncpy(dest, str, strlen(str));
|
||||
for (i = 1, act = dest; i <= index; i++, act = NULL) {
|
||||
sub = strtok_r(act, delim, &ptr);
|
||||
if (sub == NULL) break;
|
||||
}
|
||||
sub = LTrim(sub);
|
||||
sub = RTrim(sub);
|
||||
sub = Trim(sub);
|
||||
return sub;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
|
|
@ -126,7 +126,6 @@ int mod(int a, int b)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define cmin(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
void Ws2812UpdatePixelColor(int position, struct WsColor hand_color, float offset)
|
||||
{
|
||||
|
@ -140,9 +139,9 @@ void Ws2812UpdatePixelColor(int position, struct WsColor hand_color, float offse
|
|||
|
||||
color = strip->GetPixelColor(mod_position);
|
||||
float dimmer = 100 / (float)Settings.light_dimmer;
|
||||
color.R = cmin(color.R + ((hand_color.red / dimmer) * offset), 255);
|
||||
color.G = cmin(color.G + ((hand_color.green / dimmer) * offset), 255);
|
||||
color.B = cmin(color.B + ((hand_color.blue / dimmer) * offset), 255);
|
||||
color.R = tmin(color.R + ((hand_color.red / dimmer) * offset), 255);
|
||||
color.G = tmin(color.G + ((hand_color.green / dimmer) * offset), 255);
|
||||
color.B = tmin(color.B + ((hand_color.blue / dimmer) * offset), 255);
|
||||
strip->SetPixelColor(mod_position, color);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,10 @@
|
|||
#define W1_CONVERT_TEMP 0x44
|
||||
#define W1_READ_SCRATCHPAD 0xBE
|
||||
|
||||
float ds18b20_last_temperature = 0;
|
||||
uint16_t ds18b20_last_result = 0;
|
||||
float ds18b20_temperature = 0;
|
||||
uint8_t ds18b20_valid = 0;
|
||||
uint8_t ds18x20_pin = 0;
|
||||
char ds18b20_types[] = "DS18B20";
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Embedded stripped and tuned OneWire library
|
||||
|
@ -126,12 +127,7 @@ boolean OneWireCrc8(uint8_t *addr)
|
|||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Ds18x20Init()
|
||||
{
|
||||
ds18x20_pin = pin[GPIO_DSB];
|
||||
}
|
||||
|
||||
void Ds18x20Convert()
|
||||
void Ds18b20Convert()
|
||||
{
|
||||
OneWireReset();
|
||||
OneWireWrite(W1_SKIP_ROM); // Address all Sensors on Bus
|
||||
|
@ -139,25 +135,16 @@ void Ds18x20Convert()
|
|||
// delay(750); // 750ms should be enough for 12bit conv
|
||||
}
|
||||
|
||||
boolean Ds18b20Read(float &t)
|
||||
boolean Ds18b20Read()
|
||||
{
|
||||
uint8_t data[9];
|
||||
int8_t sign = 1;
|
||||
|
||||
if (!ds18b20_last_temperature) {
|
||||
t = NAN;
|
||||
} else {
|
||||
ds18b20_last_result++;
|
||||
if (ds18b20_last_result > 4) { // Reset after 4 misses
|
||||
ds18b20_last_temperature = NAN;
|
||||
}
|
||||
t = ds18b20_last_temperature;
|
||||
}
|
||||
|
||||
if (ds18b20_valid) { ds18b20_valid--; }
|
||||
/*
|
||||
if (!OneWireReadBit()) { //check measurement end
|
||||
if (!OneWireReadBit()) { // Check end of measurement
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSOR_BUSY));
|
||||
return !isnan(t);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
for (uint8_t retry = 0; retry < 3; retry++) {
|
||||
|
@ -173,44 +160,55 @@ boolean Ds18b20Read(float &t)
|
|||
temp12 = (~temp12) +1;
|
||||
sign = -1;
|
||||
}
|
||||
t = ConvertTemp(sign * temp12 * 0.0625);
|
||||
ds18b20_last_result = 0;
|
||||
}
|
||||
if (!isnan(t)) {
|
||||
ds18b20_last_temperature = t;
|
||||
ds18b20_temperature = ConvertTemp(sign * temp12 * 0.0625);
|
||||
ds18b20_valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSOR_CRC_ERROR));
|
||||
return !isnan(t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Ds18b20EverySecond()
|
||||
{
|
||||
ds18x20_pin = pin[GPIO_DSB];
|
||||
if (uptime &1) {
|
||||
// 2mS
|
||||
Ds18b20Convert(); // Start conversion, takes up to one second
|
||||
} else {
|
||||
// 12mS
|
||||
if (!Ds18b20Read()) { // Read temperature
|
||||
AddLogMissed(ds18b20_types, ds18b20_valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ds18b20Show(boolean json)
|
||||
{
|
||||
float t;
|
||||
|
||||
if (Ds18b20Read(t)) { // Check if read failed
|
||||
if (ds18b20_valid) { // Check for valid temperature
|
||||
char temperature[10];
|
||||
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
|
||||
dtostrfd(ds18b20_temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
if(json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"DS18B20\":{\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, temperature);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMP, mqtt_data, ds18b20_types, temperature);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) DomoticzSensor(DZ_TEMP, temperature);
|
||||
if (0 == tele_period) {
|
||||
DomoticzSensor(DZ_TEMP, temperature);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_TEMPERATURE, ds18b20_temperature);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "DS18B20", temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, ds18b20_types, temperature, TempUnit());
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -225,11 +223,8 @@ boolean Xsns05(byte function)
|
|||
|
||||
if (pin[GPIO_DSB] < 99) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
Ds18x20Init();
|
||||
break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
case FUNC_EVERY_SECOND:
|
||||
Ds18b20EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Ds18b20Show(1);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
/*********************************************************************************************\
|
||||
* DS18B20 - Temperature - Multiple sensors
|
||||
\*********************************************************************************************/
|
||||
//#define USE_DS18x20_RECONFIGURE // When sensor is lost keep retrying or re-configure
|
||||
|
||||
#define DS18S20_CHIPID 0x10 // +/-0.5C 9-bit
|
||||
#define DS1822_CHIPID 0x22 // +/-2C 12-bit
|
||||
|
@ -38,11 +39,16 @@
|
|||
const char kDs18x20Types[] PROGMEM = "DS18x20|DS18S20|DS1822|DS18B20|MAX31850";
|
||||
|
||||
uint8_t ds18x20_chipids[] = { 0, DS18S20_CHIPID, DS1822_CHIPID, DS18B20_CHIPID, MAX31850_CHIPID };
|
||||
uint8_t ds18x20_address[DS18X20_MAX_SENSORS][8];
|
||||
uint8_t ds18x20_index[DS18X20_MAX_SENSORS] = { 0 };
|
||||
|
||||
struct DS18X20STRUCT {
|
||||
uint8_t address[8];
|
||||
uint8_t index;
|
||||
uint8_t valid;
|
||||
float temperature;
|
||||
} ds18x20_sensor[DS18X20_MAX_SENSORS];
|
||||
uint8_t ds18x20_sensors = 0;
|
||||
uint8_t ds18x20_pin = 0;
|
||||
char ds18x20_types[9];
|
||||
char ds18x20_types[12];
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Embedded tuned OneWire library
|
||||
|
@ -246,28 +252,29 @@ void Ds18x20Init()
|
|||
uint64_t ids[DS18X20_MAX_SENSORS];
|
||||
|
||||
ds18x20_pin = pin[GPIO_DSB];
|
||||
|
||||
OneWireResetSearch();
|
||||
for (ds18x20_sensors = 0; ds18x20_sensors < DS18X20_MAX_SENSORS; ds18x20_sensors) {
|
||||
if (!OneWireSearch(ds18x20_address[ds18x20_sensors])) {
|
||||
if (!OneWireSearch(ds18x20_sensor[ds18x20_sensors].address)) {
|
||||
break;
|
||||
}
|
||||
if (OneWireCrc8(ds18x20_address[ds18x20_sensors]) &&
|
||||
((ds18x20_address[ds18x20_sensors][0] == DS18S20_CHIPID) ||
|
||||
(ds18x20_address[ds18x20_sensors][0] == DS1822_CHIPID) ||
|
||||
(ds18x20_address[ds18x20_sensors][0] == DS18B20_CHIPID) ||
|
||||
(ds18x20_address[ds18x20_sensors][0] == MAX31850_CHIPID))) {
|
||||
ds18x20_index[ds18x20_sensors] = ds18x20_sensors;
|
||||
ids[ds18x20_sensors] = ds18x20_address[ds18x20_sensors][0]; // Chip id
|
||||
if (OneWireCrc8(ds18x20_sensor[ds18x20_sensors].address) &&
|
||||
((ds18x20_sensor[ds18x20_sensors].address[0] == DS18S20_CHIPID) ||
|
||||
(ds18x20_sensor[ds18x20_sensors].address[0] == DS1822_CHIPID) ||
|
||||
(ds18x20_sensor[ds18x20_sensors].address[0] == DS18B20_CHIPID) ||
|
||||
(ds18x20_sensor[ds18x20_sensors].address[0] == MAX31850_CHIPID))) {
|
||||
ds18x20_sensor[ds18x20_sensors].index = ds18x20_sensors;
|
||||
ids[ds18x20_sensors] = ds18x20_sensor[ds18x20_sensors].address[0]; // Chip id
|
||||
for (uint8_t j = 6; j > 0; j--) {
|
||||
ids[ds18x20_sensors] = ids[ds18x20_sensors] << 8 | ds18x20_address[ds18x20_sensors][j];
|
||||
ids[ds18x20_sensors] = ids[ds18x20_sensors] << 8 | ds18x20_sensor[ds18x20_sensors].address[j];
|
||||
}
|
||||
ds18x20_sensors++;
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 0; i < ds18x20_sensors; i++) {
|
||||
for (uint8_t j = i + 1; j < ds18x20_sensors; j++) {
|
||||
if (ids[ds18x20_index[i]] > ids[ds18x20_index[j]]) { // Sort ascending
|
||||
std::swap(ds18x20_index[i], ds18x20_index[j]);
|
||||
if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending
|
||||
std::swap(ds18x20_sensor[i].index, ds18x20_sensor[j].index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +290,7 @@ void Ds18x20Convert()
|
|||
// delay(750); // 750ms should be enough for 12bit conv
|
||||
}
|
||||
|
||||
boolean Ds18x20Read(uint8_t sensor, float &t)
|
||||
bool Ds18x20Read(uint8_t sensor)
|
||||
{
|
||||
uint8_t data[9];
|
||||
int8_t sign = 1;
|
||||
|
@ -291,17 +298,17 @@ boolean Ds18x20Read(uint8_t sensor, float &t)
|
|||
int16_t temp14 = 0;
|
||||
float temp9 = 0.0;
|
||||
|
||||
t = NAN;
|
||||
|
||||
uint8_t index = ds18x20_sensor[sensor].index;
|
||||
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
|
||||
for (uint8_t retry = 0; retry < 3; retry++) {
|
||||
OneWireReset();
|
||||
OneWireSelect(ds18x20_address[ds18x20_index[sensor]]);
|
||||
OneWireSelect(ds18x20_sensor[index].address);
|
||||
OneWireWrite(W1_READ_SCRATCHPAD);
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
data[i] = OneWireRead();
|
||||
}
|
||||
if (OneWireCrc8(data)) {
|
||||
switch(ds18x20_address[ds18x20_index[sensor]][0]) {
|
||||
switch(ds18x20_sensor[index].address[0]) {
|
||||
case DS18S20_CHIPID:
|
||||
if (data[1] > 0x80) {
|
||||
data[0] = (~data[0]) +1;
|
||||
|
@ -312,19 +319,20 @@ boolean Ds18x20Read(uint8_t sensor, float &t)
|
|||
} else {
|
||||
temp9 = (data[0] >> 1) * sign;
|
||||
}
|
||||
t = ConvertTemp((temp9 - 0.25) + ((16.0 - data[6]) / 16.0));
|
||||
break;
|
||||
ds18x20_sensor[index].temperature = ConvertTemp((temp9 - 0.25) + ((16.0 - data[6]) / 16.0));
|
||||
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
case DS1822_CHIPID:
|
||||
case DS18B20_CHIPID:
|
||||
if (data[4] != 0x7F) {
|
||||
data[4] = 0x7F; // Set resolution to 12-bit
|
||||
OneWireReset();
|
||||
OneWireSelect(ds18x20_address[ds18x20_index[sensor]]);
|
||||
OneWireSelect(ds18x20_sensor[index].address);
|
||||
OneWireWrite(W1_WRITE_SCRATCHPAD);
|
||||
OneWireWrite(data[2]); // Th Register
|
||||
OneWireWrite(data[3]); // Tl Register
|
||||
OneWireWrite(data[4]); // Configuration Register
|
||||
OneWireSelect(ds18x20_address[ds18x20_index[sensor]]);
|
||||
OneWireSelect(ds18x20_sensor[index].address);
|
||||
OneWireWrite(W1_WRITE_EEPROM); // Save scratchpad to EEPROM
|
||||
}
|
||||
temp12 = (data[1] << 8) + data[0];
|
||||
|
@ -332,72 +340,99 @@ boolean Ds18x20Read(uint8_t sensor, float &t)
|
|||
temp12 = (~temp12) +1;
|
||||
sign = -1;
|
||||
}
|
||||
t = ConvertTemp(sign * temp12 * 0.0625); // Divide by 16
|
||||
break;
|
||||
ds18x20_sensor[index].temperature = ConvertTemp(sign * temp12 * 0.0625); // Divide by 16
|
||||
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
case MAX31850_CHIPID:
|
||||
temp14 = (data[1] << 8) + (data[0] & 0xFC);
|
||||
t = ConvertTemp(temp14 * 0.0625); // Divide by 16
|
||||
break;
|
||||
ds18x20_sensor[index].temperature = ConvertTemp(temp14 * 0.0625); // Divide by 16
|
||||
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!isnan(t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSOR_CRC_ERROR));
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ds18x20Name(uint8_t sensor)
|
||||
{
|
||||
uint8_t index = sizeof(ds18x20_chipids);
|
||||
while (index) {
|
||||
if (ds18x20_sensor[ds18x20_sensor[sensor].index].address[0] == ds18x20_chipids[index]) {
|
||||
break;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
GetTextIndexed(ds18x20_types, sizeof(ds18x20_types), index, kDs18x20Types);
|
||||
if (ds18x20_sensors > 1) {
|
||||
snprintf_P(ds18x20_types, sizeof(ds18x20_types), PSTR("%s-%d"), ds18x20_types, sensor +1);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Ds18x20EverySecond()
|
||||
{
|
||||
if (uptime &1) {
|
||||
// 2mS
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
} else {
|
||||
for (uint8_t i = 0; i < ds18x20_sensors; i++) {
|
||||
// 12mS per device
|
||||
if (!Ds18x20Read(i)) { // Read temperature
|
||||
Ds18x20Name(i);
|
||||
AddLogMissed(ds18x20_types, ds18x20_sensor[ds18x20_sensor[i].index].valid);
|
||||
#ifdef USE_DS18x20_RECONFIGURE
|
||||
if (!ds18x20_sensor[ds18x20_sensor[i].index].valid) {
|
||||
memset(&ds18x20_sensor, 0, sizeof(ds18x20_sensor));
|
||||
Ds18x20Init(); // Re-configure
|
||||
}
|
||||
#endif // USE_DS18x20_RECONFIGURE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ds18x20Show(boolean json)
|
||||
{
|
||||
char temperature[10];
|
||||
char stemp[12];
|
||||
float t;
|
||||
bool domoticz_flag = true;
|
||||
|
||||
for (uint8_t i = 0; i < ds18x20_sensors; i++) {
|
||||
if (Ds18x20Read(i, t)) { // Check if read failed
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
uint8_t index = ds18x20_sensor[i].index;
|
||||
|
||||
uint8_t index = sizeof(ds18x20_chipids);
|
||||
while (index) {
|
||||
if (ds18x20_address[ds18x20_index[i]][0] == ds18x20_chipids[index]) {
|
||||
break;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
GetTextIndexed(ds18x20_types, sizeof(ds18x20_types), index, kDs18x20Types);
|
||||
if (ds18x20_sensor[index].valid) { // Check for valid temperature
|
||||
dtostrfd(ds18x20_sensor[index].temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
|
||||
Ds18x20Name(i);
|
||||
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("%s-%d"), ds18x20_types, i +1);
|
||||
if (json) {
|
||||
if (1 == ds18x20_sensors) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, ds18x20_types, temperature);
|
||||
} else {
|
||||
char address[17];
|
||||
for (byte j = 0; j < 6; j++) {
|
||||
sprintf(address+2*j, "%02X", ds18x20_address[ds18x20_index[i]][6-j]); // Skip sensor type and crc
|
||||
sprintf(address+2*j, "%02X", ds18x20_sensor[index].address[6-j]); // Skip sensor type and crc
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_ID "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, stemp, address, temperature);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_ID "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, ds18x20_types, address, temperature);
|
||||
}
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period) && domoticz_flag) {
|
||||
if ((0 == tele_period) && (0 == i)) {
|
||||
DomoticzSensor(DZ_TEMP, temperature);
|
||||
domoticz_flag = false;
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
if ((0 == tele_period) && (0 == i)) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_TEMPERATURE, ds18x20_sensor[index].temperature);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, (1 == ds18x20_sensors) ? ds18x20_types : stemp, temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, ds18x20_types, temperature, TempUnit());
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -415,8 +450,8 @@ boolean Xsns05(byte function)
|
|||
case FUNC_INIT:
|
||||
Ds18x20Init();
|
||||
break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
Ds18x20Convert(); // Start conversion, takes up to one second
|
||||
case FUNC_EVERY_SECOND:
|
||||
Ds18x20EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Ds18x20Show(1);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#define DHT_MAX_SENSORS 3
|
||||
#define DHT_MAX_RETRY 8
|
||||
#define MIN_INTERVAL 2000
|
||||
|
||||
uint32_t dht_max_cycles;
|
||||
uint8_t dht_data[5];
|
||||
|
@ -63,15 +62,10 @@ int32_t DhtExpectPulse(byte sensor, bool level)
|
|||
return count;
|
||||
}
|
||||
|
||||
void DhtRead(byte sensor)
|
||||
boolean DhtRead(byte sensor)
|
||||
{
|
||||
int32_t cycles[80];
|
||||
uint32_t currenttime = millis();
|
||||
|
||||
if ((currenttime - Dht[sensor].lastreadtime) < MIN_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
Dht[sensor].lastreadtime = currenttime;
|
||||
uint8_t error = 0;
|
||||
|
||||
dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0;
|
||||
|
||||
|
@ -99,27 +93,27 @@ void DhtRead(byte sensor)
|
|||
delayMicroseconds(10);
|
||||
if (-1 == DhtExpectPulse(sensor, LOW)) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE));
|
||||
Dht[sensor].lastresult++;
|
||||
return;
|
||||
error = 1;
|
||||
}
|
||||
if (-1 == DhtExpectPulse(sensor, HIGH)) {
|
||||
else if (-1 == DhtExpectPulse(sensor, HIGH)) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_HIGH " " D_PULSE));
|
||||
Dht[sensor].lastresult++;
|
||||
return;
|
||||
error = 1;
|
||||
}
|
||||
for (int i = 0; i < 80; i += 2) {
|
||||
cycles[i] = DhtExpectPulse(sensor, LOW);
|
||||
cycles[i+1] = DhtExpectPulse(sensor, HIGH);
|
||||
else {
|
||||
for (int i = 0; i < 80; i += 2) {
|
||||
cycles[i] = DhtExpectPulse(sensor, LOW);
|
||||
cycles[i+1] = DhtExpectPulse(sensor, HIGH);
|
||||
}
|
||||
}
|
||||
interrupts();
|
||||
if (error) { return false; }
|
||||
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
int32_t lowCycles = cycles[2*i];
|
||||
int32_t highCycles = cycles[2*i+1];
|
||||
if ((-1 == lowCycles) || (-1 == highCycles)) {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_PULSE));
|
||||
Dht[sensor].lastresult++;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
dht_data[i/8] <<= 1;
|
||||
if (highCycles > lowCycles) {
|
||||
|
@ -127,57 +121,43 @@ void DhtRead(byte sensor)
|
|||
}
|
||||
}
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DHT D_RECEIVED " %02X, %02X, %02X, %02X, %02X =? %02X"),
|
||||
dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) {
|
||||
Dht[sensor].lastresult = 0;
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_CHECKSUM_FAILURE));
|
||||
Dht[sensor].lastresult++;
|
||||
uint8_t checksum = (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF;
|
||||
if (dht_data[4] != checksum) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DHT D_CHECKSUM_FAILURE " %02X, %02X, %02X, %02X, %02X =? %02X"),
|
||||
dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], checksum);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean DhtReadTempHum(byte sensor, float &t, float &h)
|
||||
void DhtReadTempHum(byte sensor)
|
||||
{
|
||||
if (NAN == Dht[sensor].h) {
|
||||
t = NAN;
|
||||
h = NAN;
|
||||
} else {
|
||||
if (Dht[sensor].lastresult > DHT_MAX_RETRY) { // Reset after 8 misses
|
||||
Dht[sensor].t = NAN;
|
||||
Dht[sensor].h = NAN;
|
||||
}
|
||||
t = Dht[sensor].t;
|
||||
h = Dht[sensor].h;
|
||||
if ((NAN == Dht[sensor].h) || (Dht[sensor].lastresult > DHT_MAX_RETRY)) { // Reset after 8 misses
|
||||
Dht[sensor].t = NAN;
|
||||
Dht[sensor].h = NAN;
|
||||
}
|
||||
|
||||
DhtRead(sensor);
|
||||
if (!Dht[sensor].lastresult) {
|
||||
if (DhtRead(sensor)) {
|
||||
switch (Dht[sensor].type) {
|
||||
case GPIO_DHT11:
|
||||
h = dht_data[0];
|
||||
t = dht_data[2];
|
||||
Dht[sensor].h = dht_data[0];
|
||||
Dht[sensor].t = dht_data[2] + ((float)dht_data[3] * 0.1f); // Issue #3164
|
||||
break;
|
||||
case GPIO_DHT22:
|
||||
case GPIO_SI7021:
|
||||
h = ((dht_data[0] << 8) | dht_data[1]) * 0.1;
|
||||
t = (((dht_data[2] & 0x7F) << 8 ) | dht_data[3]) * 0.1;
|
||||
Dht[sensor].h = ((dht_data[0] << 8) | dht_data[1]) * 0.1;
|
||||
Dht[sensor].t = (((dht_data[2] & 0x7F) << 8 ) | dht_data[3]) * 0.1;
|
||||
if (dht_data[2] & 0x80) {
|
||||
t *= -1;
|
||||
Dht[sensor].t *= -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
t = ConvertTemp(t);
|
||||
if (!isnan(t)) {
|
||||
Dht[sensor].t = t;
|
||||
}
|
||||
if (!isnan(h)) {
|
||||
Dht[sensor].h = h;
|
||||
}
|
||||
Dht[sensor].t = ConvertTemp(Dht[sensor].t);
|
||||
Dht[sensor].lastresult = 0;
|
||||
} else {
|
||||
Dht[sensor].lastresult++;
|
||||
}
|
||||
return (!isnan(t) && !isnan(h));
|
||||
}
|
||||
|
||||
boolean DhtSetup(byte pin, byte type)
|
||||
|
@ -210,41 +190,46 @@ void DhtInit()
|
|||
}
|
||||
}
|
||||
|
||||
void DhtEverySecond()
|
||||
{
|
||||
if (uptime &1) {
|
||||
// <1mS
|
||||
DhtReadPrep();
|
||||
} else {
|
||||
for (byte i = 0; i < dht_sensors; i++) {
|
||||
// DHT11 and AM2301 25mS per sensor, SI7021 5mS per sensor
|
||||
DhtReadTempHum(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DhtShow(boolean json)
|
||||
{
|
||||
char temperature[10];
|
||||
char humidity[10];
|
||||
|
||||
byte dsxflg = 0;
|
||||
for (byte i = 0; i < dht_sensors; i++) {
|
||||
float t = NAN;
|
||||
float h = NAN;
|
||||
if (DhtReadTempHum(i, t, h)) { // Read temperature
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||
dtostrfd(Dht[i].t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(Dht[i].h, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity);
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period) && !dsxflg) {
|
||||
DomoticzTempHumSensor(temperature, humidity);
|
||||
dsxflg++;
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_HUMIDITY, h);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, Dht[i].stype, temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, Dht[i].stype, humidity);
|
||||
#endif // USE_WEBSERVER
|
||||
if ((0 == tele_period) && (0 == i)) {
|
||||
DomoticzTempHumSensor(temperature, humidity);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
if ((0 == tele_period) && (0 == i)) {
|
||||
KnxSensor(KNX_TEMPERATURE, Dht[i].t);
|
||||
KnxSensor(KNX_HUMIDITY, Dht[i].h);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, Dht[i].stype, temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, Dht[i].stype, humidity);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,8 +249,8 @@ boolean Xsns06(byte function)
|
|||
case FUNC_INIT:
|
||||
DhtInit();
|
||||
break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
DhtReadPrep();
|
||||
case FUNC_EVERY_SECOND:
|
||||
DhtEverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
DhtShow(1);
|
||||
|
|
|
@ -37,6 +37,10 @@ enum {
|
|||
uint8_t sht_sda_pin;
|
||||
uint8_t sht_scl_pin;
|
||||
uint8_t sht_type = 0;
|
||||
char sht_types[] = "SHT1X";
|
||||
uint8_t sht_valid = 0;
|
||||
float sht_temperature = 0;
|
||||
float sht_humidity = 0;
|
||||
|
||||
boolean ShtReset()
|
||||
{
|
||||
|
@ -119,46 +123,32 @@ int ShtReadData()
|
|||
return val;
|
||||
}
|
||||
|
||||
boolean ShtReadTempHum(float &t, float &h)
|
||||
boolean ShtRead()
|
||||
{
|
||||
float tempRaw;
|
||||
float humRaw;
|
||||
float rhLinear;
|
||||
if (sht_valid) { sht_valid--; }
|
||||
if (!ShtReset()) { return false; }
|
||||
if (!ShtSendCommand(SHT1X_CMD_MEASURE_TEMP)) { return false; }
|
||||
if (!ShtAwaitResult()) { return false; }
|
||||
float tempRaw = ShtReadData();
|
||||
if (!ShtSendCommand(SHT1X_CMD_MEASURE_RH)) { return false; }
|
||||
if (!ShtAwaitResult()) { return false; }
|
||||
float humRaw = ShtReadData();
|
||||
|
||||
t = NAN;
|
||||
h = NAN;
|
||||
|
||||
if (!ShtReset()) {
|
||||
return false;
|
||||
}
|
||||
if (!ShtSendCommand(SHT1X_CMD_MEASURE_TEMP)) {
|
||||
return false;
|
||||
}
|
||||
if (!ShtAwaitResult()) {
|
||||
return false;
|
||||
}
|
||||
tempRaw = ShtReadData();
|
||||
// Temperature conversion coefficients from SHT1X datasheet for version 4
|
||||
const float d1 = -39.7; // 3.5V
|
||||
const float d2 = 0.01; // 14-bit
|
||||
t = d1 + (tempRaw * d2);
|
||||
if (!ShtSendCommand(SHT1X_CMD_MEASURE_RH)) {
|
||||
return false;
|
||||
}
|
||||
if (!ShtAwaitResult()) {
|
||||
return false;
|
||||
}
|
||||
humRaw = ShtReadData();
|
||||
// Temperature conversion coefficients from SHT1X datasheet for version 4
|
||||
sht_temperature = d1 + (tempRaw * d2);
|
||||
const float c1 = -2.0468;
|
||||
const float c2 = 0.0367;
|
||||
const float c3 = -1.5955E-6;
|
||||
const float t1 = 0.01;
|
||||
const float t2 = 0.00008;
|
||||
rhLinear = c1 + c2 * humRaw + c3 * humRaw * humRaw;
|
||||
h = (t - 25) * (t1 + t2 * humRaw) + rhLinear;
|
||||
t = ConvertTemp(t);
|
||||
return (!isnan(t) && !isnan(h));
|
||||
float rhLinear = c1 + c2 * humRaw + c3 * humRaw * humRaw;
|
||||
sht_humidity = (sht_temperature - 25) * (t1 + t2 * humRaw) + rhLinear;
|
||||
sht_temperature = ConvertTemp(sht_temperature);
|
||||
|
||||
sht_valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -169,12 +159,9 @@ void ShtDetect()
|
|||
return;
|
||||
}
|
||||
|
||||
float t;
|
||||
float h;
|
||||
|
||||
sht_sda_pin = pin[GPIO_I2C_SDA];
|
||||
sht_scl_pin = pin[GPIO_I2C_SCL];
|
||||
if (ShtReadTempHum(t, h)) {
|
||||
if (ShtRead()) {
|
||||
sht_type = 1;
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C D_SHT1X_FOUND));
|
||||
} else {
|
||||
|
@ -183,38 +170,44 @@ void ShtDetect()
|
|||
}
|
||||
}
|
||||
|
||||
void ShtEverySecond()
|
||||
{
|
||||
if (sht_type && !(uptime %4)) { // Update every 4 seconds
|
||||
// 344mS
|
||||
if (!ShtRead()) {
|
||||
AddLogMissed(sht_types, sht_valid);
|
||||
// if (!sht_valid) { sht_type = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShtShow(boolean json)
|
||||
{
|
||||
if (sht_type) {
|
||||
float t;
|
||||
float h;
|
||||
if (sht_valid) {
|
||||
char temperature[10];
|
||||
char humidity[10];
|
||||
|
||||
if (ShtReadTempHum(t, h)) {
|
||||
char temperature[10];
|
||||
char humidity[10];
|
||||
dtostrfd(sht_temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(sht_humidity, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", temperature, humidity);
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, sht_types, temperature, humidity);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) DomoticzTempHumSensor(temperature, humidity);
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_HUMIDITY, h);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "SHT1X", temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, "SHT1X", humidity);
|
||||
#endif // USE_WEBSERVER
|
||||
if (0 == tele_period) {
|
||||
DomoticzTempHumSensor(temperature, humidity);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, sht_temperature);
|
||||
KnxSensor(KNX_HUMIDITY, sht_humidity);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, sht_types, temperature, TempUnit());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, sht_types, humidity);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,9 +224,13 @@ boolean Xsns07(byte function)
|
|||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
// case FUNC_PREP_BEFORE_TELEPERIOD: // As this is not a real I2C device it may interfere with other sensors
|
||||
case FUNC_INIT: // Move detection to restart only removing interference
|
||||
ShtDetect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
ShtEverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
ShtShow(1);
|
||||
break;
|
||||
|
|
|
@ -58,8 +58,11 @@ const char kHtuTypes[] PROGMEM = "HTU21|SI7013|SI7020|SI7021|T/RH?";
|
|||
|
||||
uint8_t htu_address;
|
||||
uint8_t htu_type = 0;
|
||||
uint8_t delay_temp;
|
||||
uint8_t delay_humidity = 50;
|
||||
uint8_t htu_delay_temp;
|
||||
uint8_t htu_delay_humidity = 50;
|
||||
uint8_t htu_valid = 0;
|
||||
float htu_temperature = 0;
|
||||
float htu_humidity = 0;
|
||||
char htu_types[7];
|
||||
|
||||
uint8_t HtuCheckCrc8(uint16_t data)
|
||||
|
@ -135,87 +138,62 @@ void HtuInit()
|
|||
HtuSetResolution(HTU21_RES_RH12_T14);
|
||||
}
|
||||
|
||||
float HtuReadHumidity(void)
|
||||
boolean HtuRead()
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
uint16_t sensorval = 0;
|
||||
float humidity = 0.0;
|
||||
|
||||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READHUM);
|
||||
if (Wire.endTransmission() != 0) {
|
||||
return 0.0; // In case of error
|
||||
}
|
||||
delay(delay_humidity); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if (3 <= Wire.available()) {
|
||||
sensorval = Wire.read() << 8; // MSB
|
||||
sensorval |= Wire.read(); // LSB
|
||||
checksum = Wire.read();
|
||||
}
|
||||
if (HtuCheckCrc8(sensorval) != checksum) {
|
||||
return 0.0; // Checksum mismatch
|
||||
}
|
||||
|
||||
sensorval ^= 0x02; // clear status bits
|
||||
humidity = 0.001907 * (float)sensorval - 6;
|
||||
|
||||
if (humidity > 100) {
|
||||
return 100.0;
|
||||
}
|
||||
if (humidity < 0) {
|
||||
return 0.01;
|
||||
}
|
||||
|
||||
return humidity;
|
||||
}
|
||||
|
||||
float HtuReadTemperature()
|
||||
{
|
||||
uint8_t checksum=0;
|
||||
uint16_t sensorval=0;
|
||||
float t;
|
||||
if (htu_valid) { htu_valid--; }
|
||||
|
||||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READTEMP);
|
||||
if (Wire.endTransmission() != 0) {
|
||||
return 0.0; // In case of error
|
||||
}
|
||||
delay(delay_temp); // Sensor time at max resolution
|
||||
if (Wire.endTransmission() != 0) { return false; } // In case of error
|
||||
delay(htu_delay_temp); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if (3 == Wire.available()) {
|
||||
sensorval = Wire.read() << 8; // MSB
|
||||
sensorval |= Wire.read(); // LSB
|
||||
sensorval = Wire.read() << 8; // MSB
|
||||
sensorval |= Wire.read(); // LSB
|
||||
checksum = Wire.read();
|
||||
}
|
||||
if (HtuCheckCrc8(sensorval) != checksum) {
|
||||
return 0.0; // Checksum mismatch
|
||||
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
|
||||
|
||||
htu_temperature = ConvertTemp(0.002681 * (float)sensorval - 46.85);
|
||||
|
||||
Wire.beginTransmission(HTU21_ADDR);
|
||||
Wire.write(HTU21_READHUM);
|
||||
if (Wire.endTransmission() != 0) { return false; } // In case of error
|
||||
delay(htu_delay_humidity); // Sensor time at max resolution
|
||||
|
||||
Wire.requestFrom(HTU21_ADDR, 3);
|
||||
if (3 <= Wire.available()) {
|
||||
sensorval = Wire.read() << 8; // MSB
|
||||
sensorval |= Wire.read(); // LSB
|
||||
checksum = Wire.read();
|
||||
}
|
||||
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
|
||||
|
||||
sensorval ^= 0x02; // clear status bits
|
||||
htu_humidity = 0.001907 * (float)sensorval - 6;
|
||||
if (htu_humidity > 100) { htu_humidity = 100.0; }
|
||||
if (htu_humidity < 0) { htu_humidity = 0.01; }
|
||||
|
||||
if ((0.00 == htu_humidity) && (0.00 == htu_temperature)) {
|
||||
htu_humidity = 0.0;
|
||||
}
|
||||
if ((htu_temperature > 0.00) && (htu_temperature < 80.00)) {
|
||||
htu_humidity = (-0.15) * (25 - htu_temperature) + htu_humidity;
|
||||
}
|
||||
|
||||
t = ConvertTemp(0.002681 * (float)sensorval - 46.85);
|
||||
return t;
|
||||
}
|
||||
|
||||
float HtuCompensatedHumidity(float humidity, float temperature)
|
||||
{
|
||||
if(humidity == 0.00 && temperature == 0.00) {
|
||||
return 0.0;
|
||||
}
|
||||
if(temperature > 0.00 && temperature < 80.00) {
|
||||
return (-0.15)*(25-temperature)+humidity;
|
||||
}
|
||||
return humidity;
|
||||
htu_valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void HtuDetect()
|
||||
{
|
||||
if (htu_type) {
|
||||
return;
|
||||
}
|
||||
if (htu_type) { return; }
|
||||
|
||||
htu_address = HTU21_ADDR;
|
||||
htu_type = HtuReadDeviceId();
|
||||
|
@ -224,8 +202,8 @@ void HtuDetect()
|
|||
HtuInit();
|
||||
switch (htu_type) {
|
||||
case HTU21_CHIPID:
|
||||
delay_temp = 50;
|
||||
delay_humidity = 16;
|
||||
htu_delay_temp = 50;
|
||||
htu_delay_humidity = 16;
|
||||
break;
|
||||
case SI7021_CHIPID:
|
||||
index++; // 3
|
||||
|
@ -233,13 +211,13 @@ void HtuDetect()
|
|||
index++; // 2
|
||||
case SI7013_CHIPID:
|
||||
index++; // 1
|
||||
delay_temp = 12;
|
||||
delay_humidity = 23;
|
||||
htu_delay_temp = 12;
|
||||
htu_delay_humidity = 23;
|
||||
break;
|
||||
default:
|
||||
index = 4;
|
||||
delay_temp = 50;
|
||||
delay_humidity = 23;
|
||||
htu_delay_temp = 50;
|
||||
htu_delay_humidity = 23;
|
||||
}
|
||||
GetTextIndexed(htu_types, sizeof(htu_types), index, kHtuTypes);
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, htu_types, htu_address);
|
||||
|
@ -247,31 +225,45 @@ void HtuDetect()
|
|||
}
|
||||
}
|
||||
|
||||
void HtuEverySecond()
|
||||
{
|
||||
if (92 == (uptime %100)) {
|
||||
// 1mS
|
||||
HtuDetect();
|
||||
}
|
||||
else if (uptime &1) {
|
||||
// HTU21: 68mS, SI70xx: 37mS
|
||||
if (htu_type) {
|
||||
if (!HtuRead()) {
|
||||
AddLogMissed(htu_types, htu_valid);
|
||||
// if (!htu_valid) { htu_type = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HtuShow(boolean json)
|
||||
{
|
||||
if (htu_type) {
|
||||
if (htu_valid) {
|
||||
char temperature[10];
|
||||
char humidity[10];
|
||||
|
||||
float t = HtuReadTemperature();
|
||||
float h = HtuReadHumidity();
|
||||
h = HtuCompensatedHumidity(h, t);
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||
dtostrfd(htu_temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(htu_humidity, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, temperature, humidity);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) DomoticzTempHumSensor(temperature, humidity);
|
||||
if (0 == tele_period) {
|
||||
DomoticzTempHumSensor(temperature, humidity);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_HUMIDITY, h);
|
||||
KnxSensor(KNX_TEMPERATURE, htu_temperature);
|
||||
KnxSensor(KNX_HUMIDITY, htu_humidity);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, htu_types, temperature, TempUnit());
|
||||
|
@ -293,9 +285,12 @@ boolean Xsns08(byte function)
|
|||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
case FUNC_INIT:
|
||||
HtuDetect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
HtuEverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
HtuShow(1);
|
||||
break;
|
||||
|
|
|
@ -45,6 +45,11 @@ uint8_t bmp_type = 0;
|
|||
uint8_t bmp_model = 0;
|
||||
char bmp_name[7];
|
||||
|
||||
uint8_t bmp_valid = 0;
|
||||
float bmp_temperature = 0.0;
|
||||
float bmp_pressure = 0.0;
|
||||
float bmp_humidity = 0.0;
|
||||
|
||||
/*********************************************************************************************\
|
||||
* BMP085 and BME180
|
||||
\*********************************************************************************************/
|
||||
|
@ -78,7 +83,6 @@ int16_t cal_md;
|
|||
uint16_t cal_ac4;
|
||||
uint16_t cal_ac5;
|
||||
uint16_t cal_ac6;
|
||||
int32_t bmp180_b5 = 0;
|
||||
|
||||
boolean Bmp180Calibration()
|
||||
{
|
||||
|
@ -113,21 +117,15 @@ boolean Bmp180Calibration()
|
|||
return true;
|
||||
}
|
||||
|
||||
double Bmp180ReadTemperature()
|
||||
void Bmp180Read()
|
||||
{
|
||||
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE);
|
||||
delay(5); // 5ms conversion time
|
||||
int ut = I2cRead16(bmp_address, BMP180_REG_RESULT);
|
||||
int32_t x1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15;
|
||||
int32_t x2 = ((int32_t)cal_mc << 11) / (x1 + (int32_t)cal_md);
|
||||
bmp180_b5 = x1 + x2;
|
||||
|
||||
return ((bmp180_b5 + 8) >> 4) / 10.0;
|
||||
}
|
||||
|
||||
double Bmp180ReadPressure()
|
||||
{
|
||||
int32_t p;
|
||||
int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15;
|
||||
int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md);
|
||||
int32_t bmp180_b5 = xt1 + xt2;
|
||||
bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0;
|
||||
|
||||
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution
|
||||
delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution
|
||||
|
@ -146,19 +144,18 @@ double Bmp180ReadPressure()
|
|||
uint32_t b4 = ((uint32_t)cal_ac4 * (uint32_t)(x3 + 32768)) >> 15;
|
||||
uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS);
|
||||
|
||||
int32_t p;
|
||||
if (b7 < 0x80000000) {
|
||||
p = (b7 * 2) / b4;
|
||||
}
|
||||
else {
|
||||
p = (b7 / b4) * 2;
|
||||
}
|
||||
|
||||
x1 = (p >> 8) * (p >> 8);
|
||||
x1 = (x1 * 3038) >> 16;
|
||||
x2 = (-7357 * p) >> 16;
|
||||
|
||||
p += ((x1 + x2 + (int32_t)3791) >> 4);
|
||||
return p / 100.0; // convert to mbar
|
||||
bmp_pressure = (float)p / 100.0; // convert to mbar
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -215,8 +212,6 @@ struct BME280CALIBDATA
|
|||
int8_t dig_H6;
|
||||
} Bme280CalibrationData;
|
||||
|
||||
int32_t t_fine;
|
||||
|
||||
boolean Bmx280Calibrate()
|
||||
{
|
||||
// if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false;
|
||||
|
@ -233,20 +228,6 @@ boolean Bmx280Calibrate()
|
|||
Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P7);
|
||||
Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P8);
|
||||
Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P9);
|
||||
/*
|
||||
if (BME280_CHIPID == bmp_type) {
|
||||
Bme280CalibrationData.dig_H1 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H1);
|
||||
Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_H2);
|
||||
Bme280CalibrationData.dig_H3 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H3);
|
||||
Bme280CalibrationData.dig_H4 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF);
|
||||
Bme280CalibrationData.dig_H5 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5) >> 4);
|
||||
Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp_address, BME280_REGISTER_DIG_H6);
|
||||
|
||||
// Set before CONTROL_meas (DS 5.4.3)
|
||||
I2cWrite8(bmp_address, BME280_REGISTER_CONTROLHUMID, 0x05); // 16x oversampling (Adafruit)
|
||||
}
|
||||
I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit)
|
||||
*/
|
||||
if (BME280_CHIPID == bmp_type) { // #1051
|
||||
Bme280CalibrationData.dig_H1 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H1);
|
||||
Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_H2);
|
||||
|
@ -267,62 +248,42 @@ boolean Bmx280Calibrate()
|
|||
return true;
|
||||
}
|
||||
|
||||
double Bme280ReadTemperature(void)
|
||||
void Bme280Read(void)
|
||||
{
|
||||
int32_t var1;
|
||||
int32_t var2;
|
||||
|
||||
int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA);
|
||||
adc_T >>= 4;
|
||||
|
||||
var1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11;
|
||||
var2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) *
|
||||
int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11;
|
||||
int32_t vart2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) *
|
||||
((int32_t)Bme280CalibrationData.dig_T3)) >> 14;
|
||||
t_fine = var1 + var2;
|
||||
double T = (t_fine * 5 + 128) >> 8;
|
||||
return T / 100.0;
|
||||
}
|
||||
|
||||
double Bme280ReadPressure(void)
|
||||
{
|
||||
int64_t var1;
|
||||
int64_t var2;
|
||||
int64_t p;
|
||||
|
||||
// Must be done first to get the t_fine variable set up
|
||||
// Bme280ReadTemperature();
|
||||
int32_t t_fine = vart1 + vart2;
|
||||
float T = (t_fine * 5 + 128) >> 8;
|
||||
bmp_temperature = T / 100.0;
|
||||
|
||||
int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA);
|
||||
adc_P >>= 4;
|
||||
|
||||
var1 = ((int64_t)t_fine) - 128000;
|
||||
var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6;
|
||||
int64_t var1 = ((int64_t)t_fine) - 128000;
|
||||
int64_t var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6;
|
||||
var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17);
|
||||
var2 = var2 + (((int64_t)Bme280CalibrationData.dig_P4) << 35);
|
||||
var1 = ((var1 * var1 * (int64_t)Bme280CalibrationData.dig_P3) >> 8) + ((var1 * (int64_t)Bme280CalibrationData.dig_P2) << 12);
|
||||
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)Bme280CalibrationData.dig_P1) >> 33;
|
||||
if (0 == var1) {
|
||||
return 0; // avoid exception caused by division by zero
|
||||
return; // avoid exception caused by division by zero
|
||||
}
|
||||
p = 1048576 - adc_P;
|
||||
int64_t p = 1048576 - adc_P;
|
||||
p = (((p << 31) - var2) * 3125) / var1;
|
||||
var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
|
||||
var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19;
|
||||
p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4);
|
||||
return (double)p / 25600.0;
|
||||
}
|
||||
bmp_pressure = (float)p / 25600.0;
|
||||
|
||||
double Bme280ReadHumidity(void)
|
||||
{
|
||||
int32_t v_x1_u32r;
|
||||
|
||||
// Must be done first to get the t_fine variable set up
|
||||
// Bme280ReadTemperature();
|
||||
if (BMP280_CHIPID == bmp_type) { return; }
|
||||
|
||||
int32_t adc_H = I2cRead16(bmp_address, BME280_REGISTER_HUMIDDATA);
|
||||
|
||||
v_x1_u32r = (t_fine - ((int32_t)76800));
|
||||
|
||||
int32_t v_x1_u32r = (t_fine - ((int32_t)76800));
|
||||
v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) -
|
||||
(((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
|
||||
(((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) *
|
||||
|
@ -332,8 +293,8 @@ double Bme280ReadHumidity(void)
|
|||
((int32_t)Bme280CalibrationData.dig_H1)) >> 4));
|
||||
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
|
||||
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
|
||||
double h = (v_x1_u32r >> 12);
|
||||
return h / 1024.0;
|
||||
float h = (v_x1_u32r >> 12);
|
||||
bmp_humidity = h / 1024.0;
|
||||
}
|
||||
|
||||
#ifdef USE_BME680
|
||||
|
@ -345,17 +306,14 @@ double Bme280ReadHumidity(void)
|
|||
|
||||
struct bme680_dev gas_sensor;
|
||||
|
||||
float bmp_gas_resistance = 0.0;
|
||||
uint8_t bme680_state = 0;
|
||||
|
||||
static void BmeDelayMs(uint32_t ms)
|
||||
{
|
||||
delay(ms);
|
||||
}
|
||||
|
||||
uint8_t bme680_state = 0;
|
||||
float bme680_temperature;
|
||||
float bme680_pressure;
|
||||
float bme680_humidity;
|
||||
float bme680_gas_resistance;
|
||||
|
||||
boolean Bme680Init()
|
||||
{
|
||||
gas_sensor.dev_id = bmp_address;
|
||||
|
@ -400,7 +358,7 @@ boolean Bme680Init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Bme680PerformReading()
|
||||
void Bme680Read()
|
||||
{
|
||||
int8_t rslt = BME680_OK;
|
||||
|
||||
|
@ -424,14 +382,14 @@ void Bme680PerformReading()
|
|||
rslt = bme680_get_sensor_data(&data, &gas_sensor);
|
||||
if (rslt != BME680_OK) { return; }
|
||||
|
||||
bme680_temperature = data.temperature / 100.0;
|
||||
bme680_humidity = data.humidity / 1000.0;
|
||||
bme680_pressure = data.pressure;
|
||||
bmp_temperature = data.temperature / 100.0;
|
||||
bmp_humidity = data.humidity / 1000.0;
|
||||
bmp_pressure = data.pressure / 100.0;
|
||||
/* Avoid using measurements from an unstable heating setup */
|
||||
if (data.status & BME680_GASM_VALID_MSK) {
|
||||
bme680_gas_resistance = data.gas_resistance;
|
||||
bmp_gas_resistance = data.gas_resistance / 1000.0;
|
||||
} else {
|
||||
bme680_gas_resistance = 0;
|
||||
bmp_gas_resistance = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,9 +402,7 @@ void Bme680PerformReading()
|
|||
|
||||
void BmpDetect()
|
||||
{
|
||||
if (bmp_type) {
|
||||
return;
|
||||
}
|
||||
if (bmp_type) { return; }
|
||||
|
||||
for (byte i = 0; i < sizeof(bmp_addresses); i++) {
|
||||
bmp_address = bmp_addresses[i];
|
||||
|
@ -456,22 +412,21 @@ void BmpDetect()
|
|||
}
|
||||
}
|
||||
if (bmp_type) {
|
||||
bmp_model = 0;
|
||||
boolean success = false;
|
||||
switch (bmp_type) {
|
||||
case BMP180_CHIPID:
|
||||
success = Bmp180Calibration();
|
||||
break;
|
||||
case BMP280_CHIPID:
|
||||
bmp_model = 1; // 1
|
||||
success = Bmx280Calibrate();
|
||||
break;
|
||||
case BME280_CHIPID:
|
||||
bmp_model = 2; // 2
|
||||
bmp_model++; // 2
|
||||
case BMP280_CHIPID:
|
||||
bmp_model++; // 1
|
||||
success = Bmx280Calibrate();
|
||||
break;
|
||||
#ifdef USE_BME680
|
||||
case BME680_CHIPID:
|
||||
bmp_model = 3; // 2
|
||||
bmp_model = 3; // 3
|
||||
success = Bme680Init();
|
||||
break;
|
||||
#endif // USE_BME680
|
||||
|
@ -487,54 +442,57 @@ void BmpDetect()
|
|||
}
|
||||
}
|
||||
|
||||
void BmpRead()
|
||||
{
|
||||
switch (bmp_type) {
|
||||
case BMP180_CHIPID:
|
||||
Bmp180Read();
|
||||
break;
|
||||
case BMP280_CHIPID:
|
||||
case BME280_CHIPID:
|
||||
Bme280Read();
|
||||
break;
|
||||
#ifdef USE_BME680
|
||||
case BME680_CHIPID:
|
||||
Bme680Read();
|
||||
break;
|
||||
#endif // USE_BME680
|
||||
}
|
||||
if (bmp_temperature != 0.0) { bmp_temperature = ConvertTemp(bmp_temperature); }
|
||||
}
|
||||
|
||||
void BmpEverySecond()
|
||||
{
|
||||
if (91 == (uptime %100)) {
|
||||
// 1mS
|
||||
BmpDetect();
|
||||
}
|
||||
else {
|
||||
// 2mS
|
||||
BmpRead();
|
||||
}
|
||||
}
|
||||
|
||||
void BmpShow(boolean json)
|
||||
{
|
||||
if (bmp_type) {
|
||||
float t = 0.0;
|
||||
float p = 0.0;
|
||||
float h = 0.0;
|
||||
float g = 0.0;
|
||||
float bmp_sealevel = 0.0;
|
||||
|
||||
switch (bmp_type) {
|
||||
case BMP180_CHIPID:
|
||||
t = Bmp180ReadTemperature();
|
||||
p = Bmp180ReadPressure();
|
||||
break;
|
||||
case BME280_CHIPID:
|
||||
h = Bme280ReadHumidity();
|
||||
case BMP280_CHIPID:
|
||||
t = Bme280ReadTemperature();
|
||||
p = Bme280ReadPressure();
|
||||
break;
|
||||
#ifdef USE_BME680
|
||||
case BME680_CHIPID:
|
||||
t = bme680_temperature;
|
||||
p = bme680_pressure / 100.0;
|
||||
h = bme680_humidity;
|
||||
g = bme680_gas_resistance / 1000.0;
|
||||
break;
|
||||
#endif // USE_BME680
|
||||
}
|
||||
if (t != 0.0) {
|
||||
t = ConvertTemp(t);
|
||||
}
|
||||
if (p != 0.0) {
|
||||
// bmp_sealevel = p / pow(1.0 - ((float)Settings.altitude / 44330.0), 5.255); // pow adds 8k to the code
|
||||
bmp_sealevel = (p / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6;
|
||||
}
|
||||
|
||||
char temperature[10];
|
||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||
char pressure[10];
|
||||
dtostrfd(p, Settings.flag2.pressure_resolution, pressure);
|
||||
char sea_pressure[10];
|
||||
dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
|
||||
char humidity[10];
|
||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||
|
||||
if (bmp_pressure != 0.0) {
|
||||
bmp_sealevel = (bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6;
|
||||
}
|
||||
|
||||
dtostrfd(bmp_temperature, Settings.flag2.temperature_resolution, temperature);
|
||||
dtostrfd(bmp_pressure, Settings.flag2.pressure_resolution, pressure);
|
||||
dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
|
||||
dtostrfd(bmp_humidity, Settings.flag2.humidity_resolution, humidity);
|
||||
#ifdef USE_BME680
|
||||
char gas_resistance[10];
|
||||
dtostrfd(g, 2, gas_resistance);
|
||||
dtostrfd(bmp_gas_resistance, 2, gas_resistance);
|
||||
#endif // USE_BME680
|
||||
|
||||
if (json) {
|
||||
|
@ -555,15 +513,15 @@ void BmpShow(boolean json)
|
|||
if (0 == tele_period) {
|
||||
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
|
||||
#ifdef USE_BME680
|
||||
if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)g); }
|
||||
if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_gas_resistance); }
|
||||
#endif // USE_BME680
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
|
||||
#ifdef USE_KNX
|
||||
if (0 == tele_period) {
|
||||
KnxSensor(KNX_TEMPERATURE, t);
|
||||
KnxSensor(KNX_HUMIDITY, h);
|
||||
KnxSensor(KNX_TEMPERATURE, bmp_temperature);
|
||||
KnxSensor(KNX_HUMIDITY, bmp_humidity);
|
||||
}
|
||||
#endif // USE_KNX
|
||||
|
||||
|
@ -599,13 +557,11 @@ boolean Xsns09(byte function)
|
|||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
BmpDetect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
if (tele_period == Settings.tele_period -2) { // Allow 2 seconds to prepare BME680 readings
|
||||
BmpDetect();
|
||||
}
|
||||
#ifdef USE_BME680
|
||||
Bme680PerformReading();
|
||||
#endif // USE_BME680
|
||||
BmpEverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
BmpShow(1);
|
||||
|
|
|
@ -33,14 +33,20 @@
|
|||
uint8_t bh1750_address;
|
||||
uint8_t bh1750_addresses[] = { BH1750_ADDR1, BH1750_ADDR2 };
|
||||
uint8_t bh1750_type = 0;
|
||||
uint8_t bh1750_valid = 0;
|
||||
uint16_t bh1750_illuminance = 0;
|
||||
char bh1750_types[] = "BH1750";
|
||||
|
||||
uint16_t Bh1750ReadLux()
|
||||
bool Bh1750Read()
|
||||
{
|
||||
Wire.requestFrom(bh1750_address, (uint8_t)2);
|
||||
if (bh1750_valid) { bh1750_valid--; }
|
||||
|
||||
if (2 != Wire.requestFrom(bh1750_address, (uint8_t)2)) { return false; }
|
||||
byte msb = Wire.read();
|
||||
byte lsb = Wire.read();
|
||||
uint16_t value = ((msb << 8) | lsb) / 1.2;
|
||||
return value;
|
||||
bh1750_illuminance = ((msb << 8) | lsb) / 1.2;
|
||||
bh1750_valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -57,31 +63,48 @@ void Bh1750Detect()
|
|||
Wire.write(BH1750_CONTINUOUS_HIGH_RES_MODE);
|
||||
if (!Wire.endTransmission()) {
|
||||
bh1750_type = 1;
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "BH1750", bh1750_address);
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bh1750_types, bh1750_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bh1750EverySecond()
|
||||
{
|
||||
if (90 == (uptime %100)) {
|
||||
// 1mS
|
||||
Bh1750Detect();
|
||||
}
|
||||
else {
|
||||
// 1mS
|
||||
if (bh1750_type) {
|
||||
if (!Bh1750Read()) {
|
||||
AddLogMissed(bh1750_types, bh1750_valid);
|
||||
// if (!bh1750_valid) { bh1750_type = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_ILLUMINANCE[] PROGMEM =
|
||||
"%s{s}BH1750 " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
"%s{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void Bh1750Show(boolean json)
|
||||
{
|
||||
if (bh1750_type) {
|
||||
uint16_t illuminance = Bh1750ReadLux();
|
||||
|
||||
if (bh1750_valid) {
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"BH1750\":{\"" D_JSON_ILLUMINANCE "\":%d}"), mqtt_data, illuminance);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}"), mqtt_data, bh1750_types, bh1750_illuminance);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, illuminance);
|
||||
if (0 == tele_period) {
|
||||
DomoticzSensor(DZ_ILLUMINANCE, bh1750_illuminance);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, illuminance);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, bh1750_types, bh1750_illuminance);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -99,9 +122,12 @@ boolean Xsns10(byte function)
|
|||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
case FUNC_INIT:
|
||||
Bh1750Detect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
Bh1750EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Bh1750Show(1);
|
||||
break;
|
||||
|
|
|
@ -93,6 +93,11 @@ uint32_t ina219_cal_value = 0;
|
|||
// The following multiplier is used to convert raw current values to mA, taking into account the current config settings
|
||||
uint32_t ina219_current_divider_ma = 0;
|
||||
|
||||
uint8_t ina219_valid = 0;
|
||||
float ina219_voltage = 0;
|
||||
float ina219_current = 0;
|
||||
char ina219_types[] = "INA219";
|
||||
|
||||
bool Ina219SetCalibration(uint8_t mode)
|
||||
{
|
||||
uint16_t config = 0;
|
||||
|
@ -155,8 +160,20 @@ float Ina219GetCurrent_mA()
|
|||
return value;
|
||||
}
|
||||
|
||||
bool Ina219Read()
|
||||
{
|
||||
ina219_voltage = Ina219GetBusVoltage_V() + (Ina219GetShuntVoltage_mV() / 1000);
|
||||
ina219_current = Ina219GetCurrent_mA() / 1000;
|
||||
ina219_valid = SENSOR_MAX_MISS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Command Sensor13
|
||||
*
|
||||
* 0 - Max 32V 2A range
|
||||
* 1 - Max 32V 1A range
|
||||
* 2 - Max 16V 0.4A range
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Ina219CommandSensor()
|
||||
|
@ -176,21 +193,36 @@ bool Ina219CommandSensor()
|
|||
|
||||
void Ina219Detect()
|
||||
{
|
||||
if (ina219_type) {
|
||||
return;
|
||||
}
|
||||
if (ina219_type) { return; }
|
||||
|
||||
for (byte i = 0; i < sizeof(ina219_addresses); i++) {
|
||||
ina219_address = ina219_addresses[i];
|
||||
if (Ina219SetCalibration(Settings.ina219_mode)) {
|
||||
ina219_type = 1;
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "INA219", ina219_address);
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, ina219_types, ina219_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ina219EverySecond()
|
||||
{
|
||||
if (87 == (uptime %100)) {
|
||||
// 2mS
|
||||
Ina219Detect();
|
||||
}
|
||||
else {
|
||||
// 3mS
|
||||
if (ina219_type) {
|
||||
if (!Ina219Read()) {
|
||||
AddLogMissed(ina219_types, ina219_valid);
|
||||
// if (!ina219_valid) { ina219_type = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_INA219_DATA[] PROGMEM = "%s"
|
||||
"{s}INA219 " D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
|
||||
|
@ -200,21 +232,19 @@ const char HTTP_SNS_INA219_DATA[] PROGMEM = "%s"
|
|||
|
||||
void Ina219Show(boolean json)
|
||||
{
|
||||
if (ina219_type) {
|
||||
if (ina219_valid) {
|
||||
char voltage[10];
|
||||
char current[10];
|
||||
char power[10];
|
||||
|
||||
float fvoltage = Ina219GetBusVoltage_V() + (Ina219GetShuntVoltage_mV() / 1000);
|
||||
float fcurrent = Ina219GetCurrent_mA() / 1000;
|
||||
float fpower = fvoltage * fcurrent;
|
||||
dtostrfd(fvoltage, Settings.flag2.voltage_resolution, voltage);
|
||||
float fpower = ina219_voltage * ina219_current;
|
||||
dtostrfd(ina219_voltage, Settings.flag2.voltage_resolution, voltage);
|
||||
dtostrfd(fpower, Settings.flag2.wattage_resolution, power);
|
||||
dtostrfd(fcurrent, Settings.flag2.current_resolution, current);
|
||||
dtostrfd(ina219_current, Settings.flag2.current_resolution, current);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"INA219\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_POWERUSAGE "\":%s}"),
|
||||
mqtt_data, voltage, current, power);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_POWERUSAGE "\":%s}"),
|
||||
mqtt_data, ina219_types, voltage, current, power);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) {
|
||||
DomoticzSensor(DZ_VOLTAGE, voltage);
|
||||
|
@ -244,9 +274,12 @@ boolean Xsns13(byte function)
|
|||
result = Ina219CommandSensor();
|
||||
}
|
||||
break;
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
case FUNC_INIT:
|
||||
Ina219Detect();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
Ina219EverySecond();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Ina219Show(1);
|
||||
break;
|
||||
|
|
|
@ -63,9 +63,9 @@ void Tsl2561Show(boolean json)
|
|||
&& Tsl2561Util::normalizedLuminosity(gain, exposure, full = scaledFull, ir = scaledIr)
|
||||
&& Tsl2561Util::milliLux(full, ir, milliLux, Tsl2561::packageCS(id))) {
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_ILLUMINANCE " g:%d, e:%d, f:%u, i:%u -> %u.%03u " D_UNIT_LUX),
|
||||
gain, exposure, full, ir, milliLux/1000, milliLux%1000);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR(D_ILLUMINANCE " g:%d, e:%d, f:%u, i:%u -> %u.%03u " D_UNIT_LUX),
|
||||
// gain, exposure, full, ir, milliLux/1000, milliLux%1000);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_JSON_ILLUMINANCE "\":%u.%03u}"),
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
* References:
|
||||
* - https://www.dfrobot.com/wiki/index.php/Weather-proof_Ultrasonic_Sensor_SKU_:_SEN0207
|
||||
\*********************************************************************************************/
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
uint8_t sr04_echo_pin = 0;
|
||||
uint8_t sr04_trig_pin = 0;
|
||||
|
@ -42,7 +40,7 @@ uint8_t sr04_trig_pin = 0;
|
|||
#define PING_OVERHEAD 5
|
||||
|
||||
// Conversion from uS to distance (round result to nearest cm or inch).
|
||||
#define EchoConvert(echoTime, conversionFactor) (max(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0)))
|
||||
#define EchoConvert(echoTime, conversionFactor) (tmax(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0)))
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
|
@ -74,7 +72,7 @@ uint16_t Sr04Ping(uint16_t max_cm_distance)
|
|||
uint16_t duration = 0;
|
||||
uint16_t maxEchoTime;
|
||||
|
||||
maxEchoTime = min(max_cm_distance + 1, (uint16_t) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM;
|
||||
maxEchoTime = tmin(max_cm_distance + 1, (uint16_t) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM;
|
||||
|
||||
/* The following trigPin/echoPin cycle is used to determine the
|
||||
distance of the nearest object by bouncing soundwaves off of it. */
|
||||
|
|
|
@ -35,19 +35,20 @@ uint8_t tm1638_clock_pin = 0;
|
|||
uint8_t tm1638_data_pin = 0;
|
||||
uint8_t tm1638_strobe_pin = 0;
|
||||
uint8_t tm1638_displays = 8;
|
||||
uint8_t tm1638_active_display = 0;
|
||||
uint8_t tm1638_active_display = 1;
|
||||
uint8_t tm1638_intensity = 0;
|
||||
uint8_t tm1638_state = 0;
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Pieces from library https://github.com/rjbatista/tm1638-library
|
||||
* and from library https://github.com/MartyMacGyver/TM1638-demos-and-examples
|
||||
\*********************************************************************************************/
|
||||
|
||||
void Tm16XXSend(byte data)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
digitalWrite(tm1638_data_pin, !!(data & (1 << i)));
|
||||
digitalWrite(tm1638_clock_pin, LOW);
|
||||
digitalWrite(tm1638_data_pin, data & 1 ? HIGH : LOW);
|
||||
data >>= 1;
|
||||
delayMicroseconds(TM1638_CLOCK_DELAY);
|
||||
digitalWrite(tm1638_clock_pin, HIGH);
|
||||
}
|
||||
|
@ -77,11 +78,10 @@ byte Tm16XXReceive()
|
|||
pinMode(tm1638_data_pin, INPUT);
|
||||
digitalWrite(tm1638_data_pin, HIGH);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
temp >>= 1;
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
digitalWrite(tm1638_clock_pin, LOW);
|
||||
delayMicroseconds(TM1638_CLOCK_DELAY);
|
||||
if (digitalRead(tm1638_data_pin)) { temp |= 0x80; }
|
||||
temp |= digitalRead(tm1638_data_pin) << i;
|
||||
digitalWrite(tm1638_clock_pin, HIGH);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ void TmInit()
|
|||
digitalWrite(tm1638_clock_pin, HIGH);
|
||||
|
||||
Tm16XXSendCommand(0x40);
|
||||
Tm16XXSendCommand(0x80 | (tm1638_active_display ? 8 : 0) | min(7, tm1638_intensity));
|
||||
Tm16XXSendCommand(0x80 | (tm1638_active_display ? 8 : 0) | tmin(7, tm1638_intensity));
|
||||
|
||||
digitalWrite(tm1638_strobe_pin, LOW);
|
||||
Tm16XXSend(0xC0);
|
||||
|
@ -165,25 +165,32 @@ void TmInit()
|
|||
digitalWrite(tm1638_strobe_pin, HIGH);
|
||||
|
||||
tm1638_type = 1;
|
||||
tm1638_state = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void TmLoop()
|
||||
{
|
||||
byte buttons = Tm1638GetButtons();
|
||||
for (byte i = 0; i < MAX_SWITCHES; i++) {
|
||||
virtualswitch[i] = buttons &1;
|
||||
byte color = (virtualswitch[i]) ? TM1638_COLOR_RED : TM1638_COLOR_NONE;
|
||||
Tm1638SetLED(color, i);
|
||||
buttons >>= 1;
|
||||
if (tm1638_state) {
|
||||
byte buttons = Tm1638GetButtons();
|
||||
for (byte i = 0; i < MAX_SWITCHES; i++) {
|
||||
virtualswitch[i] = (buttons &1) ^1;
|
||||
byte color = (virtualswitch[i]) ? TM1638_COLOR_NONE : TM1638_COLOR_RED;
|
||||
Tm1638SetLED(color, i);
|
||||
buttons >>= 1;
|
||||
}
|
||||
SwitchHandler(1);
|
||||
}
|
||||
SwitchHandler(1);
|
||||
}
|
||||
|
||||
/*
|
||||
void TmShow(boolean json)
|
||||
{
|
||||
if (tm1638_type) {
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
|
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
xsns_29_mcp230xx.ino - Support for I2C MCP23008/MCP23017 GPIO Expander (INPUT ONLY!)
|
||||
|
||||
Copyright (C) 2018 Andre Thomas and Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifdef USE_MCP230xx
|
||||
|
||||
/*********************************************************************************************\
|
||||
MCP23008/17 - I2C GPIO EXPANDER
|
||||
|
||||
Docs at https://www.microchip.com/wwwproducts/en/MCP23008
|
||||
https://www.microchip.com/wwwproducts/en/MCP23017
|
||||
|
||||
I2C Address: 0x20 - 0x27
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_29 29
|
||||
|
||||
#define MCP230xx_ADDRESS1 0x20
|
||||
#define MCP230xx_ADDRESS2 0x21
|
||||
#define MCP230xx_ADDRESS3 0x22
|
||||
#define MCP230xx_ADDRESS4 0x23
|
||||
#define MCP230xx_ADDRESS5 0x24
|
||||
#define MCP230xx_ADDRESS6 0x25
|
||||
#define MCP230xx_ADDRESS7 0x26
|
||||
#define MCP230xx_ADDRESS8 0x27
|
||||
|
||||
/*
|
||||
Default register locations for MCP23008 - They change for MCP23017 in default bank mode
|
||||
*/
|
||||
|
||||
uint8_t MCP230xx_IODIR = 0x00;
|
||||
uint8_t MCP230xx_GPINTEN = 0x02;
|
||||
uint8_t MCP230xx_IOCON = 0x05;
|
||||
uint8_t MCP230xx_GPPU = 0x06;
|
||||
uint8_t MCP230xx_INTF = 0x07;
|
||||
uint8_t MCP230xx_INTCAP = 0x08;
|
||||
uint8_t MCP230xx_GPIO = 0x09;
|
||||
|
||||
uint8_t mcp230xx_type = 0;
|
||||
uint8_t mcp230xx_address;
|
||||
uint8_t mcp230xx_addresses[] = { MCP230xx_ADDRESS1, MCP230xx_ADDRESS2, MCP230xx_ADDRESS3, MCP230xx_ADDRESS4, MCP230xx_ADDRESS5, MCP230xx_ADDRESS6, MCP230xx_ADDRESS7, MCP230xx_ADDRESS8 };
|
||||
uint8_t mcp280xx_pincount = 0;
|
||||
|
||||
const char MCP230XX_SENSOR_RESPONSE[] PROGMEM = "{\"Sensor29\":{\"D\":%i,\"MODE\":%i,\"PULL-UP\":%i}}";
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
#ifdef USE_MCP230xx_displaymain
|
||||
const char HTTP_SNS_MCP230xx_GPIO[] PROGMEM = "%s{s}MCP230XX D%d{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
#endif // USE_MCP230xx_displaymain
|
||||
#ifdef USE_MCP230xx_webconfig
|
||||
const char MCP230XX_OPTION_SELECTED[] PROGMEM = " selected";
|
||||
const char MCP230XX_OPTION_BLANK[] PROGMEM = "";
|
||||
const char MCP230XX_OPTION_CHECKED[] PROGMEM = " checked";
|
||||
const char HTTP_FORM_I2C_MCP230XX_T[] PROGMEM = "<table>";
|
||||
const char HTTP_FORM_I2C_MCP230XX_TE[] PROGMEM = "</table>";
|
||||
|
||||
const char HTTP_FORM_MCP230XX[] PROGMEM =
|
||||
"<fieldset><legend><b> MCP230xx settings </b></legend><form method='post' action='sv'><input id='w' name='w' value='8' hidden>";
|
||||
|
||||
const char HTTP_FORM_I2C_MCP230XX[] PROGMEM =
|
||||
"<tr><td nowrap>{b0 </b> <br/></td><td nowrap><select id='{b1' name='{b1'>"
|
||||
"<option value='0'{s0>Disabled</option>"
|
||||
"<option value='1'{s1>Input</option>"
|
||||
"<option value='2'{s2>Input (Int on Change)</option>"
|
||||
"<option value='3'{s3>Input (Int when Low)</option>"
|
||||
"<option value='4'{s4>Input (Int when High)</option>"
|
||||
"</select></td>"
|
||||
"<td nowrap>Enable Pullup</td>"
|
||||
"<td nowrap><input type=checkbox name=epu{b1 value=1{b2></input></td>"
|
||||
"</tr>";
|
||||
|
||||
void HandleMCP230xxConfiguration()
|
||||
{
|
||||
if (HttpUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_MCP230XX));
|
||||
|
||||
String page = FPSTR(HTTP_HEAD);
|
||||
|
||||
page.replace("{v}", FPSTR(D_CONFIGURE_MCP230XX));
|
||||
|
||||
page += FPSTR(HTTP_HEAD_STYLE);
|
||||
page += FPSTR(HTTP_FORM_MCP230XX);
|
||||
|
||||
page += FPSTR(HTTP_FORM_I2C_MCP230XX_T);
|
||||
|
||||
for (uint8_t idx = 0; idx < mcp280xx_pincount; idx++) {
|
||||
page += FPSTR(HTTP_FORM_I2C_MCP230XX);
|
||||
page.replace("{b0", "MCP230XX D" + String(idx));
|
||||
page.replace("{b1", "D" + String(idx));
|
||||
|
||||
// determine correct dropdown state
|
||||
|
||||
uint8_t bitsetting = 0; // Default to disabled
|
||||
if (Settings.mcp230xx_config[idx].enable) {
|
||||
bitsetting = 1; // Default to normal enable (floating without interrupt)
|
||||
if (Settings.mcp230xx_config[idx].inten) { // Int choice
|
||||
bitsetting = 2; // Default to INT on Change (LOW to HIGH, and HIGH to LOW)
|
||||
if (Settings.mcp230xx_config[idx].intmode) { // On comparison
|
||||
bitsetting = 3; // On comparison default to LOW
|
||||
if (Settings.mcp230xx_config[idx].intcomp) {
|
||||
bitsetting = 4; // On comparison default to HIGH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (bitsetting) {
|
||||
case 0 : page.replace("{s0", FPSTR(MCP230XX_OPTION_SELECTED)); break;
|
||||
case 1 : page.replace("{s1", FPSTR(MCP230XX_OPTION_SELECTED)); break;
|
||||
case 2 : page.replace("{s2", FPSTR(MCP230XX_OPTION_SELECTED)); break;
|
||||
case 3 : page.replace("{s3", FPSTR(MCP230XX_OPTION_SELECTED)); break;
|
||||
case 4 : page.replace("{s4", FPSTR(MCP230XX_OPTION_SELECTED)); break;
|
||||
}
|
||||
// replace remaining unselected options - if one was replaced above it will be ignored
|
||||
page.replace("{s0", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
page.replace("{s1", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
page.replace("{s2", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
page.replace("{s3", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
page.replace("{s4", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
|
||||
if (Settings.mcp230xx_config[idx].pullup) {
|
||||
page.replace("{b2", FPSTR(MCP230XX_OPTION_CHECKED));
|
||||
} else {
|
||||
page.replace("{b2", FPSTR(MCP230XX_OPTION_BLANK));
|
||||
}
|
||||
}
|
||||
|
||||
page += FPSTR(HTTP_FORM_I2C_MCP230XX_TE);
|
||||
|
||||
page += FPSTR(HTTP_FORM_END);
|
||||
page += FPSTR(HTTP_BTN_CONF);
|
||||
ShowPage(page);
|
||||
}
|
||||
|
||||
void MCP230xx_SaveSettings()
|
||||
{
|
||||
char stemp[8];
|
||||
for (uint8_t idx = 0; idx < mcp280xx_pincount; idx++) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("D%d"), idx);
|
||||
uint8_t _pinvalue = (!strlen(WebServer->arg(stemp).c_str() )) ? 0 : atoi(WebServer->arg(stemp).c_str() );
|
||||
if (_pinvalue) {
|
||||
Settings.mcp230xx_config[idx].enable = 1;
|
||||
if (_pinvalue >= 2) {
|
||||
Settings.mcp230xx_config[idx].inten = 1;
|
||||
if (_pinvalue >= 3) {
|
||||
Settings.mcp230xx_config[idx].intmode = 1;
|
||||
if (_pinvalue >= 4) {
|
||||
Settings.mcp230xx_config[idx].intcomp = 1;
|
||||
} else {
|
||||
Settings.mcp230xx_config[idx].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[idx].intmode = 0;
|
||||
Settings.mcp230xx_config[idx].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[idx].inten = 0;
|
||||
Settings.mcp230xx_config[idx].intmode = 0;
|
||||
Settings.mcp230xx_config[idx].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[idx].enable = 0;
|
||||
Settings.mcp230xx_config[idx].inten = 0;
|
||||
Settings.mcp230xx_config[idx].intmode = 0;
|
||||
Settings.mcp230xx_config[idx].intcomp = 0;
|
||||
}
|
||||
Settings.mcp230xx_config[idx].b5 = 0;
|
||||
Settings.mcp230xx_config[idx].b6 = 0;
|
||||
Settings.mcp230xx_config[idx].b7 = 0;
|
||||
if (Settings.mcp230xx_config[idx].enable) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("epuD%d"), idx);
|
||||
Settings.mcp230xx_config[idx].pullup = (!strlen(WebServer->arg(stemp).c_str() )) ? 0 : atoi(WebServer->arg(stemp).c_str() );
|
||||
} else {
|
||||
Settings.mcp230xx_config[idx].pullup = 0;
|
||||
}
|
||||
}
|
||||
MCP230xx_ApplySettings();
|
||||
}
|
||||
|
||||
#endif // USE_MCP230xx_webconfig
|
||||
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
uint8_t MCP230xx_Type(void) {
|
||||
return mcp230xx_type;
|
||||
}
|
||||
|
||||
uint8_t MCP230xx_readGPIO(uint8_t port) {
|
||||
return I2cRead8(mcp230xx_address, MCP230xx_GPIO + port);
|
||||
}
|
||||
|
||||
void MCP230xx_ApplySettings(void) {
|
||||
uint8_t reg_gppu = 0;
|
||||
uint8_t reg_gpinten = 0;
|
||||
for (uint8_t idx = 0; idx < 8; idx++) {
|
||||
if (Settings.mcp230xx_config[idx].enable) {
|
||||
if (Settings.mcp230xx_config[idx].inten) { // Int is enabled in some form or another
|
||||
reg_gpinten |= (1 << idx);
|
||||
}
|
||||
if (Settings.mcp230xx_config[idx].pullup) {
|
||||
reg_gppu |= (1 << idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_GPPU, reg_gppu);
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_GPINTEN, reg_gpinten);
|
||||
if (mcp230xx_type == 2) { // We have a MCP23017
|
||||
reg_gppu = 0;
|
||||
reg_gpinten = 0;
|
||||
for (uint8_t idx = 8; idx < 16; idx++) {
|
||||
if (Settings.mcp230xx_config[idx].enable) {
|
||||
if (Settings.mcp230xx_config[idx].inten) { // Int is enabled in some form or another
|
||||
reg_gpinten |= (1 << idx - 8);
|
||||
}
|
||||
if (Settings.mcp230xx_config[idx].pullup) {
|
||||
reg_gppu |= (1 << idx - 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_GPPU + 1, reg_gppu);
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_GPINTEN + 1, reg_gpinten);
|
||||
}
|
||||
}
|
||||
|
||||
void MCP230xx_Detect()
|
||||
{
|
||||
uint8_t buffer;
|
||||
|
||||
if (mcp230xx_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (byte i = 0; i < sizeof(mcp230xx_addresses); i++) {
|
||||
mcp230xx_address = mcp230xx_addresses[i];
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_IOCON, 0x80); // attempt to set bank mode - this will only work on MCP23017, so its the best way to detect the different chips 23008 vs 23017
|
||||
if (I2cValidRead8(&buffer, mcp230xx_address, MCP230xx_IOCON)) {
|
||||
if (buffer == 0x00) {
|
||||
mcp230xx_type = 1; // We have a MCP23008
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "MCP23008", mcp230xx_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
mcp280xx_pincount = 8;
|
||||
MCP230xx_ApplySettings();
|
||||
} else {
|
||||
if (buffer == 0x80) {
|
||||
mcp230xx_type = 2; // We have a MCP23017
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "MCP23017", mcp230xx_address);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
mcp280xx_pincount = 16;
|
||||
// Reset bank mode to 0
|
||||
I2cWrite8(mcp230xx_address, MCP230xx_IOCON, 0x00);
|
||||
// Update register locations for MCP23017
|
||||
MCP230xx_GPINTEN = 0x04;
|
||||
MCP230xx_GPPU = 0x0C;
|
||||
MCP230xx_INTF = 0x0E;
|
||||
MCP230xx_INTCAP = 0x10;
|
||||
MCP230xx_GPIO = 0x12;
|
||||
MCP230xx_ApplySettings();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MCP230xx_CheckForInterrupt(void) {
|
||||
uint8_t intf;
|
||||
uint8_t mcp230xx_intcap = 0;
|
||||
uint8_t report_int;
|
||||
|
||||
if (I2cValidRead8(&intf, mcp230xx_address, MCP230xx_INTF)) {
|
||||
if (intf > 0) {
|
||||
if (I2cValidRead8(&mcp230xx_intcap, mcp230xx_address, MCP230xx_INTCAP)) {
|
||||
for (uint8_t intp = 0; intp < 8; intp++) {
|
||||
if ((intf >> intp) & 0x01) { // we know which pin caused interrupt
|
||||
report_int = 0;
|
||||
if (Settings.mcp230xx_config[intp].intmode) { // change on INT
|
||||
if (((mcp230xx_intcap >> intp) & 0x01) == Settings.mcp230xx_config[intp].intcomp) report_int = 1;
|
||||
} else {
|
||||
report_int = 1;
|
||||
}
|
||||
if (report_int) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"MCP230XX_INT\":{\"Pin\":\"D%i\", \"State\":%i}"), mqtt_data, intp, ((mcp230xx_intcap >> intp) & 0x01));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mcp230xx_type == 2) { // We have a MCP23017 so we need to check the other 8 bits also
|
||||
if (I2cValidRead8(&intf, mcp230xx_address, MCP230xx_INTF+1)) {
|
||||
if (intf > 0) {
|
||||
if (I2cValidRead8(&mcp230xx_intcap, mcp230xx_address, MCP230xx_INTCAP+1)) {
|
||||
for (uint8_t intp = 0; intp < 8; intp++) {
|
||||
if ((intf >> intp) & 0x01) { // we know which pin caused interrupt
|
||||
report_int = 0;
|
||||
if (Settings.mcp230xx_config[intp+8].intmode) { // change on INT
|
||||
if (((mcp230xx_intcap >> intp) & 0x01) == Settings.mcp230xx_config[intp+8].intcomp) report_int = 1;
|
||||
} else {
|
||||
report_int = 1;
|
||||
}
|
||||
if (report_int) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"MCP230XX_INT\":{\"Pin\":\"D%i\", \"State\":%i}"), mqtt_data, intp+8, ((mcp230xx_intcap >> intp) & 0x01));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MCP230xx_Show(boolean json)
|
||||
{
|
||||
if (mcp230xx_type) {
|
||||
if (json) {
|
||||
if (mcp230xx_type == 1) {
|
||||
uint8_t gpio = MCP230xx_readGPIO(0);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"MCP23008\":{\"D0\":%i,\"D1\":%i,\"D2\":%i,\"D3\":%i,\"D4\":%i,\"D5\":%i,\"D6\":%i,\"D7\":%i}"),
|
||||
mqtt_data,(gpio>>0)&1,(gpio>>1)&1,(gpio>>2)&1,(gpio>>3)&1,(gpio>>4)&1,(gpio>>5)&1,(gpio>>6)&1,(gpio>>7)&1);
|
||||
}
|
||||
if (mcp230xx_type == 2) {
|
||||
uint8_t gpio1 = MCP230xx_readGPIO(0);
|
||||
uint8_t gpio2 = MCP230xx_readGPIO(1);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"MCP23017\":{\"D0\":%i,\"D1\":%i,\"D2\":%i,\"D3\":%i,\"D4\":%i,\"D5\":%i,\"D6\":%i,\"D7\":%i,\"D8\":%i,\"D9\":%i,\"D10\":%i,\"D11\":%i,\"D12\":%i,\"D13\":%i,\"D14\":%i,\"D15\":%i}"),
|
||||
mqtt_data, (gpio1>>0)&1,(gpio1>>1)&1,(gpio1>>2)&1,(gpio1>>3)&1,(gpio1>>4)&1,(gpio1>>5)&1,(gpio1>>6)&1,(gpio1>>7)&1,(gpio2>>0)&1,(gpio2>>1)&1,(gpio2>>2)&1,(gpio2>>3)&1,(gpio2>>4)&1,(gpio2>>5)&1,(gpio2>>6)&1,(gpio2>>7)&1);
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
#ifdef USE_MCP230xx_displaymain
|
||||
} else {
|
||||
uint8_t gpio1 = MCP230xx_readGPIO(0);
|
||||
uint8_t gpio2 = 0;
|
||||
if (mcp230xx_type == 2) {
|
||||
gpio2=MCP230xx_readGPIO(1);
|
||||
}
|
||||
uint16_t gpio = (gpio2 << 8) + gpio1;
|
||||
|
||||
for (uint8_t pin = 0; pin < mcp280xx_pincount; pin++) {
|
||||
if (Settings.mcp230xx_config[pin].enable) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_MCP230xx_GPIO, mqtt_data, pin, (gpio>>pin)&1);
|
||||
}
|
||||
}
|
||||
#endif // USE_MCP230xx_displaymain
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MCP230xx_Command(void) {
|
||||
boolean serviced = true;
|
||||
uint8_t _a, _b = 0;
|
||||
uint8_t pin, pinmode, pullup = 0;
|
||||
String data = XdrvMailbox.data;
|
||||
_a = data.indexOf(",");
|
||||
_b = data.indexOf(",", _a + 1);
|
||||
if (_a < XdrvMailbox.data_len) {
|
||||
if (_b < XdrvMailbox.data_len) {
|
||||
pin = data.substring(0, _a).toInt();
|
||||
pinmode = data.substring(_a+1, _b).toInt();
|
||||
pullup = data.substring(_b+1, XdrvMailbox.data_len).toInt();
|
||||
if (pinmode) {
|
||||
Settings.mcp230xx_config[pin].enable = 1;
|
||||
if (pinmode >= 2) {
|
||||
Settings.mcp230xx_config[pin].inten = 1;
|
||||
if (pinmode >= 3) {
|
||||
Settings.mcp230xx_config[pin].intmode = 1;
|
||||
if (pinmode >= 4) {
|
||||
Settings.mcp230xx_config[pin].intcomp = 1;
|
||||
} else {
|
||||
Settings.mcp230xx_config[pin].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[pin].intmode = 0;
|
||||
Settings.mcp230xx_config[pin].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[pin].inten = 0;
|
||||
Settings.mcp230xx_config[pin].intmode = 0;
|
||||
Settings.mcp230xx_config[pin].intcomp = 0;
|
||||
}
|
||||
} else {
|
||||
Settings.mcp230xx_config[pin].enable = 0;
|
||||
Settings.mcp230xx_config[pin].inten = 0;
|
||||
Settings.mcp230xx_config[pin].intmode = 0;
|
||||
Settings.mcp230xx_config[pin].intcomp = 0;
|
||||
}
|
||||
Settings.mcp230xx_config[pin].b5 = 0;
|
||||
Settings.mcp230xx_config[pin].b6 = 0;
|
||||
Settings.mcp230xx_config[pin].b7 = 0;
|
||||
if (Settings.mcp230xx_config[pin].enable) {
|
||||
Settings.mcp230xx_config[pin].pullup = pullup;
|
||||
} else {
|
||||
Settings.mcp230xx_config[pin].pullup = 0;
|
||||
}
|
||||
MCP230xx_ApplySettings();
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_SENSOR_RESPONSE,pin,pinmode,pullup);
|
||||
} else {
|
||||
serviced = false;
|
||||
}
|
||||
} else {
|
||||
serviced = false;
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
boolean Xsns29(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_PREP_BEFORE_TELEPERIOD:
|
||||
MCP230xx_Detect();
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
MCP230xx_CheckForInterrupt();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
MCP230xx_Show(1);
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
if (XSNS_29 == XdrvMailbox.index) {
|
||||
result = MCP230xx_Command();
|
||||
}
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
#ifdef USE_MCP230xx_displaymain
|
||||
case FUNC_WEB_APPEND:
|
||||
MCP230xx_Show(0);
|
||||
break;
|
||||
#endif // USE_MCP230xx_displaymain
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_MCP230xx
|
||||
#endif // USE_I2C
|
|
@ -146,6 +146,38 @@ boolean (* const xsns_func_ptr[])(byte) PROGMEM = { // Sensor Function Pointers
|
|||
&Xsns32,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_33
|
||||
&Xsns33,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_34
|
||||
&Xsns34,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_35
|
||||
&Xsns35,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_36
|
||||
&Xsns36,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_37
|
||||
&Xsns37,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_38
|
||||
&Xsns38,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_39
|
||||
&Xsns39,
|
||||
#endif
|
||||
|
||||
#ifdef XSNS_40
|
||||
&Xsns40,
|
||||
#endif
|
||||
|
||||
// Optional user defined sensors in range 91 - 99
|
||||
|
||||
#ifdef XSNS_91
|
||||
|
@ -217,10 +249,40 @@ boolean XsnsCall(byte Function)
|
|||
{
|
||||
boolean result = false;
|
||||
|
||||
#ifdef PROFILE_XSNS_EVERY_SECOND
|
||||
uint32_t profile_start_millis = millis();
|
||||
#endif // PROFILE_XSNS_EVERY_SECOND
|
||||
|
||||
for (byte x = 0; x < xsns_present; x++) {
|
||||
|
||||
#ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND
|
||||
uint32_t profile_start_millis = millis();
|
||||
#endif // PROFILE_XSNS_SENSOR_EVERY_SECOND
|
||||
|
||||
result = xsns_func_ptr[x](Function);
|
||||
|
||||
#ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND
|
||||
uint32_t profile_millis = millis() - profile_start_millis;
|
||||
if (profile_millis) {
|
||||
if (FUNC_EVERY_SECOND == Function) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("PRF: At %08u XsnsCall %d to Sensor %d took %u mS"), uptime, Function, x, profile_millis);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
#endif // PROFILE_XSNS_SENSOR_EVERY_SECOND
|
||||
|
||||
if (result) break;
|
||||
}
|
||||
|
||||
#ifdef PROFILE_XSNS_EVERY_SECOND
|
||||
uint32_t profile_millis = millis() - profile_start_millis;
|
||||
if (profile_millis) {
|
||||
if (FUNC_EVERY_SECOND == Function) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR("PRF: At %08u XsnsCall %d took %u mS"), uptime, Function, profile_millis);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
#endif // PROFILE_XSNS_EVERY_SECOND
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ a_setoption = [
|
|||
"KNX enhancement",
|
||||
"RF receive decimal",
|
||||
"IR receive decimal",
|
||||
"Enforce HASS light group",""]
|
||||
"Enforce HASS light group",
|
||||
"Do not show Wifi and Mqtt state using Led"]
|
||||
|
||||
a_features = [[
|
||||
"","","USE_I2C","USE_SPI",
|
||||
|
@ -89,7 +90,7 @@ a_features = [[
|
|||
"USE_WS2812_DMA","USE_IR_REMOTE","USE_IR_HVAC","USE_IR_RECEIVE",
|
||||
"USE_DOMOTICZ","USE_DISPLAY","USE_HOME_ASSISTANT","USE_SERIAL_BRIDGE",
|
||||
"USE_TIMERS","USE_SUNRISE","USE_TIMERS_WEB","USE_RULES",
|
||||
"USE_KNX","","",""
|
||||
"USE_KNX","USE_WPS","USE_SMARTCONFIG",""
|
||||
],[
|
||||
"USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_ALL_SENSORS","USE_CLASSIC",
|
||||
"USE_KNX_NO_EMULATION","","","",
|
||||
|
|
Loading…
Reference in New Issue