Merge branch 'arendst:development' into rgx-preserve-ap-connections-on-sta-reconnect

This commit is contained in:
joba-1 2022-11-16 19:41:59 +01:00 committed by GitHub
commit 552c44425b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1743 additions and 1299 deletions

View File

@ -187,7 +187,7 @@ jobs:
- name: Display structure of downloaded files
run: ls -R ./mv_firmware/
- name: Release
uses: jason2866/action-gh-release@v1.1
uses: jason2866/action-gh-release@v1.2
#if: startsWith(github.ref, 'refs/tags/')
with:
tag_name: ${{ github.run_number }}

View File

@ -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 Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
- 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
@ -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)
- TuyaMcu rewrite by btsimonh (#17051)
- 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
- 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 NTAG2xx tags read and write on PN532 NFC reader (#16939)
- 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
- 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
### Changed
@ -64,7 +71,7 @@ All notable changes to this project will be documented in this file.
- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
- Prepare for DMX Art-Net support on ESP32
- Prepare for DMX ArtNet support on ESP32
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)

View File

@ -107,3 +107,4 @@ Index | Define | Driver | Device | Address(es) | Description
70 | USE_LUXV30B | xsns_99 | LUXV30B | 0x4A | DFRobot SEN0390 V30B lux 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
73 | USE_HMC5883L | xsns_101 | HMC5883L | 0x1E | 3-channels Magnetic Field Sensor

View File

@ -110,6 +110,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.4
### 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 ``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)
- 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)
@ -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 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)
- 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().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- 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
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
- 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)
- 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)
- 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)
- 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
- 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

View File

