mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' into dingtian_driver
This commit is contained in:
commit
b03476ff6f
30
CHANGELOG.md
30
CHANGELOG.md
|
@ -3,19 +3,43 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [Unreleased] - Development
|
## [Unreleased] - Development
|
||||||
|
|
||||||
## [12.2.0.2]
|
## [12.2.0.3]
|
||||||
### Added
|
### Added
|
||||||
|
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Prepare for extended calibration and move some persistent data (PowerLow)
|
|
||||||
- Tasmota ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
## [12.2.0.2] 20221107
|
||||||
|
### Added
|
||||||
|
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
|
||||||
|
- 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 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 ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
|
||||||
|
- Berry add ``dyn`` class
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Move some persistent data (PowerLow)
|
||||||
|
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
|
||||||
|
- ADE7953 monitoring from instant power to accumulated energy (#16941)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
|
||||||
|
- Serial initialization for baudrate and config (#16970)
|
||||||
|
- ModbusBridge buffer overflow (#16979)
|
||||||
|
- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
|
||||||
|
|
||||||
## [12.2.0.1] 20221026
|
## [12.2.0.1] 20221026
|
||||||
### Added
|
### Added
|
||||||
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
|
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
|
||||||
|
|
|
@ -107,22 +107,37 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||||
|
|
||||||
[Complete list](BUILDS.md) of available feature and sensors.
|
[Complete list](BUILDS.md) of available feature and sensors.
|
||||||
|
|
||||||
## Changelog v12.2.0.2
|
## Changelog v12.2.0.3
|
||||||
### 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
|
||||||
|
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
||||||
- 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 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)
|
||||||
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
|
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
|
||||||
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
|
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
|
||||||
|
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
|
||||||
|
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
|
||||||
|
- 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)
|
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
|
||||||
|
- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
|
||||||
- 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)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
|
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
|
||||||
|
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
|
||||||
|
- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
|
||||||
|
- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
|
||||||
|
- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
|
||||||
|
|
|
@ -95,7 +95,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
|
||||||
void TasmotaSerial::end(bool turnOffDebug) {
|
void TasmotaSerial::end(bool turnOffDebug) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (m_hardserial) {
|
if (m_hardserial) {
|
||||||
Serial.end();
|
// Serial.end(); // Keep active for logging
|
||||||
} else {
|
} else {
|
||||||
if (m_rx_pin > -1) {
|
if (m_rx_pin > -1) {
|
||||||
detachInterrupt(m_rx_pin);
|
detachInterrupt(m_rx_pin);
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "esp_camera.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Uninitialize the lcd_cam module
|
|
||||||
*
|
|
||||||
* @param handle Provide handle pointer to release resources
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK Success
|
|
||||||
* - ESP_FAIL Uninitialize fail
|
|
||||||
*/
|
|
||||||
esp_err_t cam_deinit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the lcd_cam module
|
|
||||||
*
|
|
||||||
* @param config Configurations - see lcd_cam_config_t struct
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* - ESP_OK Success
|
|
||||||
* - ESP_ERR_INVALID_ARG Parameter error
|
|
||||||
* - ESP_ERR_NO_MEM No memory to initialize lcd_cam
|
|
||||||
* - ESP_FAIL Initialize fail
|
|
||||||
*/
|
|
||||||
esp_err_t cam_init(const camera_config_t *config);
|
|
||||||
|
|
||||||
esp_err_t cam_config(const camera_config_t *config, framesize_t frame_size, uint16_t sensor_pid);
|
|
||||||
|
|
||||||
void cam_stop(void);
|
|
||||||
|
|
||||||
void cam_start(void);
|
|
||||||
|
|
||||||
camera_fb_t *cam_take(TickType_t timeout);
|
|
||||||
|
|
||||||
void cam_give(camera_fb_t *dma_buffer);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -166,7 +166,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
||||||
#ifdef USE_ALEXA_AVS
|
#ifdef USE_ALEXA_AVS
|
||||||
&be_native_module(crypto),
|
&be_native_module(crypto),
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
|
#if defined(USE_BERRY_ULP) && ((CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
|
||||||
&be_native_module(ULP),
|
&be_native_module(ULP),
|
||||||
#endif // USE_BERRY_ULP
|
#endif // USE_BERRY_ULP
|
||||||
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
|
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
|
||||||
|
@ -178,6 +178,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
||||||
NULL /* do not remove */
|
NULL /* do not remove */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
be_extern_native_class(dyn);
|
||||||
be_extern_native_class(tasmota);
|
be_extern_native_class(tasmota);
|
||||||
be_extern_native_class(Trigger);
|
be_extern_native_class(Trigger);
|
||||||
be_extern_native_class(Driver);
|
be_extern_native_class(Driver);
|
||||||
|
@ -228,6 +229,7 @@ be_extern_native_class(int64);
|
||||||
BERRY_LOCAL bclass_array be_class_table = {
|
BERRY_LOCAL bclass_array be_class_table = {
|
||||||
#ifdef TASMOTA
|
#ifdef TASMOTA
|
||||||
/* first list are direct classes */
|
/* first list are direct classes */
|
||||||
|
&be_native_class(dyn),
|
||||||
&be_native_class(tasmota),
|
&be_native_class(tasmota),
|
||||||
&be_native_class(Trigger),
|
&be_native_class(Trigger),
|
||||||
&be_native_class(Driver),
|
&be_native_class(Driver),
|
||||||
|
|
|
@ -957,7 +957,6 @@ static int m_setfloat(bvm *vm)
|
||||||
* `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
|
* `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
|
||||||
static int m_setbytes(bvm *vm)
|
static int m_setbytes(bvm *vm)
|
||||||
{
|
{
|
||||||
int argc = be_top(vm);
|
int argc = be_top(vm);
|
||||||
|
@ -968,7 +967,7 @@ static int m_setbytes(bvm *vm)
|
||||||
size_t from_len_total;
|
size_t from_len_total;
|
||||||
const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
|
const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
|
||||||
if (idx < 0) { idx = 0; }
|
if (idx < 0) { idx = 0; }
|
||||||
if ((size_t)idx >= attr.len) { idx = attr.len; }
|
if (idx >= attr.len) { idx = attr.len; }
|
||||||
|
|
||||||
int32_t from_byte = 0;
|
int32_t from_byte = 0;
|
||||||
if (argc >= 4 && be_isint(vm, 4)) {
|
if (argc >= 4 && be_isint(vm, 4)) {
|
||||||
|
@ -981,9 +980,9 @@ static int m_setbytes(bvm *vm)
|
||||||
if (argc >= 5 && be_isint(vm, 5)) {
|
if (argc >= 5 && be_isint(vm, 5)) {
|
||||||
from_len = be_toint(vm, 5);
|
from_len = be_toint(vm, 5);
|
||||||
if (from_len < 0) { from_len = 0; }
|
if (from_len < 0) { from_len = 0; }
|
||||||
if (from_len >= from_len_total) { from_len = from_len_total; }
|
if (from_len >= (int32_t)from_len_total) { from_len = from_len_total; }
|
||||||
}
|
}
|
||||||
if ((size_t) idx + (size_t)from_len >= attr.len) { from_len = attr.len - idx; }
|
if (idx + from_len >= attr.len) { from_len = attr.len - idx; }
|
||||||
|
|
||||||
// all parameters ok
|
// all parameters ok
|
||||||
if (from_len > 0) {
|
if (from_len > 0) {
|
||||||
|
@ -993,6 +992,66 @@ static int m_setbytes(bvm *vm)
|
||||||
be_return_nil(vm);
|
be_return_nil(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reverses in-place a sub-buffer composed of groups of n-bytes packets
|
||||||
|
*
|
||||||
|
* This is useful for pixel manipulation when displaying RGB pixels
|
||||||
|
*
|
||||||
|
* `reverse([index:int, len:int, grouplen:int]) -> self`
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int m_reverse(bvm *vm)
|
||||||
|
{
|
||||||
|
int argc = be_top(vm);
|
||||||
|
buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
|
||||||
|
check_ptr(vm, &attr);
|
||||||
|
|
||||||
|
int32_t idx = 0; /* start from index 0 */
|
||||||
|
int32_t len = attr.len; /* entire len */
|
||||||
|
int32_t grouplen = 1; /* default to 1-byte group */
|
||||||
|
|
||||||
|
if (argc >= 2 && be_isint(vm, 2)) {
|
||||||
|
idx = be_toint(vm, 2);
|
||||||
|
if (idx < 0) { idx = 0; } /* railguards */
|
||||||
|
if (idx > attr.len) { idx = attr.len; }
|
||||||
|
}
|
||||||
|
if (argc >= 3 && be_isint(vm, 3)) {
|
||||||
|
len = be_toint(vm, 3);
|
||||||
|
if (len < 0) { len = attr.len - idx; } /* negative len means */
|
||||||
|
}
|
||||||
|
if (idx + len >= attr.len) { len = attr.len - idx; }
|
||||||
|
|
||||||
|
// truncate len to multiple of grouplen
|
||||||
|
if (argc >= 4 && be_isint(vm, 4)) {
|
||||||
|
grouplen = be_toint(vm, 4);
|
||||||
|
if (grouplen <= 0) { grouplen = 1; }
|
||||||
|
}
|
||||||
|
len = len - (len % grouplen);
|
||||||
|
|
||||||
|
// apply reverse
|
||||||
|
if (len > 0) {
|
||||||
|
if (grouplen == 1) {
|
||||||
|
/* fast version if simple byte inversion */
|
||||||
|
for (int32_t i = idx, j = idx + len -1; i < j; i++, j--) {
|
||||||
|
uint8_t temp = attr.bufptr[i];
|
||||||
|
attr.bufptr[i] = attr.bufptr[j];
|
||||||
|
attr.bufptr[j] = temp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int32_t i = idx, j = idx + len - grouplen; i < j; i += grouplen, j -= grouplen) {
|
||||||
|
for (int32_t k = 0; k < grouplen; k++) {
|
||||||
|
uint8_t temp = attr.bufptr[i+k];
|
||||||
|
attr.bufptr[i+k] = attr.bufptr[j+k];
|
||||||
|
attr.bufptr[j+k] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_pushvalue(vm, 1); /* push bytes object */
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
|
||||||
static int m_setitem(bvm *vm)
|
static int m_setitem(bvm *vm)
|
||||||
{
|
{
|
||||||
int argc = be_top(vm);
|
int argc = be_top(vm);
|
||||||
|
@ -1627,6 +1686,7 @@ void be_load_byteslib(bvm *vm)
|
||||||
{ "size", m_size },
|
{ "size", m_size },
|
||||||
{ "resize", m_resize },
|
{ "resize", m_resize },
|
||||||
{ "clear", m_clear },
|
{ "clear", m_clear },
|
||||||
|
{ "reverse", m_reverse },
|
||||||
{ "copy", m_copy },
|
{ "copy", m_copy },
|
||||||
{ "+", m_merge },
|
{ "+", m_merge },
|
||||||
{ "..", m_connect },
|
{ "..", m_connect },
|
||||||
|
@ -1672,6 +1732,7 @@ class be_class_bytes (scope: global, name: bytes) {
|
||||||
size, func(m_size)
|
size, func(m_size)
|
||||||
resize, func(m_resize)
|
resize, func(m_resize)
|
||||||
clear, func(m_clear)
|
clear, func(m_clear)
|
||||||
|
reverse, func(m_reverse)
|
||||||
copy, func(m_copy)
|
copy, func(m_copy)
|
||||||
+, func(m_merge)
|
+, func(m_merge)
|
||||||
.., func(m_connect)
|
.., func(m_connect)
|
||||||
|
|
|
@ -225,3 +225,26 @@ assert(a == bytes('112233445566CCDD99'))
|
||||||
a = b.copy()
|
a = b.copy()
|
||||||
a.setbytes(0, a0)
|
a.setbytes(0, a0)
|
||||||
assert(a == bytes('112233445566'))
|
assert(a == bytes('112233445566'))
|
||||||
|
|
||||||
|
# reverse
|
||||||
|
assert(bytes().reverse() == bytes())
|
||||||
|
assert(bytes("AA").reverse() == bytes("AA"))
|
||||||
|
assert(bytes("1122334455").reverse() == bytes("5544332211"))
|
||||||
|
assert(bytes("11223344").reverse() == bytes("44332211"))
|
||||||
|
|
||||||
|
assert(bytes("0011223344").reverse(1) == bytes("0044332211"))
|
||||||
|
assert(bytes("0011223344").reverse(3) == bytes("0011224433"))
|
||||||
|
assert(bytes("0011223344").reverse(4) == bytes("0011223344"))
|
||||||
|
assert(bytes("0011223344").reverse(5) == bytes("0011223344"))
|
||||||
|
assert(bytes("0011223344").reverse(15) == bytes("0011223344"))
|
||||||
|
assert(bytes("0011223344").reverse(-2) == bytes("4433221100"))
|
||||||
|
|
||||||
|
assert(bytes("0011223344").reverse(1,3) == bytes("0033221144"))
|
||||||
|
assert(bytes("0011223344").reverse(1,0) == bytes("0011223344"))
|
||||||
|
assert(bytes("0011223344").reverse(2,2) == bytes("0011332244"))
|
||||||
|
assert(bytes("0011223344").reverse(0,2) == bytes("1100223344"))
|
||||||
|
assert(bytes("0011223344").reverse(nil,2) == bytes("1100223344"))
|
||||||
|
assert(bytes("0011223344").reverse(1, nil) == bytes("0044332211"))
|
||||||
|
|
||||||
|
assert(bytes("0011223344").reverse(nil, nil, 2) == bytes("2233001144"))
|
||||||
|
assert(bytes("001122334455").reverse(nil, nil, 3) == bytes("334455001122"))
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
#include "be_constobj.h"
|
#include "be_constobj.h"
|
||||||
#include "be_mapping.h"
|
#include "be_mapping.h"
|
||||||
|
|
||||||
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
|
#if defined(USE_BERRY_ULP) && (defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
|
||||||
|
|
||||||
#include "esp32/ulp.h"
|
// #include "esp32/ulp.h"
|
||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
@ -37,8 +37,6 @@ BE_FUNC_CTYPE_DECLARE(be_ULP_sleep, "", "[i]"); // optional int arg
|
||||||
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
|
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
|
||||||
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
|
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
|
||||||
|
|
||||||
#include "be_fixed_ULP.h"
|
|
||||||
|
|
||||||
/* @const_object_info_begin
|
/* @const_object_info_begin
|
||||||
module ULP (scope: global) {
|
module ULP (scope: global) {
|
||||||
run, ctype_func(be_ULP_run)
|
run, ctype_func(be_ULP_run)
|
||||||
|
@ -51,5 +49,6 @@ module ULP (scope: global) {
|
||||||
adc_config, ctype_func(be_ULP_adc_config)
|
adc_config, ctype_func(be_ULP_adc_config)
|
||||||
}
|
}
|
||||||
@const_object_info_end */
|
@const_object_info_end */
|
||||||
|
#include "be_fixed_ULP.h"
|
||||||
|
|
||||||
#endif // USE_BERRY_ULP
|
#endif // USE_BERRY_ULP
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Tasmota dyn class
|
||||||
|
*******************************************************************/
|
||||||
|
#include "solidify/solidified_dyn.h"
|
|
@ -94,10 +94,30 @@ extern "C" {
|
||||||
int32_t be_udp_read(struct bvm *vm) {
|
int32_t be_udp_read(struct bvm *vm) {
|
||||||
WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL);
|
WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL);
|
||||||
if (udp->parsePacket()) {
|
if (udp->parsePacket()) {
|
||||||
int btr = udp->available();
|
int btr = udp->available(); // btr contains the size of bytes_to_read
|
||||||
uint8_t * buf = (uint8_t*) be_pushbuffer(vm, btr);
|
|
||||||
|
int argc = be_top(vm);
|
||||||
|
if (argc >= 2 && be_isbytes(vm, 2)) {
|
||||||
|
// we have already a bytes() buffer
|
||||||
|
be_pushvalue(vm, 2); // push on top
|
||||||
|
// resize to btr
|
||||||
|
be_getmember(vm, -1, "resize");
|
||||||
|
be_pushvalue(vm, -2);
|
||||||
|
be_pushint(vm, btr);
|
||||||
|
be_call(vm, 2);
|
||||||
|
be_pop(vm, 3);
|
||||||
|
} else {
|
||||||
|
be_pushbytes(vm, nullptr, btr); // allocate a buffer of size btr filled with zeros
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the address of the buffer
|
||||||
|
be_getmember(vm, -1, "_buffer");
|
||||||
|
be_pushvalue(vm, -2);
|
||||||
|
be_call(vm, 1);
|
||||||
|
uint8_t * buf = (uint8_t*) be_tocomptr(vm, -2);
|
||||||
|
be_pop(vm, 2);
|
||||||
|
|
||||||
int32_t btr2 = udp->read(buf, btr);
|
int32_t btr2 = udp->read(buf, btr);
|
||||||
be_pushbytes(vm, buf, btr2);
|
|
||||||
|
|
||||||
// set remotet ip
|
// set remotet ip
|
||||||
IPAddress remote_ip = udp->remoteIP();
|
IPAddress remote_ip = udp->remoteIP();
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#################################################################################
|
||||||
|
# dyn class
|
||||||
|
#
|
||||||
|
# Allows to use a map with members
|
||||||
|
# see https://github.com/berry-lang/berry/wiki/Chapter-8
|
||||||
|
#################################################################################
|
||||||
|
#@ solidify:dyn
|
||||||
|
class dyn
|
||||||
|
var _attr
|
||||||
|
def init()
|
||||||
|
self._attr = {}
|
||||||
|
end
|
||||||
|
def setmember(name, value)
|
||||||
|
self._attr[name] = value
|
||||||
|
end
|
||||||
|
def member(name)
|
||||||
|
if self._attr.contains(name)
|
||||||
|
return self._attr[name]
|
||||||
|
else
|
||||||
|
import undefined
|
||||||
|
return undefined
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def tostring()
|
||||||
|
return self._attr.tostring()
|
||||||
|
end
|
||||||
|
end
|
|
@ -117,8 +117,14 @@ class Leds : Leds_ntv
|
||||||
def dirty()
|
def dirty()
|
||||||
self.call_native(5)
|
self.call_native(5)
|
||||||
end
|
end
|
||||||
def pixels_buffer()
|
def pixels_buffer(old_buf)
|
||||||
return self.call_native(6)
|
var buf = self.call_native(6) # address of buffer in memory
|
||||||
|
if old_buf == nil
|
||||||
|
return bytes(buf, self.pixel_size() * self.pixel_count())
|
||||||
|
else
|
||||||
|
old_buf._change_buffer(buf)
|
||||||
|
return old_buf
|
||||||
|
end
|
||||||
end
|
end
|
||||||
def pixel_size()
|
def pixel_size()
|
||||||
return self.call_native(7)
|
return self.call_native(7)
|
||||||
|
@ -275,7 +281,7 @@ class Leds : Leds_ntv
|
||||||
# don't trigger on segment, you will need to trigger on full strip instead
|
# don't trigger on segment, you will need to trigger on full strip instead
|
||||||
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
|
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
|
||||||
self.strip.show()
|
self.strip.show()
|
||||||
self.pix_buffer = self.strip.pixels_buffer() # update buffer after show()
|
self.pix_buffer = self.strip.pixels_buffer(self.pix_buffer) # update buffer after show()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
def can_show()
|
def can_show()
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
/* Solidification of dyn.h */
|
||||||
|
/********************************************************************\
|
||||||
|
* Generated code, don't edit *
|
||||||
|
\********************************************************************/
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: tostring
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_tostring, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
3, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 2]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
/* K1 */ be_nested_str(tostring),
|
||||||
|
}),
|
||||||
|
&be_const_str_tostring,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 4]) { /* code */
|
||||||
|
0x88040100, // 0000 GETMBR R1 R0 K0
|
||||||
|
0x8C040301, // 0001 GETMET R1 R1 K1
|
||||||
|
0x7C040200, // 0002 CALL R1 1
|
||||||
|
0x80040200, // 0003 RET 1 R1
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: member
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_member, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
5, /* nstack */
|
||||||
|
2, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 3]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
/* K1 */ be_nested_str(contains),
|
||||||
|
/* K2 */ be_nested_str(undefined),
|
||||||
|
}),
|
||||||
|
&be_const_str_member,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[12]) { /* code */
|
||||||
|
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||||
|
0x8C080501, // 0001 GETMET R2 R2 K1
|
||||||
|
0x5C100200, // 0002 MOVE R4 R1
|
||||||
|
0x7C080400, // 0003 CALL R2 2
|
||||||
|
0x780A0003, // 0004 JMPF R2 #0009
|
||||||
|
0x88080100, // 0005 GETMBR R2 R0 K0
|
||||||
|
0x94080401, // 0006 GETIDX R2 R2 R1
|
||||||
|
0x80040400, // 0007 RET 1 R2
|
||||||
|
0x70020001, // 0008 JMP #000B
|
||||||
|
0xA40A0400, // 0009 IMPORT R2 K2
|
||||||
|
0x80040400, // 000A RET 1 R2
|
||||||
|
0x80000000, // 000B RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: setmember
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_setmember, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
4, /* nstack */
|
||||||
|
3, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 1]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
}),
|
||||||
|
&be_const_str_setmember,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 3]) { /* code */
|
||||||
|
0x880C0100, // 0000 GETMBR R3 R0 K0
|
||||||
|
0x980C0202, // 0001 SETIDX R3 R1 R2
|
||||||
|
0x80000000, // 0002 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: init
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_init, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
2, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 1]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
}),
|
||||||
|
&be_const_str_init,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 4]) { /* code */
|
||||||
|
0x60040013, // 0000 GETGBL R1 G19
|
||||||
|
0x7C040000, // 0001 CALL R1 0
|
||||||
|
0x90020001, // 0002 SETMBR R0 K0 R1
|
||||||
|
0x80000000, // 0003 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified class: dyn
|
||||||
|
********************************************************************/
|
||||||
|
be_local_class(dyn,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
be_nested_map(5,
|
||||||
|
( (struct bmapnode*) &(const bmapnode[]) {
|
||||||
|
{ be_const_key(tostring, 2), be_const_closure(dyn_tostring_closure) },
|
||||||
|
{ be_const_key(member, 3), be_const_closure(dyn_member_closure) },
|
||||||
|
{ be_const_key(init, 4), be_const_closure(dyn_init_closure) },
|
||||||
|
{ be_const_key(setmember, -1), be_const_closure(dyn_setmember_closure) },
|
||||||
|
{ be_const_key(_attr, -1), be_const_var(0) },
|
||||||
|
})),
|
||||||
|
(bstring*) &be_const_str_dyn
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
void be_load_dyn_class(bvm *vm) {
|
||||||
|
be_pushntvclass(vm, &be_class_dyn);
|
||||||
|
be_setglobal(vm, "dyn");
|
||||||
|
be_pop(vm, 1);
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/* End of solidification */
|
|
@ -1118,7 +1118,7 @@ be_local_closure(Leds_matrix_pixel_count, /* name */
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
be_local_closure(Leds_matrix_show, /* name */
|
be_local_closure(Leds_matrix_show, /* name */
|
||||||
be_nested_proto(
|
be_nested_proto(
|
||||||
4, /* nstack */
|
5, /* nstack */
|
||||||
2, /* argc */
|
2, /* argc */
|
||||||
2, /* varg */
|
2, /* varg */
|
||||||
0, /* has upvals */
|
0, /* has upvals */
|
||||||
|
@ -1139,29 +1139,30 @@ be_local_closure(Leds_matrix_show, /* name */
|
||||||
}),
|
}),
|
||||||
&be_const_str_show,
|
&be_const_str_show,
|
||||||
&be_const_str_solidified,
|
&be_const_str_solidified,
|
||||||
( &(const binstruction[22]) { /* code */
|
( &(const binstruction[23]) { /* code */
|
||||||
0x60080017, // 0000 GETGBL R2 G23
|
0x60080017, // 0000 GETGBL R2 G23
|
||||||
0x5C0C0200, // 0001 MOVE R3 R1
|
0x5C0C0200, // 0001 MOVE R3 R1
|
||||||
0x7C080200, // 0002 CALL R2 1
|
0x7C080200, // 0002 CALL R2 1
|
||||||
0x740A0009, // 0003 JMPT R2 #000E
|
0x740A0009, // 0003 JMPT R2 #000E
|
||||||
0x88080100, // 0004 GETMBR R2 R0 K0
|
0x88080100, // 0004 GETMBR R2 R0 K0
|
||||||
0x1C080501, // 0005 EQ R2 R2 K1
|
0x1C080501, // 0005 EQ R2 R2 K1
|
||||||
0x780A000D, // 0006 JMPF R2 #0015
|
0x780A000E, // 0006 JMPF R2 #0016
|
||||||
0x88080102, // 0007 GETMBR R2 R0 K2
|
0x88080102, // 0007 GETMBR R2 R0 K2
|
||||||
0x880C0103, // 0008 GETMBR R3 R0 K3
|
0x880C0103, // 0008 GETMBR R3 R0 K3
|
||||||
0x08080403, // 0009 MUL R2 R2 R3
|
0x08080403, // 0009 MUL R2 R2 R3
|
||||||
0x880C0104, // 000A GETMBR R3 R0 K4
|
0x880C0104, // 000A GETMBR R3 R0 K4
|
||||||
0x880C0705, // 000B GETMBR R3 R3 K5
|
0x880C0705, // 000B GETMBR R3 R3 K5
|
||||||
0x1C080403, // 000C EQ R2 R2 R3
|
0x1C080403, // 000C EQ R2 R2 R3
|
||||||
0x780A0006, // 000D JMPF R2 #0015
|
0x780A0007, // 000D JMPF R2 #0016
|
||||||
0x88080104, // 000E GETMBR R2 R0 K4
|
0x88080104, // 000E GETMBR R2 R0 K4
|
||||||
0x8C080506, // 000F GETMET R2 R2 K6
|
0x8C080506, // 000F GETMET R2 R2 K6
|
||||||
0x7C080200, // 0010 CALL R2 1
|
0x7C080200, // 0010 CALL R2 1
|
||||||
0x88080104, // 0011 GETMBR R2 R0 K4
|
0x88080104, // 0011 GETMBR R2 R0 K4
|
||||||
0x8C080508, // 0012 GETMET R2 R2 K8
|
0x8C080508, // 0012 GETMET R2 R2 K8
|
||||||
0x7C080200, // 0013 CALL R2 1
|
0x88100107, // 0013 GETMBR R4 R0 K7
|
||||||
0x90020E02, // 0014 SETMBR R0 K7 R2
|
0x7C080400, // 0014 CALL R2 2
|
||||||
0x80000000, // 0015 RET 0
|
0x90020E02, // 0015 SETMBR R0 K7 R2
|
||||||
|
0x80000000, // 0016 RET 0
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1452,24 +1453,44 @@ be_local_closure(Leds_create_matrix, /* name */
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
be_local_closure(Leds_pixels_buffer, /* name */
|
be_local_closure(Leds_pixels_buffer, /* name */
|
||||||
be_nested_proto(
|
be_nested_proto(
|
||||||
4, /* nstack */
|
8, /* nstack */
|
||||||
1, /* argc */
|
2, /* argc */
|
||||||
2, /* varg */
|
2, /* varg */
|
||||||
0, /* has upvals */
|
0, /* has upvals */
|
||||||
NULL, /* no upvals */
|
NULL, /* no upvals */
|
||||||
0, /* has sup protos */
|
0, /* has sup protos */
|
||||||
NULL, /* no sub protos */
|
NULL, /* no sub protos */
|
||||||
1, /* has constants */
|
1, /* has constants */
|
||||||
( &(const bvalue[ 1]) { /* constants */
|
( &(const bvalue[ 4]) { /* constants */
|
||||||
/* K0 */ be_nested_str(call_native),
|
/* K0 */ be_nested_str(call_native),
|
||||||
|
/* K1 */ be_nested_str(pixel_size),
|
||||||
|
/* K2 */ be_nested_str(pixel_count),
|
||||||
|
/* K3 */ be_nested_str(_change_buffer),
|
||||||
}),
|
}),
|
||||||
&be_const_str_pixels_buffer,
|
&be_const_str_pixels_buffer,
|
||||||
&be_const_str_solidified,
|
&be_const_str_solidified,
|
||||||
( &(const binstruction[ 4]) { /* code */
|
( &(const binstruction[21]) { /* code */
|
||||||
0x8C040100, // 0000 GETMET R1 R0 K0
|
0x8C080100, // 0000 GETMET R2 R0 K0
|
||||||
0x540E0005, // 0001 LDINT R3 6
|
0x54120005, // 0001 LDINT R4 6
|
||||||
0x7C040400, // 0002 CALL R1 2
|
0x7C080400, // 0002 CALL R2 2
|
||||||
0x80040200, // 0003 RET 1 R1
|
0x4C0C0000, // 0003 LDNIL R3
|
||||||
|
0x1C0C0203, // 0004 EQ R3 R1 R3
|
||||||
|
0x780E0009, // 0005 JMPF R3 #0010
|
||||||
|
0x600C0015, // 0006 GETGBL R3 G21
|
||||||
|
0x5C100400, // 0007 MOVE R4 R2
|
||||||
|
0x8C140101, // 0008 GETMET R5 R0 K1
|
||||||
|
0x7C140200, // 0009 CALL R5 1
|
||||||
|
0x8C180102, // 000A GETMET R6 R0 K2
|
||||||
|
0x7C180200, // 000B CALL R6 1
|
||||||
|
0x08140A06, // 000C MUL R5 R5 R6
|
||||||
|
0x7C0C0400, // 000D CALL R3 2
|
||||||
|
0x80040600, // 000E RET 1 R3
|
||||||
|
0x70020003, // 000F JMP #0014
|
||||||
|
0x8C0C0303, // 0010 GETMET R3 R1 K3
|
||||||
|
0x5C140400, // 0011 MOVE R5 R2
|
||||||
|
0x7C0C0400, // 0012 CALL R3 2
|
||||||
|
0x80040200, // 0013 RET 1 R1
|
||||||
|
0x80000000, // 0014 RET 0
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -139,6 +139,11 @@ def esp32_create_combined_bin(source, target, env):
|
||||||
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
|
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
|
||||||
chip = env.get("BOARD_MCU")
|
chip = env.get("BOARD_MCU")
|
||||||
tasmota_platform = esp32_create_chip_string(chip)
|
tasmota_platform = esp32_create_chip_string(chip)
|
||||||
|
|
||||||
|
if "-DUSE_USB_CDC_CONSOLE" in env.BoardConfig().get("build.extra_flags") and "cdc" not in tasmota_platform:
|
||||||
|
tasmota_platform += "cdc"
|
||||||
|
print("WARNING: board definition uses CDC configuration, but environment name does not -> changing tasmota safeboot binary to:", tasmota_platform + "-safeboot.bin")
|
||||||
|
|
||||||
if not os.path.exists(variants_dir):
|
if not os.path.exists(variants_dir):
|
||||||
os.makedirs(variants_dir)
|
os.makedirs(variants_dir)
|
||||||
if("safeboot" in firmware_name):
|
if("safeboot" in firmware_name):
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
# Art-Net driver
|
||||||
|
|
||||||
|
class ArtNet
|
||||||
|
var matrix # the led matrix
|
||||||
|
var port # port number for listening for incoming packets
|
||||||
|
var udp_server # instance of `udp` class
|
||||||
|
var universe_start # base universe number
|
||||||
|
var universe_end # last universe number allowed (excluded)
|
||||||
|
# static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
|
||||||
|
static var artnet_sig_0 = 0x4172742D # "Art-"
|
||||||
|
static var artnet_sig_4 = 0x4E657400 # "Net\x00"
|
||||||
|
|
||||||
|
var packet # try reusing the same packer bytes() object for performance
|
||||||
|
|
||||||
|
# local copy of led matrix attributes for faster access
|
||||||
|
var alternate # field from matrix, alternate lines (reversed). Contains 0 if not alternate, or the number of bytes per pixel
|
||||||
|
|
||||||
|
def init(matrix, universe_start, port, ip_addr)
|
||||||
|
self.matrix = matrix
|
||||||
|
self.alternate = matrix.alternate ? matrix.pixel_size() : 0
|
||||||
|
# self.v = self.matrix.v
|
||||||
|
if universe_start == nil universe_start = 0 end
|
||||||
|
self.universe_start = universe_start
|
||||||
|
self.universe_end = universe_start + matrix.h
|
||||||
|
|
||||||
|
if port == nil port = 6454 end
|
||||||
|
self.port = int(port)
|
||||||
|
if ip_addr == nil ip_addr = "" end
|
||||||
|
|
||||||
|
self.packet = bytes() # instanciate a single bytes() buffer that will be used for all received packets
|
||||||
|
|
||||||
|
self.udp_server = udp()
|
||||||
|
self.udp_server.begin(ip_addr, self.port)
|
||||||
|
|
||||||
|
# register as fast_loop
|
||||||
|
tasmota.add_fast_loop(/-> self.fast_loop())
|
||||||
|
# set sleep to 5 for a smooth animation
|
||||||
|
tasmota.global.sleep = 5
|
||||||
|
end
|
||||||
|
|
||||||
|
def fast_loop()
|
||||||
|
var universe_start = self.universe_start
|
||||||
|
var universe_end = self.universe_end
|
||||||
|
var artnet_sig_0 = self.artnet_sig_0
|
||||||
|
var artnet_sig_4 = self.artnet_sig_4
|
||||||
|
var dirty = false
|
||||||
|
var packet = self.udp_server.read(self.packet)
|
||||||
|
while (packet != nil)
|
||||||
|
if size(packet) >= 18 &&
|
||||||
|
packet.get(0, -4) == artnet_sig_0 && packet.get(4, -4) == artnet_sig_4
|
||||||
|
var opcode = packet.get(8, 2) # should be 0x5000
|
||||||
|
var protocol = packet.get(10, -2) # big endian, should be 14
|
||||||
|
var universe = packet.get(14, 2)
|
||||||
|
|
||||||
|
if opcode == 0x5000 && protocol == 14 && universe >= universe_start && universe < universe_end
|
||||||
|
# tasmota.log("DMX: received Art-Net packet :" + packet.tohex())
|
||||||
|
# var seq = packet.get(12, 1)
|
||||||
|
# var phy = packet.get(13, 1)
|
||||||
|
var data_len = packet.get(16, -2)
|
||||||
|
# data starts at offset 18
|
||||||
|
if size(packet) >= 18 + data_len # check size
|
||||||
|
if self.alternate > 0 && (universe - self.universe_start) % 2
|
||||||
|
packet.reverse(18, self.alternate, -1)
|
||||||
|
end
|
||||||
|
self.matrix.set_bytes(universe, packet, 18, data_len)
|
||||||
|
dirty = true
|
||||||
|
end
|
||||||
|
# import string
|
||||||
|
# tasmota.log(string.format("DMX: opcode=0x%04X protocol=%i seq=%i phy=%i universe=%i data_len=%i data=%s",
|
||||||
|
# opcode, protocol, seq, phy, universe, data_len, packet[18..-1].tohex()))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
packet = self.udp_server.read(self.packet)
|
||||||
|
if packet == nil
|
||||||
|
tasmota.delay_microseconds(20) # wait 20 us just in case
|
||||||
|
packet = self.udp_server.read(self.packet)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if dirty
|
||||||
|
self.matrix.dirty()
|
||||||
|
self.matrix.show()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ArtNet
|
||||||
|
|
||||||
|
#-
|
||||||
|
# Example for M5Stack ATOM Matrix (5x5 matrix without alternate)
|
||||||
|
import artnet
|
||||||
|
# var artnet = ArtNet
|
||||||
|
var strip = Leds(25, gpio.pin(gpio.WS2812, 0))
|
||||||
|
var m = strip.create_matrix(5, 5, 0)
|
||||||
|
var dmx = artnet(m)
|
||||||
|
-#
|
|
@ -0,0 +1,190 @@
|
||||||
|
#-
|
||||||
|
Simplified Tasmota TM1637 driver written in Berry
|
||||||
|
Might be helpful in the case of using multiple displays
|
||||||
|
Supports only the 4 digit basic display
|
||||||
|
|
||||||
|
DIO_PIN and CLK_PIN are your esp32 pin numbers
|
||||||
|
How to use
|
||||||
|
|
||||||
|
> load('tm1637')
|
||||||
|
> tm = Tm1637(DIO_PIN, CLK_PIN)
|
||||||
|
> tm.set_on(4)
|
||||||
|
> tm.print('0123')
|
||||||
|
> tm.print(456)
|
||||||
|
|
||||||
|
Add custom commands to the native Tasmota console:
|
||||||
|
> tm_add_custom_commands(DIO_PIN, CLK_PIN)
|
||||||
|
|
||||||
|
And then:
|
||||||
|
TmBrightness 2
|
||||||
|
TmPrint 0123
|
||||||
|
TmPrint -5.67
|
||||||
|
|
||||||
|
Note: adding these commands to autoexec.be should be performed via creating an additional .be file with the content:
|
||||||
|
tm_add_custom_commands(DIO_PIN, CLK_PIN)
|
||||||
|
|
||||||
|
and then loading it in autoexec.be via load('tm1637') and load('script_name')
|
||||||
|
The direct addition may not work
|
||||||
|
-#
|
||||||
|
|
||||||
|
class Tm1637
|
||||||
|
static var CMD_CTRL = 0x80
|
||||||
|
static var CMD_DISP_ON = 0x08
|
||||||
|
static var CMD_DATA = 0x40
|
||||||
|
static var CMD_ADDR = 0xC0
|
||||||
|
|
||||||
|
static var SYMB_DOT = 0x80
|
||||||
|
|
||||||
|
static var DIGIT_MAP = {
|
||||||
|
'0': 0x3F,
|
||||||
|
'1': 0x06,
|
||||||
|
'2': 0x5B,
|
||||||
|
'3': 0x4F,
|
||||||
|
'4': 0x66,
|
||||||
|
'5': 0x6D,
|
||||||
|
'6': 0x7D,
|
||||||
|
'7': 0x07,
|
||||||
|
'8': 0x7F,
|
||||||
|
'9': 0x6F,
|
||||||
|
'-': 0x40,
|
||||||
|
' ': 0x00
|
||||||
|
}
|
||||||
|
|
||||||
|
var PIN_DIO
|
||||||
|
var PIN_CLK
|
||||||
|
|
||||||
|
def init(dio, clk)
|
||||||
|
self.PIN_DIO = dio
|
||||||
|
self.PIN_CLK = clk
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
|
||||||
|
gpio.pin_mode(self.PIN_CLK, gpio.OUTPUT)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def start()
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop()
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 0)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ack()
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.INPUT_PULLUP)
|
||||||
|
var ack_state = gpio.digital_read(self.PIN_DIO) == 0
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_bit(bitval)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.digital_write(self.PIN_DIO, bitval)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_byte(byteval)
|
||||||
|
for pos: 0..7
|
||||||
|
self.write_bit((byteval >> pos) & 0x01)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_command(command)
|
||||||
|
self.start()
|
||||||
|
self.write_byte(command)
|
||||||
|
var ack_state = self.ack()
|
||||||
|
self.stop()
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_data(data)
|
||||||
|
var ack_state = true
|
||||||
|
self.start()
|
||||||
|
for i : 0..size(data)-1
|
||||||
|
self.write_byte(data[i])
|
||||||
|
ack_state = self.ack() && ack_state
|
||||||
|
end
|
||||||
|
self.stop()
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
# 0-8 range, 0 to 'OFF'
|
||||||
|
def set_on(brightness)
|
||||||
|
if brightness == nil || brightness > 8
|
||||||
|
brightness = 8
|
||||||
|
elif brightness < 0
|
||||||
|
brightness = 0
|
||||||
|
end
|
||||||
|
var cmd = self.CMD_CTRL
|
||||||
|
if brightness
|
||||||
|
cmd |= self.CMD_DISP_ON
|
||||||
|
brightness -= 1
|
||||||
|
end
|
||||||
|
return self.send_command(cmd | brightness)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print(num)
|
||||||
|
import string
|
||||||
|
|
||||||
|
num = str(num)
|
||||||
|
var max_str_len = 4
|
||||||
|
|
||||||
|
do
|
||||||
|
var dot_pos = string.find(num, '.')
|
||||||
|
if dot_pos >= 0 && dot_pos < 5
|
||||||
|
max_str_len = 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if size(num) > max_str_len
|
||||||
|
num = string.split(num, max_str_len)[0]
|
||||||
|
end
|
||||||
|
num = string.format('%4s', num)
|
||||||
|
var payload = bytes(-5)
|
||||||
|
payload[0] = self.CMD_ADDR
|
||||||
|
var int_offset = 1
|
||||||
|
for i : 0..size(num)-1
|
||||||
|
if num[i] == '.'
|
||||||
|
payload[i] |= self.SYMB_DOT
|
||||||
|
int_offset = 0
|
||||||
|
else
|
||||||
|
payload[i + int_offset] = self.DIGIT_MAP[num[i]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
var ack_state = self.send_command(self.CMD_DATA) && self.send_data(payload)
|
||||||
|
if !ack_state
|
||||||
|
log('TM1637 - no ACK, please check connections')
|
||||||
|
end
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear()
|
||||||
|
self.print(' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Won't be called on the system restart
|
||||||
|
def deinit()
|
||||||
|
self.set_on(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tm_add_custom_commands(dio, clk)
|
||||||
|
var tm = Tm1637(dio, clk)
|
||||||
|
tm.clear()
|
||||||
|
tm.set_on(4)
|
||||||
|
tasmota.add_cmd('tmprint', def(cmd, idx, payload)
|
||||||
|
tm.print(payload) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
|
||||||
|
end)
|
||||||
|
# 0-8 range, 0 to 'OFF'
|
||||||
|
tasmota.add_cmd('tmbrightness', def(cmd, idx, payload)
|
||||||
|
tm.set_on(int(payload)) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
|
||||||
|
end)
|
||||||
|
log("Tasmota custom commands registered: TmPrint, TmBrightness")
|
||||||
|
end
|
|
@ -753,6 +753,10 @@
|
||||||
// Commands xdrv_60_shift595.ino - 74x595 family shift register driver
|
// Commands xdrv_60_shift595.ino - 74x595 family shift register driver
|
||||||
#define D_CMND_SHIFT595_DEVICE_COUNT "Shift595DeviceCount"
|
#define D_CMND_SHIFT595_DEVICE_COUNT "Shift595DeviceCount"
|
||||||
|
|
||||||
|
// Commands xdrv_89_dali.ino
|
||||||
|
#define D_CMND_DALI_POWER "power"
|
||||||
|
#define D_CMND_DALI_DIMMER "dim"
|
||||||
|
|
||||||
// Commands xsns_02_analog.ino
|
// Commands xsns_02_analog.ino
|
||||||
#define D_CMND_ADCPARAM "AdcParam"
|
#define D_CMND_ADCPARAM "AdcParam"
|
||||||
|
|
||||||
|
|
|
@ -362,7 +362,7 @@ enum SO32_49Index { P_HOLD_TIME, // SetOption32 - (Button/Switch) K
|
||||||
P_IR_TOLERANCE, // SetOption44 - (IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)
|
P_IR_TOLERANCE, // SetOption44 - (IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)
|
||||||
P_BISTABLE_PULSE, // SetOption45 - (Bistable) Pulse time for two coil bistable latching relays (default 40)
|
P_BISTABLE_PULSE, // SetOption45 - (Bistable) Pulse time for two coil bistable latching relays (default 40)
|
||||||
P_POWER_ON_DELAY, // SetOption46 - (PowerOn) Add delay of 10 x value milliseconds at power on
|
P_POWER_ON_DELAY, // SetOption46 - (PowerOn) Add delay of 10 x value milliseconds at power on
|
||||||
P_SO47_FREE, // SetOption47
|
P_POWER_ON_DELAY2, // SetOption47 - (PowerOn) Add delay of value seconds at power on before activating relays
|
||||||
P_SO48_FREE, // SetOption48
|
P_SO48_FREE, // SetOption48
|
||||||
P_SO49_FREE // SetOption49
|
P_SO49_FREE // SetOption49
|
||||||
}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
|
}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
|
||||||
|
@ -459,10 +459,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
|
||||||
|
|
||||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||||
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_MAX };
|
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_MAX };
|
||||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
||||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
||||||
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole";
|
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47";
|
||||||
|
|
||||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||||
|
|
||||||
|
|
|
@ -723,6 +723,7 @@
|
||||||
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
|
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
|
||||||
//#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code)
|
//#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code)
|
||||||
//#define USE_THERMOSTAT // Add support for Thermostat
|
//#define USE_THERMOSTAT // Add support for Thermostat
|
||||||
|
#define USE_BP1658CJ // Add support for BP1658CJ 5 channel led controller as used in Orein OS0100411267 Bulb
|
||||||
#define USE_ETHERNET // Add support for ethernet (+20k code)
|
#define USE_ETHERNET // Add support for ethernet (+20k code)
|
||||||
#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 display driver used by Sonoff POWR3xxD and THR3xxD
|
#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 display driver used by Sonoff POWR3xxD and THR3xxD
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,8 @@ enum UserSelectablePins {
|
||||||
GPIO_ADE7953_RST, // ADE7953 Reset
|
GPIO_ADE7953_RST, // ADE7953 Reset
|
||||||
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
|
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
|
||||||
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
|
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
|
||||||
|
GPIO_DALI_RX, GPIO_DALI_TX, // Dali
|
||||||
|
GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ
|
||||||
GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins
|
GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins
|
||||||
GPIO_SENSOR_END };
|
GPIO_SENSOR_END };
|
||||||
|
|
||||||
|
@ -444,6 +446,8 @@ const char kSensorNames[] PROGMEM =
|
||||||
D_SENSOR_ADE7953_RST "|"
|
D_SENSOR_ADE7953_RST "|"
|
||||||
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
|
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
|
||||||
D_SENSOR_ADE7953_CS "|"
|
D_SENSOR_ADE7953_CS "|"
|
||||||
|
D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
|
||||||
|
D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|"
|
||||||
D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|"
|
D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -459,6 +463,7 @@ const char kSensorNamesFixed[] PROGMEM =
|
||||||
#define MAX_SM2135_DAT 10
|
#define MAX_SM2135_DAT 10
|
||||||
#define MAX_SM2335_DAT 16
|
#define MAX_SM2335_DAT 16
|
||||||
#define MAX_DSB 4
|
#define MAX_DSB 4
|
||||||
|
#define MAX_BP1658CJ_DAT 16
|
||||||
#define MAX_DINGTIAN_SHIFT 4
|
#define MAX_DINGTIAN_SHIFT 4
|
||||||
|
|
||||||
const uint16_t kGpioNiceList[] PROGMEM = {
|
const uint16_t kGpioNiceList[] PROGMEM = {
|
||||||
|
@ -530,6 +535,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||||
* Protocol specifics
|
* Protocol specifics
|
||||||
\*-------------------------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if defined(USE_DALI) && defined(ESP32)
|
||||||
|
AGPIO(GPIO_DALI_RX), // DALI RX
|
||||||
|
AGPIO(GPIO_DALI_TX), // DALI TX
|
||||||
|
#endif // USE_DALI
|
||||||
|
|
||||||
#ifdef USE_I2C
|
#ifdef USE_I2C
|
||||||
AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL
|
AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL
|
||||||
AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA
|
AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA
|
||||||
|
@ -711,6 +721,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
||||||
AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK
|
AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK
|
||||||
AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA
|
AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA
|
||||||
#endif // USE_SM2335
|
#endif // USE_SM2335
|
||||||
|
#ifdef USE_BP1658CJ
|
||||||
|
AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK
|
||||||
|
AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA
|
||||||
|
#endif // USE_BP1658CJ
|
||||||
#ifdef USE_BP5758D
|
#ifdef USE_BP5758D
|
||||||
AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK
|
AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK
|
||||||
AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA
|
AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA
|
||||||
|
|
|
@ -574,8 +574,7 @@ typedef struct {
|
||||||
SOBitfield3 flag3; // 3A0
|
SOBitfield3 flag3; // 3A0
|
||||||
uint16_t energy_kWhdoy; // 3A4
|
uint16_t energy_kWhdoy; // 3A4
|
||||||
uint16_t energy_min_power; // 3A6
|
uint16_t energy_min_power; // 3A6
|
||||||
|
uint32_t pn532_password; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
|
||||||
uint8_t free_3A8[4]; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
|
|
||||||
|
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
@ -688,15 +687,15 @@ typedef struct {
|
||||||
uint16_t mqtt_socket_timeout; // 52E
|
uint16_t mqtt_socket_timeout; // 52E
|
||||||
uint8_t mqtt_wifi_timeout; // 530
|
uint8_t mqtt_wifi_timeout; // 530
|
||||||
uint8_t ina219_mode; // 531
|
uint8_t ina219_mode; // 531
|
||||||
uint16_t ex_pulse_timer[8]; // 532 Free since 11.0.0.3
|
|
||||||
|
uint16_t ex_pulse_timer[8]; // 532 ex_pulse_timer free since 11.0.0.3
|
||||||
|
|
||||||
uint16_t button_debounce; // 542
|
uint16_t button_debounce; // 542
|
||||||
uint32_t ipv4_address[5]; // 544
|
uint32_t ipv4_address[5]; // 544
|
||||||
uint32_t ipv4_rgx_address; // 558
|
uint32_t ipv4_rgx_address; // 558
|
||||||
uint32_t ipv4_rgx_subnetmask; // 55C
|
uint32_t ipv4_rgx_subnetmask; // 55C
|
||||||
uint16_t pwm_value_ext[16-5]; // 560 Extension to pwm_value to store up to 16 PWM for ESP32. This array stores values 5..15
|
uint16_t pwm_value_ext[16-5]; // 560 Extension to pwm_value to store up to 16 PWM for ESP32. This array stores values 5..15
|
||||||
|
uint16_t pn532_pack; // 576
|
||||||
uint8_t free_576[2]; // 576
|
|
||||||
|
|
||||||
int32_t weight_offset; // 578
|
int32_t weight_offset; // 578
|
||||||
uint16_t pulse_timer[MAX_PULSETIMERS]; // 57C
|
uint16_t pulse_timer[MAX_PULSETIMERS]; // 57C
|
||||||
SysMBitfield1 flag2; // 5BC
|
SysMBitfield1 flag2; // 5BC
|
||||||
|
@ -842,7 +841,9 @@ typedef struct {
|
||||||
uint16_t flowratemeter_calibration[2];// F78
|
uint16_t flowratemeter_calibration[2];// F78
|
||||||
int32_t energy_kWhexport_ph[3]; // F7C
|
int32_t energy_kWhexport_ph[3]; // F7C
|
||||||
uint32_t eth_ipv4_address[5]; // F88
|
uint32_t eth_ipv4_address[5]; // F88
|
||||||
|
|
||||||
uint32_t ex_energy_kWhtotal; // F9C
|
uint32_t ex_energy_kWhtotal; // F9C
|
||||||
|
|
||||||
SBitfield1 sbflag1; // FA0
|
SBitfield1 sbflag1; // FA0
|
||||||
TeleinfoCfg teleinfo; // FA4
|
TeleinfoCfg teleinfo; // FA4
|
||||||
uint64_t rf_protocol_mask; // FA8
|
uint64_t rf_protocol_mask; // FA8
|
||||||
|
|
|
@ -20,6 +20,6 @@
|
||||||
#ifndef _TASMOTA_VERSION_H_
|
#ifndef _TASMOTA_VERSION_H_
|
||||||
#define _TASMOTA_VERSION_H_
|
#define _TASMOTA_VERSION_H_
|
||||||
|
|
||||||
const uint32_t VERSION = 0x0C020002; // 12.2.0.2
|
const uint32_t VERSION = 0x0C020003; // 12.2.0.3
|
||||||
|
|
||||||
#endif // _TASMOTA_VERSION_H_
|
#endif // _TASMOTA_VERSION_H_
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energie Vandag"
|
#define D_ENERGY_TODAY "Energie Vandag"
|
||||||
#define D_ENERGY_YESTERDAY "Energie Gister"
|
#define D_ENERGY_YESTERDAY "Energie Gister"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "Diep slaap"
|
#define D_SENSOR_DEEPSLEEP "Diep slaap"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Консумация за днес"
|
#define D_ENERGY_TODAY "Консумация за днес"
|
||||||
#define D_ENERGY_YESTERDAY "Консумация за вчера"
|
#define D_ENERGY_YESTERDAY "Консумация за вчера"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energy Today"
|
#define D_ENERGY_TODAY "Energy Today"
|
||||||
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Spotřeba Dnes"
|
#define D_ENERGY_TODAY "Spotřeba Dnes"
|
||||||
#define D_ENERGY_YESTERDAY "Spotřeba Včera"
|
#define D_ENERGY_YESTERDAY "Spotřeba Včera"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gefunden an Adresse"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gefunden an Adresse"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Zigbee Parameter erstellt, Überprüfung mit 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Zigbee Parameter erstellt, Überprüfung mit 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energie heute"
|
#define D_ENERGY_TODAY "Energie heute"
|
||||||
#define D_ENERGY_YESTERDAY "Energie gestern"
|
#define D_ENERGY_YESTERDAY "Energie gestern"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
|
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
|
||||||
#define D_ENERGY_YESTERDAY "Ενέργεια χθες"
|
#define D_ENERGY_YESTERDAY "Ενέργεια χθες"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energy Today"
|
#define D_ENERGY_TODAY "Energy Today"
|
||||||
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Encontrada EEPROM de ZBBridge en"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Encontrada EEPROM de ZBBridge en"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Configurando parámetros Zigbee de forma aleatoria. Usar 'ZbConfig' para revisarlos."
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Configurando parámetros Zigbee de forma aleatoria. Usar 'ZbConfig' para revisarlos."
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energía Hoy"
|
#define D_ENERGY_TODAY "Energía Hoy"
|
||||||
#define D_ENERGY_YESTERDAY "Energía Ayer"
|
#define D_ENERGY_YESTERDAY "Energía Ayer"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge trouvée à l'adresse"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge trouvée à l'adresse"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomisation des paramètres ZigBee, veuillez vérifier avec 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomisation des paramètres ZigBee, veuillez vérifier avec 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xsns_03_energy.ino
|
// xsns_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Énergie aujourd'hui"
|
#define D_ENERGY_TODAY "Énergie aujourd'hui"
|
||||||
#define D_ENERGY_YESTERDAY "Énergie hier"
|
#define D_ENERGY_YESTERDAY "Énergie hier"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 DAT"
|
#define D_SENSOR_SM2135_DAT "SM2135 DAT"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 CLK"
|
#define D_SENSOR_SM2335_CLK "SM2335 CLK"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 DAT"
|
#define D_SENSOR_SM2335_DAT "SM2335 DAT"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "Hibernation"
|
#define D_SENSOR_DEEPSLEEP "Hibernation"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM fûn op adres"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM fûn op adres"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, kontrolearje asjebleaft mei 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, kontrolearje asjebleaft mei 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Konsumpsje hjoed"
|
#define D_ENERGY_TODAY "Konsumpsje hjoed"
|
||||||
#define D_ENERGY_YESTERDAY "Konsumpsje juster"
|
#define D_ENERGY_YESTERDAY "Konsumpsje juster"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "צריכה יומית"
|
#define D_ENERGY_TODAY "צריכה יומית"
|
||||||
#define D_ENERGY_YESTERDAY "צריכה בעבר"
|
#define D_ENERGY_YESTERDAY "צריכה בעבר"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM található a címen"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM található a címen"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zigbee paramétereknek véletlennek kell lenniük, ellenőrizd a 'ZbConfig'-gal"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zigbee paramétereknek véletlennek kell lenniük, ellenőrizd a 'ZbConfig'-gal"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Mai energia"
|
#define D_ENERGY_TODAY "Mai energia"
|
||||||
#define D_ENERGY_YESTERDAY "Tegnapi energia"
|
#define D_ENERGY_YESTERDAY "Tegnapi energia"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||||
* Use online command Prefix to translate cmnd, stat and tele.
|
* Use online command Prefix to translate cmnd, stat and tele.
|
||||||
*
|
*
|
||||||
* Updated until v9.4.0.1 - Last update 05.10.2022
|
* Updated until v9.4.0.1 - Last update 30.10.2022
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
|
|
||||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||||
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Trovata EEPROM ZBBridge all'indirizzo"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Trovata EEPROM ZBBridge all'indirizzo"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali - RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali - TX"
|
||||||
|
#define D_CONFIGURE_DALI "DALI - Config"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energia - oggi"
|
#define D_ENERGY_TODAY "Energia - oggi"
|
||||||
#define D_ENERGY_YESTERDAY "Energia - ieri"
|
#define D_ENERGY_YESTERDAY "Energia - ieri"
|
||||||
|
@ -793,6 +798,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 - DATI"
|
#define D_SENSOR_SM2135_DAT "SM2135 - DATI"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 - CLK"
|
#define D_SENSOR_SM2335_CLK "SM2335 - CLK"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 - DATI"
|
#define D_SENSOR_SM2335_DAT "SM2335 - DATI"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ - CLK"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ - DATI"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D - CLK"
|
#define D_SENSOR_BP5758D_CLK "BP5758D - CLK"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D - DATI"
|
#define D_SENSOR_BP5758D_DAT "BP5758D - DATI"
|
||||||
#define D_SENSOR_DEEPSLEEP "Sleep profondo"
|
#define D_SENSOR_DEEPSLEEP "Sleep profondo"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "금일 전력 사용량"
|
#define D_ENERGY_TODAY "금일 전력 사용량"
|
||||||
#define D_ENERGY_YESTERDAY "어제 전력 사용량"
|
#define D_ENERGY_YESTERDAY "어제 전력 사용량"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM aanwezig op adres"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM aanwezig op adres"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Willekeurige Zigbee parameters gemaakt, controleer met 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Willekeurige Zigbee parameters gemaakt, controleer met 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Verbruik vandaag"
|
#define D_ENERGY_TODAY "Verbruik vandaag"
|
||||||
#define D_ENERGY_YESTERDAY "Verbruik gisteren"
|
#define D_ENERGY_YESTERDAY "Verbruik gisteren"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Znaleziono ZBBridge EEPROM na adresie"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Znaleziono ZBBridge EEPROM na adresie"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Losowanie parametrów Zigbee, proszę sprawdzić 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Losowanie parametrów Zigbee, proszę sprawdzić 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energia dzisiaj"
|
#define D_ENERGY_TODAY "Energia dzisiaj"
|
||||||
#define D_ENERGY_YESTERDAY "Energia wczoraj"
|
#define D_ENERGY_YESTERDAY "Energia wczoraj"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
|
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge encontrada no endereço" // "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge encontrada no endereço" // "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizando parametros Zigbee, por favor congira em 'ZbConfig'" // "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizando parametros Zigbee, por favor congira em 'ZbConfig'" // "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
||||||
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
|
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM encontrada no edereço"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM encontrada no edereço"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomização de parâmetros Zigbee, por-favor verifique a 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomização de parâmetros Zigbee, por-favor verifique a 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
||||||
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
|
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energia de Azi"
|
#define D_ENERGY_TODAY "Energia de Azi"
|
||||||
#define D_ENERGY_YESTERDAY "Energia de Ieri"
|
#define D_ENERGY_YESTERDAY "Energia de Ieri"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Конфигурация DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Энергия Сегодня"
|
#define D_ENERGY_TODAY "Энергия Сегодня"
|
||||||
#define D_ENERGY_YESTERDAY "Энергия Вчера"
|
#define D_ENERGY_YESTERDAY "Энергия Вчера"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Spotreba dnes"
|
#define D_ENERGY_TODAY "Spotreba dnes"
|
||||||
#define D_ENERGY_YESTERDAY "Spotreba včera"
|
#define D_ENERGY_YESTERDAY "Spotreba včera"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energi idag"
|
#define D_ENERGY_TODAY "Energi idag"
|
||||||
#define D_ENERGY_YESTERDAY "Energi igår"
|
#define D_ENERGY_YESTERDAY "Energi igår"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Energy Today"
|
#define D_ENERGY_TODAY "Energy Today"
|
||||||
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
#define D_ENERGY_YESTERDAY "Energy Yesterday"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Енергія Сьогодні"
|
#define D_ENERGY_TODAY "Енергія Сьогодні"
|
||||||
#define D_ENERGY_YESTERDAY "Енергія Вчора"
|
#define D_ENERGY_YESTERDAY "Енергія Вчора"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
|
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
|
||||||
#define D_ENERGY_YESTERDAY "Năng lượng tiêu thụ hôm qua"
|
#define D_ENERGY_YESTERDAY "Năng lượng tiêu thụ hôm qua"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "找到 ZBBridge EEPROM, 地址:"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "找到 ZBBridge EEPROM, 地址:"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "正在随机化 Zigbee 参数, 请通过 'ZbConfig' 检查"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "正在随机化 Zigbee 参数, 请通过 'ZbConfig' 检查"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "今日用电量"
|
#define D_ENERGY_TODAY "今日用电量"
|
||||||
#define D_ENERGY_YESTERDAY "昨日用电量"
|
#define D_ENERGY_YESTERDAY "昨日用电量"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -511,6 +511,11 @@
|
||||||
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
|
||||||
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
|
||||||
|
|
||||||
|
// xdrv_89_dali.ino
|
||||||
|
#define D_SENSOR_DALI_RX "Dali RX"
|
||||||
|
#define D_SENSOR_DALI_TX "Dali TX"
|
||||||
|
#define D_CONFIGURE_DALI "Config DALI"
|
||||||
|
|
||||||
// xdrv_03_energy.ino
|
// xdrv_03_energy.ino
|
||||||
#define D_ENERGY_TODAY "今日用電量"
|
#define D_ENERGY_TODAY "今日用電量"
|
||||||
#define D_ENERGY_YESTERDAY "昨日用電量"
|
#define D_ENERGY_YESTERDAY "昨日用電量"
|
||||||
|
@ -795,6 +800,8 @@
|
||||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||||
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
|
||||||
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
|
||||||
|
#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
|
||||||
|
#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
|
||||||
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
|
||||||
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
|
||||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||||
|
|
|
@ -562,6 +562,7 @@
|
||||||
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
|
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
|
||||||
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
|
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
|
||||||
#define USE_SM2335 // Add support for SM2335 RGBCW led control as used in SwitchBot Color Bulb (+0k7 code)
|
#define USE_SM2335 // Add support for SM2335 RGBCW led control as used in SwitchBot Color Bulb (+0k7 code)
|
||||||
|
#define USE_BP1658CJ // Add support for BP1658CJ RGBCW led control as used in Orein OS0100411267 Bulb
|
||||||
#define USE_BP5758D // Add support for BP5758D RGBCW led control as used in some Tuya lightbulbs (+0k8 code)
|
#define USE_BP5758D // Add support for BP5758D RGBCW led control as used in some Tuya lightbulbs (+0k8 code)
|
||||||
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
|
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
|
||||||
#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code)
|
#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code)
|
||||||
|
@ -776,9 +777,8 @@
|
||||||
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
|
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
|
||||||
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
|
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
|
||||||
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
|
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
|
||||||
//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
|
//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
|
||||||
// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
|
// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
|
||||||
// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
|
|
||||||
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
|
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
|
||||||
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
|
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
|
||||||
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
|
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
|
||||||
|
@ -1034,6 +1034,11 @@
|
||||||
|
|
||||||
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
|
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
|
||||||
|
|
||||||
|
// #define USE_DALI // Add support for DALI
|
||||||
|
#define DALI_IN_INVERT 0 // DALI RX inverted ?
|
||||||
|
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
|
||||||
|
#define DALI_TIMER 0 // ESP32 hardware timer number 0-3 !!! timer 3 used in xdrv_10_scripter.ino !!!
|
||||||
|
|
||||||
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
|
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
|
||||||
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
|
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
|
||||||
|
|
||||||
|
@ -1070,6 +1075,7 @@
|
||||||
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
||||||
#define USE_BERRY_IRAM // Allocate some data structures in IRAM (which is ususally unused) when possible and if no PSRAM is available
|
#define USE_BERRY_IRAM // Allocate some data structures in IRAM (which is ususally unused) when possible and if no PSRAM is available
|
||||||
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
|
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
|
||||||
|
// #define UBE_BERRY_DEBUG_GC // Print low-level GC metrics
|
||||||
// #define USE_BERRY_INT64 // Add 64 bits integer support (+1.7KB Flash)
|
// #define USE_BERRY_INT64 // Add 64 bits integer support (+1.7KB Flash)
|
||||||
#define USE_WEBCLIENT // Enable `webclient` to make HTTP/HTTPS requests. Can be disabled for security reasons.
|
#define USE_WEBCLIENT // Enable `webclient` to make HTTP/HTTPS requests. Can be disabled for security reasons.
|
||||||
// #define USE_WEBCLIENT_HTTPS // Enable HTTPS outgoing requests based on BearSSL (much ligher then mbedTLS, 42KB vs 150KB) in insecure mode (no verification of server's certificate)
|
// #define USE_WEBCLIENT_HTTPS // Enable HTTPS outgoing requests based on BearSSL (much ligher then mbedTLS, 42KB vs 150KB) in insecure mode (no verification of server's certificate)
|
||||||
|
|
|
@ -253,6 +253,7 @@ struct TasmotaGlobal_t {
|
||||||
power_t blink_power; // Blink power state
|
power_t blink_power; // Blink power state
|
||||||
power_t blink_powersave; // Blink start power save state
|
power_t blink_powersave; // Blink start power save state
|
||||||
power_t blink_mask; // Blink relay active mask
|
power_t blink_mask; // Blink relay active mask
|
||||||
|
power_t power_on_delay_state;
|
||||||
|
|
||||||
int serial_in_byte_counter; // Index in receive buffer
|
int serial_in_byte_counter; // Index in receive buffer
|
||||||
|
|
||||||
|
@ -333,6 +334,7 @@ struct TasmotaGlobal_t {
|
||||||
uint8_t last_source; // Last command source
|
uint8_t last_source; // Last command source
|
||||||
uint8_t shutters_present; // Number of actual define shutters
|
uint8_t shutters_present; // Number of actual define shutters
|
||||||
uint8_t discovery_counter; // Delayed discovery counter
|
uint8_t discovery_counter; // Delayed discovery counter
|
||||||
|
uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)
|
||||||
#ifdef USE_PWM_DIMMER
|
#ifdef USE_PWM_DIMMER
|
||||||
uint8_t restore_powered_off_led_counter; // Seconds before powered-off LED (LEDLink) is restored
|
uint8_t restore_powered_off_led_counter; // Seconds before powered-off LED (LEDLink) is restored
|
||||||
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
|
||||||
|
@ -516,7 +518,7 @@ void setup(void) {
|
||||||
Settings->baudrate = APP_BAUDRATE / 300;
|
Settings->baudrate = APP_BAUDRATE / 300;
|
||||||
Settings->serial_config = TS_SERIAL_8N1;
|
Settings->serial_config = TS_SERIAL_8N1;
|
||||||
}
|
}
|
||||||
SetSerialBaudrate(Settings->baudrate * 300); // Reset serial interface if current baudrate is different from requested baudrate
|
SetSerialInitBegin(); // Reset serial interface if current baudrate and/or config is different from requested settings
|
||||||
|
|
||||||
if (1 == RtcReboot.fast_reboot_count) { // Allow setting override only when all is well
|
if (1 == RtcReboot.fast_reboot_count) { // Allow setting override only when all is well
|
||||||
UpdateQuickPowerCycle(true);
|
UpdateQuickPowerCycle(true);
|
||||||
|
|
|
@ -45,7 +45,7 @@ void RtcSettingsSave(void) {
|
||||||
if (RTC_MEM_VALID != RtcSettings.valid) {
|
if (RTC_MEM_VALID != RtcSettings.valid) {
|
||||||
memset(&RtcSettings, 0, sizeof(RtcSettings));
|
memset(&RtcSettings, 0, sizeof(RtcSettings));
|
||||||
RtcSettings.valid = RTC_MEM_VALID;
|
RtcSettings.valid = RTC_MEM_VALID;
|
||||||
// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2;
|
// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
|
||||||
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
|
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
|
||||||
for (uint32_t i = 0; i < 3; i++) {
|
for (uint32_t i = 0; i < 3; i++) {
|
||||||
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
|
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
|
||||||
|
@ -914,6 +914,7 @@ void SettingsDefaultSet2(void) {
|
||||||
// Serial
|
// Serial
|
||||||
Settings->serial_config = TS_SERIAL_8N1;
|
Settings->serial_config = TS_SERIAL_8N1;
|
||||||
Settings->baudrate = APP_BAUDRATE / 300;
|
Settings->baudrate = APP_BAUDRATE / 300;
|
||||||
|
Settings->sserial_config = TS_SERIAL_8N1;
|
||||||
Settings->sbaudrate = SOFT_BAUDRATE / 300;
|
Settings->sbaudrate = SOFT_BAUDRATE / 300;
|
||||||
Settings->serial_delimiter = 0xff;
|
Settings->serial_delimiter = 0xff;
|
||||||
Settings->seriallog_level = SERIAL_LOG_LEVEL;
|
Settings->seriallog_level = SERIAL_LOG_LEVEL;
|
||||||
|
@ -1535,8 +1536,8 @@ void SettingsDelta(void) {
|
||||||
memset(&Settings->energy_kWhtoday_ph, 0, 36);
|
memset(&Settings->energy_kWhtoday_ph, 0, 36);
|
||||||
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
|
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
|
||||||
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
|
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
|
||||||
Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2;
|
Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
|
||||||
Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2;
|
Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2; // = ex_energy_kWhyesterday
|
||||||
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
|
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
|
||||||
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
|
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,11 @@ uint32_t ResetReason(void) {
|
||||||
return ESP_ResetInfoReason();
|
return ESP_ResetInfoReason();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResetReasonPowerOn(void) {
|
||||||
|
uint32_t reset_reason = ESP_ResetInfoReason();
|
||||||
|
return ((reset_reason == REASON_DEFAULT_RST) || (reset_reason == REASON_EXT_SYS_RST));
|
||||||
|
}
|
||||||
|
|
||||||
String GetResetReason(void) {
|
String GetResetReason(void) {
|
||||||
if (OsWatchBlockedLoop()) {
|
if (OsWatchBlockedLoop()) {
|
||||||
char buff[32];
|
char buff[32];
|
||||||
|
@ -1977,6 +1982,13 @@ void SetSerialBegin(void) {
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSerialInitBegin(void) {
|
||||||
|
TasmotaGlobal.baudrate = Settings->baudrate * 300;
|
||||||
|
if ((GetSerialBaudrate() != TasmotaGlobal.baudrate) || (TS_SERIAL_8N1 != Settings->serial_config)) {
|
||||||
|
SetSerialBegin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetSerialConfig(uint32_t serial_config) {
|
void SetSerialConfig(uint32_t serial_config) {
|
||||||
if (serial_config > TS_SERIAL_8O2) {
|
if (serial_config > TS_SERIAL_8O2) {
|
||||||
serial_config = TS_SERIAL_8N1;
|
serial_config = TS_SERIAL_8N1;
|
||||||
|
|
|
@ -99,13 +99,49 @@ void *special_calloc(size_t num, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String GetDeviceHardware(void) {
|
String GetDeviceHardware(void) {
|
||||||
|
/*
|
||||||
|
ESP8266 SoCs
|
||||||
|
- 32-bit MCU & 2.4 GHz Wi-Fi
|
||||||
|
- High-performance 160 MHz single-core CPU
|
||||||
|
- +19.5 dBm output power ensures a good physical range
|
||||||
|
- Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
|
||||||
|
- Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
|
||||||
|
*/
|
||||||
// esptool.py get_efuses
|
// esptool.py get_efuses
|
||||||
uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
|
uint32_t efuse0 = *(uint32_t*)(0x3FF00050);
|
||||||
uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
|
// uint32_t efuse1 = *(uint32_t*)(0x3FF00054);
|
||||||
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
|
uint32_t efuse2 = *(uint32_t*)(0x3FF00058);
|
||||||
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
|
uint32_t efuse3 = *(uint32_t*)(0x3FF0005C);
|
||||||
|
|
||||||
if (((efuse1 & (1 << 4)) || (efuse2 & (1 << 16))) && (ESP.getFlashChipRealSize() < 1048577)) { // ESP8285 can only have 1M flash
|
bool r0_4 = efuse0 & (1 << 4); // ESP8285
|
||||||
|
bool r2_16 = efuse2 & (1 << 16); // ESP8285
|
||||||
|
if (r0_4 || r2_16) { // ESP8285
|
||||||
|
// 1M 2M 2M 4M
|
||||||
|
// r0_4 1 1 0 0
|
||||||
|
bool r3_25 = efuse3 & (1 << 25); // ESP8285 flash matrix 0 0 1 1
|
||||||
|
bool r3_26 = efuse3 & (1 << 26); // ESP8285 flash matrix 0 1 0 1
|
||||||
|
bool r3_27 = efuse3 & (1 << 27); // ESP8285 flash matrix 0 0 0 0
|
||||||
|
uint32_t pkg_version = 0;
|
||||||
|
if (!r3_27) {
|
||||||
|
if (r0_4 && !r3_25) {
|
||||||
|
pkg_version = (r3_26) ? 2 : 1;
|
||||||
|
}
|
||||||
|
else if (!r0_4 && r3_25) {
|
||||||
|
pkg_version = (r3_26) ? 4 : 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool max_temp = efuse0 & (1 << 5); // Max flash temperature (0 = 85C, 1 = 105C)
|
||||||
|
switch (pkg_version) {
|
||||||
|
case 1:
|
||||||
|
if (max_temp) { return F("ESP8285H08"); } // 1M flash
|
||||||
|
else { return F("ESP8285N08"); }
|
||||||
|
case 2:
|
||||||
|
if (max_temp) { return F("ESP8285H16"); } // 2M flash
|
||||||
|
else { return F("ESP8285N16"); }
|
||||||
|
case 4:
|
||||||
|
if (max_temp) { return F("ESP8285H32"); } // 4M flash
|
||||||
|
else { return F("ESP8285N32"); }
|
||||||
|
}
|
||||||
return F("ESP8285");
|
return F("ESP8285");
|
||||||
}
|
}
|
||||||
return F("ESP8266EX");
|
return F("ESP8266EX");
|
||||||
|
@ -768,6 +804,17 @@ typedef struct {
|
||||||
bool single_core = (1 == chip_info.cores);
|
bool single_core = (1 == chip_info.cores);
|
||||||
|
|
||||||
if (chip_model < 2) { // ESP32
|
if (chip_model < 2) { // ESP32
|
||||||
|
/*
|
||||||
|
ESP32 Series
|
||||||
|
- 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth/Bluetooth LE
|
||||||
|
- Two or one CPU core(s) with adjustable clock frequency, ranging from 80 MHz to 240 MHz
|
||||||
|
- +19.5 dBm output power ensures a good physical range
|
||||||
|
- Classic Bluetooth for legacy connections, also supporting L2CAP, SDP, GAP, SMP, AVDTP, AVCTP, A2DP (SNK) and AVRCP (CT)
|
||||||
|
- Support for Bluetooth Low Energy (Bluetooth LE) profiles including L2CAP, GAP, GATT, SMP, and GATT-based profiles like BluFi, SPP-like, etc
|
||||||
|
- Bluetooth Low Energy (Bluetooth LE) connects to smart phones, broadcasting low-energy beacons for easy detection
|
||||||
|
- Sleep current is less than 5 μA, making it suitable for battery-powered and wearable-electronics applications
|
||||||
|
- Peripherals include capacitive touch sensors, Hall sensor, SD card interface, Ethernet, high-speed SPI, UART, I2S and I2C
|
||||||
|
*/
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
/* esptool:
|
/* esptool:
|
||||||
def get_pkg_version(self):
|
def get_pkg_version(self):
|
||||||
|
@ -807,6 +854,15 @@ typedef struct {
|
||||||
return F("ESP32");
|
return F("ESP32");
|
||||||
}
|
}
|
||||||
else if (2 == chip_model) { // ESP32-S2
|
else if (2 == chip_model) { // ESP32-S2
|
||||||
|
/*
|
||||||
|
ESP32-S2 Series
|
||||||
|
- 32-bit MCU & 2.4 GHz Wi-Fi
|
||||||
|
- High-performance 240 MHz single-core CPU
|
||||||
|
- Ultra-low-power performance: fine-grained clock gating, dynamic voltage and frequency scaling
|
||||||
|
- Security features: eFuse、flash encryption, secure boot, signature verification, integrated AES, SHA and RSA algorithms
|
||||||
|
- Peripherals include 43 GPIOs, 1 full-speed USB OTG interface, SPI, I2S, UART, I2C, LED PWM, LCD interface, camera interface, ADC, DAC, touch sensor, temperature sensor
|
||||||
|
- Availability of common cloud connectivity agents and common product features shortens the time to market
|
||||||
|
*/
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||||
/* esptool:
|
/* esptool:
|
||||||
def get_flash_version(self):
|
def get_flash_version(self):
|
||||||
|
@ -840,13 +896,19 @@ typedef struct {
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||||
return F("ESP32-S2");
|
return F("ESP32-S2");
|
||||||
}
|
}
|
||||||
else if (9 == chip_model) { // ESP32-S3
|
else if (4 == chip_model) { // ESP32-S3(beta2)
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
return F("ESP32-S3");
|
||||||
// no variants for now
|
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
|
|
||||||
}
|
}
|
||||||
else if (5 == chip_model) { // ESP32-C3
|
else if (5 == chip_model) { // ESP32-C3 = ESP8685
|
||||||
|
/*
|
||||||
|
ESP32-C3 Series
|
||||||
|
- 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
|
||||||
|
- 32-bit RISC-V single-core processor with a four-stage pipeline that operates at up to 160 MHz
|
||||||
|
- State-of-the-art power and RF performance
|
||||||
|
- 400 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, and QPI interfaces that allow connection to flash
|
||||||
|
- Reliable security features ensured by RSA-3072-based secure boot, AES-128-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, hardware acceleration support for cryptographic algorithms
|
||||||
|
- Rich set of peripheral interfaces and GPIOs, ideal for various scenarios and complex applications
|
||||||
|
*/
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||||
/* esptool:
|
/* esptool:
|
||||||
def get_pkg_version(self):
|
def get_pkg_version(self):
|
||||||
|
@ -894,7 +956,22 @@ typedef struct {
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32C6
|
#endif // CONFIG_IDF_TARGET_ESP32C6
|
||||||
return F("ESP32-C6");
|
return F("ESP32-C6");
|
||||||
}
|
}
|
||||||
else if (10 == chip_model) { // ESP32-H2
|
else if (9 == chip_model) { // ESP32-S3
|
||||||
|
/*
|
||||||
|
ESP32-S3 Series
|
||||||
|
- 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
|
||||||
|
- Xtensa® 32-bit LX7 dual-core processor that operates at up to 240 MHz
|
||||||
|
- 512 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, Octal SPI, QPI, and OPI interfaces that allow connection to flash and external RAM
|
||||||
|
- Additional support for vector instructions in the MCU, which provides acceleration for neural network computing and signal processing workloads
|
||||||
|
- Peripherals include 45 programmable GPIOs, SPI, I2S, I2C, PWM, RMT, ADC and UART, SD/MMC host and TWAITM
|
||||||
|
- Reliable security features ensured by RSA-based secure boot, AES-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, “World Controller”
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
// no variants for now
|
||||||
|
#endif // CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
|
||||||
|
}
|
||||||
|
else if (10 == chip_model) { // ESP32-H2(beta1)
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32H2
|
#ifdef CONFIG_IDF_TARGET_ESP32H2
|
||||||
/* esptool:
|
/* esptool:
|
||||||
def get_pkg_version(self):
|
def get_pkg_version(self):
|
||||||
|
@ -916,6 +993,33 @@ typedef struct {
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32H2
|
#endif // CONFIG_IDF_TARGET_ESP32H2
|
||||||
return F("ESP32-H2");
|
return F("ESP32-H2");
|
||||||
}
|
}
|
||||||
|
else if (12 == chip_model) { // ESP32-C2 = ESP8684
|
||||||
|
/*
|
||||||
|
ESP32-C2 Series
|
||||||
|
- 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
|
||||||
|
- 32-bit RISC-V single-core processor that operates at up to 120 MHz
|
||||||
|
- State-of-the-art power and RF performance
|
||||||
|
- 576 KB ROM, 272 KB SRAM (16 KB for cache) on the chip
|
||||||
|
- 14 programmable GPIOs: SPI, UART, I2C, LED PWM controller, General DMA controller (GDMA), SAR ADC, Temperature sensor
|
||||||
|
*/
|
||||||
|
|
||||||
|
return F("ESP32-C2");
|
||||||
|
}
|
||||||
|
else if (13 == chip_model) { // ESP32-C6
|
||||||
|
/*
|
||||||
|
ESP32-C6 Series
|
||||||
|
- 32-bit RISC-V MCU & 2.4 GHz Wi-Fi 6 & Bluetooth 5 (LE) & IEEE 802.15.4
|
||||||
|
- 32-bit RISC-V single-core processor that operates at up to 160 MHz
|
||||||
|
- State-of-the-art power and RF performance
|
||||||
|
- 320 KB ROM, 512 KB SRAM, 16 KB Low-power SRAM on the chip, and works with external flash
|
||||||
|
- 30 (QFN40) or 22 (QFN32) programmable GPIOs, with support for SPI, UART, I2C, I2S, RMT, TWAI and PWM
|
||||||
|
*/
|
||||||
|
|
||||||
|
return F("ESP32-C6");
|
||||||
|
}
|
||||||
|
else if (14 == chip_model) { // ESP32-H2(beta2)
|
||||||
|
return F("ESP32-H2");
|
||||||
|
}
|
||||||
return F("ESP32");
|
return F("ESP32");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -840,10 +840,15 @@ void ResponseAppendFeatures(void)
|
||||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_MODBUS_ENERGY)
|
#if defined(USE_ENERGY_SENSOR) && defined(USE_MODBUS_ENERGY)
|
||||||
feature9 |= 0x00000010; // xnrg_29_modbus.ino
|
feature9 |= 0x00000010; // xnrg_29_modbus.ino
|
||||||
#endif
|
#endif
|
||||||
// feature9 |= 0x00000020;
|
#if defined(USE_SPI) && defined(USE_SHELLY_PRO)
|
||||||
// feature9 |= 0x00000040;
|
feature9 |= 0x00000020; // xdrv_88_esp32_shelly_pro.ino
|
||||||
// feature9 |= 0x00000080;
|
#endif
|
||||||
|
#ifdef USE_DALI
|
||||||
|
feature9 |= 0x00000040; // xdrv_89_esp32_dali.ino
|
||||||
|
#endif
|
||||||
|
#if defined(USE_LIGHT) && defined(USE_BP1658CJ)
|
||||||
|
feature9 |= 0x00000080; // xlgt_10_bp1658cj.ino
|
||||||
|
#endif
|
||||||
// feature9 |= 0x00000100;
|
// feature9 |= 0x00000100;
|
||||||
// feature9 |= 0x00000200;
|
// feature9 |= 0x00000200;
|
||||||
// feature9 |= 0x00000400;
|
// feature9 |= 0x00000400;
|
||||||
|
|
|
@ -240,6 +240,11 @@ void SetLatchingRelay(power_t lpower, uint32_t state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDevicePower(power_t rpower, uint32_t source) {
|
void SetDevicePower(power_t rpower, uint32_t source) {
|
||||||
|
if (TasmotaGlobal.power_on_delay) {
|
||||||
|
TasmotaGlobal.power_on_delay_state = rpower;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ShowSource(source);
|
ShowSource(source);
|
||||||
TasmotaGlobal.last_source = source;
|
TasmotaGlobal.last_source = source;
|
||||||
|
|
||||||
|
@ -384,7 +389,7 @@ void SetPowerOnState(void)
|
||||||
SetDevicePower(1, SRC_RESTART);
|
SetDevicePower(1, SRC_RESTART);
|
||||||
} else {
|
} else {
|
||||||
power_t devices_mask = POWER_MASK >> (POWER_SIZE - TasmotaGlobal.devices_present);
|
power_t devices_mask = POWER_MASK >> (POWER_SIZE - TasmotaGlobal.devices_present);
|
||||||
if ((ResetReason() == REASON_DEFAULT_RST) || (ResetReason() == REASON_EXT_SYS_RST)) {
|
if (ResetReasonPowerOn()) {
|
||||||
switch (Settings->poweronstate) {
|
switch (Settings->poweronstate) {
|
||||||
case POWER_ALL_OFF:
|
case POWER_ALL_OFF:
|
||||||
case POWER_ALL_OFF_PULSETIME_ON:
|
case POWER_ALL_OFF_PULSETIME_ON:
|
||||||
|
@ -422,7 +427,8 @@ void SetPowerOnState(void)
|
||||||
uint32_t port = 0;
|
uint32_t port = 0;
|
||||||
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
|
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (!Settings->flag3.no_power_feedback) { // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
|
if (!Settings->flag3.no_power_feedback && // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
|
||||||
|
!TasmotaGlobal.power_on_delay) { // SetOption47 - Delay switching relays to reduce power surge at power on
|
||||||
if ((port < MAX_RELAYS) && PinUsed(GPIO_REL1, port)) {
|
if ((port < MAX_RELAYS) && PinUsed(GPIO_REL1, port)) {
|
||||||
if (bitRead(TasmotaGlobal.rel_bistable, port)) {
|
if (bitRead(TasmotaGlobal.rel_bistable, port)) {
|
||||||
port++; // Skip both bistable relays as always 0
|
port++; // Skip both bistable relays as always 0
|
||||||
|
@ -1056,6 +1062,29 @@ void PerformEverySecond(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TasmotaGlobal.power_on_delay) {
|
||||||
|
if (1 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 1
|
||||||
|
// Allow relay power on once network is available
|
||||||
|
if (!TasmotaGlobal.global_state.network_down) {
|
||||||
|
TasmotaGlobal.power_on_delay = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (2 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 2
|
||||||
|
// Allow relay power on once mqtt is available
|
||||||
|
if (!TasmotaGlobal.global_state.mqtt_down) {
|
||||||
|
TasmotaGlobal.power_on_delay = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // SetOption47 3..255
|
||||||
|
// Allow relay power on after x seconds
|
||||||
|
TasmotaGlobal.power_on_delay--;
|
||||||
|
}
|
||||||
|
if (!TasmotaGlobal.power_on_delay && TasmotaGlobal.power_on_delay_state) {
|
||||||
|
// Set relays according to last SetDevicePower() request
|
||||||
|
SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_SO47);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (TasmotaGlobal.mqtt_cmnd_blocked_reset) {
|
if (TasmotaGlobal.mqtt_cmnd_blocked_reset) {
|
||||||
TasmotaGlobal.mqtt_cmnd_blocked_reset--;
|
TasmotaGlobal.mqtt_cmnd_blocked_reset--;
|
||||||
if (!TasmotaGlobal.mqtt_cmnd_blocked_reset) {
|
if (!TasmotaGlobal.mqtt_cmnd_blocked_reset) {
|
||||||
|
@ -2046,6 +2075,19 @@ void GpioInit(void)
|
||||||
|
|
||||||
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0]));
|
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0]));
|
||||||
|
|
||||||
|
if (ResetReasonPowerOn()) {
|
||||||
|
TasmotaGlobal.power_on_delay = Settings->param[P_POWER_ON_DELAY2]; // SetOption47 - Delay switching relays to reduce power surge at power on
|
||||||
|
if (TasmotaGlobal.power_on_delay) {
|
||||||
|
// This is the earliest possibility to disable relays connected to esp8266/esp32 gpios at power up to reduce power surge
|
||||||
|
for (uint32_t i = 0; i < MAX_RELAYS; i++) {
|
||||||
|
if (PinUsed(GPIO_REL1, i)) {
|
||||||
|
DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); // Off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 %d Power off relays"), Settings->param[P_POWER_ON_DELAY2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
analogWriteRange(Settings->pwm_range); // Default is 1023 (Arduino.h)
|
analogWriteRange(Settings->pwm_range); // Default is 1023 (Arduino.h)
|
||||||
analogWriteFreq(Settings->pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
analogWriteFreq(Settings->pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
||||||
|
|
||||||
|
@ -2169,7 +2211,11 @@ void GpioInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(Settings->param[P_POWER_ON_DELAY] * 10); // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
|
if (Settings->param[P_POWER_ON_DELAY]) { // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
|
||||||
|
uint32_t init_delay = Settings->param[P_POWER_ON_DELAY] * 10;
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO46 Wait %d msec"), init_delay);
|
||||||
|
delay(init_delay);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_I2C
|
#ifdef USE_I2C
|
||||||
TasmotaGlobal.i2c_enabled = (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA));
|
TasmotaGlobal.i2c_enabled = (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA));
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
#define D_CMND_TARIFF "Tariff"
|
#define D_CMND_TARIFF "Tariff"
|
||||||
#define D_CMND_MODULEADDRESS "ModuleAddress"
|
#define D_CMND_MODULEADDRESS "ModuleAddress"
|
||||||
|
|
||||||
|
enum EnergyCalibration {
|
||||||
|
ENERGY_POWER_CALIBRATION, ENERGY_VOLTAGE_CALIBRATION, ENERGY_CURRENT_CALIBRATION, ENERGY_FREQUENCY_CALIBRATION };
|
||||||
|
|
||||||
enum EnergyCommands {
|
enum EnergyCommands {
|
||||||
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL,
|
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL,
|
||||||
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_ENERGYCONFIG };
|
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_ENERGYCONFIG };
|
||||||
|
@ -412,8 +415,8 @@ bool EnergyMargin(bool type, uint16_t margin, uint16_t value, bool &flag, bool &
|
||||||
return (change != save_flag);
|
return (change != save_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnergyMarginCheck(void)
|
void EnergyMarginCheck(void) {
|
||||||
{
|
if (!Energy.phase_count || (TasmotaGlobal.uptime < 8)) { return; }
|
||||||
if (Energy.power_steady_counter) {
|
if (Energy.power_steady_counter) {
|
||||||
Energy.power_steady_counter--;
|
Energy.power_steady_counter--;
|
||||||
return;
|
return;
|
||||||
|
@ -637,11 +640,6 @@ void EnergyEverySecond(void)
|
||||||
* Commands
|
* Commands
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
void EnergyCommandCalResponse(uint32_t nvalue) {
|
|
||||||
snprintf_P(XdrvMailbox.command, CMDSZ, PSTR("%sCal"), XdrvMailbox.command);
|
|
||||||
ResponseCmndNumber(nvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResponseCmndEnergyTotalYesterdayToday(void) {
|
void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||||
char value_chr[TOPSZ]; // Used by EnergyFormatIndex
|
char value_chr[TOPSZ]; // Used by EnergyFormatIndex
|
||||||
char value2_chr[TOPSZ];
|
char value2_chr[TOPSZ];
|
||||||
|
@ -835,71 +833,117 @@ void CmndTariff(void) {
|
||||||
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
|
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
|
||||||
|
uint32_t channel = ((1 == chan) && (2 == Energy.phase_count)) ? 1 : 0;
|
||||||
|
if (channel) {
|
||||||
|
switch (cal_type) {
|
||||||
|
case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration2;
|
||||||
|
case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration2;
|
||||||
|
case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (cal_type) {
|
||||||
|
case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration;
|
||||||
|
case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration;
|
||||||
|
case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Settings->energy_frequency_calibration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnergyCommandCalSetResponse(uint32_t cal_type) {
|
||||||
|
if (XdrvMailbox.payload > 99) {
|
||||||
|
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
|
||||||
|
if (channel) {
|
||||||
|
switch (cal_type) {
|
||||||
|
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (cal_type) {
|
||||||
|
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration = XdrvMailbox.payload; break;
|
||||||
|
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ENERGY_FREQUENCY_CALIBRATION == cal_type) {
|
||||||
|
ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
|
||||||
|
} else {
|
||||||
|
if (2 == Energy.phase_count) {
|
||||||
|
ResponseAppend_P(PSTR("[%d,%d]}"), EnergyGetCalibration(0, cal_type), EnergyGetCalibration(1, cal_type));
|
||||||
|
} else {
|
||||||
|
ResponseAppend_P(PSTR("%d}"), EnergyGetCalibration(0, cal_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnergyCommandCalResponse(uint32_t cal_type) {
|
||||||
|
Response_P(PSTR("{\"%s\":"), XdrvMailbox.command);
|
||||||
|
EnergyCommandCalSetResponse(cal_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnergyCommandSetCalResponse(uint32_t cal_type) {
|
||||||
|
Response_P(PSTR("{\"%sCal\":"), XdrvMailbox.command);
|
||||||
|
EnergyCommandCalSetResponse(cal_type);
|
||||||
|
}
|
||||||
|
|
||||||
void CmndPowerCal(void) {
|
void CmndPowerCal(void) {
|
||||||
Energy.command_code = CMND_POWERCAL;
|
Energy.command_code = CMND_POWERCAL;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
||||||
if (XdrvMailbox.payload > 999) {
|
EnergyCommandCalResponse(ENERGY_POWER_CALIBRATION);
|
||||||
Settings->energy_power_calibration = XdrvMailbox.payload;
|
|
||||||
}
|
|
||||||
ResponseCmndNumber(Settings->energy_power_calibration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndVoltageCal(void) {
|
void CmndVoltageCal(void) {
|
||||||
Energy.command_code = CMND_VOLTAGECAL;
|
Energy.command_code = CMND_VOLTAGECAL;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
||||||
if (XdrvMailbox.payload > 999) {
|
EnergyCommandCalResponse(ENERGY_VOLTAGE_CALIBRATION);
|
||||||
Settings->energy_voltage_calibration = XdrvMailbox.payload;
|
|
||||||
}
|
|
||||||
ResponseCmndNumber(Settings->energy_voltage_calibration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndCurrentCal(void) {
|
void CmndCurrentCal(void) {
|
||||||
Energy.command_code = CMND_CURRENTCAL;
|
Energy.command_code = CMND_CURRENTCAL;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
||||||
if (XdrvMailbox.payload > 999) {
|
EnergyCommandCalResponse(ENERGY_CURRENT_CALIBRATION);
|
||||||
Settings->energy_current_calibration = XdrvMailbox.payload;
|
|
||||||
}
|
|
||||||
ResponseCmndNumber(Settings->energy_current_calibration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndFrequencyCal(void) {
|
void CmndFrequencyCal(void) {
|
||||||
Energy.command_code = CMND_FREQUENCYCAL;
|
Energy.command_code = CMND_FREQUENCYCAL;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
if (XnrgCall(FUNC_COMMAND)) { // microseconds
|
||||||
if (XdrvMailbox.payload > 999) {
|
EnergyCommandCalResponse(ENERGY_FREQUENCY_CALIBRATION);
|
||||||
Settings->energy_frequency_calibration = XdrvMailbox.payload;
|
|
||||||
}
|
|
||||||
ResponseCmndNumber(Settings->energy_frequency_calibration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndPowerSet(void) {
|
void CmndPowerSet(void) {
|
||||||
Energy.command_code = CMND_POWERSET;
|
Energy.command_code = CMND_POWERSET;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // Watt
|
if (XnrgCall(FUNC_COMMAND)) { // Watt
|
||||||
EnergyCommandCalResponse(Settings->energy_power_calibration);
|
EnergyCommandSetCalResponse(ENERGY_POWER_CALIBRATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndVoltageSet(void) {
|
void CmndVoltageSet(void) {
|
||||||
Energy.command_code = CMND_VOLTAGESET;
|
Energy.command_code = CMND_VOLTAGESET;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // Volt
|
if (XnrgCall(FUNC_COMMAND)) { // Volt
|
||||||
EnergyCommandCalResponse(Settings->energy_voltage_calibration);
|
EnergyCommandSetCalResponse(ENERGY_VOLTAGE_CALIBRATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndCurrentSet(void) {
|
void CmndCurrentSet(void) {
|
||||||
Energy.command_code = CMND_CURRENTSET;
|
Energy.command_code = CMND_CURRENTSET;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
|
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
|
||||||
EnergyCommandCalResponse(Settings->energy_current_calibration);
|
EnergyCommandSetCalResponse(ENERGY_CURRENT_CALIBRATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndFrequencySet(void) {
|
void CmndFrequencySet(void) {
|
||||||
Energy.command_code = CMND_FREQUENCYSET;
|
Energy.command_code = CMND_FREQUENCYSET;
|
||||||
if (XnrgCall(FUNC_COMMAND)) { // Hz
|
if (XnrgCall(FUNC_COMMAND)) { // Hz
|
||||||
EnergyCommandCalResponse(Settings->energy_frequency_calibration);
|
EnergyCommandSetCalResponse(ENERGY_FREQUENCY_CALIBRATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,9 +1094,6 @@ void EnergyDrvInit(void) {
|
||||||
Energy.voltage_available = true; // Enable if voltage is measured
|
Energy.voltage_available = true; // Enable if voltage is measured
|
||||||
Energy.current_available = true; // Enable if current is measured
|
Energy.current_available = true; // Enable if current is measured
|
||||||
Energy.power_on = true;
|
Energy.power_on = true;
|
||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
|
||||||
Energy.power_steady_counter = 8; // Allow for power on stabilization
|
|
||||||
#endif // USE_ENERGY_MARGIN_DETECTION
|
|
||||||
|
|
||||||
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
||||||
XnrgCall(FUNC_PRE_INIT); // Find first energy driver
|
XnrgCall(FUNC_PRE_INIT); // Find first energy driver
|
||||||
|
|
|
@ -1763,6 +1763,7 @@ void LightReapplyColor(void) {
|
||||||
void LightAnimate(void)
|
void LightAnimate(void)
|
||||||
{
|
{
|
||||||
bool power_off = false;
|
bool power_off = false;
|
||||||
|
static int32_t sleep_previous = -1; // previous value of sleep before changing it to PWM_MAX_SLEEP, -1 means unchanged
|
||||||
|
|
||||||
// make sure we update CT range in case SetOption82 was changed
|
// make sure we update CT range in case SetOption82 was changed
|
||||||
Light.strip_timer_counter++;
|
Light.strip_timer_counter++;
|
||||||
|
@ -1770,13 +1771,17 @@ void LightAnimate(void)
|
||||||
// set sleep parameter: either settings,
|
// set sleep parameter: either settings,
|
||||||
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
|
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
|
||||||
if (Light.power || Light.fade_running) {
|
if (Light.power || Light.fade_running) {
|
||||||
if (Settings->sleep > PWM_MAX_SLEEP) {
|
if (TasmotaGlobal.sleep > PWM_MAX_SLEEP) {
|
||||||
|
sleep_previous = TasmotaGlobal.sleep; // save previous value of sleep
|
||||||
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maximum value (in milliseconds) to sleep to ensure that animations are smooth
|
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maximum value (in milliseconds) to sleep to ensure that animations are smooth
|
||||||
} else {
|
} else {
|
||||||
TasmotaGlobal.sleep = Settings->sleep; // or keep the current sleep if it's low enough
|
sleep_previous = -1; // if low enough, don't change it
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TasmotaGlobal.sleep = Settings->sleep;
|
if (sleep_previous > 0) {
|
||||||
|
TasmotaGlobal.sleep = sleep_previous;
|
||||||
|
sleep_previous = -1; // rearm
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Light.power) { // All channels powered off
|
if (!Light.power) { // All channels powered off
|
||||||
|
|
|
@ -253,10 +253,10 @@ uint16_t TimerGetTimeOfDay(uint8_t index)
|
||||||
int16_t xtime = xtimer.time;
|
int16_t xtime = xtimer.time;
|
||||||
#ifdef USE_SUNRISE
|
#ifdef USE_SUNRISE
|
||||||
if (xtimer.mode) {
|
if (xtimer.mode) {
|
||||||
if (xtime >= 12*60) xtime = 12*60 - xtime;
|
ApplyTimerOffsets(&xtimer);
|
||||||
xtime += (int16_t)SunMinutes(xtimer.mode-1);
|
xtime = xtimer.time;
|
||||||
if (xtime < 0) xtime += 24*60;
|
if (xtime==2047 && xtimer.mode==1) xtime *= -1; // Sun always has already rises
|
||||||
if (xtime >= 24*60) xtime -= 24*60;
|
if (xtime==2046 && xtimer.mode==2) xtime *= -1; // Sun always has already set
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return xtime;
|
return xtime;
|
||||||
|
|
|
@ -1458,19 +1458,7 @@ bool findNextVariableValue(char * &pVarname, float &value)
|
||||||
} else if (sVarName.startsWith(F("TIMER"))) {
|
} else if (sVarName.startsWith(F("TIMER"))) {
|
||||||
uint32_t index = sVarName.substring(5).toInt();
|
uint32_t index = sVarName.substring(5).toInt();
|
||||||
if (index > 0 && index <= MAX_TIMERS) {
|
if (index > 0 && index <= MAX_TIMERS) {
|
||||||
value = Settings->timer[index -1].time;
|
value = TimerGetTimeOfDay(index -1);
|
||||||
#if defined(USE_SUNRISE)
|
|
||||||
// Correct %timerN% values for sunrise/sunset timers
|
|
||||||
if ((1 == Settings->timer[index -1].mode) || (2 == Settings->timer[index -1].mode)) {
|
|
||||||
// in this context, time variable itself is merely an offset, with <720 being negative
|
|
||||||
value += -720 + SunMinutes(Settings->timer[index -1].mode -1);
|
|
||||||
if (2 == Settings->timer[index -1].mode) {
|
|
||||||
// To aid rule comparative statements, sunset past midnight (high lattitudes) is expressed past 24h00
|
|
||||||
// So sunset at 00h45 is at 24h45
|
|
||||||
if (value < 360) { value += 1440; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // USE_SUNRISE
|
|
||||||
}
|
}
|
||||||
#if defined(USE_SUNRISE)
|
#if defined(USE_SUNRISE)
|
||||||
} else if (sVarName.equals(F("SUNRISE"))) {
|
} else if (sVarName.equals(F("SUNRISE"))) {
|
||||||
|
|
|
@ -118,11 +118,14 @@ void DeepSleepPrepare(void)
|
||||||
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
|
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
|
||||||
// It may happen that wakeup in just <5 seconds in future
|
// It may happen that wakeup in just <5 seconds in future
|
||||||
// In this case also add deepsleep to nextwakeup
|
// In this case also add deepsleep to nextwakeup
|
||||||
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
|
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
|
||||||
// ensure nextwakeup is at least in the future
|
// ensure nextwakeup is at least in the future, and add 5%
|
||||||
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
|
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
|
||||||
|
RtcSettings.nextwakeup += Settings->deepsleep * 0.05;
|
||||||
|
// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time too short: time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
|
||||||
}
|
}
|
||||||
|
|
||||||
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
|
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
|
||||||
|
|
|
@ -151,19 +151,11 @@ extern "C" {
|
||||||
break;
|
break;
|
||||||
case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer)
|
case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer)
|
||||||
{
|
{
|
||||||
size_t pixels_bytes;
|
|
||||||
if (s_ws2812_grb) pixels_bytes = s_ws2812_grb->PixelsSize();
|
|
||||||
if (s_sk6812_grbw) pixels_bytes = s_sk6812_grbw->PixelsSize();
|
|
||||||
|
|
||||||
uint8_t * pixels;
|
uint8_t * pixels;
|
||||||
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
|
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
|
||||||
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
|
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
|
||||||
|
|
||||||
be_getbuiltin(vm, "bytes");
|
|
||||||
be_pushcomptr(vm, pixels);
|
be_pushcomptr(vm, pixels);
|
||||||
be_pushint(vm, pixels_bytes);
|
|
||||||
be_call(vm, 2);
|
|
||||||
be_pop(vm, 2);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // # 07 : PixelSize void -> int
|
case 7: // # 07 : PixelSize void -> int
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32
|
xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32, ESP32S2, ESP32S3
|
||||||
|
|
||||||
Copyright (C) 2021 Stephan Hadinger & Christian Baars, Berry language by Guan Wenliang https://github.com/Skiars/berry
|
Copyright (C) 2021 Stephan Hadinger & Christian Baars, Berry language by Guan Wenliang https://github.com/Skiars/berry
|
||||||
|
|
||||||
|
@ -21,9 +21,21 @@
|
||||||
#ifdef USE_BERRY_ULP
|
#ifdef USE_BERRY_ULP
|
||||||
#include <berry.h>
|
#include <berry.h>
|
||||||
|
|
||||||
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
|
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
#include "esp32/ulp.h"
|
#include "esp32/ulp.h"
|
||||||
|
#endif // esp32
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
#include "esp32s2/ulp.h"
|
||||||
|
#include "esp32s2/ulp_riscv.h"
|
||||||
|
#include "esp32s2/ulp_riscv_adc.h"
|
||||||
|
#endif // s2
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
#include "esp32s3/ulp.h"
|
||||||
|
#include "esp32s3/ulp_riscv.h"
|
||||||
|
#include "esp32s3/ulp_riscv_adc.h"
|
||||||
|
#endif //s3
|
||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
@ -36,7 +48,11 @@ extern "C" {
|
||||||
//
|
//
|
||||||
// `ULP.run() -> nil`
|
// `ULP.run() -> nil`
|
||||||
void be_ULP_run(int32_t entry) {
|
void be_ULP_run(int32_t entry) {
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
ulp_run(entry); // entry point should be at the beginning of program
|
ulp_run(entry); // entry point should be at the beginning of program
|
||||||
|
#else // S2 or S3
|
||||||
|
ulp_riscv_run();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// `ULP.wake_period(period_index:int, period_us:int) -> nil`
|
// `ULP.wake_period(period_index:int, period_us:int) -> nil`
|
||||||
|
@ -52,7 +68,11 @@ extern "C" {
|
||||||
|
|
||||||
// `ULP.get_mem(position:int) -> int`
|
// `ULP.get_mem(position:int) -> int`
|
||||||
int32_t be_ULP_get_mem(int32_t pos) {
|
int32_t be_ULP_get_mem(int32_t pos) {
|
||||||
return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
|
||||||
|
#else
|
||||||
|
return RTC_SLOW_MEM[pos]; // full 32bit for RISCV ULP
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// `ULP.gpio_init(pin:int, mode:int) -> rtc_pin:int`
|
// `ULP.gpio_init(pin:int, mode:int) -> rtc_pin:int`
|
||||||
|
@ -70,25 +90,40 @@ extern "C" {
|
||||||
// `ULP.adc_config(channel:int, attenuation:int, width:int) -> nil`
|
// `ULP.adc_config(channel:int, attenuation:int, width:int) -> nil`
|
||||||
//
|
//
|
||||||
// enums: channel 0-7, attenuation 0-3, width 0-3
|
// enums: channel 0-7, attenuation 0-3, width 0-3
|
||||||
void be_ULP_adc_config(struct bvm *vm, adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width) {
|
void be_ULP_adc_config(struct bvm *vm, int32_t channel, int32_t attenuation, int32_t width) {
|
||||||
esp_err_t err = adc1_config_channel_atten(channel, attenuation);
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
err += adc1_config_width(width);
|
esp_err_t err = adc1_config_channel_atten((adc1_channel_t)channel, (adc_atten_t)attenuation);
|
||||||
|
err += adc1_config_width((adc_bits_width_t)width);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
|
be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
|
||||||
} else {
|
} else {
|
||||||
adc1_ulp_enable();
|
adc1_ulp_enable();
|
||||||
}
|
}
|
||||||
|
#else // S2 or S3
|
||||||
|
ulp_riscv_adc_cfg_t cfg = {
|
||||||
|
.channel = (adc_channel_t)channel,
|
||||||
|
.atten = (adc_atten_t)attenuation,
|
||||||
|
.width = (adc_bits_width_t)width
|
||||||
|
};
|
||||||
|
esp_err_t err = ulp_riscv_adc_init(&cfg);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load a Berry byte buffer containing a ULP program as raw byte data
|
* @brief Load a Berry byte buffer containing a ULP program as raw byte data
|
||||||
*
|
*
|
||||||
* @param vm as `ULP.load(code:bytes) -> nil`
|
* @param vm as `ULP.load(code:bytes) -> nil`
|
||||||
* @return void
|
* @return void for ESP32 or binary type as int32_t on RISCV capable SOC's
|
||||||
*/
|
*/
|
||||||
void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) {
|
void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) {
|
||||||
// AddLog(LOG_LEVEL_INFO, "ULP: load addr=%p size=%i %*_H", buf, size/4, size, buf);
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
esp_err_t err = ulp_load_binary(0, buf, size / 4);
|
esp_err_t err = ulp_load_binary(0, buf, size / 4); // FSM type only, specific header, size in long words
|
||||||
|
#else // S2 or S3
|
||||||
|
esp_err_t err = ulp_riscv_load_binary(buf, size); // there are no header bytes, just load and hope for a valid binary - size in bytes
|
||||||
|
#endif // defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err);
|
be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err);
|
||||||
}
|
}
|
||||||
|
@ -109,10 +144,9 @@ extern "C" {
|
||||||
esp_deep_sleep_start();
|
esp_deep_sleep_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} //extern "C"
|
} //extern "C"
|
||||||
|
|
||||||
#endif //CONFIG_IDF_TARGET_ESP32
|
#endif //CONFIG_IDF_TARGET_ESP32 .. S2 .. S3
|
||||||
|
|
||||||
#endif // USE_BERRY_ULP
|
#endif // USE_BERRY_ULP
|
||||||
#endif // USE_BERRY
|
#endif // USE_BERRY
|
||||||
|
|
|
@ -231,6 +231,7 @@ void BerryObservability(bvm *vm, int event...) {
|
||||||
slots_used_before_gc, slots_allocated_before_gc,
|
slots_used_before_gc, slots_allocated_before_gc,
|
||||||
slots_used_after_gc, slots_allocated_after_gc);
|
slots_used_after_gc, slots_allocated_after_gc);
|
||||||
|
|
||||||
|
#ifdef UBE_BERRY_DEBUG_GC
|
||||||
// Add more in-deptch metrics
|
// Add more in-deptch metrics
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_BERRY "GC timing (us) 1:%i 2:%i 3:%i 4:%i 5:%i total:%i",
|
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_BERRY "GC timing (us) 1:%i 2:%i 3:%i 4:%i 5:%i total:%i",
|
||||||
vm->micros_gc1 - vm->micros_gc0,
|
vm->micros_gc1 - vm->micros_gc0,
|
||||||
|
@ -254,6 +255,7 @@ void BerryObservability(bvm *vm, int event...) {
|
||||||
vm->gc_mark_module,
|
vm->gc_mark_module,
|
||||||
vm->gc_mark_comobj
|
vm->gc_mark_comobj
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
// make new threshold tighter when we reach high memory usage
|
// make new threshold tighter when we reach high memory usage
|
||||||
if (!UsePSRAM() && vm->gc.threshold > 20*1024) {
|
if (!UsePSRAM() && vm->gc.threshold > 20*1024) {
|
||||||
vm->gc.threshold = vm->gc.usage + 10*1024; // increase by only 10 KB
|
vm->gc.threshold = vm->gc.usage + 10*1024; // increase by only 10 KB
|
||||||
|
|
|
@ -35,10 +35,10 @@
|
||||||
*
|
*
|
||||||
* -- Write multiple coils --
|
* -- Write multiple coils --
|
||||||
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
|
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
|
||||||
*
|
*
|
||||||
* Info for modbusBridgeTCPServer:
|
* Info for modbusBridgeTCPServer:
|
||||||
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
|
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
|
||||||
*
|
*
|
||||||
* Info for modbus serial communications:
|
* Info for modbus serial communications:
|
||||||
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
|
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
|
||||||
* https://www.modbustools.com/modbus.html
|
* https://www.modbustools.com/modbus.html
|
||||||
|
@ -102,7 +102,7 @@ ModbusBridgeTCP modbusBridgeTCP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <TasmotaModbus.h>
|
#include <TasmotaModbus.h>
|
||||||
TasmotaModbus *tasmotaModbus = nullptr;
|
TasmotaModbus *modbusBridgeModbus = nullptr;
|
||||||
|
|
||||||
enum class ModbusBridgeError
|
enum class ModbusBridgeError
|
||||||
{
|
{
|
||||||
|
@ -172,22 +172,18 @@ ModbusBridge modbusBridge;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
//
|
//
|
||||||
// Helper functions for data conversion between little and big endian
|
// Helper functions
|
||||||
//
|
//
|
||||||
uint16_t swap_endian16(uint16_t num)
|
uint16_t ModbusBridgeSwapEndian16(uint16_t num)
|
||||||
{
|
{
|
||||||
return (num>>8) | (num<<8);
|
return (num>>8) | (num<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t swap_endian32(uint32_t num)
|
void ModbusBridgeAllocError(const char* s)
|
||||||
{
|
{
|
||||||
return ((num>>24)&0xff) | // move byte 3 to byte 0
|
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
|
||||||
((num<<8)&0xff0000) | // move byte 1 to byte 2
|
|
||||||
((num>>8)&0xff00) | // move byte 2 to byte 1
|
|
||||||
((num<<24)&0xff000000); // byte 0 to byte 3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
//
|
//
|
||||||
// Applies serial configuration to modbus serial port
|
// Applies serial configuration to modbus serial port
|
||||||
|
@ -199,7 +195,7 @@ bool ModbusBridgeBegin(void)
|
||||||
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
|
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
|
||||||
Settings->modbus_sconfig = TS_SERIAL_8N1;
|
Settings->modbus_sconfig = TS_SERIAL_8N1;
|
||||||
|
|
||||||
int result = tasmotaModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
|
int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (2 == result)
|
if (2 == result)
|
||||||
|
@ -211,7 +207,7 @@ bool ModbusBridgeBegin(void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetModbusBridgeConfig(uint32_t serial_config)
|
void ModbusBridgeSetConfig(uint32_t serial_config)
|
||||||
{
|
{
|
||||||
if (serial_config > TS_SERIAL_8O2)
|
if (serial_config > TS_SERIAL_8O2)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +220,7 @@ void SetModbusBridgeConfig(uint32_t serial_config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetModbusBridgeBaudrate(uint32_t baudrate)
|
void ModbusBridgeSetBaudrate(uint32_t baudrate)
|
||||||
{
|
{
|
||||||
if ((baudrate >= 300) && (baudrate <= 115200))
|
if ((baudrate >= 300) && (baudrate <= 115200))
|
||||||
{
|
{
|
||||||
|
@ -242,14 +238,19 @@ void SetModbusBridgeBaudrate(uint32_t baudrate)
|
||||||
//
|
//
|
||||||
void ModbusBridgeHandle(void)
|
void ModbusBridgeHandle(void)
|
||||||
{
|
{
|
||||||
bool data_ready = tasmotaModbus->ReceiveReady();
|
bool data_ready = modbusBridgeModbus->ReceiveReady();
|
||||||
if (data_ready)
|
if (data_ready)
|
||||||
{
|
{
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
|
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
|
||||||
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
|
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
|
||||||
|
if (nullptr == buffer)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("read"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
memset(buffer, 0, 9 + modbusBridge.byteCount);
|
memset(buffer, 0, 9 + modbusBridge.byteCount);
|
||||||
uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
|
uint32_t error = modbusBridgeModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
|
||||||
|
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
|
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
|
||||||
|
@ -257,7 +258,7 @@ void ModbusBridgeHandle(void)
|
||||||
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
|
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
uint8_t header[8];
|
uint8_t header[9];
|
||||||
uint8_t nrOfBytes = 8;
|
uint8_t nrOfBytes = 8;
|
||||||
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
|
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
|
||||||
header[1] = modbusBridgeTCP.tcp_transaction_id;
|
header[1] = modbusBridgeTCP.tcp_transaction_id;
|
||||||
|
@ -274,7 +275,7 @@ void ModbusBridgeHandle(void)
|
||||||
nrOfBytes += 1;
|
nrOfBytes += 1;
|
||||||
client.write(header, 9);
|
client.write(header, 9);
|
||||||
}
|
}
|
||||||
else if (buffer[1] <= 2)
|
else if (buffer[1] <= 2)
|
||||||
{
|
{
|
||||||
header[4] = modbusBridge.byteCount >> 8;
|
header[4] = modbusBridge.byteCount >> 8;
|
||||||
header[5] = modbusBridge.byteCount + 3;
|
header[5] = modbusBridge.byteCount + 3;
|
||||||
|
@ -284,7 +285,7 @@ void ModbusBridgeHandle(void)
|
||||||
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
|
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
|
||||||
nrOfBytes += modbusBridge.byteCount;
|
nrOfBytes += modbusBridge.byteCount;
|
||||||
}
|
}
|
||||||
else if (buffer[1] <= 4)
|
else if (buffer[1] <= 4)
|
||||||
{
|
{
|
||||||
header[4] = modbusBridge.byteCount >> 8;
|
header[4] = modbusBridge.byteCount >> 8;
|
||||||
header[5] = modbusBridge.byteCount + 3;
|
header[5] = modbusBridge.byteCount + 3;
|
||||||
|
@ -358,10 +359,10 @@ void ModbusBridgeHandle(void)
|
||||||
if (modbusBridge.type == ModbusBridgeType::mb_raw)
|
if (modbusBridge.type == ModbusBridgeType::mb_raw)
|
||||||
{
|
{
|
||||||
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
|
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
|
||||||
for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
|
for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR("%d"), buffer[i]);
|
ResponseAppend_P(PSTR("%d"), buffer[i]);
|
||||||
if (i < tasmotaModbus->ReceiveCount() - 1)
|
if (i < modbusBridgeModbus->ReceiveCount() - 1)
|
||||||
ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR(","));
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("]}"));
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
@ -371,10 +372,10 @@ void ModbusBridgeHandle(void)
|
||||||
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
|
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
|
||||||
{
|
{
|
||||||
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
|
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
|
||||||
for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
|
for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
|
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
|
||||||
if (i < tasmotaModbus->ReceiveCount() - 1)
|
if (i < modbusBridgeModbus->ReceiveCount() - 1)
|
||||||
ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR(","));
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("]}"));
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
@ -396,7 +397,7 @@ void ModbusBridgeHandle(void)
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
||||||
dataOffset = 4;
|
dataOffset = 4;
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
|
||||||
|
|
||||||
|
@ -530,7 +531,7 @@ void ModbusBridgeHandle(void)
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
|
||||||
ResponseAppend_P(PSTR("}"));
|
ResponseAppend_P(PSTR("}"));
|
||||||
ResponseJsonEnd();
|
ResponseJsonEnd();
|
||||||
|
@ -557,14 +558,14 @@ void ModbusBridgeInit(void)
|
||||||
{
|
{
|
||||||
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
|
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
|
||||||
{
|
{
|
||||||
tasmotaModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
|
modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
|
||||||
ModbusBridgeBegin();
|
ModbusBridgeBegin();
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
// If TCP bridge is enabled allocate a TCP receive buffer
|
// If TCP bridge is enabled allocate a TCP receive buffer
|
||||||
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
|
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
|
||||||
if (!modbusBridgeTCP.tcp_buf)
|
if (nullptr == modbusBridgeTCP.tcp_buf)
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: MBRTCP could not allocate buffer"));
|
ModbusBridgeAllocError(PSTR("TCP"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -582,7 +583,7 @@ void ModbusTCPHandle(void)
|
||||||
bool busy; // did we transfer some data?
|
bool busy; // did we transfer some data?
|
||||||
int32_t buf_len;
|
int32_t buf_len;
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check for a new client connection
|
// check for a new client connection
|
||||||
|
@ -656,8 +657,8 @@ void ModbusTCPHandle(void)
|
||||||
if (mbfunctioncode <= 2)
|
if (mbfunctioncode <= 2)
|
||||||
{
|
{
|
||||||
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
||||||
modbusBridge.byteCount = ((count - 1) >> 3) + 1;
|
modbusBridge.byteCount = ((count - 1) >> 3) + 1;
|
||||||
modbusBridge.dataCount = ((count - 1) >> 4) + 1;
|
modbusBridge.dataCount = ((count - 1) >> 4) + 1;
|
||||||
}
|
}
|
||||||
else if (mbfunctioncode <= 4)
|
else if (mbfunctioncode <= 4)
|
||||||
{
|
{
|
||||||
|
@ -667,17 +668,22 @@ void ModbusTCPHandle(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For functioncode 15 & 16 ignore bytecount, tasmotaModbus does calculate this
|
// For functioncode 15 & 16 ignore bytecount, modbusBridgeModbus does calculate this
|
||||||
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
|
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
|
||||||
uint16_t byteCount = (buf_len - dataStartByte);
|
uint16_t byteCount = (buf_len - dataStartByte);
|
||||||
modbusBridge.byteCount = 2;
|
modbusBridge.byteCount = 2;
|
||||||
modbusBridge.dataCount = 1;
|
modbusBridge.dataCount = 1;
|
||||||
|
|
||||||
writeData = (uint16_t *)malloc((byteCount / 2)+1);
|
writeData = (uint16_t *)malloc((byteCount / 2)+1);
|
||||||
|
if (nullptr == writeData)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("write"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
||||||
else count = 1;
|
else count = 1;
|
||||||
|
|
||||||
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
|
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
|
||||||
{
|
{
|
||||||
if (dataPointer % 2 == 0)
|
if (dataPointer % 2 == 0)
|
||||||
|
@ -685,7 +691,7 @@ void ModbusTCPHandle(void)
|
||||||
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
|
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
|
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,7 +700,7 @@ void ModbusTCPHandle(void)
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
|
||||||
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
|
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
|
||||||
|
|
||||||
tasmotaModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
|
modbusBridgeModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
|
||||||
|
|
||||||
free(writeData);
|
free(writeData);
|
||||||
}
|
}
|
||||||
|
@ -860,6 +866,11 @@ void CmndModbusBridgeSend(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
|
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
|
||||||
|
if (nullptr == writeData)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("write"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
|
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
|
||||||
{
|
{
|
||||||
|
@ -889,7 +900,7 @@ void CmndModbusBridgeSend(void)
|
||||||
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
|
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
|
||||||
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_hex:
|
case ModbusBridgeType::mb_hex:
|
||||||
case ModbusBridgeType::mb_raw:
|
case ModbusBridgeType::mb_raw:
|
||||||
case ModbusBridgeType::mb_uint8:
|
case ModbusBridgeType::mb_uint8:
|
||||||
|
@ -899,31 +910,31 @@ void CmndModbusBridgeSend(void)
|
||||||
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
|
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
|
||||||
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_int16:
|
case ModbusBridgeType::mb_int16:
|
||||||
writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
||||||
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
|
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_uint16:
|
case ModbusBridgeType::mb_uint16:
|
||||||
writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
||||||
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
|
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_int32:
|
case ModbusBridgeType::mb_int32:
|
||||||
writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
||||||
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
|
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
|
||||||
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
|
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_uint32:
|
case ModbusBridgeType::mb_uint32:
|
||||||
writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
|
||||||
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
|
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_float:
|
case ModbusBridgeType::mb_float:
|
||||||
// TODO
|
// TODO
|
||||||
default:
|
default:
|
||||||
|
@ -952,20 +963,20 @@ void CmndModbusBridgeSend(void)
|
||||||
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
|
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
|
||||||
modbusBridge.dataCount = 1;
|
modbusBridge.dataCount = 1;
|
||||||
|
|
||||||
uint8_t error = tasmotaModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
|
uint8_t error = modbusBridgeModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
|
||||||
free(writeData);
|
free(writeData);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndModbusBridgeSetBaudrate(void)
|
void CmndModbusBridgeSetBaudrate(void)
|
||||||
{
|
{
|
||||||
SetModbusBridgeBaudrate(XdrvMailbox.payload);
|
ModbusBridgeSetBaudrate(XdrvMailbox.payload);
|
||||||
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
|
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,7 +992,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
{ // Use 0..23 as serial config option
|
{ // Use 0..23 as serial config option
|
||||||
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
|
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
|
||||||
{
|
{
|
||||||
SetModbusBridgeConfig(XdrvMailbox.payload);
|
ModbusBridgeSetConfig(XdrvMailbox.payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
|
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
|
||||||
|
@ -989,7 +1000,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
||||||
if (serial_config >= 0)
|
if (serial_config >= 0)
|
||||||
{
|
{
|
||||||
SetModbusBridgeConfig(serial_config);
|
ModbusBridgeSetConfig(serial_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1015,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
void CmndModbusTCPStart(void)
|
void CmndModbusTCPStart(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1068,7 @@ void CmndModbusTCPConnect(void)
|
||||||
{
|
{
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1127,7 @@ bool Xdrv63(uint8_t function)
|
||||||
{
|
{
|
||||||
ModbusBridgeInit();
|
ModbusBridgeInit();
|
||||||
}
|
}
|
||||||
else if (tasmotaModbus)
|
else if (modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
|
|
|
@ -191,8 +191,9 @@ bool WcPinUsed(void) {
|
||||||
}
|
}
|
||||||
if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) ||
|
if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) ||
|
||||||
!PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) ||
|
!PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) ||
|
||||||
!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) {
|
((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled_2) // preferred option is to reuse and share I2Cbus 2
|
||||||
pin_used = false;
|
) {
|
||||||
|
pin_used = false;
|
||||||
}
|
}
|
||||||
return pin_used;
|
return pin_used;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +342,14 @@ uint32_t WcSetup(int32_t fsiz) {
|
||||||
config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); // PCLK_GPIO_NUM;
|
config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); // PCLK_GPIO_NUM;
|
||||||
config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); // VSYNC_GPIO_NUM;
|
config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); // VSYNC_GPIO_NUM;
|
||||||
config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM;
|
config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM;
|
||||||
config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM;
|
config.pin_sccb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; - unset to use shared I2C bus 2
|
||||||
config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
|
config.pin_sccb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
|
||||||
|
if(TasmotaGlobal.i2c_enabled_2){ // configure SIOD and SIOC as SDA,2 and SCL,2
|
||||||
|
config.sccb_i2c_port = 1; // reuse initialized bus 2, can be shared now
|
||||||
|
if(config.pin_sccb_sda < 0){ // GPIO_WEBCAM_SIOD must not be set to really make it happen
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("CAM: use I2C bus 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
config.pin_pwdn = Pin(GPIO_WEBCAM_PWDN); // PWDN_GPIO_NUM;
|
config.pin_pwdn = Pin(GPIO_WEBCAM_PWDN); // PWDN_GPIO_NUM;
|
||||||
config.pin_reset = Pin(GPIO_WEBCAM_RESET); // RESET_GPIO_NUM;
|
config.pin_reset = Pin(GPIO_WEBCAM_RESET); // RESET_GPIO_NUM;
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: Template pin config"));
|
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: Template pin config"));
|
||||||
|
|
|
@ -49,13 +49,15 @@ void ShellyProUpdate(void) {
|
||||||
// bit 3 = wifi led green
|
// bit 3 = wifi led green
|
||||||
// bit 4 = wifi led red
|
// bit 4 = wifi led red
|
||||||
// bit 5 - 7 = nc
|
// bit 5 - 7 = nc
|
||||||
uint32_t val = SPro.power | SPro.ledlink;
|
// OE is connected to Gnd with 470 ohm resistor R62 AND a capacitor C81 to 3V3
|
||||||
|
// - this inhibits output of signals (also relay state) during power on for a few seconds
|
||||||
|
uint8_t val = SPro.power | SPro.ledlink;
|
||||||
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
|
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
|
||||||
SPI.transfer(val); // Write 74HC595 shift register
|
SPI.transfer(val); // Write 74HC595 shift register
|
||||||
SPI.endTransaction();
|
SPI.endTransaction();
|
||||||
delayMicroseconds(2); // Wait for SPI clock to stop
|
// delayMicroseconds(2); // Wait for SPI clock to stop
|
||||||
digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
|
digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
|
||||||
delayMicroseconds(2); // Shelly 10mS
|
delayMicroseconds(1); // Shelly 10mS
|
||||||
digitalWrite(SPro.pin_shift595_rclk, 0);
|
digitalWrite(SPro.pin_shift595_rclk, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,9 +66,9 @@ void ShellyProPreInit(void) {
|
||||||
PinUsed(GPIO_SPI_CS) &&
|
PinUsed(GPIO_SPI_CS) &&
|
||||||
TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
|
TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
|
||||||
|
|
||||||
if (PinUsed(GPIO_SWT1)) {
|
if (PinUsed(GPIO_SWT1) || PinUsed(GPIO_KEY1)) {
|
||||||
TasmotaGlobal.devices_present++; // Shelly Pro 1
|
TasmotaGlobal.devices_present++; // Shelly Pro 1
|
||||||
if (PinUsed(GPIO_SWT1, 1)) {
|
if (PinUsed(GPIO_SWT1, 1) || PinUsed(GPIO_KEY1, 1)) {
|
||||||
TasmotaGlobal.devices_present++; // Shelly Pro 2
|
TasmotaGlobal.devices_present++; // Shelly Pro 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,21 +78,18 @@ void ShellyProPreInit(void) {
|
||||||
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
|
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
|
||||||
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
||||||
|
|
||||||
SPro.power = TasmotaGlobal.power &3; // Restore power
|
SPro.ledlink = 0x18; // Blue led on - set by first call ShellyProPower()
|
||||||
SPro.ledlink = 0x18; // Blue led on
|
|
||||||
ShellyProUpdate();
|
|
||||||
|
|
||||||
SPro.detected = true;
|
SPro.detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShellyProInit(void) {
|
void ShellyProInit(void) {
|
||||||
int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
|
int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
|
||||||
// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
|
// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
|
||||||
digitalWrite(pin_lan_reset, 0);
|
digitalWrite(pin_lan_reset, 0);
|
||||||
pinMode(pin_lan_reset, OUTPUT);
|
pinMode(pin_lan_reset, OUTPUT);
|
||||||
delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
|
delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
|
||||||
digitalWrite(pin_lan_reset, 1);
|
digitalWrite(pin_lan_reset, 1);
|
||||||
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
|
AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
|
||||||
|
@ -123,9 +122,14 @@ void ShellyProLedLink(void) {
|
||||||
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
|
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
|
||||||
*/
|
*/
|
||||||
SPro.last_update = TasmotaGlobal.uptime;
|
SPro.last_update = TasmotaGlobal.uptime;
|
||||||
uint32_t ledlink = 0x1C; // All leds off
|
uint32_t ledlink = 0x1C; // All leds off
|
||||||
if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
|
if (XdrvMailbox.index) {
|
||||||
if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
|
ledlink &= 0xFB; // Blue blinks if wifi/mqtt lost
|
||||||
|
}
|
||||||
|
else if (!TasmotaGlobal.global_state.wifi_down) {
|
||||||
|
ledlink &= 0xF7; // Green On
|
||||||
|
}
|
||||||
|
|
||||||
ShellyProUpdateLedLink(ledlink);
|
ShellyProUpdateLedLink(ledlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,583 @@
|
||||||
|
/*
|
||||||
|
xdrv_89_esp32_dali.ino - DALI support for Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2022 Andrei Kazmirtsuk aka eeak
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
Version yyyymmdd Action Description
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
0.0.0.1 20221027 publish - initial version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#ifdef USE_DALI
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* DALI support for Tasmota
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XDRV_89 89
|
||||||
|
|
||||||
|
#ifndef DALI_TIMER
|
||||||
|
#define DALI_TIMER 0 // Default timer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BROADCAST_DP 0b11111110 // 0xFE
|
||||||
|
#define DALI_TOPIC "DALI"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DALI_NO_ACTION,
|
||||||
|
DALI_SENDING_DATA,
|
||||||
|
DALI_RECEIVING_DATA,
|
||||||
|
DALI_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
// http and json defines
|
||||||
|
#define D_NAME_DALI "DALI"
|
||||||
|
|
||||||
|
const char S_JSON_DALI_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_DALI "\":{\"%s\":%d}}";
|
||||||
|
const char kDALI_Commands[] PROGMEM = D_CMND_DALI_POWER "|" D_CMND_DALI_DIMMER;
|
||||||
|
|
||||||
|
enum DALI_Commands { // commands for Console
|
||||||
|
CMND_DALI_PWR,
|
||||||
|
CMND_DALI_DIM,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DALI {
|
||||||
|
uint16_t send_dali_data; // data to send to DALI bus
|
||||||
|
uint16_t received_dali_data; // data received from DALI bus
|
||||||
|
uint8_t flag; // DALI status flag
|
||||||
|
uint8_t bit_count; // nr of rec/send bits
|
||||||
|
uint16_t tick_count; // nr of ticks of the timer
|
||||||
|
bool former_val; // bit value in previous tick of timer
|
||||||
|
hw_timer_t *timer; // hardware timer
|
||||||
|
} *Dali = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* DALI low level
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles hardware timer Handler.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void IRAM_ATTR DALI_Tick_Handler(void)
|
||||||
|
{
|
||||||
|
if (getDaliFlag() == DALI_RECEIVING_DATA)
|
||||||
|
{
|
||||||
|
receive_tick();
|
||||||
|
}
|
||||||
|
else if (getDaliFlag() == DALI_SENDING_DATA)
|
||||||
|
{
|
||||||
|
send_tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function enable data transfer start interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void enableDaliRxInterrupt() {
|
||||||
|
Dali->flag = DALI_NO_ACTION;
|
||||||
|
timerAlarmDisable(Dali->timer);
|
||||||
|
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function disable data transfer start interrupt.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void disableRxInterrupt() {
|
||||||
|
timerAlarmEnable(Dali->timer);
|
||||||
|
detachInterrupt(Pin(GPIO_DALI_RX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief receiving flag status
|
||||||
|
* @param None
|
||||||
|
* @retval uint8_t flag
|
||||||
|
*/
|
||||||
|
uint8_t getDaliFlag(void)
|
||||||
|
{
|
||||||
|
return Dali->flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DALI data received callback
|
||||||
|
* @param None
|
||||||
|
* @retval uint8_t flag
|
||||||
|
*/
|
||||||
|
void DataReceivedCallback() {
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali->received_dali_data>>9, Dali->received_dali_data&0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************** R E C E I V E * P R O C E D U R E S *******/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief receive data from DALI bus
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void receiveDaliData()
|
||||||
|
{
|
||||||
|
// null variables
|
||||||
|
Dali->received_dali_data = 0;
|
||||||
|
Dali->bit_count = 0;
|
||||||
|
Dali->tick_count = 0;
|
||||||
|
Dali->former_val = true;
|
||||||
|
|
||||||
|
Dali->flag = DALI_RECEIVING_DATA;
|
||||||
|
|
||||||
|
disableRxInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get state of DALIIN pin
|
||||||
|
* @param None
|
||||||
|
* @retval bool status
|
||||||
|
*/
|
||||||
|
bool get_DALIIN(void)
|
||||||
|
{
|
||||||
|
bool dali_read = digitalRead(Pin(GPIO_DALI_RX));
|
||||||
|
return (false == DALI_IN_INVERT) ? dali_read : !dali_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief receiving data from DALI bus
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*
|
||||||
|
* |--------|----|---------------------------|----|
|
||||||
|
* 0 24 32 160 176
|
||||||
|
* wait start data stop
|
||||||
|
*/
|
||||||
|
void receive_tick(void)
|
||||||
|
{
|
||||||
|
// four ticks per bit
|
||||||
|
bool actual_val = get_DALIIN();
|
||||||
|
Dali->tick_count++;
|
||||||
|
|
||||||
|
// edge detected
|
||||||
|
if(actual_val != Dali->former_val)
|
||||||
|
{
|
||||||
|
switch(Dali->bit_count)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (Dali->tick_count > 2)
|
||||||
|
{
|
||||||
|
Dali->tick_count = 0;
|
||||||
|
Dali->bit_count = 1; // start bit
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 17: // 1st stop bit
|
||||||
|
if(Dali->tick_count > 6) { // stop bit error, no edge should exist
|
||||||
|
Dali->flag = DALI_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // other bits
|
||||||
|
if(Dali->tick_count > 6)
|
||||||
|
{
|
||||||
|
Dali->received_dali_data |= (actual_val << (16-Dali->bit_count));
|
||||||
|
Dali->bit_count++;
|
||||||
|
Dali->tick_count = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else // voltage level stable
|
||||||
|
{
|
||||||
|
switch(Dali->bit_count)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if(Dali->tick_count==8) { // too long start bit
|
||||||
|
Dali->flag = DALI_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
// First stop bit
|
||||||
|
if (Dali->tick_count==8)
|
||||||
|
{
|
||||||
|
if (actual_val==0) // wrong level of stop bit
|
||||||
|
{
|
||||||
|
Dali->flag = DALI_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dali->bit_count++;
|
||||||
|
Dali->tick_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
// Second stop bit
|
||||||
|
if (Dali->tick_count==8)
|
||||||
|
{
|
||||||
|
enableDaliRxInterrupt();
|
||||||
|
DataReceivedCallback();
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // normal bits
|
||||||
|
if(Dali->tick_count==10)
|
||||||
|
{ // too long delay before edge
|
||||||
|
Dali->flag = DALI_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dali->former_val = actual_val;
|
||||||
|
if(getDaliFlag() == DALI_ERROR)
|
||||||
|
{
|
||||||
|
enableDaliRxInterrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************** S E N D * P R O C E D U R E S *************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set value to the DALIOUT pin
|
||||||
|
* @param bool
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void set_DALIOUT(bool pin_value)
|
||||||
|
{
|
||||||
|
digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALI_OUT_INVERT ? LOW : HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets state of the DALIOUT pin
|
||||||
|
* @param None
|
||||||
|
* @retval bool state of the DALIOUT pin
|
||||||
|
*/
|
||||||
|
bool get_DALIOUT(void)
|
||||||
|
{
|
||||||
|
bool dali_read = digitalRead(Pin(GPIO_DALI_TX));
|
||||||
|
return (false == DALI_OUT_INVERT) ? dali_read : !dali_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send data to DALI bus
|
||||||
|
* @param byteToSend
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void sendDaliData(uint8_t firstByte, uint8_t secondByte)
|
||||||
|
{
|
||||||
|
Dali->send_dali_data = firstByte << 8;
|
||||||
|
Dali->send_dali_data += secondByte & 0xff;
|
||||||
|
Dali->bit_count = 0;
|
||||||
|
Dali->tick_count = 0;
|
||||||
|
|
||||||
|
Dali->flag = DALI_SENDING_DATA;
|
||||||
|
|
||||||
|
disableRxInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DALI protocol physical layer for slave device
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*
|
||||||
|
* |--------|----|---------------------------|----|
|
||||||
|
* 0 24 32 160 176
|
||||||
|
* wait start data stop
|
||||||
|
*/
|
||||||
|
void send_tick(void)
|
||||||
|
{
|
||||||
|
// access to the routine just every 4 ticks = every half bit
|
||||||
|
if ((Dali->tick_count & 0x03) == 0)
|
||||||
|
{
|
||||||
|
if (Dali->tick_count < 160)
|
||||||
|
{
|
||||||
|
// settling time between forward and backward frame
|
||||||
|
if (Dali->tick_count < 24)
|
||||||
|
{
|
||||||
|
Dali->tick_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start of the start bit
|
||||||
|
if (Dali->tick_count == 24)
|
||||||
|
{
|
||||||
|
// GPIOB->ODR ^= GPIO_ODR_7;
|
||||||
|
set_DALIOUT(false);
|
||||||
|
Dali->tick_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge of the start bit
|
||||||
|
// 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
|
||||||
|
if (Dali->tick_count == 28)
|
||||||
|
{
|
||||||
|
set_DALIOUT(true);
|
||||||
|
Dali->tick_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bit value (edge) selection
|
||||||
|
bool bit_value = (bool)((Dali->send_dali_data >> (15 - Dali->bit_count)) & 0x01);
|
||||||
|
|
||||||
|
// Every half bit -> Manchester coding
|
||||||
|
if (!((Dali->tick_count - 24) & 0x0007))
|
||||||
|
{ // div by 8
|
||||||
|
if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
|
||||||
|
set_DALIOUT((bool)(1 - bit_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate edge for actual bit
|
||||||
|
if (!((Dali->tick_count - 28) & 0x0007))
|
||||||
|
{
|
||||||
|
set_DALIOUT(bit_value);
|
||||||
|
Dali->bit_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // end of data byte, start of stop bits
|
||||||
|
if (Dali->tick_count == 160)
|
||||||
|
{
|
||||||
|
set_DALIOUT(true); // start of stop bit
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of stop bits, no settling time
|
||||||
|
if (Dali->tick_count == 176)
|
||||||
|
{
|
||||||
|
enableDaliRxInterrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dali->tick_count++;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
|
||||||
|
void DaliPreInit() {
|
||||||
|
if (!PinUsed(GPIO_DALI_TX) || !PinUsed(GPIO_DALI_RX)) { return; }
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("DLI: Init - RX-pin: %d, TX-pin: %d"), Pin(GPIO_DALI_RX), Pin(GPIO_DALI_TX));
|
||||||
|
// pinMode(LED, OUTPUT);
|
||||||
|
pinMode(Pin(GPIO_DALI_TX), OUTPUT);
|
||||||
|
digitalWrite(Pin(GPIO_DALI_TX), HIGH);
|
||||||
|
pinMode(Pin(GPIO_DALI_RX), INPUT);
|
||||||
|
|
||||||
|
Dali = (DALI*)calloc(1,sizeof(DALI));
|
||||||
|
if (!Dali) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("DLI: Memory allocation error"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Dali->timer = timerBegin(DALI_TIMER, 13, true);
|
||||||
|
timerAttachInterrupt(Dali->timer, &DALI_Tick_Handler, true);
|
||||||
|
timerAlarmWrite(Dali->timer, 641, true);
|
||||||
|
|
||||||
|
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
|
||||||
|
enableDaliRxInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DaliPwr(uint8_t val){
|
||||||
|
sendDaliData(BROADCAST_DP, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaliCmd(void)
|
||||||
|
{
|
||||||
|
char command[CMDSZ];
|
||||||
|
uint8_t name_len = strlen(D_NAME_DALI);
|
||||||
|
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_DALI), name_len))
|
||||||
|
{
|
||||||
|
uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kDALI_Commands);
|
||||||
|
switch (command_code)
|
||||||
|
{
|
||||||
|
case CMND_DALI_PWR:
|
||||||
|
if (XdrvMailbox.data_len)
|
||||||
|
{
|
||||||
|
if (254 >= XdrvMailbox.payload)
|
||||||
|
{
|
||||||
|
DaliPwr(XdrvMailbox.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response_P(S_JSON_DALI_COMMAND_NVALUE, command, XdrvMailbox.payload);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DaliMqtt()
|
||||||
|
{
|
||||||
|
char stopic[TOPSZ];
|
||||||
|
strncpy(stopic, XdrvMailbox.topic, TOPSZ);
|
||||||
|
XdrvMailbox.topic[TOPSZ - 1] = 0;
|
||||||
|
|
||||||
|
char *items[10];
|
||||||
|
char *p = stopic;
|
||||||
|
int cnt = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
items[cnt] = strtok(p, "/");
|
||||||
|
cnt++;
|
||||||
|
p = nullptr;
|
||||||
|
} while (items[cnt - 1]);
|
||||||
|
cnt--; // repreents the number of items
|
||||||
|
|
||||||
|
if (cnt < 3)
|
||||||
|
{ // not for us?
|
||||||
|
AddLog(LOG_LEVEL_INFO,PSTR("cnt: %d < 3"), cnt);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DALIindex = 0;
|
||||||
|
int ADRindex = 0;
|
||||||
|
int CMDindex = 0;
|
||||||
|
uint8_t DALIaddr = BROADCAST_DP;
|
||||||
|
if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0)
|
||||||
|
{
|
||||||
|
if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0)
|
||||||
|
{
|
||||||
|
if (strcasecmp_P(items[cnt - 1], PSTR(DALI_TOPIC)) != 0)
|
||||||
|
{
|
||||||
|
return false; // not for us
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (true == DaliJsonParse()) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DALIindex = cnt - 2;
|
||||||
|
CMDindex = cnt - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DALIindex = cnt - 3;
|
||||||
|
CMDindex = cnt - 2;
|
||||||
|
ADRindex = cnt - 1;
|
||||||
|
DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t level;
|
||||||
|
uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
|
||||||
|
if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
|
||||||
|
float percent = (float)(254 * value * 0.01);
|
||||||
|
level = (uint8_t)percent;
|
||||||
|
}
|
||||||
|
else if (strcasecmp_P(items[CMDindex], PSTR("level")) == 0) {
|
||||||
|
level = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AddLog(LOG_LEVEL_INFO,PSTR("command not recognized: %s"), items[CMDindex]);
|
||||||
|
return false; // not for us
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLog(LOG_LEVEL_INFO,PSTR("Dali value %d on address %d"), value, DALIaddr);
|
||||||
|
sendDaliData(DALIaddr, level);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaliJsonParse()
|
||||||
|
{
|
||||||
|
bool served = false;
|
||||||
|
JsonParser parser((char *)XdrvMailbox.data);
|
||||||
|
JsonParserObject root = parser.getRootObject();
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
int DALIindex = 0;
|
||||||
|
int ADRindex = 0;
|
||||||
|
int8_t DALIdim = -1;
|
||||||
|
uint8_t DALIaddr = BROADCAST_DP;
|
||||||
|
|
||||||
|
JsonParserToken val = root[PSTR("cmd")];
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
uint8_t cmd = val.getUInt();
|
||||||
|
val = root[PSTR("addr")];
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
uint8_t addr = val.getUInt();
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
|
||||||
|
sendDaliData(addr, cmd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = root[PSTR("addr")];
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
uint8_t addr = val.getUInt();
|
||||||
|
if ((addr >= 0) && (addr < 64))
|
||||||
|
DALIaddr = addr << 1;
|
||||||
|
}
|
||||||
|
val = root[PSTR("dim")];
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
uint8_t dim = val.getUInt();
|
||||||
|
if (dim < 255)
|
||||||
|
DALIdim = dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendDaliData(DALIaddr, DALIdim);
|
||||||
|
served = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return served;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xdrv89(uint8_t function)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (FUNC_INIT == function)
|
||||||
|
{
|
||||||
|
DaliPreInit();
|
||||||
|
}
|
||||||
|
else if (Dali)
|
||||||
|
{
|
||||||
|
switch (function)
|
||||||
|
{
|
||||||
|
case FUNC_MQTT_DATA:
|
||||||
|
result = DaliMqtt();
|
||||||
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = DaliCmd();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_DALI
|
||||||
|
#endif // ESP32
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
xlgt_10_bp1658cj.ino - bp1658cj five channel led support for Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2022 Theo Arends and Cossid
|
||||||
|
|
||||||
|
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_LIGHT
|
||||||
|
#ifdef USE_BP1658CJ
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* BP1658CJ RGBCW Led bulbs like the Orein OS0100411267 Bulb
|
||||||
|
*
|
||||||
|
* Orein OS0100411267 Bulb
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* FIXME
|
||||||
|
* {"NAME":"Orein OS0100411267 Bulb","GPIO":[0,0,0,0,9129,9088,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XLGT_10 10
|
||||||
|
|
||||||
|
// 10 = identification | 00 = Standby | 0000 = start at OUT1/5
|
||||||
|
#define BP1658CJ_ADDR_STANDBY 0x80 // 10000000 0x80
|
||||||
|
// 10 = identification | 01 = 3 channels (RGB) | 0000 = start at OUT1/5
|
||||||
|
//#define BP1658CJ_ADDR_START_3CH 0x90 // 10010000 0xC8
|
||||||
|
// 10 = identification | 10 = 2 channels (CW) | 0000 = start at OUT1/5
|
||||||
|
//#define BP1658CJ_ADDR_START_2CH 0xA0 // 10100000 0xA0
|
||||||
|
// 10 = identification | 11 = 5 channels (RGB+CW) | 0000 = start at OUT1/5
|
||||||
|
#define BP1658CJ_ADDR_START_5CH 0xB0 // 10110000 0xB0
|
||||||
|
|
||||||
|
// Current values
|
||||||
|
// 0x0 // 0000 RGB 0mA | CW 0mA
|
||||||
|
// 0x1 // 0001 RGB 10mA | CW 5mA
|
||||||
|
// 0x2 // 0010 RGB 20mA | CW 10mA
|
||||||
|
// 0x3 // 0011 RGB 30mA | CW 15mA
|
||||||
|
// 0x4 // 0100 RGB 40mA | CW 20mA
|
||||||
|
// 0x5 // 0101 RGB 50mA | CW 25mA
|
||||||
|
// 0x6 // 0110 RGB 60mA | CW 30mA
|
||||||
|
// 0x7 // 0111 RGB 70mA | CW 35mA
|
||||||
|
// 0x8 // 1000 RGB 80mA | CW 40mA
|
||||||
|
// 0x9 // 1001 RGB 900mA | CW 45mA
|
||||||
|
// 0xA // 1010 RGB 100mA | CW 50mA
|
||||||
|
// 0xB // 1011 RGB 110mA | CW 55mA
|
||||||
|
// 0xC // 1100 RGB 120mA | CW 60mA
|
||||||
|
// 0xD // 1101 RGB 130mA | CW 65mA
|
||||||
|
// 0xE // 1110 RGB 140mA | CW 70mA
|
||||||
|
// 0xF // 1111 RGB 150mA | CW 75mA
|
||||||
|
|
||||||
|
struct BP1658CJ {
|
||||||
|
uint8_t clk = 0;
|
||||||
|
uint8_t data = 0;
|
||||||
|
uint8_t current;
|
||||||
|
} Bp1658cj;
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* BP1658CJ code - inspired by Bp5758d/SM2335
|
||||||
|
\*********************************************************************************************/
|
||||||
|
const uint8_t BP1658CJ_DELAY = 2;
|
||||||
|
|
||||||
|
void BP1658CJInit(void) {
|
||||||
|
pinMode(Bp1658cj.data, OUTPUT);
|
||||||
|
pinMode(Bp1658cj.clk, OUTPUT);
|
||||||
|
BP1658CJStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BP1658CJWrite(uint8_t value) {
|
||||||
|
for (int bit_idx = 7; bit_idx >= 0; bit_idx--) {
|
||||||
|
bool bit = bitRead(value, bit_idx);
|
||||||
|
digitalWrite(Bp1658cj.data, bit);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
digitalWrite(Bp1658cj.clk, HIGH);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
digitalWrite(Bp1658cj.clk, LOW);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
}
|
||||||
|
// Wait for ACK
|
||||||
|
pinMode(Bp1658cj.data, INPUT);
|
||||||
|
digitalWrite(Bp1658cj.clk, HIGH);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
digitalWrite(Bp1658cj.clk, LOW);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
pinMode(Bp1658cj.data, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BP1658CJStart(uint8_t addr) {
|
||||||
|
digitalWrite(Bp1658cj.data, LOW);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
digitalWrite(Bp1658cj.clk, LOW);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
BP1658CJWrite(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BP1658CJStop(void) {
|
||||||
|
digitalWrite(Bp1658cj.clk, HIGH);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
digitalWrite(Bp1658cj.data, HIGH);
|
||||||
|
delayMicroseconds(BP1658CJ_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
bool BP1658CJSetChannels(void) {
|
||||||
|
uint16_t *cur_col_10 = (uint16_t*)XdrvMailbox.command;
|
||||||
|
|
||||||
|
// If we receive 0 for all channels, we'll assume that the lightbulb is off, and activate BP1658CJ's standby mode.
|
||||||
|
if (cur_col_10[0] == 0 && cur_col_10[1] == 0 && cur_col_10[2] == 0 && cur_col_10[3] == 0 && cur_col_10[4] == 0) {
|
||||||
|
BP1658CJStart(BP1658CJ_ADDR_STANDBY);
|
||||||
|
// Clear all remaining data. This clears out Current, Red, Green, Blue, Cold White, Warm White.
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
BP1658CJWrite(0);
|
||||||
|
}
|
||||||
|
BP1658CJStop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the header activating all 5 channels
|
||||||
|
BP1658CJStart(BP1658CJ_ADDR_START_5CH);
|
||||||
|
// Set the current defined in ModuleSelected.
|
||||||
|
BP1658CJWrite(Bp1658cj.current);
|
||||||
|
// Set RGB and CW grayscale.
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
BP1658CJWrite((uint8_t)(cur_col_10[i] & 0x1F));
|
||||||
|
BP1658CJWrite((uint8_t)(cur_col_10[i] >> 5));
|
||||||
|
}
|
||||||
|
BP1658CJStop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BP1658CJModuleSelected(void)
|
||||||
|
{
|
||||||
|
if (PinUsed(GPIO_BP1658CJ_CLK) && PinUsed(GPIO_BP1658CJ_DAT, GPIO_ANY)) {
|
||||||
|
Bp1658cj.clk = Pin(GPIO_BP1658CJ_CLK);
|
||||||
|
Bp1658cj.data = Pin(GPIO_BP1658CJ_DAT, GPIO_ANY);
|
||||||
|
// See #define MAX_BP1658CJ_DAT 16 in tasmota_template.h
|
||||||
|
int currentDat = GetPin(Bp1658cj.data) - AGPIO(GPIO_BP1658CJ_DAT); // 0 .. 15
|
||||||
|
// Split RGB and CW current.
|
||||||
|
Bp1658cj.current = (currentDat << 4) | currentDat;
|
||||||
|
|
||||||
|
BP1658CJInit();
|
||||||
|
|
||||||
|
TasmotaGlobal.light_type = LT_RGBWC;
|
||||||
|
TasmotaGlobal.light_driver = XLGT_10;
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("LGT: BP1658CJ Found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xlgt10(uint8_t function)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_SET_CHANNELS:
|
||||||
|
result = BP1658CJSetChannels();
|
||||||
|
break;
|
||||||
|
case FUNC_MODULE_INIT:
|
||||||
|
BP1658CJModuleSelected();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_BP1658CJ
|
||||||
|
#endif // USE_LIGHT
|
|
@ -290,17 +290,17 @@ bool HlwCommand(void) {
|
||||||
}
|
}
|
||||||
else if (CMND_POWERSET == Energy.command_code) {
|
else if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Hlw.cf_power_pulse_length ) {
|
if (XdrvMailbox.data_len && Hlw.cf_power_pulse_length ) {
|
||||||
Settings->energy_power_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
|
XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Hlw.cf1_voltage_pulse_length ) {
|
if (XdrvMailbox.data_len && Hlw.cf1_voltage_pulse_length ) {
|
||||||
Settings->energy_voltage_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
|
XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Hlw.cf1_current_pulse_length) {
|
if (XdrvMailbox.data_len && Hlw.cf1_current_pulse_length) {
|
||||||
Settings->energy_current_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
|
XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -63,7 +63,8 @@ void CseReceived(void) {
|
||||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
// F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load
|
// F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load
|
||||||
// 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W)
|
// 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W)
|
||||||
// 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok
|
// 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok, F1 = CF overflow, no problem
|
||||||
|
// 55 5A 02 F1 E8 00 07 9D 00 3F 3E 00 35 F8 50 DB 38 00 B2 A2 F1 D6 97 3E - CF overflow
|
||||||
|
|
||||||
// 55 5A 02 DB 40 00 03 25 00 3D 18 03 8E CD 4F 0A 60 2A 56 85 61 01 02 1A - OK voltage
|
// 55 5A 02 DB 40 00 03 25 00 3D 18 03 8E CD 4F 0A 60 2A 56 85 61 01 02 1A - OK voltage
|
||||||
// 55 5A 02 DB 40 07 17 1D 00 3D 18 03 8E CD 4F 0A 60 2B EF EA 61 01 02 2C - Wrong voltage
|
// 55 5A 02 DB 40 07 17 1D 00 3D 18 03 8E CD 4F 0A 60 2B EF EA 61 01 02 2C - Wrong voltage
|
||||||
|
@ -256,17 +257,17 @@ bool CseCommand(void) {
|
||||||
|
|
||||||
if (CMND_POWERSET == Energy.command_code) {
|
if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Cse.power_cycle) {
|
if (XdrvMailbox.data_len && Cse.power_cycle) {
|
||||||
Settings->energy_power_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
|
XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Cse.voltage_cycle) {
|
if (XdrvMailbox.data_len && Cse.voltage_cycle) {
|
||||||
Settings->energy_voltage_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
|
XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Cse.current_cycle) {
|
if (XdrvMailbox.data_len && Cse.current_cycle) {
|
||||||
Settings->energy_current_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
|
XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -602,7 +602,7 @@ bool McpCommand(void)
|
||||||
if (XdrvMailbox.data_len && mcp_active_power) {
|
if (XdrvMailbox.data_len && mcp_active_power) {
|
||||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100);
|
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100);
|
||||||
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
||||||
Settings->energy_power_calibration = value;
|
XdrvMailbox.payload = value;
|
||||||
mcp_calibrate |= MCP_CALIBRATE_POWER;
|
mcp_calibrate |= MCP_CALIBRATE_POWER;
|
||||||
McpGetCalibration();
|
McpGetCalibration();
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ bool McpCommand(void)
|
||||||
if (XdrvMailbox.data_len && mcp_voltage_rms) {
|
if (XdrvMailbox.data_len && mcp_voltage_rms) {
|
||||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
||||||
if ((value > 1000) && (value < 2600)) { // Between 100V and 260V
|
if ((value > 1000) && (value < 2600)) { // Between 100V and 260V
|
||||||
Settings->energy_voltage_calibration = value;
|
XdrvMailbox.payload = value;
|
||||||
mcp_calibrate |= MCP_CALIBRATE_VOLTAGE;
|
mcp_calibrate |= MCP_CALIBRATE_VOLTAGE;
|
||||||
McpGetCalibration();
|
McpGetCalibration();
|
||||||
}
|
}
|
||||||
|
@ -622,7 +622,7 @@ bool McpCommand(void)
|
||||||
if (XdrvMailbox.data_len && mcp_current_rms) {
|
if (XdrvMailbox.data_len && mcp_current_rms) {
|
||||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
|
||||||
if ((value > 100) && (value < 80000)) { // Between 10mA and 8A
|
if ((value > 100) && (value < 80000)) { // Between 10mA and 8A
|
||||||
Settings->energy_current_calibration = value;
|
XdrvMailbox.payload = value;
|
||||||
mcp_calibrate |= MCP_CALIBRATE_CURRENT;
|
mcp_calibrate |= MCP_CALIBRATE_CURRENT;
|
||||||
McpGetCalibration();
|
McpGetCalibration();
|
||||||
}
|
}
|
||||||
|
@ -632,7 +632,7 @@ bool McpCommand(void)
|
||||||
if (XdrvMailbox.data_len && mcp_line_frequency) {
|
if (XdrvMailbox.data_len && mcp_line_frequency) {
|
||||||
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000);
|
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000);
|
||||||
if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz
|
if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz
|
||||||
Settings->energy_frequency_calibration = value;
|
XdrvMailbox.payload = value;
|
||||||
mcp_calibrate |= MCP_CALIBRATE_FREQUENCY;
|
mcp_calibrate |= MCP_CALIBRATE_FREQUENCY;
|
||||||
McpGetFrequency();
|
McpGetFrequency();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
#define ADE7953_ACCU_ENERGY // Use accumulating energy instead of instant power
|
||||||
|
|
||||||
//#define ADE7953_DUMP_REGS
|
//#define ADE7953_DUMP_REGS
|
||||||
|
|
||||||
#define ADE7953_PREF 1540 // 4194304 / (1540 / 1000) = 2723574 (= WGAIN, VAGAIN and VARGAIN)
|
#define ADE7953_PREF 1540 // 4194304 / (1540 / 1000) = 2723574 (= WGAIN, VAGAIN and VARGAIN)
|
||||||
|
@ -201,10 +203,22 @@ const uint16_t Ade7953CalibRegs[2][ADE7953_CALIBREGS] {
|
||||||
|
|
||||||
const uint8_t ADE7953_REGISTERS = 6;
|
const uint8_t ADE7953_REGISTERS = 6;
|
||||||
const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
|
const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
|
||||||
|
#ifdef ADE7953_ACCU_ENERGY
|
||||||
|
{ ADE7953_IRMSA, ADE7953_AENERGYA, ADE7953_APENERGYA, ADE7953_RENERGYA, ADE7953_VRMS, ADE7943_Period },
|
||||||
|
{ ADE7953_IRMSB, ADE7953_AENERGYB, ADE7953_APENERGYB, ADE7953_RENERGYB, ADE7953_VRMS, ADE7943_Period }
|
||||||
|
#else // No ADE7953_ACCU_ENERGY
|
||||||
{ ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
|
{ ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
|
||||||
{ ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
|
{ ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
|
||||||
|
#endif // ADE7953_ACCU_ENERGY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ADE7953_ACCU_ENERGY
|
||||||
|
const float ADE7953_LSB_PER_WATTSECOND = 2.5;
|
||||||
|
const float ADE7953_POWER_CORRECTION = 23.41494; // See https://github.com/arendst/Tasmota/pull/16941
|
||||||
|
#else // No ADE7953_ACCU_ENERGY
|
||||||
|
const float ADE7953_LSB_PER_WATTSECOND = 44;
|
||||||
|
#endif // ADE7953_ACCU_ENERGY
|
||||||
|
|
||||||
struct Ade7953 {
|
struct Ade7953 {
|
||||||
uint32_t voltage_rms[2] = { 0, 0 };
|
uint32_t voltage_rms[2] = { 0, 0 };
|
||||||
uint32_t current_rms[2] = { 0, 0 };
|
uint32_t current_rms[2] = { 0, 0 };
|
||||||
|
@ -272,7 +286,7 @@ void Ade7953Write(uint16_t reg, uint32_t val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Ade7953Read(uint16_t reg) {
|
int32_t Ade7953Read(uint16_t reg) {
|
||||||
uint32_t response = 0;
|
uint32_t response = 0;
|
||||||
|
|
||||||
int size = Ade7953RegSize(reg);
|
int size = Ade7953RegSize(reg);
|
||||||
if (size) {
|
if (size) {
|
||||||
|
@ -304,7 +318,7 @@ int32_t Ade7953Read(uint16_t reg) {
|
||||||
}
|
}
|
||||||
#endif // USE_ESP32_SPI
|
#endif // USE_ESP32_SPI
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADE7953_DUMP_REGS
|
#ifdef ADE7953_DUMP_REGS
|
||||||
|
@ -439,6 +453,9 @@ void Ade7953GetData(void) {
|
||||||
acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
|
acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
|
||||||
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
|
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
|
||||||
|
|
||||||
|
// If the device is initializing, we read the energy registers to reset them, but don't report the values as the first read may be inaccurate
|
||||||
|
if (Ade7953.init_step) { return; }
|
||||||
|
|
||||||
uint32_t apparent_power[2] = { 0, 0 };
|
uint32_t apparent_power[2] = { 0, 0 };
|
||||||
uint32_t reactive_power[2] = { 0, 0 };
|
uint32_t reactive_power[2] = { 0, 0 };
|
||||||
|
|
||||||
|
@ -463,12 +480,19 @@ void Ade7953GetData(void) {
|
||||||
for (uint32_t channel = 0; channel < 2; channel++) {
|
for (uint32_t channel = 0; channel < 2; channel++) {
|
||||||
Energy.data_valid[channel] = 0;
|
Energy.data_valid[channel] = 0;
|
||||||
|
|
||||||
|
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10;
|
||||||
|
#ifdef ADE7953_ACCU_ENERGY
|
||||||
|
power_calibration /= ADE7953_POWER_CORRECTION;
|
||||||
|
#endif // ADE7953_ACCU_ENERGY
|
||||||
|
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION);
|
||||||
|
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10;
|
||||||
|
|
||||||
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
|
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
|
||||||
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
|
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
|
||||||
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
|
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
|
||||||
divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
|
divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
|
||||||
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
|
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
|
||||||
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
|
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
|
||||||
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
|
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
|
||||||
if (ADE7953_SHELLY_EM == Ade7953.model) {
|
if (ADE7953_SHELLY_EM == Ade7953.model) {
|
||||||
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
|
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
|
||||||
|
@ -478,12 +502,12 @@ void Ade7953GetData(void) {
|
||||||
Energy.reactive_power[channel] *= -1;
|
Energy.reactive_power[channel] *= -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
|
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
|
||||||
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
|
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
|
||||||
if (0 == Energy.active_power[channel]) {
|
if (0 == Energy.active_power[channel]) {
|
||||||
Energy.current[channel] = 0;
|
Energy.current[channel] = 0;
|
||||||
} else {
|
} else {
|
||||||
divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
|
divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : current_calibration;
|
||||||
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
|
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
|
||||||
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
|
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
|
||||||
}
|
}
|
||||||
|
@ -493,14 +517,13 @@ void Ade7953GetData(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ade7953EnergyEverySecond(void) {
|
void Ade7953EnergyEverySecond(void) {
|
||||||
if (Ade7953.init_step) {
|
if (Ade7953.init_step) {
|
||||||
if (1 == Ade7953.init_step) {
|
if (2 == Ade7953.init_step) { Ade7953Init(); }
|
||||||
Ade7953Init();
|
if (1 == Ade7953.init_step) { Ade7953GetData(); } // Read registers but do not display yet
|
||||||
}
|
|
||||||
Ade7953.init_step--;
|
Ade7953.init_step--;
|
||||||
} else {
|
} else {
|
||||||
Ade7953GetData();
|
Ade7953GetData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
@ -657,11 +680,14 @@ void Ade7953DrvInit(void) {
|
||||||
Settings->energy_power_calibration = ADE7953_PREF;
|
Settings->energy_power_calibration = ADE7953_PREF;
|
||||||
Settings->energy_voltage_calibration = ADE7953_UREF;
|
Settings->energy_voltage_calibration = ADE7953_UREF;
|
||||||
Settings->energy_current_calibration = ADE7953_IREF;
|
Settings->energy_current_calibration = ADE7953_IREF;
|
||||||
|
Settings->energy_power_calibration2 = ADE7953_PREF;
|
||||||
|
Settings->energy_voltage_calibration2 = ADE7953_UREF;
|
||||||
|
Settings->energy_current_calibration2 = ADE7953_IREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ade7953Defaults();
|
Ade7953Defaults();
|
||||||
|
|
||||||
Ade7953.init_step = 2;
|
Ade7953.init_step = 3;
|
||||||
|
|
||||||
// Energy.phase_count = 1;
|
// Energy.phase_count = 1;
|
||||||
// Energy.voltage_common = false;
|
// Energy.voltage_common = false;
|
||||||
|
@ -705,21 +731,27 @@ bool Ade7953Command(void) {
|
||||||
else if (CMND_POWERSET == Energy.command_code) {
|
else if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
|
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
|
||||||
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
||||||
Settings->energy_power_calibration = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
|
#ifdef ADE7953_ACCU_ENERGY
|
||||||
|
float power_calibration = (float)(Ade7953.active_power[channel] * 1000) / value; // 0.00 W
|
||||||
|
power_calibration *= ADE7953_POWER_CORRECTION;
|
||||||
|
XdrvMailbox.payload = (uint32_t)power_calibration; // 0.00 W
|
||||||
|
#else // No ADE7953_ACCU_ENERGY
|
||||||
|
XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
|
||||||
|
#endif // ADE7953_ACCU_ENERGY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
|
if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
|
||||||
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
|
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
|
||||||
Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
|
XdrvMailbox.payload = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) {
|
if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) {
|
||||||
if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
|
if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
|
||||||
Settings->energy_current_calibration = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
|
XdrvMailbox.payload = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,9 +193,11 @@ void Bl09XXUpdateEnergy() {
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
|
||||||
#endif
|
#endif
|
||||||
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
|
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
|
||||||
if (Bl09XX.power[chan] > Settings->energy_power_calibration) { // We need at least 1W
|
uint32_t power_calibration = EnergyGetCalibration(chan, ENERGY_POWER_CALIBRATION);
|
||||||
Energy.active_power[chan] = (float)Bl09XX.power[chan] / Settings->energy_power_calibration;
|
uint32_t current_calibration = EnergyGetCalibration(chan, ENERGY_CURRENT_CALIBRATION);
|
||||||
Energy.current[chan] = (float)Bl09XX.current[chan] / Settings->energy_current_calibration;
|
if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
|
||||||
|
Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
|
||||||
|
Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration;
|
||||||
} else {
|
} else {
|
||||||
Energy.active_power[chan] = 0;
|
Energy.active_power[chan] = 0;
|
||||||
Energy.current[chan] = 0;
|
Energy.current[chan] = 0;
|
||||||
|
@ -289,6 +291,9 @@ void Bl09XXInit(void) {
|
||||||
Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model];
|
Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model];
|
||||||
Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model];
|
Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model];
|
||||||
Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model];
|
Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model];
|
||||||
|
Settings->energy_voltage_calibration2 = bl09xx_uref[Bl09XX.model];
|
||||||
|
Settings->energy_current_calibration2 = bl09xx_iref[Bl09XX.model];
|
||||||
|
Settings->energy_power_calibration2 = bl09xx_pref[Bl09XX.model];
|
||||||
}
|
}
|
||||||
if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) {
|
if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) {
|
||||||
Settings->energy_current_calibration *= 100;
|
Settings->energy_current_calibration *= 100;
|
||||||
|
@ -357,17 +362,17 @@ bool Bl09XXCommand(void) {
|
||||||
|
|
||||||
if (CMND_POWERSET == Energy.command_code) {
|
if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Bl09XX.power[channel]) {
|
if (XdrvMailbox.data_len && Bl09XX.power[channel]) {
|
||||||
Settings->energy_power_calibration = (Bl09XX.power[channel] * 100) / value;
|
XdrvMailbox.payload = (Bl09XX.power[channel] * 100) / value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Bl09XX.voltage) {
|
if (XdrvMailbox.data_len && Bl09XX.voltage) {
|
||||||
Settings->energy_voltage_calibration = (Bl09XX.voltage * 100) / value;
|
XdrvMailbox.payload = (Bl09XX.voltage * 100) / value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && Bl09XX.current[channel]) {
|
if (XdrvMailbox.data_len && Bl09XX.current[channel]) {
|
||||||
Settings->energy_current_calibration = (Bl09XX.current[channel] * 100) / value;
|
XdrvMailbox.payload = (Bl09XX.current[channel] * 100) / value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else serviced = false; // Unknown command
|
else serviced = false; // Unknown command
|
||||||
|
|
|
@ -152,7 +152,7 @@ PROGMEM
|
||||||
"|"
|
"|"
|
||||||
;
|
;
|
||||||
|
|
||||||
#define TELEINFO_SERIAL_BUFFER_STANDARD 512 // Receive buffer size for Standard mode
|
#define TELEINFO_SERIAL_BUFFER_STANDARD 1536 // Receive buffer size for Standard mode
|
||||||
#define TELEINFO_SERIAL_BUFFER_HISTORIQUE 512 // Receive buffer size for Legacy mode
|
#define TELEINFO_SERIAL_BUFFER_HISTORIQUE 512 // Receive buffer size for Legacy mode
|
||||||
#define TELEINFO_PROCESS_BUFFER 32 // Local processing buffer
|
#define TELEINFO_PROCESS_BUFFER 32 // Local processing buffer
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ uint8_t tic_rx_pin = NOT_A_PIN;
|
||||||
char serialNumber[13] = ""; // Serial number is 12 char long
|
char serialNumber[13] = ""; // Serial number is 12 char long
|
||||||
bool tinfo_found = false;
|
bool tinfo_found = false;
|
||||||
int serial_buffer_size;
|
int serial_buffer_size;
|
||||||
|
uint32_t total_wh;
|
||||||
int contrat;
|
int contrat;
|
||||||
int tarif;
|
int tarif;
|
||||||
int isousc;
|
int isousc;
|
||||||
|
@ -183,7 +184,12 @@ char * getValueFromLabelIndex(int labelIndex, char * value)
|
||||||
// Get the label name
|
// Get the label name
|
||||||
GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel);
|
GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel);
|
||||||
// Get value of label name
|
// Get value of label name
|
||||||
return tinfo.valueGet(labelName, value) ;
|
tinfo.valueGet(labelName, value) ;
|
||||||
|
// Standard mode has values with space before/after
|
||||||
|
if (tinfo_mode==TINFO_MODE_STANDARD) {
|
||||||
|
Trim(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/* ======================================================================
|
||||||
|
@ -329,12 +335,11 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
||||||
char value[32];
|
char value[32];
|
||||||
uint32_t hc = 0;
|
uint32_t hc = 0;
|
||||||
uint32_t hp = 0;
|
uint32_t hp = 0;
|
||||||
uint32_t total = 0;
|
|
||||||
|
|
||||||
// Base, un seul index
|
// Base, un seul index
|
||||||
if (ilabel == LABEL_BASE) {
|
if (ilabel == LABEL_BASE) {
|
||||||
total = atol(me->value);
|
total_wh = atol(me->value);
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total_wh);
|
||||||
// Heures creuses/pleines calculer total
|
// Heures creuses/pleines calculer total
|
||||||
} else {
|
} else {
|
||||||
// Heures creuses get heures pleines
|
// Heures creuses get heures pleines
|
||||||
|
@ -352,15 +357,17 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hc>0 && hp>0) {
|
if (hc>0 && hp>0) {
|
||||||
total = hc + hp;
|
total_wh = hc + hp;
|
||||||
}
|
}
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total_wh);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total);
|
AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total_wh);
|
||||||
if (total>0) {
|
if (total_wh>0) {
|
||||||
Energy.import_active[0] = (float)total/1000.0f;
|
Energy.total[0] = (float) total_wh / 1000.0f;
|
||||||
EnergyUpdateTotal();
|
Energy.import_active[0] = Energy.total[0];
|
||||||
|
//Energy.import_active[0] = (float)total/1000.0f;
|
||||||
|
//EnergyUpdateTotal();
|
||||||
AddLog (LOG_LEVEL_DEBUG_MORE, PSTR ("TIC: import_active[0]=%.3fKWh"), Energy.import_active[0] );
|
AddLog (LOG_LEVEL_DEBUG_MORE, PSTR ("TIC: import_active[0]=%.3fKWh"), Energy.import_active[0] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,10 +375,10 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
||||||
// Wh total index (all contract)
|
// Wh total index (all contract)
|
||||||
else if ( ilabel == LABEL_EAST)
|
else if ( ilabel == LABEL_EAST)
|
||||||
{
|
{
|
||||||
uint32_t total = atol(me->value);
|
total_wh = atol(me->value);
|
||||||
Energy.import_active[0] = (float)total/1000.0f;
|
Energy.total[0] = (float) total_wh / 1000.0f;
|
||||||
EnergyUpdateTotal();
|
Energy.import_active[0] = Energy.total[0];
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total_wh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wh indexes (standard)
|
// Wh indexes (standard)
|
||||||
|
@ -538,7 +545,7 @@ void NewFrameCallback(struct _ValueList * me)
|
||||||
Energy.data_valid[0] = 0;
|
Energy.data_valid[0] = 0;
|
||||||
|
|
||||||
// Deprecated see setOption108
|
// Deprecated see setOption108
|
||||||
// send teleinfo raw data only if setup like that
|
// send teleinfo MQTT raw data only if setup like that
|
||||||
if (Settings->teleinfo.raw_send) {
|
if (Settings->teleinfo.raw_send) {
|
||||||
// Do we need to skip this frame
|
// Do we need to skip this frame
|
||||||
if (raw_skip == 0 ) {
|
if (raw_skip == 0 ) {
|
||||||
|
@ -578,6 +585,7 @@ void TInfoDrvInit(void) {
|
||||||
Energy.voltage_available = false;
|
Energy.voltage_available = false;
|
||||||
Energy.phase_count = 1;
|
Energy.phase_count = 1;
|
||||||
// init hardware energy counters
|
// init hardware energy counters
|
||||||
|
total_wh = 0;
|
||||||
Settings->flag3.hardware_energy_total = true;
|
Settings->flag3.hardware_energy_total = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,6 +681,25 @@ void TInfoInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
/* ======================================================================
|
||||||
|
Function: TInfoSaveBeforeRestart
|
||||||
|
Purpose : Save data before ESP restart
|
||||||
|
Input : -
|
||||||
|
Output : -
|
||||||
|
Comments: -
|
||||||
|
====================================================================== */
|
||||||
|
void TInfoSaveBeforeRestart()
|
||||||
|
{
|
||||||
|
// if teleinfo enabled, set it low
|
||||||
|
if (PinUsed (GPIO_TELEINFO_ENABLE)) {
|
||||||
|
digitalWrite( Pin(GPIO_TELEINFO_ENABLE), LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update energy total (in kwh)
|
||||||
|
EnergyUpdateTotal();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/* ======================================================================
|
||||||
Function: TInfoCmd
|
Function: TInfoCmd
|
||||||
|
@ -842,6 +869,7 @@ Comments: -
|
||||||
void TInfoProcess(void)
|
void TInfoProcess(void)
|
||||||
{
|
{
|
||||||
static char buff[TELEINFO_PROCESS_BUFFER];
|
static char buff[TELEINFO_PROCESS_BUFFER];
|
||||||
|
static uint32_t tick_update = 0;
|
||||||
#ifdef MEASURE_PERF
|
#ifdef MEASURE_PERF
|
||||||
static unsigned long max_time = 0;
|
static unsigned long max_time = 0;
|
||||||
unsigned long duration = millis();
|
unsigned long duration = millis();
|
||||||
|
@ -872,6 +900,14 @@ void TInfoProcess(void)
|
||||||
if (duration > max_time) { max_time = duration; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_time=%lu"), max_time); }
|
if (duration > max_time) { max_time = duration; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_time=%lu"), max_time); }
|
||||||
if (tmp_size > max_size) { max_size = tmp_size; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_size=%d"), max_size); }
|
if (tmp_size > max_size) { max_size = tmp_size; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_size=%d"), max_size); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// if needed, update energy total every hour
|
||||||
|
if (tick_update++ > 3600 * 4) {
|
||||||
|
EnergyUpdateTotal();
|
||||||
|
AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %lu Wh"), total_wh);
|
||||||
|
tick_update = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================
|
/* ======================================================================
|
||||||
|
@ -886,7 +922,8 @@ const char HTTP_ENERGY_ID_TELEINFO[] PROGMEM = "{s}ID{m}%s{e}" ;
|
||||||
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
|
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
|
||||||
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
|
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
|
||||||
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
|
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
|
||||||
const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s%s{e}" ;
|
const char HTTP_ENERGY_TARIF_TELEINFO_STD[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s{e}" ;
|
||||||
|
const char HTTP_ENERGY_TARIF_TELEINFO_HISTO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}Heures %s{e}" ;
|
||||||
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
|
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
|
||||||
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
|
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
|
||||||
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
|
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
|
||||||
|
@ -977,9 +1014,9 @@ void TInfoShow(bool json)
|
||||||
if (tarif) {
|
if (tarif) {
|
||||||
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
|
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
|
||||||
if (tinfo_mode==TINFO_MODE_STANDARD ) {
|
if (tinfo_mode==TINFO_MODE_STANDARD ) {
|
||||||
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "", name);
|
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, name);
|
||||||
} else {
|
} else {
|
||||||
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "Heures ", name);
|
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_HISTO, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contrat && isousc) {
|
if (contrat && isousc) {
|
||||||
|
@ -1006,7 +1043,7 @@ void TInfoShow(bool json)
|
||||||
WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value));
|
WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value));
|
||||||
}
|
}
|
||||||
if (getValueFromLabelIndex(LABEL_LTARF, value) ) {
|
if (getValueFromLabelIndex(LABEL_LTARF, value) ) {
|
||||||
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, value);
|
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, value);
|
||||||
}
|
}
|
||||||
if (getValueFromLabelIndex(LABEL_NGTF, value) ) {
|
if (getValueFromLabelIndex(LABEL_NGTF, value) ) {
|
||||||
if (isousc) {
|
if (isousc) {
|
||||||
|
@ -1035,6 +1072,9 @@ bool Xnrg15(uint8_t function)
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
TInfoInit();
|
TInfoInit();
|
||||||
break;
|
break;
|
||||||
|
case FUNC_SAVE_BEFORE_RESTART:
|
||||||
|
if (tinfo_found) { TInfoSaveBeforeRestart(); }
|
||||||
|
break;
|
||||||
case FUNC_PRE_INIT:
|
case FUNC_PRE_INIT:
|
||||||
TInfoDrvInit();
|
TInfoDrvInit();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -226,6 +226,8 @@ bool Cse7761ChipInit(void) {
|
||||||
Settings->energy_voltage_calibration = Cse7761Ref(RmsUC);
|
Settings->energy_voltage_calibration = Cse7761Ref(RmsUC);
|
||||||
Settings->energy_current_calibration = Cse7761Ref(RmsIAC);
|
Settings->energy_current_calibration = Cse7761Ref(RmsIAC);
|
||||||
Settings->energy_power_calibration = Cse7761Ref(PowerPAC);
|
Settings->energy_power_calibration = Cse7761Ref(PowerPAC);
|
||||||
|
Settings->energy_current_calibration2 = Settings->energy_current_calibration;
|
||||||
|
Settings->energy_power_calibration2 = Settings->energy_power_calibration;
|
||||||
}
|
}
|
||||||
// Just to fix intermediate users
|
// Just to fix intermediate users
|
||||||
if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) {
|
if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) {
|
||||||
|
@ -466,15 +468,17 @@ void Cse7761GetData(void) {
|
||||||
|
|
||||||
for (uint32_t channel = 0; channel < 2; channel++) {
|
for (uint32_t channel = 0; channel < 2; channel++) {
|
||||||
Energy.data_valid[channel] = 0;
|
Energy.data_valid[channel] = 0;
|
||||||
|
uint32_t power_calibration = EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION);
|
||||||
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
|
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
|
||||||
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
|
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
|
||||||
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / Settings->energy_power_calibration; // W
|
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
|
||||||
if (0 == Energy.active_power[channel]) {
|
if (0 == Energy.active_power[channel]) {
|
||||||
Energy.current[channel] = 0;
|
Energy.current[channel] = 0;
|
||||||
} else {
|
} else {
|
||||||
|
uint32_t current_calibration = EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION);
|
||||||
// Current = RmsIA * RmsIAC / 0x800000
|
// Current = RmsIA * RmsIAC / 0x800000
|
||||||
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
|
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
|
||||||
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / Settings->energy_current_calibration; // A
|
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A
|
||||||
CSE7761Data.energy[channel] += Energy.active_power[channel];
|
CSE7761Data.energy[channel] += Energy.active_power[channel];
|
||||||
CSE7761Data.energy_update[channel]++;
|
CSE7761Data.energy_update[channel]++;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +620,7 @@ bool Cse7761Command(void) {
|
||||||
else if (CMND_POWERSET == Energy.command_code) {
|
else if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && CSE7761Data.active_power[channel]) {
|
if (XdrvMailbox.data_len && CSE7761Data.active_power[channel]) {
|
||||||
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
|
||||||
Settings->energy_power_calibration = ((CSE7761Data.active_power[channel]) / value) * 100;
|
XdrvMailbox.payload = ((CSE7761Data.active_power[channel]) / value) * 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,7 +631,7 @@ bool Cse7761Command(void) {
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && CSE7761Data.voltage_rms) {
|
if (XdrvMailbox.data_len && CSE7761Data.voltage_rms) {
|
||||||
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
|
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
|
||||||
Settings->energy_voltage_calibration = (CSE7761Data.voltage_rms * 100) / value;
|
XdrvMailbox.payload = (CSE7761Data.voltage_rms * 100) / value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +642,7 @@ bool Cse7761Command(void) {
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && CSE7761Data.current_rms[channel]) {
|
if (XdrvMailbox.data_len && CSE7761Data.current_rms[channel]) {
|
||||||
if ((value > 1000) && (value < 1000000)) { // Between 10mA and 10A
|
if ((value > 1000) && (value < 1000000)) { // Between 10mA and 10A
|
||||||
Settings->energy_current_calibration = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
|
XdrvMailbox.payload = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,7 +654,7 @@ bool Cse7761Command(void) {
|
||||||
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len && CSE7761Data.frequency) {
|
if (XdrvMailbox.data_len && CSE7761Data.frequency) {
|
||||||
if ((value > 4500) && (value < 6500)) { // Between 45.00Hz and 65.00Hz
|
if ((value > 4500) && (value < 6500)) { // Between 45.00Hz and 65.00Hz
|
||||||
Settings->energy_frequency_calibration = (CSE7761Data.frequency * 8 * value) / 100;
|
XdrvMailbox.payload = (CSE7761Data.frequency * 8 * value) / 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,24 +22,24 @@
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Chinese BL6523 based Watt hour meter
|
* Chinese BL6523 based Watt hour meter
|
||||||
*
|
*
|
||||||
* This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
|
* This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
|
||||||
* To use Tasmota the user needs to add an ESP8266 or ESP32
|
* To use Tasmota the user needs to add an ESP8266 or ESP32
|
||||||
* Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
|
* Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
|
||||||
*
|
*
|
||||||
* Connection Eg (ESP8266) - Non - Isolated:
|
* Connection Eg (ESP8266) - Non - Isolated:
|
||||||
* BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
|
* BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
|
||||||
* BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
|
* BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
|
||||||
* BL6523 GND -> ESP GND
|
* BL6523 GND -> ESP GND
|
||||||
*
|
*
|
||||||
* Connection Eg (ESP32) - Non - Isolated:
|
* Connection Eg (ESP32) - Non - Isolated:
|
||||||
* BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
|
* BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
|
||||||
* BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
|
* BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
|
||||||
* BL6523 GND -> ESP GND
|
* BL6523 GND -> ESP GND
|
||||||
*
|
*
|
||||||
* To build add the below to user_config_override.h
|
* To build add the below to user_config_override.h
|
||||||
* #define USE_ENERGY_SENSOR // Enable Energy sensor framework
|
* #define USE_ENERGY_SENSOR // Enable Energy sensor framework
|
||||||
* #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
|
* #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
|
||||||
*
|
*
|
||||||
* After Installation use the below template sample:
|
* After Installation use the below template sample:
|
||||||
* {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
* {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -106,7 +106,7 @@ bool Bl6523ReadData(void)
|
||||||
Bl6523RxSerial->flush(); // Make room for another burst
|
Bl6523RxSerial->flush(); // Make room for another burst
|
||||||
|
|
||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
|
||||||
|
|
||||||
i=0;
|
i=0;
|
||||||
while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
|
while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -116,15 +116,15 @@ bool Bl6523ReadData(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
|
uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
|
||||||
Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
|
Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
|
||||||
Bl6523TxSerial->flush(); // Make room for another burst
|
Bl6523TxSerial->flush(); // Make room for another burst
|
||||||
|
|
||||||
|
|
||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
|
||||||
|
|
||||||
/* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
|
/* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
|
||||||
uint8_t crc = rx_buffer[1]; //Addr
|
uint8_t crc = rx_buffer[1]; //Addr
|
||||||
for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
|
for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
|
||||||
|
@ -136,15 +136,15 @@ bool Bl6523ReadData(void)
|
||||||
if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
|
if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE));
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE));
|
||||||
Bl6523TxSerial->flush();
|
Bl6523TxSerial->flush();
|
||||||
Bl6523RxSerial->flush();
|
Bl6523RxSerial->flush();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
|
/* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
|
||||||
WRITE Sample(RX):
|
WRITE Sample(RX):
|
||||||
RX: CA 3E 55 00 00 6C (WRPROT - allow)
|
RX: CA 3E 55 00 00 6C (WRPROT - allow)
|
||||||
RX: CA 14 00 00 10 DB (MODE)
|
RX: CA 14 00 00 10 DB (MODE)
|
||||||
RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
|
RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
|
||||||
RX: CA 19 08 00 00 DE (WA_CFDIV )
|
RX: CA 19 08 00 00 DE (WA_CFDIV )
|
||||||
RX: CA 3E AA 00 00 17 (WRPROT - disable)
|
RX: CA 3E AA 00 00 17 (WRPROT - disable)
|
||||||
|
@ -154,8 +154,8 @@ RX: CA 3E AA 00 00 17 (WRPROT - disable)
|
||||||
READ Sample(RX-TX) Data:
|
READ Sample(RX-TX) Data:
|
||||||
RX: 35 05 TX: E4 00 00 16 (IA rms )
|
RX: 35 05 TX: E4 00 00 16 (IA rms )
|
||||||
RX: 35 07 TX: D5 A3 2E 52 (V rms )
|
RX: 35 07 TX: D5 A3 2E 52 (V rms )
|
||||||
RX: 35 09 TX: F0 FB 02 09 (FREQ)
|
RX: 35 09 TX: F0 FB 02 09 (FREQ)
|
||||||
RX: 35 0A TX: 00 00 00 F5 (WATT)
|
RX: 35 0A TX: 00 00 00 F5 (WATT)
|
||||||
RX: 35 08 TX: 00 00 00 F7 (PF)
|
RX: 35 08 TX: 00 00 00 F7 (PF)
|
||||||
RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
|
RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
|
||||||
*/
|
*/
|
||||||
|
@ -169,7 +169,7 @@ switch(rx_buffer[1]) {
|
||||||
break;
|
break;
|
||||||
case BL6523_REG_FREQ :
|
case BL6523_REG_FREQ :
|
||||||
Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz
|
Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz
|
||||||
break;
|
break;
|
||||||
case BL6523_REG_WATTS :
|
case BL6523_REG_WATTS :
|
||||||
Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_power_calibration; // -196.3 W
|
Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_power_calibration; // -196.3 W
|
||||||
break;
|
break;
|
||||||
|
@ -181,7 +181,7 @@ switch(rx_buffer[1]) {
|
||||||
powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
|
powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
|
||||||
powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
|
powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
|
||||||
for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
|
for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
|
||||||
powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
|
powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
|
||||||
powf_word = powf_word & (0x7fffff >> (1+i));
|
powf_word = powf_word & (0x7fffff >> (1+i));
|
||||||
}
|
}
|
||||||
powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
|
powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
|
||||||
|
@ -190,8 +190,8 @@ switch(rx_buffer[1]) {
|
||||||
case BL6523_REG_WATTHR :
|
case BL6523_REG_WATTHR :
|
||||||
Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( Settings->energy_power_calibration - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal()
|
Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( Settings->energy_power_calibration - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal()
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Energy.data_valid[SINGLE_PHASE] = 0;
|
Energy.data_valid[SINGLE_PHASE] = 0;
|
||||||
EnergyUpdateTotal();
|
EnergyUpdateTotal();
|
||||||
|
@ -201,7 +201,7 @@ switch(rx_buffer[1]) {
|
||||||
Bl6523.discovery_triggered = true;
|
Bl6523.discovery_triggered = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
@ -216,7 +216,7 @@ void Bl6523Update(void)
|
||||||
{
|
{
|
||||||
if (Bl6523.valid) {
|
if (Bl6523.valid) {
|
||||||
Bl6523.valid--;
|
Bl6523.valid--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ void Bl6523Update(void)
|
||||||
|
|
||||||
void Bl6523Init(void)
|
void Bl6523Init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
Bl6523.type = 0;
|
Bl6523.type = 0;
|
||||||
Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
|
Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
|
||||||
Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
|
Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
|
||||||
|
@ -247,7 +247,7 @@ void Bl6523Init(void)
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" ));
|
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" ));
|
||||||
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bl6523Command(void) {
|
bool Bl6523Command(void) {
|
||||||
|
@ -262,28 +262,28 @@ bool Bl6523Command(void) {
|
||||||
else if (CMND_POWERSET == Energy.command_code) {
|
else if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value > 100) && (abs_value < 200000)) { // Between 1.00 and 2000.00 W
|
if ((abs_value > 100) && (abs_value < 200000)) { // Between 1.00 and 2000.00 W
|
||||||
Settings->energy_power_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value > 10000) && (abs_value < 26000)) { // Between 100.00 and 260.00 V
|
if ((abs_value > 10000) && (abs_value < 26000)) { // Between 100.00 and 260.00 V
|
||||||
Settings->energy_voltage_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value > 1000) && (abs_value < 1000000)) { // Between 10.00 mA and 10.00000 A
|
if ((abs_value > 1000) && (abs_value < 1000000)) { // Between 10.00 mA and 10.00000 A
|
||||||
Settings->energy_current_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value > 4500) && (abs_value < 6500)) { // Between 45.00 and 65.00 Hz
|
if ((abs_value > 4500) && (abs_value < 6500)) { // Between 45.00 and 65.00 Hz
|
||||||
Settings->energy_frequency_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ void Bl6523DrvInit(void)
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" ));
|
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" ));
|
||||||
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -333,7 +333,7 @@ void Bl6523DrvInit(void)
|
||||||
bool Xnrg22(uint8_t function)
|
bool Xnrg22(uint8_t function)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
case FUNC_EVERY_250_MSECOND:
|
case FUNC_EVERY_250_MSECOND:
|
||||||
|
@ -341,7 +341,7 @@ bool Xnrg22(uint8_t function)
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = Bl6523Command();
|
result = Bl6523Command();
|
||||||
break;
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
Bl6523Init();
|
Bl6523Init();
|
||||||
break;
|
break;
|
||||||
|
@ -349,7 +349,7 @@ bool Xnrg22(uint8_t function)
|
||||||
Bl6523DrvInit();
|
Bl6523DrvInit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,14 +55,20 @@ struct {
|
||||||
void NrgDummyEverySecond(void) {
|
void NrgDummyEverySecond(void) {
|
||||||
if (Energy.power_on) { // Powered on
|
if (Energy.power_on) { // Powered on
|
||||||
for (uint32_t channel = 0; channel < Energy.phase_count; channel++) {
|
for (uint32_t channel = 0; channel < Energy.phase_count; channel++) {
|
||||||
Energy.voltage[channel] = ((float)Settings->energy_voltage_calibration / 100); // V
|
|
||||||
Energy.frequency[channel] = ((float)Settings->energy_frequency_calibration / 100); // Hz
|
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 100;
|
||||||
if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
|
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION) / 100;
|
||||||
Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : ((float)Settings->energy_power_calibration / 100); // W
|
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) / 100000;
|
||||||
|
float frequency_calibration = (float)EnergyGetCalibration(channel, ENERGY_FREQUENCY_CALIBRATION) / 100;
|
||||||
|
|
||||||
|
Energy.voltage[channel] = power_calibration; // V
|
||||||
|
Energy.frequency[channel] = frequency_calibration; // Hz
|
||||||
|
if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
|
||||||
|
Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : voltage_calibration; // W
|
||||||
if (0 == Energy.active_power[channel]) {
|
if (0 == Energy.active_power[channel]) {
|
||||||
Energy.current[channel] = 0;
|
Energy.current[channel] = 0;
|
||||||
} else {
|
} else {
|
||||||
Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : ((float)Settings->energy_current_calibration / 100000); // A
|
Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : current_calibration; // A
|
||||||
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
|
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
|
||||||
}
|
}
|
||||||
Energy.data_valid[channel] = 0;
|
Energy.data_valid[channel] = 0;
|
||||||
|
@ -84,28 +90,28 @@ bool NrgDummyCommand(void) {
|
||||||
else if (CMND_POWERSET == Energy.command_code) {
|
else if (CMND_POWERSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value >= 100) && (abs_value <= 16000000)) { // Between 1.00 and 160000.00 W
|
if ((abs_value >= 100) && (abs_value <= 16000000)) { // Between 1.00 and 160000.00 W
|
||||||
Settings->energy_power_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_VOLTAGESET == Energy.command_code) {
|
else if (CMND_VOLTAGESET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value >= 10000) && (abs_value <= 40000)) { // Between 100.00 and 400.00 V
|
if ((abs_value >= 10000) && (abs_value <= 40000)) { // Between 100.00 and 400.00 V
|
||||||
Settings->energy_voltage_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_CURRENTSET == Energy.command_code) {
|
else if (CMND_CURRENTSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value >= 1000) && (abs_value <= 40000000)) { // Between 10.00 mA and 400.00000 A
|
if ((abs_value >= 1000) && (abs_value <= 40000000)) { // Between 10.00 mA and 400.00000 A
|
||||||
Settings->energy_current_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
else if (CMND_FREQUENCYSET == Energy.command_code) {
|
||||||
if (XdrvMailbox.data_len) {
|
if (XdrvMailbox.data_len) {
|
||||||
if ((abs_value >= 4500) && (abs_value <= 6500)) { // Between 45.00 and 65.00 Hz
|
if ((abs_value >= 4500) && (abs_value <= 6500)) { // Between 45.00 and 65.00 Hz
|
||||||
Settings->energy_frequency_calibration = abs_value;
|
XdrvMailbox.payload = abs_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,6 +140,9 @@ void NrgDummyDrvInit(void) {
|
||||||
Settings->energy_voltage_calibration = NRG_DUMMY_UREF;
|
Settings->energy_voltage_calibration = NRG_DUMMY_UREF;
|
||||||
Settings->energy_current_calibration = NRG_DUMMY_IREF;
|
Settings->energy_current_calibration = NRG_DUMMY_IREF;
|
||||||
Settings->energy_power_calibration = NRG_DUMMY_PREF;
|
Settings->energy_power_calibration = NRG_DUMMY_PREF;
|
||||||
|
Settings->energy_voltage_calibration2 = NRG_DUMMY_UREF;
|
||||||
|
Settings->energy_current_calibration2 = NRG_DUMMY_IREF;
|
||||||
|
Settings->energy_power_calibration2 = NRG_DUMMY_PREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
Energy.phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
|
Energy.phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota
|
xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota
|
||||||
|
|
||||||
Copyright (C) 2021 Andre Thomas and Theo Arends
|
Copyright (C) 2021 Andre Thomas, Theo Arends and md5sum-as (https://github.com/md5sum-as)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -47,24 +47,48 @@ TasmotaSerial *PN532_Serial;
|
||||||
#define PN532_COMMAND_SAMCONFIGURATION 0x14
|
#define PN532_COMMAND_SAMCONFIGURATION 0x14
|
||||||
#define PN532_COMMAND_RFCONFIGURATION 0x32
|
#define PN532_COMMAND_RFCONFIGURATION 0x32
|
||||||
#define PN532_COMMAND_INDATAEXCHANGE 0x40
|
#define PN532_COMMAND_INDATAEXCHANGE 0x40
|
||||||
|
#define PN532_COMMAND_INCOMMUNICATETHRU 0x42
|
||||||
#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A
|
#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A
|
||||||
|
#define PN532_COMMAND_INRELEASE 0x52
|
||||||
|
#define PN532_COMMAND_INSELECT 0x54
|
||||||
#define PN532_MIFARE_ISO14443A 0x00
|
#define PN532_MIFARE_ISO14443A 0x00
|
||||||
#define MIFARE_CMD_READ 0x30
|
#define MIFARE_CMD_READ 0x30
|
||||||
#define MIFARE_CMD_AUTH_A 0x60
|
#define MIFARE_CMD_AUTH_A 0x60
|
||||||
#define MIFARE_CMD_AUTH_B 0x61
|
#define MIFARE_CMD_AUTH_B 0x61
|
||||||
#define MIFARE_CMD_WRITE 0xA0
|
#define MIFARE_CMD_WRITE 0xA0
|
||||||
|
|
||||||
|
#define NTAG21X_CMD_GET_VERSION 0x60
|
||||||
|
#define NTAG2XX_CMD_READ 0x30
|
||||||
|
#define NTAG21X_CMD_FAST_READ 0x3A
|
||||||
|
#define NTAG21X_CMD_PWD_AUTH 0x1B
|
||||||
|
#define NTAG2XX_CMD_WRITE 0xA2
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
uint8_t version[6];
|
||||||
|
uint8_t confPage;
|
||||||
|
} NTAG[] PROGMEM ={
|
||||||
|
{.version={0x04, 0x02, 0x01, 0x00, 0x0f, 0x03},.confPage=0x29}, /* NTAG213 */
|
||||||
|
{.version={0x04, 0x02, 0x01, 0x00, 0x11, 0x03},.confPage=0x83}, /* NTAG215 */
|
||||||
|
{.version={0x04, 0x02, 0x01, 0x00, 0x13, 0x03},.confPage=0xe3}, /* NTAG216 */
|
||||||
|
{.version={0x04, 0x05, 0x02, 0x02, 0x13, 0x03},.confPage=0xe3}, /* NT3H2111 */
|
||||||
|
{.version={0x04, 0x05, 0x02, 0x02, 0x15, 0x03},.confPage=0xe3}, /* NT3H2211 */
|
||||||
|
};
|
||||||
|
#define NTAG_CNT (sizeof(NTAG)/7) // num records in NTAG array
|
||||||
|
|
||||||
struct PN532 {
|
struct PN532 {
|
||||||
char uids[21]; // Number of bytes in the UID. 4, 7 or 10
|
char uids[21]; // Number of bytes in the UID. 4, 7 or 10
|
||||||
uint8_t packetbuffer[64]; // Global buffer used to store packet
|
uint8_t packetbuffer[64]; // Global buffer used to store packet
|
||||||
uint8_t command = 0; // Carry command code between functions
|
uint8_t command = 0; // Carry command code between functions
|
||||||
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
|
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
|
||||||
bool present = false; // Maintain detection flag
|
bool present = false; // Maintain detection flag
|
||||||
|
uint16_t atqa;
|
||||||
#ifdef USE_PN532_DATA_FUNCTION
|
#ifdef USE_PN532_DATA_FUNCTION
|
||||||
uint8_t newdata[16];
|
uint8_t newdata[16];
|
||||||
uint8_t function = 0;
|
uint8_t function = 0;
|
||||||
uint8_t newdata_len = 0;
|
uint32_t pwd_auth;
|
||||||
|
uint16_t pwd_pack;
|
||||||
|
uint32_t pwd_auth_new;
|
||||||
|
uint16_t pwd_pack_new;
|
||||||
#endif // USE_PN532_DATA_FUNCTION
|
#endif // USE_PN532_DATA_FUNCTION
|
||||||
} Pn532;
|
} Pn532;
|
||||||
|
|
||||||
|
@ -82,6 +106,10 @@ void PN532_Init(void) {
|
||||||
PN532_SAMConfig();
|
PN532_SAMConfig();
|
||||||
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
|
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
|
||||||
Pn532.present = true;
|
Pn532.present = true;
|
||||||
|
#ifdef USE_PN532_DATA_FUNCTION
|
||||||
|
Pn532.pwd_auth=Settings->pn532_password;
|
||||||
|
Pn532.pwd_pack=Settings->pn532_pack;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,9 +301,9 @@ bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidL
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sens_res = Pn532.packetbuffer[2];
|
Pn532.atqa = Pn532.packetbuffer[2];
|
||||||
sens_res <<= 8;
|
Pn532.atqa <<= 8;
|
||||||
sens_res |= Pn532.packetbuffer[3];
|
Pn532.atqa |= Pn532.packetbuffer[3];
|
||||||
|
|
||||||
/* Card appears to be Mifare Classic */
|
/* Card appears to be Mifare Classic */
|
||||||
*uidLength = Pn532.packetbuffer[5];
|
*uidLength = Pn532.packetbuffer[5];
|
||||||
|
@ -310,9 +338,27 @@ bool PN532_SAMConfig(void) {
|
||||||
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* void PN532_inSelect(void) {
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
|
||||||
|
Pn532.packetbuffer[1] = 1;
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
|
||||||
|
} */
|
||||||
|
|
||||||
#ifdef USE_PN532_DATA_FUNCTION
|
#ifdef USE_PN532_DATA_FUNCTION
|
||||||
|
|
||||||
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
|
void PN532_inRelease(void) {
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
||||||
|
Pn532.packetbuffer[1] = 1;
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t PN532_mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint8_t _key[6];
|
uint8_t _key[6];
|
||||||
uint8_t _uid[7];
|
uint8_t _uid[7];
|
||||||
|
@ -349,7 +395,7 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
|
uint8_t PN532_mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||||
/* Prepare the command */
|
/* Prepare the command */
|
||||||
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||||
Pn532.packetbuffer[1] = 1; /* Card number */
|
Pn532.packetbuffer[1] = 1; /* Card number */
|
||||||
|
@ -376,7 +422,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
|
uint8_t PN532_mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||||
/* Prepare the first command */
|
/* Prepare the first command */
|
||||||
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||||
Pn532.packetbuffer[1] = 1; /* Card number */
|
Pn532.packetbuffer[1] = 1; /* Card number */
|
||||||
|
@ -393,73 +439,181 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||||
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t PN532_ntag21x_probe (void) {
|
||||||
|
uint8_t result=0;
|
||||||
|
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
|
||||||
|
Pn532.packetbuffer[1] = NTAG21X_CMD_GET_VERSION;
|
||||||
|
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))<9){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pn532.packetbuffer[3] != 4) { // not NTAG type
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<NTAG_CNT; i++) {
|
||||||
|
if (0 == memcmp_P(&Pn532.packetbuffer[3],&NTAG[i].version[0],6)) {
|
||||||
|
memcpy_P(&result,&NTAG[i].confPage,sizeof(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result; //Return configuration page address
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PN532_ntag21x_auth(void) {
|
||||||
|
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
|
||||||
|
Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH;
|
||||||
|
memcpy(&Pn532.packetbuffer[2],&Pn532.pwd_auth,4);
|
||||||
|
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 6)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<3){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Pn532.packetbuffer[0]) { //PN532 return any error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PN532_ntag2xx_read16 (const uint8_t page, char *out) {
|
||||||
|
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
|
||||||
|
Pn532.packetbuffer[1] = NTAG2XX_CMD_READ;
|
||||||
|
Pn532.packetbuffer[2] = page;
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Pn532.packetbuffer[0]!=0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(out,&Pn532.packetbuffer[1],16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PN532_ntag2xx_write4(uint8_t page, char *in) {
|
||||||
|
|
||||||
|
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
|
||||||
|
Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE;
|
||||||
|
Pn532.packetbuffer[2] = page; // first page
|
||||||
|
memcpy(&Pn532.packetbuffer[3],in,4);
|
||||||
|
|
||||||
|
if (PN532_writeCommand(Pn532.packetbuffer, 7)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PN532_ntag2xx_write16(uint8_t page, char *in) {
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
if (!PN532_ntag2xx_write4(page +i, &in[i << 2])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PN532_ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
|
||||||
|
char card_datas[16];
|
||||||
|
|
||||||
|
if (PN532_ntag2xx_read16(confPage, card_datas)) {
|
||||||
|
if (unsetPasswd) {
|
||||||
|
card_datas[3]=0xFF;
|
||||||
|
return PN532_ntag2xx_write4(confPage, card_datas);
|
||||||
|
}
|
||||||
|
card_datas[3]=0; // Set AUTH0 for protect all pages
|
||||||
|
card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
|
||||||
|
memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
|
||||||
|
memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
|
||||||
|
return PN532_ntag2xx_write16(confPage, card_datas);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // USE_PN532_DATA_FUNCTION
|
#endif // USE_PN532_DATA_FUNCTION
|
||||||
|
|
||||||
void PN532_ScanForTag(void) {
|
void PN532_ScanForTag(void) {
|
||||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
uint8_t uid_len = 0;
|
uint8_t uid_len = 0;
|
||||||
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) {
|
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) {
|
||||||
|
|
||||||
ToHex_P((unsigned char*)uid, uid_len, Pn532.uids, sizeof(Pn532.uids));
|
ToHex_P((unsigned char*)uid, uid_len, Pn532.uids, sizeof(Pn532.uids));
|
||||||
|
|
||||||
#ifdef USE_PN532_DATA_FUNCTION
|
#ifdef USE_PN532_DATA_FUNCTION
|
||||||
bool erase_success = false;
|
bool success = false;
|
||||||
bool set_success = false;
|
char card_datas[17]={0};
|
||||||
char card_datas[34];
|
enum {NOPWD, PWD_NONE, PWD_OK, PWD_NOK} str_pwd=NOPWD;
|
||||||
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
|
|
||||||
|
if (Pn532.atqa == 0x44) {
|
||||||
|
uint8_t confPage=0;
|
||||||
|
uint8_t nuid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
uint8_t nuid_len = 0;
|
||||||
|
if ((confPage=PN532_ntag21x_probe())>0) {
|
||||||
|
/* NTAG EV1 found*/
|
||||||
|
str_pwd=PWD_NONE;
|
||||||
|
if (!PN532_ntag2xx_read16(4, card_datas)) {
|
||||||
|
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
|
||||||
|
if (memcmp(uid, nuid, sizeof(uid))==0) {
|
||||||
|
if (PN532_ntag21x_auth()) {
|
||||||
|
str_pwd=PWD_OK;
|
||||||
|
if (Pn532.function == 3) { /* new password */
|
||||||
|
success = PN532_ntag21x_set_password(confPage, false);
|
||||||
|
}
|
||||||
|
if (Pn532.function == 4) { /* clear password */
|
||||||
|
success = PN532_ntag21x_set_password(confPage, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str_pwd=PWD_NOK;
|
||||||
|
}
|
||||||
|
if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Pn532.function == 3) { /* new password */
|
||||||
|
success = PN532_ntag21x_set_password(confPage, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
|
||||||
|
if (memcmp(uid, nuid, sizeof(uid))==0) {
|
||||||
|
if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Pn532.function == 1) || (Pn532.function == 2)) {
|
||||||
|
success = PN532_ntag2xx_write16(4, (char *)Pn532.newdata);
|
||||||
|
if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
|
||||||
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
|
if (PN532_mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
|
||||||
uint8_t card_data[16];
|
if ((Pn532.function == 1) || (Pn532.function == 2)) {
|
||||||
if (mifareclassic_ReadDataBlock(1, card_data)) {
|
success=PN532_mifareclassic_WriteDataBlock(1, Pn532.newdata);
|
||||||
#ifdef USE_PN532_DATA_RAW
|
|
||||||
memcpy(&card_datas,&card_data,sizeof(card_data));
|
|
||||||
#else
|
|
||||||
for (uint32_t i = 0;i < sizeof(card_data);i++) {
|
|
||||||
if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) {
|
|
||||||
card_datas[i] = char(card_data[i]);
|
|
||||||
} else {
|
|
||||||
card_datas[i] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // USE_PN532_DATA_RAW
|
|
||||||
}
|
}
|
||||||
if (Pn532.function == 1) { // erase block 1 of card
|
if (PN532_mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
|
||||||
for (uint32_t i = 0;i<16;i++) {
|
for (uint32_t i = 0; i < 16; i++) {
|
||||||
card_data[i] = 0x00;
|
if (!isprint(card_datas[i])) {
|
||||||
}
|
// do not output non-printable characters to the console
|
||||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
card_datas[i] = 0;
|
||||||
erase_success = true;
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
|
|
||||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Pn532.function == 2) {
|
|
||||||
#ifdef USE_PN532_DATA_RAW
|
|
||||||
memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
|
|
||||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
|
||||||
set_success = true;
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
|
|
||||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool IsAlphaNumeric = true;
|
|
||||||
for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
|
|
||||||
if ((!isalpha(Pn532.newdata[i])) && (!isdigit(Pn532.newdata[i]))) {
|
|
||||||
IsAlphaNumeric = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsAlphaNumeric) {
|
} else {
|
||||||
memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
|
card_datas[0] = 0;
|
||||||
card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
|
|
||||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
|
||||||
set_success = true;
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
|
|
||||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric"));
|
|
||||||
}
|
|
||||||
#endif // USE_PN532_DATA_RAW
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sprintf_P(card_datas, PSTR("AUTHFAIL"));
|
sprintf_P(card_datas, PSTR("AUTHFAIL"));
|
||||||
|
@ -467,19 +621,50 @@ void PN532_ScanForTag(void) {
|
||||||
}
|
}
|
||||||
switch (Pn532.function) {
|
switch (Pn532.function) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
if (!erase_success) {
|
if (success) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase success"));
|
||||||
|
} else {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase fail - exiting erase mode"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
if (!set_success) {
|
if (success) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Data write successful"));
|
||||||
|
} else{
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Write failed - exiting set mode"));
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
if (success) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password successful"));
|
||||||
|
} else{
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password failed - exiting set mode"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
if (success) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password successful"));
|
||||||
|
} else{
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password failed - exiting set mode"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Pn532.function = 0;
|
Pn532.function = 0;
|
||||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Pn532.uids, card_datas);
|
card_datas[16] = 0;
|
||||||
|
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas);
|
||||||
|
if (str_pwd == PWD_NONE) {
|
||||||
|
ResponseAppend_P(PSTR(",\"Auth\":\"None\""));
|
||||||
|
} else
|
||||||
|
if (str_pwd == PWD_OK) {
|
||||||
|
ResponseAppend_P(PSTR(",\"Auth\":\"Ok\""));
|
||||||
|
} else
|
||||||
|
if (str_pwd == PWD_NOK) {
|
||||||
|
ResponseAppend_P(PSTR(",\"Auth\":\"NOk\""));
|
||||||
|
}
|
||||||
|
ResponseAppend_P(PSTR("}}"));
|
||||||
|
PN532_inRelease();
|
||||||
#else
|
#else
|
||||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
|
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
|
||||||
#endif // USE_PN532_DATA_FUNCTION
|
#endif // USE_PN532_DATA_FUNCTION
|
||||||
|
@ -492,44 +677,73 @@ void PN532_ScanForTag(void) {
|
||||||
#ifdef USE_PN532_DATA_FUNCTION
|
#ifdef USE_PN532_DATA_FUNCTION
|
||||||
|
|
||||||
bool PN532_Command(void) {
|
bool PN532_Command(void) {
|
||||||
bool serviced = true;
|
bool serviced = false;
|
||||||
uint8_t paramcount = 0;
|
char command[10];
|
||||||
if (XdrvMailbox.data_len > 0) {
|
char log[70];
|
||||||
paramcount=1;
|
if (ArgC() < 1) {
|
||||||
} else {
|
|
||||||
serviced = false;
|
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
char argument[XdrvMailbox.data_len];
|
char argument[XdrvMailbox.data_len];
|
||||||
for (uint32_t ca=0;ca<XdrvMailbox.data_len;ca++) {
|
ArgV(argument, 1);
|
||||||
if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; }
|
strncpy(command,UpperCase(argument,argument),sizeof(command));
|
||||||
if (',' == XdrvMailbox.data[ca]) { paramcount++; }
|
|
||||||
}
|
if (!strcmp_P(argument,PSTR("ERASE"))) {
|
||||||
UpperCase(XdrvMailbox.data,XdrvMailbox.data);
|
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
|
||||||
if (!strcmp(ArgV(argument, 1),"E")) {
|
|
||||||
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
|
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
|
snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be erased"));
|
||||||
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
|
serviced = true;
|
||||||
return serviced;
|
|
||||||
}
|
}
|
||||||
if (!strcmp(ArgV(argument, 1),"S")) {
|
if (!strcmp_P(argument,PSTR("WRITE"))) {
|
||||||
if (paramcount > 1) {
|
if (ArgC() > 1) {
|
||||||
if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
|
|
||||||
serviced = false;
|
|
||||||
return serviced;
|
|
||||||
}
|
|
||||||
ArgV(argument, 2);
|
ArgV(argument, 2);
|
||||||
Pn532.newdata_len = strlen(argument);
|
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
|
||||||
if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
|
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
|
||||||
memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
|
if (strlen(argument)>16) argument[16]=0;
|
||||||
Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
|
|
||||||
Pn532.function = 2;
|
Pn532.function = 2;
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
|
snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be set to '%s'"), argument);
|
||||||
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
|
serviced = true;
|
||||||
return serviced;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
if (!strcmp_P(argument,PSTR("AUTH"))) {
|
||||||
|
if (ArgC() > 1) {
|
||||||
|
Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
|
||||||
|
}
|
||||||
|
if (ArgC() > 2) {
|
||||||
|
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
|
||||||
|
}
|
||||||
|
Settings->pn532_password=Pn532.pwd_auth;
|
||||||
|
Settings->pn532_pack=Pn532.pwd_pack;
|
||||||
|
|
||||||
|
serviced = true;
|
||||||
|
}
|
||||||
|
if (!strcmp_P(argument,PSTR("SET_PWD"))) {
|
||||||
|
snprintf_P(log, sizeof(log), PSTR("will be protected"));
|
||||||
|
Pn532.pwd_auth_new=Pn532.pwd_auth;
|
||||||
|
Pn532.pwd_pack_new=Pn532.pwd_pack;
|
||||||
|
if (ArgC() > 1) {
|
||||||
|
Pn532.pwd_auth_new=strtoul(ArgV(argument,2),nullptr,0);
|
||||||
|
}
|
||||||
|
if (ArgC() > 2) {
|
||||||
|
Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0);
|
||||||
|
}
|
||||||
|
Pn532.function = 3;
|
||||||
|
serviced = true;
|
||||||
|
}
|
||||||
|
if (!strcmp_P(argument,PSTR("UNSET_PWD"))) {
|
||||||
|
snprintf_P(log, sizeof(log), PSTR("will be unprotected"));
|
||||||
|
Pn532.function = 4;
|
||||||
|
serviced = true;
|
||||||
|
}
|
||||||
|
if (!strcmp_P(argument,PSTR("CANCEL"))) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Job canceled"));
|
||||||
|
Pn532.function = 0;
|
||||||
|
serviced = true;
|
||||||
|
} else {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag %s"), log);
|
||||||
|
}
|
||||||
|
if (serviced) ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"%s\"}}"),command);
|
||||||
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_PN532_DATA_FUNCTION
|
#endif // USE_PN532_DATA_FUNCTION
|
||||||
|
|
|
@ -1683,7 +1683,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
|
||||||
meter_spos[meters] = 0;
|
meter_spos[meters] = 0;
|
||||||
}
|
}
|
||||||
// modbus
|
// modbus
|
||||||
if (meter_spos[meters] >= 8) {
|
if (meter_spos[meters] >= 3) {
|
||||||
uint32_t mlen = smltbuf[meters][2] + 5;
|
uint32_t mlen = smltbuf[meters][2] + 5;
|
||||||
if (mlen > SML_BSIZ) mlen = SML_BSIZ;
|
if (mlen > SML_BSIZ) mlen = SML_BSIZ;
|
||||||
if (meter_spos[meters] >= mlen) {
|
if (meter_spos[meters] >= mlen) {
|
||||||
|
|
|
@ -97,8 +97,8 @@ a_setoption = [[
|
||||||
"(Rotary) Rotary step boundary (default 10)",
|
"(Rotary) Rotary step boundary (default 10)",
|
||||||
"(IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)",
|
"(IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)",
|
||||||
"(Bistable) Pulse time in milliseconds for two coil bistable latching relays (default 40)",
|
"(Bistable) Pulse time in milliseconds for two coil bistable latching relays (default 40)",
|
||||||
"(not used) Tuya MCU power Id",
|
"(PowerOn) Add delay of 10 x value milliseconds at power on",
|
||||||
"(not used) Energy Tariff1 start hour",
|
"(PowerOn) Add delay of value seconds at power on before activating relays",
|
||||||
"(not used) Energy Tariff2 start hour",
|
"(not used) Energy Tariff2 start hour",
|
||||||
"",
|
"",
|
||||||
],[
|
],[
|
||||||
|
@ -287,7 +287,7 @@ a_features = [[
|
||||||
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
|
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
|
||||||
],[
|
],[
|
||||||
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
|
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
|
||||||
"USE_MODBUS_ENERGY","","","",
|
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
"","","","",
|
"","","","",
|
||||||
|
@ -321,7 +321,7 @@ else:
|
||||||
obj = json.load(fp)
|
obj = json.load(fp)
|
||||||
|
|
||||||
def StartDecode():
|
def StartDecode():
|
||||||
print ("\n*** decode-status.py v12.1.1.4 by Theo Arends and Jacek Ziolkowski ***")
|
print ("\n*** decode-status.py v12.2.0.3 by Theo Arends and Jacek Ziolkowski ***")
|
||||||
|
|
||||||
# print("Decoding\n{}".format(obj))
|
# print("Decoding\n{}".format(obj))
|
||||||
|
|
||||||
|
|
|
@ -5717,6 +5717,6 @@
|
||||||
:20CA1800A0C902000C010020A8C9020000010020B0C9020004010020B8C902000801002086
|
:20CA1800A0C902000C010020A8C9020000010020B0C9020004010020B8C902000801002086
|
||||||
:020000040005F5
|
:020000040005F5
|
||||||
:207FA800000080011000C0FFFDFF58003AC1B9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
|
:207FA800000080011000C0FFFDFF58003AC1B9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
|
||||||
:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF90
|
:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF97
|
||||||
:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
|
:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
|
||||||
:00000001FF
|
:00000001FF
|
||||||
|
|
Loading…
Reference in New Issue