mirror of https://github.com/arendst/Tasmota.git
Merge branch 'arendst:development' into rgx-preserve-ap-connections-on-sta-reconnect
This commit is contained in:
commit
552c44425b
|
@ -187,7 +187,7 @@ jobs:
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -R ./mv_firmware/
|
run: ls -R ./mv_firmware/
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: jason2866/action-gh-release@v1.1
|
uses: jason2866/action-gh-release@v1.2
|
||||||
#if: startsWith(github.ref, 'refs/tags/')
|
#if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.run_number }}
|
tag_name: ${{ github.run_number }}
|
||||||
|
|
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -8,7 +8,12 @@ All notable changes to this project will be documented in this file.
|
||||||
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
|
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
|
||||||
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
|
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
|
||||||
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
|
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
|
||||||
- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
|
- WS2812 and Light ArtNet DMX control over UDP port 6454 (#17059)
|
||||||
|
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
|
||||||
|
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
|
||||||
|
- Berry add ``udp->close()`` method (#17094)
|
||||||
|
- Command ``RgxClients`` for range extender clients list (#17048)
|
||||||
|
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings (#17092)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
|
@ -17,6 +22,8 @@ All notable changes to this project will be documented in this file.
|
||||||
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
|
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
|
||||||
- TuyaMcu rewrite by btsimonh (#17051)
|
- TuyaMcu rewrite by btsimonh (#17051)
|
||||||
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
|
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
|
||||||
|
- Zigbee improved Aqara plug support and completed cluster 0x0702 (#17073)
|
||||||
|
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- SenseAir S8 module detection (#17033)
|
- SenseAir S8 module detection (#17033)
|
||||||
|
@ -39,9 +46,9 @@ All notable changes to this project will be documented in this file.
|
||||||
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
||||||
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
|
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
|
||||||
- Berry ``bytes().reverse()`` method (#16977)
|
- Berry ``bytes().reverse()`` method (#16977)
|
||||||
- ESP32 Support for DMX Art-Net Led matrix animations (#16984)
|
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
|
||||||
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
||||||
- ESP32 DMX Art-Net optimization to avoid any object allocation and avoid garbage collector pauses
|
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
|
||||||
- Berry add ``dyn`` class
|
- Berry add ``dyn`` class
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -64,7 +71,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Berry add `bytes().setbytes()` (#16892)
|
- Berry add `bytes().setbytes()` (#16892)
|
||||||
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
|
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
|
||||||
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
|
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
|
||||||
- Prepare for DMX Art-Net support on ESP32
|
- Prepare for DMX ArtNet support on ESP32
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
|
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
|
||||||
|
|
|
@ -107,3 +107,4 @@ Index | Define | Driver | Device | Address(es) | Description
|
||||||
70 | USE_LUXV30B | xsns_99 | LUXV30B | 0x4A | DFRobot SEN0390 V30B lux sensor
|
70 | USE_LUXV30B | xsns_99 | LUXV30B | 0x4A | DFRobot SEN0390 V30B lux sensor
|
||||||
71 | USE_QMC5883L | xsns_33 | QMC5883L | 0x0D | Magnetic Field Sensor
|
71 | USE_QMC5883L | xsns_33 | QMC5883L | 0x0D | Magnetic Field Sensor
|
||||||
72 | USE_INA3221 | xsns_100 | INA3221 | 0x40-0x43 | 3-channels Voltage and Current sensor
|
72 | USE_INA3221 | xsns_100 | INA3221 | 0x40-0x43 | 3-channels Voltage and Current sensor
|
||||||
|
73 | USE_HMC5883L | xsns_101 | HMC5883L | 0x1E | 3-channels Magnetic Field Sensor
|
||||||
|
|
|
@ -110,6 +110,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||||
## Changelog v12.2.0.4
|
## Changelog v12.2.0.4
|
||||||
### Added
|
### Added
|
||||||
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
||||||
|
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
|
||||||
|
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
|
||||||
|
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
|
||||||
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
|
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
|
||||||
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
||||||
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
|
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
|
||||||
|
@ -119,23 +122,26 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||||
- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
|
- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
|
||||||
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
|
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
|
||||||
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
|
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
|
||||||
- WS2812 and Light Art-Net DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
|
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069)
|
||||||
|
- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
|
||||||
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
|
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
|
||||||
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
|
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
|
||||||
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
|
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
|
||||||
- ESP32 Support for DMX Art-Net Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
|
- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
|
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
|
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
|
||||||
|
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
|
||||||
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
|
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
|
||||||
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
|
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
|
||||||
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
|
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
|
||||||
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
|
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
|
||||||
- TuyaMcu rewrite by btsimonh [#17051](https://github.com/arendst/Tasmota/issues/17051)
|
- TuyaMcu rewrite by btsimonh [#17051](https://github.com/arendst/Tasmota/issues/17051)
|
||||||
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds [#17055](https://github.com/arendst/Tasmota/issues/17055)
|
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds [#17055](https://github.com/arendst/Tasmota/issues/17055)
|
||||||
|
- Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
|
- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@ extern "C" {
|
||||||
return be_call_c_func(vm, (void*) &be_udp_deinit_ntv, "=.p", "");
|
return be_call_c_func(vm, (void*) &be_udp_deinit_ntv, "=.p", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// udp.begin(address:string, port:int) -> nil
|
// udp.begin(address:string, port:int) -> bool
|
||||||
int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) {
|
int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) {
|
||||||
IPAddress addr((uint32_t)0);
|
IPAddress addr((uint32_t)0);
|
||||||
// if no host or host is "" then we defult to INADDR_ANY (0.0.0.0)
|
// if no host or host is "" then we defult to INADDR_ANY (0.0.0.0)
|
||||||
|
@ -50,6 +50,14 @@ extern "C" {
|
||||||
return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".si");
|
return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".si");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// udp.stop() -> nil
|
||||||
|
void be_udp_stop_ntv(WiFiUDP *udp) {
|
||||||
|
udp->stop();
|
||||||
|
}
|
||||||
|
int32_t be_udp_stop(struct bvm *vm) {
|
||||||
|
return be_call_c_func(vm, (void*) &be_udp_stop_ntv, "b", ".");
|
||||||
|
}
|
||||||
|
|
||||||
// udp.begin_multicast(address:string, port:int) -> nil
|
// udp.begin_multicast(address:string, port:int) -> nil
|
||||||
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
|
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
|
||||||
IPAddress addr((uint32_t)0);
|
IPAddress addr((uint32_t)0);
|
||||||
|
@ -159,6 +167,7 @@ class be_class_udp (scope: global, name: udp) {
|
||||||
begin, func(be_udp_begin)
|
begin, func(be_udp_begin)
|
||||||
begin_multicast, func(be_udp_begin_mcast)
|
begin_multicast, func(be_udp_begin_mcast)
|
||||||
read, func(be_udp_read)
|
read, func(be_udp_read)
|
||||||
|
close, func(be_udp_stop)
|
||||||
}
|
}
|
||||||
@const_object_info_end */
|
@const_object_info_end */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "lvgl",
|
"name": "lvgl",
|
||||||
"version": "8.3.2",
|
"version": "8.3.3",
|
||||||
"keywords": "graphics, gui, embedded, tft, lvgl",
|
"keywords": "graphics, gui, embedded, tft, lvgl",
|
||||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name=lvgl
|
name=lvgl
|
||||||
version=8.3.2
|
version=8.3.3
|
||||||
author=kisvegabor
|
author=kisvegabor
|
||||||
maintainer=kisvegabor,embeddedt,pete-pjb
|
maintainer=kisvegabor,embeddedt,pete-pjb
|
||||||
sentence=Full-featured Graphics Library for Embedded Systems
|
sentence=Full-featured Graphics Library for Embedded Systems
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @file lv_conf.h
|
* @file lv_conf.h
|
||||||
* Configuration file for v8.3.2
|
* Configuration file for v8.3.3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern "C" {
|
||||||
***************************/
|
***************************/
|
||||||
#define LVGL_VERSION_MAJOR 8
|
#define LVGL_VERSION_MAJOR 8
|
||||||
#define LVGL_VERSION_MINOR 3
|
#define LVGL_VERSION_MINOR 3
|
||||||
#define LVGL_VERSION_PATCH 1
|
#define LVGL_VERSION_PATCH 3
|
||||||
#define LVGL_VERSION_INFO ""
|
#define LVGL_VERSION_INFO ""
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
|
|
@ -502,8 +502,7 @@
|
||||||
#define D_CMND_PALETTE "Palette"
|
#define D_CMND_PALETTE "Palette"
|
||||||
#define D_CMND_PIXELS "Pixels"
|
#define D_CMND_PIXELS "Pixels"
|
||||||
#define D_CMND_STEPPIXELS "StepPixels"
|
#define D_CMND_STEPPIXELS "StepPixels"
|
||||||
#define D_CMND_ARTNET_START "ArtNetStart"
|
#define D_CMND_ARTNET "ArtNet"
|
||||||
#define D_CMND_ARTNET_STOP "ArtNetStop"
|
|
||||||
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
|
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
|
||||||
#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
|
#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
|
||||||
#define D_CMND_RGBWWTABLE "RGBWWTable"
|
#define D_CMND_RGBWWTABLE "RGBWWTable"
|
||||||
|
@ -689,6 +688,7 @@
|
||||||
#define D_CMND_ZIGBEE_LOAD "Load"
|
#define D_CMND_ZIGBEE_LOAD "Load"
|
||||||
#define D_CMND_ZIGBEE_LOADDUMP "LoadDump"
|
#define D_CMND_ZIGBEE_LOADDUMP "LoadDump"
|
||||||
#define D_CMND_ZIGBEE_UNLOAD "Unload"
|
#define D_CMND_ZIGBEE_UNLOAD "Unload"
|
||||||
|
#define D_CMND_ZIGBEE_ATTRDUMP "AttrDump"
|
||||||
|
|
||||||
// Commands xdrv_25_A4988_Stepper.ino
|
// Commands xdrv_25_A4988_Stepper.ino
|
||||||
#define D_CMND_MOTOR "MOTOR"
|
#define D_CMND_MOTOR "MOTOR"
|
||||||
|
|
|
@ -322,8 +322,17 @@ enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI
|
||||||
|
|
||||||
enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD};
|
enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD};
|
||||||
|
|
||||||
enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI,
|
enum SwitchModeOptions {TOGGLE, // 0
|
||||||
FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, PUSHON, PUSHON_INV, PUSH_IGNORE, MAX_SWITCH_OPTION};
|
FOLLOW, FOLLOW_INV, // 1, 2 - Follow switch state
|
||||||
|
PUSHBUTTON, PUSHBUTTON_INV, // 3, 4 - Pushbutton (default 1, 0 = toggle)
|
||||||
|
PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, // 5, 6 - Pushbutton with hold (default 1, 0 = toggle, Hold = hold)
|
||||||
|
PUSHBUTTON_TOGGLE, // 7 - = 0
|
||||||
|
TOGGLEMULTI, // 8 - = 0 with multi toggle
|
||||||
|
FOLLOWMULTI, FOLLOWMULTI_INV, // 9, 10 - Multi change follow (0 = off, 1 = on, 2x change = hold)
|
||||||
|
PUSHHOLDMULTI, PUSHHOLDMULTI_INV, // 11, 12 - Pushbutton with dimmer mode
|
||||||
|
PUSHON, PUSHON_INV, // 13, 14 - Pushon mode (1 = on, switch off using PulseTime)
|
||||||
|
PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16 - Send only MQTT message on switch change
|
||||||
|
MAX_SWITCH_OPTION};
|
||||||
|
|
||||||
enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION};
|
enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION};
|
||||||
|
|
||||||
|
|
|
@ -559,6 +559,7 @@
|
||||||
#undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code)
|
#undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code)
|
||||||
|
|
||||||
#define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code)
|
#define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code)
|
||||||
|
#define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
|
||||||
|
|
||||||
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
|
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
|
||||||
|
|
||||||
|
|
|
@ -571,7 +571,7 @@
|
||||||
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
|
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
|
||||||
//#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code)
|
//#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code)
|
||||||
|
|
||||||
// #define USE_LIGHT_ARTNET // Add support for DMX/Art-Net via UDP on port 6454 (+3.5k code)
|
// #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
|
||||||
#define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.24
|
#define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.24
|
||||||
|
|
||||||
// -- Counter input -------------------------------
|
// -- Counter input -------------------------------
|
||||||
|
@ -691,6 +691,7 @@
|
||||||
// #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code)
|
// #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code)
|
||||||
// #define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code)
|
// #define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code)
|
||||||
// #define USE_QMC5883L // [I2CDriver71] Enable QMC5883L magnetic induction sensor (I2C address 0x0D) (+0k8 code)
|
// #define USE_QMC5883L // [I2CDriver71] Enable QMC5883L magnetic induction sensor (I2C address 0x0D) (+0k8 code)
|
||||||
|
// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E) (+1k3 code)
|
||||||
// #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
|
// #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
|
||||||
// #define USE_INA3221 // [I2CDriver72] Enable INA3221 3-channel DC voltage and current sensor (I2C address 0x40-0x44) (+3.2k code)
|
// #define USE_INA3221 // [I2CDriver72] Enable INA3221 3-channel DC voltage and current sensor (I2C address 0x40-0x44) (+3.2k code)
|
||||||
// #define INA3221_ADDRESS1 // allow to change the 1st address to search for INA3221 to 0x41..0x43
|
// #define INA3221_ADDRESS1 // allow to change the 1st address to search for INA3221 to 0x41..0x43
|
||||||
|
|
|
@ -852,7 +852,9 @@ void ResponseAppendFeatures(void)
|
||||||
#ifdef USE_DINGTIAN_RELAY
|
#ifdef USE_DINGTIAN_RELAY
|
||||||
feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino
|
feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino
|
||||||
#endif
|
#endif
|
||||||
// feature9 |= 0x00000200;
|
#if defined(USE_I2C) && defined(USE_HMC5883L)
|
||||||
|
feature9 |= 0x00000200; // xsns_101_hmc5883l.ino
|
||||||
|
#endif
|
||||||
// feature9 |= 0x00000400;
|
// feature9 |= 0x00000400;
|
||||||
// feature9 |= 0x00000800;
|
// feature9 |= 0x00000800;
|
||||||
|
|
||||||
|
|
|
@ -409,6 +409,9 @@ void SwitchHandler(uint32_t mode) {
|
||||||
Switch.last_state[i] = button; // Update switch state before publishing
|
Switch.last_state[i] = button; // Update switch state before publishing
|
||||||
MqttPublishSensor();
|
MqttPublishSensor();
|
||||||
break;
|
break;
|
||||||
|
case PUSH_IGNORE_INV:
|
||||||
|
MqttPublishSensor(); // Publishing before update
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Switch.last_state[i] = button;
|
Switch.last_state[i] = button;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
|
||||||
"|" D_CMND_SEQUENCE_OFFSET
|
"|" D_CMND_SEQUENCE_OFFSET
|
||||||
#endif // USE_DGR_LIGHT_SEQUENCE
|
#endif // USE_DGR_LIGHT_SEQUENCE
|
||||||
#ifdef USE_LIGHT_ARTNET
|
#ifdef USE_LIGHT_ARTNET
|
||||||
"|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
|
"|" D_CMND_ARTNET "|" D_CMND_ARTNET_CONFIG
|
||||||
#endif
|
#endif
|
||||||
"|UNDOCA" ;
|
"|UNDOCA" ;
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ void (* const LightCommand[])(void) PROGMEM = {
|
||||||
&CmndSequenceOffset,
|
&CmndSequenceOffset,
|
||||||
#endif // USE_DGR_LIGHT_SEQUENCE
|
#endif // USE_DGR_LIGHT_SEQUENCE
|
||||||
#ifdef USE_LIGHT_ARTNET
|
#ifdef USE_LIGHT_ARTNET
|
||||||
&CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
|
&CmndArtNet, &CmndArtNetConfig,
|
||||||
#endif
|
#endif
|
||||||
&CmndUndocA };
|
&CmndUndocA };
|
||||||
|
|
||||||
|
|
|
@ -223,9 +223,9 @@ void ArtNetLoop(void)
|
||||||
packet_len = ArtNetUdp->parsePacket();
|
packet_len = ArtNetUdp->parsePacket();
|
||||||
packet_ready = (packet_len > 0);
|
packet_ready = (packet_len > 0);
|
||||||
while (packet_ready) {
|
while (packet_ready) {
|
||||||
uint8_t packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
|
uint8_t packet_buffer[WS2812_ARTNET_UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
|
||||||
|
|
||||||
packet_len = ArtNetUdp->read(packet_buffer, UDP_BUFFER_SIZE);
|
packet_len = ArtNetUdp->read(packet_buffer, WS2812_ARTNET_UDP_BUFFER_SIZE);
|
||||||
ArtNetUdp->flush(); // Finish reading the current packet
|
ArtNetUdp->flush(); // Finish reading the current packet
|
||||||
#endif
|
#endif
|
||||||
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet %*_H (%d)"), 32, packet_buffer, packet_len);
|
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet %*_H (%d)"), 32, packet_buffer, packet_len);
|
||||||
|
@ -381,18 +381,6 @@ bool ArtNetStart(void) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Command `ArtNetStart`
|
|
||||||
// Params: XXX
|
|
||||||
//
|
|
||||||
void CmndArtNetStart(void) {
|
|
||||||
if (ArtNetStart()) {
|
|
||||||
ResponseCmndDone();
|
|
||||||
} else {
|
|
||||||
ResponseCmndError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the ArtNet UDP flow and disconnect server
|
// Stop the ArtNet UDP flow and disconnect server
|
||||||
void ArtNetStop(void) {
|
void ArtNetStop(void) {
|
||||||
artnet_udp_connected = false;
|
artnet_udp_connected = false;
|
||||||
|
@ -411,14 +399,20 @@ void ArtNetStop(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndArtNetStop(void) {
|
void CmndArtNet(void) {
|
||||||
|
if (0 == XdrvMailbox.payload) {
|
||||||
ArtNetStop();
|
ArtNetStop();
|
||||||
// restore default scheme
|
Settings->flag6.artnet_autorun = false; // SetOption148 - (Light) start DMX ArtNet at boot, listen to UDP port as soon as network is up
|
||||||
Settings->light_scheme = LS_POWER;
|
// Settings->light_scheme = LS_POWER; // restore default scheme
|
||||||
// Restore sleep value
|
TasmotaGlobal.sleep = Settings->sleep; // Restore sleep value
|
||||||
TasmotaGlobal.sleep = Settings->sleep;
|
Light.update = true; // Restore old color
|
||||||
// OK
|
}
|
||||||
ResponseCmndDone();
|
if (1 == XdrvMailbox.payload) {
|
||||||
|
if (!ArtNetStart()) {
|
||||||
|
Settings->flag6.artnet_autorun = false; // SetOption148 - (Light) start DMX ArtNet at boot, listen to UDP port as soon as network is up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ResponseCmndStateText(artnet_udp_connected & Settings->flag6.artnet_autorun);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_LIGHT_ARTNET
|
#endif // USE_LIGHT_ARTNET
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1129,7 +1129,35 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
||||||
{ Zuint8, Cx0500, 0xFFF0 + ZA_GlassBreak, Z_(GlassBreak),Cm1, 0 },
|
{ Zuint8, Cx0500, 0xFFF0 + ZA_GlassBreak, Z_(GlassBreak),Cm1, 0 },
|
||||||
|
|
||||||
// Metering (Smart Energy) cluster
|
// Metering (Smart Energy) cluster
|
||||||
{ Zuint48, Cx0702, 0x0000, Z_(EnergyTotal), Cm1, 0 },
|
{ Zuint48, Cx0702, 0x0000, Z_(CurrentSummationDelivered),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0001, Z_(CurrentSummationReceived),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0002, Z_(CurrentMaxDemandDelivered),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0003, Z_(CurrentMaxDemandReceived),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0004, Z_(DFTSummation), Cm1, 0 },
|
||||||
|
{ Zuint16, Cx0702, 0x0005, Z_(DailyFreezeTime), Cm1, 0 },
|
||||||
|
{ Zint8, Cx0702, 0x0006, Z_(PowerFactor), Cm1, 0 },
|
||||||
|
{ ZUTC, Cx0702, 0x0007, Z_(ReadingSnapShotTime), Cm1, 0 },
|
||||||
|
{ ZUTC, Cx0702, 0x0008, Z_(CurrentMaxDemandDeliveredTime),Cm1, 0 },
|
||||||
|
{ ZUTC, Cx0702, 0x0009, Z_(CurrentMaxDemandReceivedTime),Cm1, 0 },
|
||||||
|
{ Zuint8, Cx0702, 0x000A, Z_(DefaultUpdatePeriod), Cm1, 0 },
|
||||||
|
{ Zuint8, Cx0702, 0x000B, Z_(FastPollUpdatePeriod), Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x000C, Z_(CurrentBlockPeriodConsumptionDelivered),Cm1, 0 },
|
||||||
|
{ Zuint24, Cx0702, 0x000D, Z_(DailyConsumptionTarget),Cm1, 0 },
|
||||||
|
{ Zenum8, Cx0702, 0x000E, Z_(CurrentBlock), Cm1, 0 },
|
||||||
|
{ Zenum8, Cx0702, 0x000F, Z_(ProfileIntervalPeriod),Cm1, 0 },
|
||||||
|
{ Zuint16, Cx0702, 0x0010, Z_(IntervalReadReportingPeriod),Cm1, 0 },
|
||||||
|
{ Zuint16, Cx0702, 0x0011, Z_(PresetReadingTime), Cm1, 0 },
|
||||||
|
{ Zuint16, Cx0702, 0x0012, Z_(VolumePerReport), Cm1, 0 },
|
||||||
|
{ Zuint8, Cx0702, 0x0013, Z_(FlowRestriction), Cm1, 0 },
|
||||||
|
{ Zenum8, Cx0702, 0x0014, Z_(SupplyStatus), Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0015, Z_(CurrentInletEnergyCarrierSummation),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x0016, Z_(CurrentOutletEnergyCarrierSummation),Cm1, 0 },
|
||||||
|
{ Zint24, Cx0702, 0x0017, Z_(InletTemperature), Cm1, 0 },
|
||||||
|
{ Zint24, Cx0702, 0x0018, Z_(OutletTemperature), Cm1, 0 },
|
||||||
|
{ Zint24, Cx0702, 0x0019, Z_(ControlTemperature), Cm1, 0 },
|
||||||
|
{ Zint24, Cx0702, 0x001A, Z_(CurrentInletEnergyCarrierDemand),Cm1, 0 },
|
||||||
|
{ Zint24, Cx0702, 0x001B, Z_(CurrentOutletEnergyCarrierDemand),Cm1, 0 },
|
||||||
|
{ Zuint48, Cx0702, 0x001C, Z_(PreviousBlockPeriodConsumptionDelivered),Cm1, 0 },
|
||||||
|
|
||||||
// Meter Identification cluster
|
// Meter Identification cluster
|
||||||
{ Zstring, Cx0B01, 0x0000, Z_(CompanyName), Cm1, 0 },
|
{ Zstring, Cx0B01, 0x0000, Z_(CompanyName), Cm1, 0 },
|
||||||
|
|
|
@ -717,6 +717,9 @@ void ZCLFrame::applySynonymAttributes(Z_attribute_list& attr_list) {
|
||||||
Z_attribute_synonym syn = Z_plugin_matchAttributeSynonym(device.modelId, device.manufacturerId,
|
Z_attribute_synonym syn = Z_plugin_matchAttributeSynonym(device.modelId, device.manufacturerId,
|
||||||
attr.cluster, attr.attr_id);
|
attr.cluster, attr.attr_id);
|
||||||
if (syn.found()) {
|
if (syn.found()) {
|
||||||
|
if (syn.new_attribute == 0xFFFF) { // if attr is 0xFFFF, remove attribute
|
||||||
|
attr_list.removeAttribute(&attr);
|
||||||
|
} else {
|
||||||
attr.setKeyId(syn.new_cluster, syn.new_attribute);
|
attr.setKeyId(syn.new_cluster, syn.new_attribute);
|
||||||
if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
|
if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
|
||||||
// we need to change the value
|
// we need to change the value
|
||||||
|
@ -735,6 +738,7 @@ void ZCLFrame::applySynonymAttributes(Z_attribute_list& attr_list) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute new attributes based on the standard set
|
// Compute new attributes based on the standard set
|
||||||
|
@ -1189,9 +1193,6 @@ void ZCLFrame::syntheticAnalogValue(Z_attribute_list &attr_list, class Z_attribu
|
||||||
if (modelId.startsWith(F("lumi.sensor_cube"))) {
|
if (modelId.startsWith(F("lumi.sensor_cube"))) {
|
||||||
attr.setKeyId(0x000C, 0xFF55); // change to AqaraRotate
|
attr.setKeyId(0x000C, 0xFF55); // change to AqaraRotate
|
||||||
}
|
}
|
||||||
if (modelId.startsWith(F("lumi.plug"))) {
|
|
||||||
attr.setKeyId(0x0702, 0x0000); // change to EnergyTotal
|
|
||||||
}
|
|
||||||
if (modelId.startsWith(F("lumi.ctrl"))) {
|
if (modelId.startsWith(F("lumi.ctrl"))) {
|
||||||
attr.setKeyId(0x0B04, 0x050B); // change to ActivePower
|
attr.setKeyId(0x0B04, 0x050B); // change to ActivePower
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#define XDRV_23 23
|
#define XDRV_23 23
|
||||||
|
|
||||||
|
// #define ZIGBEE_DOC // enable special functions used for Zigbee documentation generation - generally not useful
|
||||||
|
|
||||||
#include "UnishoxStrings.h"
|
#include "UnishoxStrings.h"
|
||||||
|
|
||||||
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
||||||
|
@ -41,6 +43,9 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
|
||||||
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|" D_CMND_ZIGBEE_LEAVE "|"
|
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|" D_CMND_ZIGBEE_LEAVE "|"
|
||||||
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA "|" D_CMND_ZIGBEE_SCAN "|" D_CMND_ZIGBEE_ENROLL "|" D_CMND_ZIGBEE_CIE "|"
|
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA "|" D_CMND_ZIGBEE_SCAN "|" D_CMND_ZIGBEE_ENROLL "|" D_CMND_ZIGBEE_CIE "|"
|
||||||
D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP
|
D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP
|
||||||
|
#ifdef ZIGBEE_DOC
|
||||||
|
"|" D_CMND_ZIGBEE_ATTRDUMP
|
||||||
|
#endif // ZIGBEE_DOC
|
||||||
;
|
;
|
||||||
|
|
||||||
SO_SYNONYMS(kZbSynonyms,
|
SO_SYNONYMS(kZbSynonyms,
|
||||||
|
@ -64,6 +69,9 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
|
||||||
&CmndZbConfig, &CmndZbData, &CmndZbScan,
|
&CmndZbConfig, &CmndZbData, &CmndZbScan,
|
||||||
&CmndZbenroll, &CmndZbcie,
|
&CmndZbenroll, &CmndZbcie,
|
||||||
&CmndZbLoad, &CmndZbUnload, &CmndZbLoadDump,
|
&CmndZbLoad, &CmndZbUnload, &CmndZbLoadDump,
|
||||||
|
#ifdef ZIGBEE_DOC
|
||||||
|
&CmndZbAttrDump,
|
||||||
|
#endif // ZIGBEE_DOC
|
||||||
};
|
};
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
@ -1119,8 +1127,16 @@ void CmndZbProbe(void) {
|
||||||
//
|
//
|
||||||
void CmndZbProbeOrPing(boolean probe) {
|
void CmndZbProbeOrPing(boolean probe) {
|
||||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload).shortaddr;
|
uint16_t parsed_shortaddr = BAD_SHORTADDR;
|
||||||
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
|
uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, &parsed_shortaddr, nullptr, XdrvMailbox.payload).shortaddr;
|
||||||
|
if (BAD_SHORTADDR == shortaddr) {
|
||||||
|
if (BAD_SHORTADDR == parsed_shortaddr) { // second chance if we provided 0x.... address for a device not in the list
|
||||||
|
ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
shortaddr = parsed_shortaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set a timer for Reachable - 2s default value
|
// set a timer for Reachable - 2s default value
|
||||||
zigbee_devices.setTimer(shortaddr, 0, Z_CAT_REACHABILITY_TIMEOUT, 0, 0, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
zigbee_devices.setTimer(shortaddr, 0, Z_CAT_REACHABILITY_TIMEOUT, 0, 0, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
||||||
|
@ -1417,6 +1433,45 @@ void CmndZbLoadDump(void) {
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZIGBEE_DOC
|
||||||
|
// Command `ZbAttrDump`
|
||||||
|
// Dump all the attribute aliases for documentation purpose
|
||||||
|
//
|
||||||
|
void CmndZbAttrDump(void) {
|
||||||
|
// does not require Zigbee to actually run
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("Alias|Cluster|Attribute|Type"));
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(":---|:---|:---|:---"));
|
||||||
|
for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) {
|
||||||
|
const Z_AttributeConverter *converter = &Z_PostProcess[i];
|
||||||
|
if (0 == pgm_read_word(&converter->name_offset)) { continue; }
|
||||||
|
const char * alias = Z_strings + pgm_read_word(&converter->name_offset);
|
||||||
|
uint16_t cluster = CxToCluster(pgm_read_byte(&converter->cluster_short));
|
||||||
|
uint16_t attrid = pgm_read_word(&converter->attribute);
|
||||||
|
uint8_t attrtype = pgm_read_byte(&converter->type);
|
||||||
|
char type_name[16];
|
||||||
|
Z_getTypeByNumber(type_name, sizeof(type_name), attrtype);
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("`%s`|0x%04X|0x%04X|%%%02X - %s"), alias, cluster, attrid, attrtype, type_name);
|
||||||
|
}
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(""));
|
||||||
|
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("Alias|Cluster|Command"));
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(":---|:---|:---"));
|
||||||
|
for (uint32_t i = 0; i < sizeof(Z_Commands) / sizeof(Z_Commands[0]); i++) {
|
||||||
|
const Z_CommandConverter *conv = &Z_Commands[i];
|
||||||
|
const char * alias = Z_strings + pgm_read_word(&conv->tasmota_cmd_offset);
|
||||||
|
uint16_t cluster = pgm_read_word(&conv->cluster);
|
||||||
|
uint8_t direction = pgm_read_byte(&conv->direction);
|
||||||
|
uint8_t cmd = pgm_read_byte(&conv->cmd);
|
||||||
|
if (direction & 0x01) { // only coordinator to device
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("`%s`|0x%04X|0x%02X"), alias, cluster, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(""));
|
||||||
|
|
||||||
|
ResponseCmndDone();
|
||||||
|
}
|
||||||
|
#endif // ZIGBEE_DOC
|
||||||
|
|
||||||
//
|
//
|
||||||
// Command `ZbScan`
|
// Command `ZbScan`
|
||||||
// Run an energy scan
|
// Run an energy scan
|
||||||
|
|
|
@ -97,10 +97,8 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
|
||||||
"|"
|
"|"
|
||||||
"Port"
|
"Port"
|
||||||
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
|
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
|
||||||
#ifdef ESP32
|
|
||||||
"|"
|
"|"
|
||||||
"Clients"
|
"Clients"
|
||||||
#endif // ESP32
|
|
||||||
"|"
|
"|"
|
||||||
"Address"
|
"Address"
|
||||||
"|"
|
"|"
|
||||||
|
@ -114,9 +112,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
|
||||||
&CmndRgxNAPT,
|
&CmndRgxNAPT,
|
||||||
&CmndRgxPort,
|
&CmndRgxPort,
|
||||||
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
|
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
|
||||||
#ifdef ESP32
|
|
||||||
&CmndRgxClients,
|
&CmndRgxClients,
|
||||||
#endif // ESP32
|
|
||||||
&CmndRgxAddresses,
|
&CmndRgxAddresses,
|
||||||
&CmndRgxAddresses,
|
&CmndRgxAddresses,
|
||||||
};
|
};
|
||||||
|
@ -173,17 +169,18 @@ void RgxCheckConfig(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
void CmndRgxClients(void)
|
void CmndRgxClients(void)
|
||||||
{
|
{
|
||||||
|
Response_P(PSTR("{\"RgxClients\":{"));
|
||||||
|
const char *sep = "";
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
wifi_sta_list_t wifi_sta_list = {0};
|
wifi_sta_list_t wifi_sta_list = {0};
|
||||||
tcpip_adapter_sta_list_t adapter_sta_list = {0};
|
tcpip_adapter_sta_list_t adapter_sta_list = {0};
|
||||||
|
|
||||||
esp_wifi_ap_get_sta_list(&wifi_sta_list);
|
esp_wifi_ap_get_sta_list(&wifi_sta_list);
|
||||||
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
|
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
|
||||||
|
|
||||||
Response_P(PSTR("{\"RgxClients\":{"));
|
|
||||||
const char *sep = "";
|
|
||||||
for (int i=0; i<adapter_sta_list.num; i++)
|
for (int i=0; i<adapter_sta_list.num; i++)
|
||||||
{
|
{
|
||||||
const uint8_t *m = adapter_sta_list.sta[i].mac;
|
const uint8_t *m = adapter_sta_list.sta[i].mac;
|
||||||
|
@ -191,9 +188,21 @@ void CmndRgxClients(void)
|
||||||
sep, m[0], m[1], m[2], m[3], m[4], m[5], adapter_sta_list.sta[i].ip, wifi_sta_list.sta[i].rssi);
|
sep, m[0], m[1], m[2], m[3], m[4], m[5], adapter_sta_list.sta[i].ip, wifi_sta_list.sta[i].rssi);
|
||||||
sep = ",";
|
sep = ",";
|
||||||
}
|
}
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
struct station_info *station = wifi_softap_get_station_info();
|
||||||
|
while (station)
|
||||||
|
{
|
||||||
|
const uint8_t *m = station->bssid;
|
||||||
|
ResponseAppend_P(PSTR("%s\"%02X%02X%02X%02X%02X%02X\":{\"" D_CMND_IPADDRESS "\":\"%_I\"}"),
|
||||||
|
sep, m[0], m[1], m[2], m[3], m[4], m[5], station->ip.addr);
|
||||||
|
sep = ",";
|
||||||
|
station = STAILQ_NEXT(station, next);
|
||||||
|
}
|
||||||
|
wifi_softap_free_station_info();
|
||||||
|
#endif
|
||||||
|
|
||||||
ResponseAppend_P(PSTR("}}"));
|
ResponseAppend_P(PSTR("}}"));
|
||||||
}
|
}
|
||||||
#endif // ESP32
|
|
||||||
|
|
||||||
void CmndRgxState(void)
|
void CmndRgxState(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -785,7 +785,7 @@ void CmndWidth(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Internal calls for Art-Net
|
* Internal calls for ArtNet
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
// check is the Neopixel strip is configured
|
// check is the Neopixel strip is configured
|
||||||
bool Ws2812StripConfigured(void) {
|
bool Ws2812StripConfigured(void) {
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
xsns_101_hmc5883l.ino - HMC5883L 3-Axis Digital Compass sensor support for Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2022 Andreas Achtzehn (inspired by Helge Scheunemann)
|
||||||
|
|
||||||
|
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_HMC5883L
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* HMC5883L is 3-Axis Digital Compass sensor
|
||||||
|
*
|
||||||
|
* Datasheet: https://cdn-shop.adafruit.com/datasheets/HMC5883L_3-Axis_Digital_Compass_IC.pdf
|
||||||
|
* I2C Address: 0x1E
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
// Define driver ID
|
||||||
|
#define XSNS_101 101
|
||||||
|
#define XI2C_73 73 // See I2CDEVICES.md
|
||||||
|
|
||||||
|
/* The default I2C address of this chip */
|
||||||
|
#define HMC5883L_ADDR 0x1E
|
||||||
|
|
||||||
|
/* Register locations */
|
||||||
|
#define HMC5883L_X_LSB 0x04
|
||||||
|
#define HMC5883L_X_MSB 0x03
|
||||||
|
#define HMC5883L_Y_LSB 0x08
|
||||||
|
#define HMC5883L_Y_MSB 0x07
|
||||||
|
#define HMC5883L_Z_LSB 0x06
|
||||||
|
#define HMC5883L_Z_MSB 0x05
|
||||||
|
#define HMC5883L_STATUS 0x09
|
||||||
|
#define HMC5883L_CONFIG_A 0x00
|
||||||
|
#define HMC5883L_CONFIG_B 0x01
|
||||||
|
#define HMC5883L_MODE 0x02
|
||||||
|
#define HMC5883L_CHIP_ID_A 0x0A
|
||||||
|
#define HMC5883L_CHIP_ID_B 0x0B
|
||||||
|
#define HMC5883L_CHIP_ID_C 0x0C
|
||||||
|
|
||||||
|
/* Bit values for the STATUS register */
|
||||||
|
const uint8_t HMC5883L_STATUS_RDY = 0b00000001;
|
||||||
|
const uint8_t HMC5883L_STATUS_LOCK = 0b00000010;
|
||||||
|
|
||||||
|
/* Modes for the sampling in the MODE register */
|
||||||
|
const uint8_t HMC5883L_MODE_CONT = 0b00000000;
|
||||||
|
const uint8_t HMC5883L_MODE_SINGLE = 0b00000001;
|
||||||
|
const uint8_t HMC5883L_MODE_IDLE = 0b00000010;
|
||||||
|
|
||||||
|
/* Gain value mask for CONFIG B register */
|
||||||
|
const uint8_t HMC5883L_CONFIG_B_GAIN_MASK = 0b11100000; // shift operation, values 0-7
|
||||||
|
const uint8_t HMC5883L_CONFIG_B_GAIN_SHIFT = 5;
|
||||||
|
|
||||||
|
/* Averaging value for CONFIG A register: pow(2,N) */
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_AVG_MASK = 0b01100000;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_AVG_SHIFT = 5;
|
||||||
|
|
||||||
|
/* Data output rate */
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_RATE_MASK = 0b00011100;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_RATE_SHIFT = 2;
|
||||||
|
|
||||||
|
/* Data measurement mode */
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_MMODE_NORM = 0;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_MMODE_POSBIAS = 1;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_MMODE_NEGBIAS = 2;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_MMODE_MASK = 0b00000011;
|
||||||
|
const uint8_t HMC5883L_CONFIG_A_MMODE_SHIFT = 0;
|
||||||
|
|
||||||
|
/* Data output X register A contains the MSB from the measurement result,
|
||||||
|
and data output X register B contains the LSB from the measurement result. The value stored in these two registers is a
|
||||||
|
16-bit value in 2’s complement form, whose range is 0xF800 to 0x07FF. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// data field
|
||||||
|
struct HMC5883L_s {
|
||||||
|
int16_t MX, MY, MZ;
|
||||||
|
uint16_t magnitude;
|
||||||
|
int8_t measurement_mode;
|
||||||
|
int8_t data_rate;
|
||||||
|
int8_t average_mode;
|
||||||
|
int8_t gain;
|
||||||
|
int8_t mode;
|
||||||
|
} *HMC5883L = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
// Change configuration registers of the device
|
||||||
|
bool HMC5883L_SetConfig() {
|
||||||
|
if ( HMC5883L == nullptr ) { return false; }
|
||||||
|
|
||||||
|
uint8_t cfgA = (( (HMC5883L->measurement_mode) << HMC5883L_CONFIG_A_MMODE_SHIFT ) & HMC5883L_CONFIG_A_MMODE_MASK ) |
|
||||||
|
(( (HMC5883L->data_rate ) << HMC5883L_CONFIG_A_RATE_SHIFT ) & HMC5883L_CONFIG_A_RATE_MASK ) |
|
||||||
|
(( (HMC5883L->average_mode ) << HMC5883L_CONFIG_A_AVG_SHIFT ) & HMC5883L_CONFIG_A_AVG_MASK );
|
||||||
|
|
||||||
|
uint8_t cfgB = (( (HMC5883L->gain ) << HMC5883L_CONFIG_B_GAIN_SHIFT ) & HMC5883L_CONFIG_B_GAIN_MASK );
|
||||||
|
|
||||||
|
AddLog(LOG_LEVEL_INFO,"HMC: CONFIG A: %#X CONFIG B: %#X MODE: %#X", cfgA, cfgB, HMC5883L->mode);
|
||||||
|
|
||||||
|
if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) {
|
||||||
|
AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG A failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) {
|
||||||
|
AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG B failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (HMC5883L->mode == HMC5883L_MODE_CONT) {
|
||||||
|
if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false) {
|
||||||
|
AddLog(LOG_LEVEL_INFO,"HMC: Setting continuous mode failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the device
|
||||||
|
void HMC5883L_Init() {
|
||||||
|
if (!I2cSetDevice(HMC5883L_ADDR)) { return; }
|
||||||
|
|
||||||
|
HMC5883L = (HMC5883L_s *)calloc(1, sizeof(struct HMC5883L_s));
|
||||||
|
// standard configuration
|
||||||
|
HMC5883L->gain = 5;
|
||||||
|
HMC5883L->average_mode = 3;
|
||||||
|
HMC5883L->data_rate = 2;
|
||||||
|
HMC5883L->measurement_mode = HMC5883L_CONFIG_A_MMODE_NORM;
|
||||||
|
HMC5883L->mode = HMC5883L_MODE_SINGLE;
|
||||||
|
|
||||||
|
HMC5883L_SetConfig();
|
||||||
|
|
||||||
|
I2cSetActiveFound(HMC5883L_ADDR, "HMC5883L");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read the magnetic data
|
||||||
|
void HMC5883L_ReadData(void) {
|
||||||
|
if (HMC5883L->mode == HMC5883L_MODE_SINGLE) {
|
||||||
|
if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = millis() + 20;
|
||||||
|
while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) {
|
||||||
|
if (millis() > timeout) { return; } // Chip not yet ready, next round try again
|
||||||
|
}
|
||||||
|
|
||||||
|
HMC5883L->MX = I2cReadS16(HMC5883L_ADDR, HMC5883L_X_MSB); // Select starting with MSB register
|
||||||
|
HMC5883L->MY = I2cReadS16(HMC5883L_ADDR, HMC5883L_Y_MSB);
|
||||||
|
HMC5883L->MZ = I2cReadS16(HMC5883L_ADDR, HMC5883L_Z_MSB);
|
||||||
|
|
||||||
|
// calculate magnetic induction magnitude
|
||||||
|
HMC5883L->magnitude = SqrtInt((HMC5883L->MX * HMC5883L->MX) + (HMC5883L->MY * HMC5883L->MY) + (HMC5883L->MZ * HMC5883L->MZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Presentation
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
const char HTTP_SNS_HMC5883L[] PROGMEM =
|
||||||
|
"{s}HMC5883L " D_MX "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
"{s}HMC5883L " D_MY "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
"{s}HMC5883L " D_MZ "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
"{s}HMC5883L " D_MAGNETICFLD "{m}%d " D_UNIT_MICROTESLA "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void HMC5883L_Show(uint8_t json) {
|
||||||
|
if (json) {
|
||||||
|
ResponseAppend_P(PSTR(",\"HMC5883L\":{\"" D_JSON_MX "\":%d,\"" D_JSON_MY "\":%d,\"" D_JSON_MZ "\":%d,\"" D_JSON_MAGNETICFLD "\":%u,\""),
|
||||||
|
HMC5883L->MX, HMC5883L->MY, HMC5883L->MZ, HMC5883L->magnitude);
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
} else {
|
||||||
|
WSContentSend_PD(HTTP_SNS_HMC5883L, HMC5883L->MX, HMC5883L->MY, HMC5883L->MZ, HMC5883L->magnitude);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process configuration commands
|
||||||
|
bool HMC5883L_Command() {
|
||||||
|
bool commandKnown = false;
|
||||||
|
char cmd[20];
|
||||||
|
char ss2[20];
|
||||||
|
|
||||||
|
subStr(cmd, XdrvMailbox.data, ",", 1);
|
||||||
|
int8_t value = atoi(subStr(ss2, XdrvMailbox.data, ",", 2));
|
||||||
|
|
||||||
|
if (strcmp(cmd,"GAIN")) {
|
||||||
|
HMC5883L->gain = value;
|
||||||
|
commandKnown = true;
|
||||||
|
}
|
||||||
|
if (strcmp(cmd,"AVG")) {
|
||||||
|
HMC5883L->average_mode = value;
|
||||||
|
commandKnown = true;
|
||||||
|
}
|
||||||
|
if (strcmp(cmd,"RATE")) {
|
||||||
|
HMC5883L->data_rate = value;
|
||||||
|
commandKnown = true;
|
||||||
|
}
|
||||||
|
if (strcmp(cmd,"MMODE")) {
|
||||||
|
HMC5883L->measurement_mode = value;
|
||||||
|
commandKnown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown);
|
||||||
|
|
||||||
|
if (commandKnown == false) { return false; }
|
||||||
|
|
||||||
|
AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: Reconfiguring."));
|
||||||
|
|
||||||
|
return HMC5883L_SetConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xsns101(uint32_t function) {
|
||||||
|
if (!I2cEnabled(XI2C_73)) { return false; }
|
||||||
|
|
||||||
|
if (FUNC_INIT == function) {
|
||||||
|
HMC5883L_Init();
|
||||||
|
}
|
||||||
|
else if (HMC5883L != nullptr) {
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_COMMAND_SENSOR:
|
||||||
|
if (XSNS_101 == XdrvMailbox.index) {
|
||||||
|
return HMC5883L_Command(); // Return true on success
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FUNC_JSON_APPEND:
|
||||||
|
HMC5883L_Show(1);
|
||||||
|
break;
|
||||||
|
case FUNC_EVERY_SECOND:
|
||||||
|
HMC5883L_ReadData();
|
||||||
|
break;
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
case FUNC_WEB_SENSOR:
|
||||||
|
HMC5883L_Show(0);
|
||||||
|
break;
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // USE_HMC5883L
|
||||||
|
#endif // USE_I2C
|
|
@ -0,0 +1,6 @@
|
||||||
|
#Z2Tv1
|
||||||
|
# Aqara Smart Plug EU
|
||||||
|
# https://zigbee.blakadder.com/Aqara_SP-EUC01.html
|
||||||
|
:lumi.plug.*,LUMI
|
||||||
|
0B04/050B=0B04/FFFF # ignore the original ActivePower since it returns always zero
|
||||||
|
000C/0055=0B04/050B
|
|
@ -0,0 +1,5 @@
|
||||||
|
#Z2Tv1
|
||||||
|
# Tuya fix humidity by 10
|
||||||
|
# https://zigbee.blakadder.com/Tuya_KCTW1Z.html
|
||||||
|
:TS0201,_TZ3000_ywagc4rj
|
||||||
|
0405/0000=0405/0000,mul:10
|
|
@ -288,7 +288,7 @@ a_features = [[
|
||||||
],[
|
],[
|
||||||
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
|
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
|
||||||
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
|
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
|
||||||
"USE_DINGTIAN_RELAY","","","",
|
"USE_DINGTIAN_RELAY","USE_HMC5883L","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
|
|
Loading…
Reference in New Issue