@ -37,7 +37,7 @@ extern "C" {
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) {
IPAddress addr((uint32_t)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");
}
// 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
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
IPAddress addr((uint32_t)0);
@ -159,6 +167,7 @@ class be_class_udp (scope: global, name: udp) {
begin, func(be_udp_begin)
begin_multicast, func(be_udp_begin_mcast)
read, func(be_udp_read)
close, func(be_udp_stop)
}
@const_object_info_end */

View File

@ -1,6 +1,6 @@
{
"name": "lvgl",
"version": "8.3.2",
"version": "8.3.3",
"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.",
"repository": {

View File

@ -1,5 +1,5 @@
name=lvgl
version=8.3.2
version=8.3.3
author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems

View File

@ -1,6 +1,6 @@
/**
* @file lv_conf.h
* Configuration file for v8.3.2
* Configuration file for v8.3.3
*/
/*

View File

@ -15,7 +15,7 @@ extern "C" {
***************************/
#define LVGL_VERSION_MAJOR 8
#define LVGL_VERSION_MINOR 3
#define LVGL_VERSION_PATCH 1
#define LVGL_VERSION_PATCH 3
#define LVGL_VERSION_INFO ""
/*********************

View File

@ -502,8 +502,7 @@
#define D_CMND_PALETTE "Palette"
#define D_CMND_PIXELS "Pixels"
#define D_CMND_STEPPIXELS "StepPixels"
#define D_CMND_ARTNET_START "ArtNetStart"
#define D_CMND_ARTNET_STOP "ArtNetStop"
#define D_CMND_ARTNET "ArtNet"
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
#define D_CMND_RGBWWTABLE "RGBWWTable"
@ -689,6 +688,7 @@
#define D_CMND_ZIGBEE_LOAD "Load"
#define D_CMND_ZIGBEE_LOADDUMP "LoadDump"
#define D_CMND_ZIGBEE_UNLOAD "Unload"
#define D_CMND_ZIGBEE_ATTRDUMP "AttrDump"
// Commands xdrv_25_A4988_Stepper.ino
#define D_CMND_MOTOR "MOTOR"

View File

@ -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 SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI,
FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, PUSHON, PUSHON_INV, PUSH_IGNORE, MAX_SWITCH_OPTION};
enum SwitchModeOptions {TOGGLE, // 0
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};

View File

@ -559,6 +559,7 @@
#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_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)

View File

@ -571,7 +571,7 @@
#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_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
// -- Counter input -------------------------------
@ -691,6 +691,7 @@
// #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_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 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

View File

@ -852,7 +852,9 @@ void ResponseAppendFeatures(void)
#ifdef USE_DINGTIAN_RELAY
feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino
#endif
// feature9 |= 0x00000200;
#if defined(USE_I2C) && defined(USE_HMC5883L)
feature9 |= 0x00000200; // xsns_101_hmc5883l.ino
#endif
// feature9 |= 0x00000400;
// feature9 |= 0x00000800;

View File

@ -409,6 +409,9 @@ void SwitchHandler(uint32_t mode) {
Switch.last_state[i] = button; // Update switch state before publishing
MqttPublishSensor();
break;
case PUSH_IGNORE_INV:
MqttPublishSensor(); // Publishing before update
break;
}
Switch.last_state[i] = button;
}

View File

@ -151,7 +151,7 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
"|" D_CMND_SEQUENCE_OFFSET
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
"|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
"|" D_CMND_ARTNET "|" D_CMND_ARTNET_CONFIG
#endif
"|UNDOCA" ;
@ -175,7 +175,7 @@ void (* const LightCommand[])(void) PROGMEM = {
&CmndSequenceOffset,
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
&CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
&CmndArtNet, &CmndArtNetConfig,
#endif
&CmndUndocA };
@ -1962,7 +1962,7 @@ void LightAnimate(void)
Light.fade_start_10[channel_ct] = Light.fade_end_10[channel_ct];
}
}
Light.fade_running = true;
Light.fade_duration = 0; // set the value to zero to force a recompute
Light.fade_start = 0;

View File

@ -145,9 +145,9 @@ void ArtNetProcessPacket(uint8_t * buf, size_t len) {
if (artnet_conf.matrix) {
// Ws2812 led strip
size_t pix_size = Ws2812StripGetPixelSize();
size_t pix_size = Ws2812StripGetPixelSize();
datalen = datalen - (datalen % pix_size);
if (artnet_conf.alt && (row % 2)) {
for (int32_t i = idx, j = idx + datalen - pix_size; i < j; i += pix_size, j -= pix_size) {
for (int32_t k = 0; k < pix_size; k++) {
@ -223,9 +223,9 @@ void ArtNetLoop(void)
packet_len = ArtNetUdp->parsePacket();
packet_ready = (packet_len > 0);
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
#endif
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet %*_H (%d)"), 32, packet_buffer, packet_len);
@ -237,7 +237,7 @@ void ArtNetLoop(void)
packet_ready = ArtNetUdp->next();
if (!packet_ready) {
// if no more incoming packet, still wait for 20 microseconds
delay(1); // delayMicroseconds seems broken, need to
delay(1); // delayMicroseconds seems broken, need to
packet_ready = ArtNetUdp->next();
}
#else
@ -291,13 +291,13 @@ void CmndArtNetConfig() {
ArtNetStop();
}
ArtNetLoadSettings();
TrimSpace(XdrvMailbox.data);
if (strlen(XdrvMailbox.data) > 0) {
JsonParser parser(XdrvMailbox.data);
JsonParserObject root = parser.getRootObject();
if (!root) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
artnet_conf.rows = root.getUInt(PSTR("Rows"), artnet_conf.rows);
artnet_conf.cols = root.getUInt(PSTR("Cols"), artnet_conf.cols);
artnet_conf.offs = root.getUInt(PSTR("Offset"), artnet_conf.offs);
@ -381,18 +381,6 @@ bool ArtNetStart(void) {
return true;
}
//
// Command `ArtNetStart`
// Params: XXX
//
void CmndArtNetStart(void) {
if (ArtNetStart()) {
ResponseCmndDone();
} else {
ResponseCmndError();
}
}
// Stop the ArtNet UDP flow and disconnect server
void ArtNetStop(void) {
artnet_udp_connected = false;
@ -411,14 +399,20 @@ void ArtNetStop(void) {
}
}
void CmndArtNetStop(void) {
ArtNetStop();
// restore default scheme
Settings->light_scheme = LS_POWER;
// Restore sleep value
TasmotaGlobal.sleep = Settings->sleep;
// OK
ResponseCmndDone();
void CmndArtNet(void) {
if (0 == XdrvMailbox.payload) {
ArtNetStop();
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; // restore default scheme
TasmotaGlobal.sleep = Settings->sleep; // Restore sleep value
Light.update = true; // Restore old color
}
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

File diff suppressed because it is too large Load Diff

View File

@ -1129,7 +1129,35 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
{ Zuint8, Cx0500, 0xFFF0 + ZA_GlassBreak, Z_(GlassBreak),Cm1, 0 },
// 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
{ Zstring, Cx0B01, 0x0000, Z_(CompanyName), Cm1, 0 },

View File

@ -717,20 +717,24 @@ void ZCLFrame::applySynonymAttributes(Z_attribute_list& attr_list) {
Z_attribute_synonym syn = Z_plugin_matchAttributeSynonym(device.modelId, device.manufacturerId,
attr.cluster, attr.attr_id);
if (syn.found()) {
attr.setKeyId(syn.new_cluster, syn.new_attribute);
if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
// we need to change the value
float fval = attr.getFloat();
if (syn.multiplier != 1 && syn.multiplier != 0) {
fval = fval * syn.multiplier;
if (syn.new_attribute == 0xFFFF) { // if attr is 0xFFFF, remove attribute
attr_list.removeAttribute(&attr);
} else {
attr.setKeyId(syn.new_cluster, syn.new_attribute);
if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
// we need to change the value
float fval = attr.getFloat();
if (syn.multiplier != 1 && syn.multiplier != 0) {
fval = fval * syn.multiplier;
}
if (syn.divider != 1 && syn.divider != 0) {
fval = fval / syn.divider;
}
if (syn.base != 0) {
fval = fval + syn.base;
}
attr.setFloat(fval);
}
if (syn.divider != 1 && syn.divider != 0) {
fval = fval / syn.divider;
}
if (syn.base != 0) {
fval = fval + syn.base;
}
attr.setFloat(fval);
}
}
}
@ -1189,9 +1193,6 @@ void ZCLFrame::syntheticAnalogValue(Z_attribute_list &attr_list, class Z_attribu
if (modelId.startsWith(F("lumi.sensor_cube"))) {
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"))) {
attr.setKeyId(0x0B04, 0x050B); // change to ActivePower
}

View File

@ -21,6 +21,8 @@
#define XDRV_23 23
// #define ZIGBEE_DOC // enable special functions used for Zigbee documentation generation - generally not useful
#include "UnishoxStrings.h"
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_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
#ifdef ZIGBEE_DOC
"|" D_CMND_ZIGBEE_ATTRDUMP
#endif // ZIGBEE_DOC
;
SO_SYNONYMS(kZbSynonyms,
@ -64,6 +69,9 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
&CmndZbConfig, &CmndZbData, &CmndZbScan,
&CmndZbenroll, &CmndZbcie,
&CmndZbLoad, &CmndZbUnload, &CmndZbLoadDump,
#ifdef ZIGBEE_DOC
&CmndZbAttrDump,
#endif // ZIGBEE_DOC
};
/********************************************************************************************/
@ -1119,8 +1127,16 @@ void CmndZbProbe(void) {
//
void CmndZbProbeOrPing(boolean probe) {
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;
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
uint16_t parsed_shortaddr = BAD_SHORTADDR;
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
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();
}
#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`
// Run an energy scan

View File

@ -97,10 +97,8 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
"|"
"Port"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
#ifdef ESP32
"|"
"Clients"
#endif // ESP32
"|"
"Address"
"|"
@ -114,9 +112,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
&CmndRgxNAPT,
&CmndRgxPort,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
#ifdef ESP32
&CmndRgxClients,
#endif // ESP32
&CmndRgxAddresses,
&CmndRgxAddresses,
};
@ -173,17 +169,18 @@ void RgxCheckConfig(void)
}
}
#ifdef ESP32
void CmndRgxClients(void)
{
Response_P(PSTR("{\"RgxClients\":{"));
const char *sep = "";
#if defined(ESP32)
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
esp_wifi_ap_get_sta_list(&wifi_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++)
{
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 = ",";
}
#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("}}"));
}
#endif // ESP32
void CmndRgxState(void)
{

View File

@ -785,7 +785,7 @@ void CmndWidth(void)
}
/*********************************************************************************************\
* Internal calls for Art-Net
* Internal calls for ArtNet
\*********************************************************************************************/
// check is the Neopixel strip is configured
bool Ws2812StripConfigured(void) {

View File

@ -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 2s 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

View File

@ -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

View File

@ -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

View File

@ -288,7 +288,7 @@ a_features = [[
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
"USE_DINGTIAN_RELAY","","","",
"USE_DINGTIAN_RELAY","USE_HMC5883L","","",
"","","","",
"","","","",
"","","","",