Closed kofec closed 4 days ago
This is as designed.
What you see is the rules engine polling sensors for value changes. Depending on the amount of different sensor types the loop can take from minimal 1 second to several seconds.
With version 4.2 this polling has been extended to drivers. The TasmotaClient is a driver and hence responds to rule polling.
It's not a bug. It's a feature allowing rules to kick-in as soon as possible.
I'll chk now why the TasmotaClient MQTT messages are reported as they shouldn't.
I just tested TasmotaClient with our default Atmega program /tools/fw_TasmotaClient_arduino/ProATmega328P-3V3-8MHz/AnalogJSON.ino.hex
and it works as designed.
00:00:00.001 CMD: Using USB CDC
00:00:00.001 HDW: ESP32-C3 v0.3
00:00:00.008 UFS: FlashFS mounted with 296 kB free
00:00:00.013 CFG: Loaded from File, Count 154
00:00:00.016 SER: Set to 8N1 115200 bit/s
00:00:00.016 SER: HWCDC supports 115200 bit/s only
00:00:00.021 QPC: Count 1
00:00:00.025 ROT: Mode 1
00:00:00.044 CFG: No '*.autoconf' file found
00:00:00.047 BRY: Berry initialized, RAM used 3712 bytes
00:00:00.052 BRY: No 'preinit.be'
00:00:00.053 SRC: Restart
00:00:00.057 Project tasmota - LolinC3Pico1 Version 14.3.0.7(theo)-3_1_0(2024-11-18T22:50:56)
00:00:00.068 BRY: No 'autoexec.be'
00:00:00.260 WIF: Attempting connection...
00:00:01.002 WIF: Connecting to AP1 indebuurt_IoT Channel 11 BSSId 18:E8:29:CA:17:C1 in mode HT40 as lolinc3pico1...
00:00:01.110 WIF: IPv4 192.168.2.139, mask 255.255.255.0, gateway 192.168.2.254
00:00:03.439 WIF: IPv6 Local fe80::a276:4eff:fe1b:938c%st1
00:00:03.501 WIF: Connected
00:00:03.706 HTP: Web server active on lolinc3pico1 with IP address 192.168.2.139
00:00:05.021 NTP: No reply from 127.0.1.1
00:00:05.079 RTC: UTC 2024-11-23T11:32:54Z, DST 2024-03-31T02:00:00, STD 2024-10-27T03:00:00
12:32:54.000 RTC: Synced by NTP
12:32:54.456 MQT: Attempting connection...
12:32:54.584 MQT: Connected
12:32:54.587 MQT: tele/lolinc3pico1/LWT = Online (retained)
12:32:54.590 MQT: cmnd/lolinc3pico1/POWER =
12:32:54.591 MQT: Subscribe to cmnd/lolinc3pico1/#
12:32:54.592 MQT: Subscribe to cmnd/tasmotas/#
12:32:54.595 MQT: Subscribe to cmnd/DVES_1B938C_fb/#
12:32:54.598 MQT: tele/lolinc3pico1/INFO1 = {"Info1":{"Module":"ESP32C3","Version":"14.3.0.7(theo)","FallbackTopic":"cmnd/DVES_1B938C_fb/","GroupTopic":"cmnd/tasmotas/"}}
12:32:54.601 MQT: tele/lolinc3pico1/INFO2 = {"Info2":{"WebServerMode":"Admin","Hostname":"lolinc3pico1","IPAddress":"192.168.2.139","IP6Global":"fd84:7996:2cbf:1349:a276:4eff:fe1b:938c","IP6Local":"fe80::a276:4eff:fe1b:938c%st1"}}
12:32:54.604 MQT: tele/lolinc3pico1/INFO3 = {"Info3":{"RestartReason":"Software reset CPU","BootCount":50}}
12:32:54.607 MQT: stat/lolinc3pico1/RESULT = {"POWER":"OFF"}
12:32:54.609 MQT: stat/lolinc3pico1/POWER = OFF
12:32:56.001 QPC: Reset
12:32:56.439 WIF: IPv6 Global fd84:7996:2cbf:1349:a276:4eff:fe1b:938c
12:32:56.853 HTP: Main Menu
12:32:57.977 APP: Boot Count 50
12:32:58.217 CFG: Saved, Count 155, Bytes 4096
12:32:58.980 MQT: tele/lolinc3pico1/STATE = {"Time":"2024-11-23T12:32:58","Uptime":"0T00:00:10","UptimeSec":10,"Heap":196,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":27,"MqttCount":1,"Berry":{"HeapUsed":3,"Objects":35},"POWER":"OFF","Dimmer":20,"Color":"033300","HSBColor":"116,100,20","Channel":[1,20,0],"Scheme":0,"Width":1,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"HT40","RSSI":100,"Signal":-38,"LinkCount":1,"Downtime":"0T00:00:04"}}
12:32:59.182 TCL: Serial UART1
12:32:59.189 TCL: Enabled
12:33:01.008 TCL: Version 20191129
12:33:12.248 CMD: teleperiod
12:33:12.249 SRC: UsbConsole
12:33:12.250 CMD: Grp 0, Cmd 'TELEPERIOD', Idx 1, Len 0, Pld -99, Data ''
12:33:12.254 MQT: stat/lolinc3pico1/RESULT = {"TelePeriod":300}
12:33:13.009 MQT: tele/lolinc3pico1/STATE = {"Time":"2024-11-23T12:33:13","Uptime":"0T00:00:25","UptimeSec":25,"Heap":189,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":1,"Berry":{"HeapUsed":3,"Objects":35},"POWER":"OFF","Dimmer":20,"Color":"033300","HSBColor":"116,100,20","Channel":[1,20,0],"Scheme":0,"Width":1,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"HT40","RSSI":100,"Signal":-38,"LinkCount":1,"Downtime":"0T00:00:04"}}
12:33:13.039 MQT: tele/lolinc3pico1/SENSOR = {"Time":"2024-11-23T12:33:13","TasmotaClient":{"A0":135,"A1":128,"A2":136,"A3":136,"A4":138,"A5":122,"A6":123,"A7":144}}
12:33:27.764 CMD: rule
12:33:27.766 SRC: UsbConsole
12:33:27.768 CMD: Grp 0, Cmd 'RULE', Idx 1, Len 0, Pld -99, Data ''
12:33:27.773 MQT: stat/lolinc3pico1/RESULT = {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":0,"Free":511,"Rules":""}}
12:34:48.746 CMD: rule1 on TasmotaClient#A0 do var1 %value% endon
12:34:48.748 SRC: UsbConsole
12:34:48.749 CMD: Grp 0, Cmd 'RULE', Idx 1, Len 41, Pld -99, Data 'on TasmotaClient#A0 do var1 %value% endon'
12:34:48.751 RUL: Stored uncompressed, would compress from 41 to 31 (-24%)
12:34:48.755 MQT: stat/lolinc3pico1/RESULT = {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":41,"Free":470,"Rules":"on TasmotaClient#A0 do var1 %value% endon"}}
12:34:49.477 CFG: Saved, Count 156, Bytes 4096
12:34:53.445 CMD: rule1 1
12:34:53.446 SRC: UsbConsole
12:34:53.448 CMD: Grp 0, Cmd 'RULE', Idx 1, Len 1, Pld 1, Data '1'
12:34:53.452 MQT: stat/lolinc3pico1/RESULT = {"Rule1":{"State":"ON","Once":"OFF","StopOnError":"OFF","Length":41,"Free":470,"Rules":"on TasmotaClient#A0 do var1 %value% endon"}}
12:34:54.320 RUL: TASMOTACLIENT#A0 performs 'var1 154'
12:34:54.321 SRC: Rule
12:34:54.323 CMD: Grp 0, Cmd 'VAR', Idx 1, Len 3, Pld 154, Data '154'
12:34:54.327 MQT: stat/lolinc3pico1/RESULT = {"Var1":"154"}
12:34:54.464 CFG: Saved, Count 157, Bytes 4096
12:34:55.299 RUL: TASMOTACLIENT#A0 performs 'var1 153'
12:34:55.301 SRC: Rule
12:34:55.302 CMD: Grp 0, Cmd 'VAR', Idx 1, Len 3, Pld 153, Data '153'
12:34:55.308 MQT: stat/lolinc3pico1/RESULT = {"Var1":"153"}
12:34:56.300 RUL: TASMOTACLIENT#A0 performs 'var1 158'
12:34:56.302 SRC: Rule
12:34:56.304 CMD: Grp 0, Cmd 'VAR', Idx 1, Len 3, Pld 158, Data '158'
12:34:56.308 MQT: stat/lolinc3pico1/RESULT = {"Var1":"158"}
...
12:35:21.320 RUL: TASMOTACLIENT#A0 performs 'var1 155'
12:35:21.322 SRC: Rule
12:35:21.327 CMD: Grp 0, Cmd 'VAR', Idx 1, Len 3, Pld 155, Data '155'
12:35:21.333 MQT: stat/lolinc3pico1/RESULT = {"Var1":"155"}
12:35:21.646 CMD: rule1 0
12:35:21.647 SRC: UsbConsole
12:35:21.649 CMD: Grp 0, Cmd 'RULE', Idx 1, Len 1, Pld 0, Data '0'
12:35:21.655 MQT: stat/lolinc3pico1/RESULT = {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"ON","Length":41,"Free":470,"Rules":"on TasmotaClient#A0 do var1 %value% endon"}}
12:35:22.459 CFG: Saved, Count 159, Bytes 4096
12:38:12.989 MQT: tele/lolinc3pico1/STATE = {"Time":"2024-11-23T12:38:12","Uptime":"0T00:05:24","UptimeSec":324,"Heap":189,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":1,"Berry":{"HeapUsed":3,"Objects":35},"POWER":"OFF","Dimmer":20,"Color":"033300","HSBColor":"116,100,20","Channel":[1,20,0],"Scheme":0,"Width":1,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"HT40","RSSI":100,"Signal":-38,"LinkCount":1,"Downtime":"0T00:00:04"}}
12:38:13.021 MQT: tele/lolinc3pico1/SENSOR = {"Time":"2024-11-23T12:38:12","TasmotaClient":{"A0":135,"A1":130,"A2":137,"A3":136,"A4":136,"A5":122,"A6":129,"A7":146}}
So as long as no rules are active you won't see the rules engine polling TasmotaClient (which it still does). Also no non-teleperiod TasmotaClient MQTT messages.
As you self-compile do you use rules or script?
Also provide all requested information like status 0
and if any rules are defined.
Pls provide your ATmega arduino code so I can have a look what happens.
I am not proud of this code :-) :
/*
TasmotaClientKinowa.ino - Arduino nano w sali kinowej
3 // Pin where dallase sensor is connected
8 // Arduino Digital I/O pin for button/reed - OknoKinowaLewe
9 // Arduino Digital I/O pin for button/reed - OknoKinowaPrawe
10 // Arduino Digital I/O pin for button/reed - DrzwiGarazZboku
11 // Arduino Digital I/O pin for button/reed - DrzwiKinowa
12 // Arduino Digital I/O pin for button/reed - DrzwiGarazNaWprost
*/
#include <Arduino.h>
#include <TasmotaClient.h>
#include <EEPROM.h>
// libraries for 1wire
#include <DallasTemperature.h>
#include <OneWire.h>
TasmotaClient client(&Serial);
bool debug = false;
bool TeleTemp = false;
#define VOLTS_GATE A7 //measure voltage on trigger
#define RELAY_PIN1 7 // Arduino Digital I/O pin number for first relay - Brama Garaz - D7
#define ONE_WIRE_BUS1 3 // Pin where dallase sensor is connected - D3
#define ONE_WIRE_BUS2 4 // Pin where dallase sensor is connected - D4 - tylko jeden
#define ONE_WIRE_BUS3 5 // Pin where dallase sensor is connected - D5 - tylko jeden
#define NUMER_KONTAKTRONS 4 //number of connected kontaktrons +1 - last is D12
#define RELAY_ON 1
#define RELAY_OFF 0
#define MAX_ATTACHED_DS18B20 7
OneWire oneWire1(ONE_WIRE_BUS1); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire2(ONE_WIRE_BUS2);
OneWire oneWire3(ONE_WIRE_BUS3);
DallasTemperature sensors1(&oneWire1); // Pass the oneWire reference to Dallas Temperature.
#define NUM_EXTRA_GPIO_DS18B20 2
DallasTemperature sensors2(&oneWire2);
DallasTemperature sensors3(&oneWire3);
int oldVoltsGate=-1;
int oldStanDX[NUMER_KONTAKTRONS+1];
uint8_t numFailureRead=11;
uint8_t successReadTemp=0;
int numsensors1=0;
//info to send and string for easier operations
char msgInfoChar[60] = "";
String msgInfoString = "";
// typedef uint8_t DeviceAddress[8];
DeviceAddress dsaddr[MAX_ATTACHED_DS18B20];
unsigned long lastTimeLoop = millis();
/*******************************************************************\
* Normal setup() function for Arduino to configure the serial port
* speed (which should match what was configured in Tasmota) and
* attach any callback functions associated with specific requests
* or commands that are sent by Tasmota.
\*******************************************************************/
void setup() {
// Configure the LED pin as OUTPUT
pinMode(LED_BUILTIN, OUTPUT);
// Setup locally attached sensors
pinMode(RELAY_PIN1,OUTPUT);
// Setup locally attached kontaktrons
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
pinMode(i,INPUT_PULLUP);
}
// Make sure relays are on when starting up
digitalWrite(RELAY_PIN1, RELAY_ON);
// Configure the serial port baud rate
Serial.begin(57600);
// Attach the function which will respond to the JSON request from Tasmota
client.attach_FUNC_JSON(user_FUNC_JSON);
// Attach the function which will be called when the Tasmota device sends data using ClientSend command
client.attach_FUNC_COMMAND_SEND(user_FUNC_RECEIVE);
// Startup up the OneWire library
sensors1.begin();
sensors2.begin();
sensors3.begin();
// Fetch the number of attached temperature sensors
numsensors1 = sensors1.getDeviceCount();
// check parasite power requirements
sensors1.isParasitePowerMode();
sensors2.isParasitePowerMode();
sensors3.isParasitePowerMode();
// get address
for (int i=0; i<numsensors1 && i<MAX_ATTACHED_DS18B20; i++) {
sensors1.getAddress(dsaddr[i],i);
// MAX_ATTACHED_DS18B20 - 1
}
if (sensors2.getDeviceCount() == 1) {
sensors2.getAddress(dsaddr[numsensors1],0);
}
if (sensors3.getDeviceCount() == 1) {
sensors3.getAddress(dsaddr[numsensors1+1],0);
}
oldVoltsGate = analogRead(VOLTS_GATE);
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
oldStanDX[i-12+NUMER_KONTAKTRONS] = digitalRead(i);
}
}
void VerifyTemp(float temperature, int i) {
char response[40];
// Only send data if no error
if (temperature != -127.00 && temperature != 85.00) {
// Send in the new temperature
String addrString = "";
// Uzyj ponizsze jezeli pomiar z kropka
//char temp_char[10];
for (uint8_t j = 0; j < 8; j++)
{
if (dsaddr[i][j] < 16) addrString += String(0,HEX);
addrString += String(dsaddr[i][j],HEX);
}
addrString.toCharArray(msgInfoChar, addrString.length()+1);
// dla pomiaru z kropka
//dtostrf(temperature, 3, 1, temp_char); //3 is mininum width, 1 is precision
//sprintf(response,"{\"%s\":\"%s\"}", msgInfoChar, temp_char);
sprintf(response,"{\"%s\":\"%d\"}", msgInfoChar, (int)(temperature*10));
client.SendTele(response);
successReadTemp++;
delay(100);
}
}
void PomiarTemperatury() {
char response[40];
numsensors1 = sensors1.getDeviceCount();
sprintf(response,"{\"numsensors1\":%d}", numsensors1);
client.SendTele(response);
successReadTemp = 0;
// Fetch temperatures from Dallas sensors
sensors1.requestTemperatures();
sensors2.requestTemperatures();
sensors3.requestTemperatures();
// query conversion time and sleep until conversion completed
int16_t conversionTime = sensors1.millisToWaitForConversion(sensors1.getResolution());
// sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
delay(conversionTime);
float temperature = 85;
// Read temperatures on A and send them to controller
for (int i=0; i<numsensors1 && i<MAX_ATTACHED_DS18B20; i++) {
msgInfoString = "";
// Fetch and round temperature to one decimal
temperature = static_cast<float>(static_cast<int>((sensors1.getTempCByIndex(i)) * 10.)) / 10.;
VerifyTemp(temperature,i);
}
sprintf(response,"{\"numsensors2\":%d}", sensors2.getDeviceCount());
client.SendTele(response);
if (sensors2.getDeviceCount() == 1) {
temperature = static_cast<float>(static_cast<int>((sensors2.getTempCByIndex(0)) * 10.)) / 10.;
VerifyTemp(temperature,numsensors1);
}
sprintf(response,"{\"numsensors3\":%d}", sensors3.getDeviceCount());
if (sensors2.getDeviceCount() == 1) {
temperature = static_cast<float>(static_cast<int>((sensors3.getTempCByIndex(0)) * 10.)) / 10.;
VerifyTemp(temperature,numsensors1+1);
}
}
void TempInicijalizacja() {
msgInfoString = "";
// Startup up the OneWire library
sensors1.begin();
// Fetch the number of attached temperature sensors
numsensors1 = sensors1.getDeviceCount();
// report parasite power requirements
msgInfoString = "{\"NumberDevD3\":"+ String(numsensors1) + ",\"Parasite\":\"";
if (sensors1.isParasitePowerMode()) msgInfoString +="ON\"}";
else msgInfoString +="OFF\"}";
msgInfoString.toCharArray(msgInfoChar, (msgInfoString.length()+1));
client.SendTele(msgInfoChar);
msgInfoString = "{\"NumberDevD4\":"+ String(sensors2.getDeviceCount()) + ",\"Parasite\":\"";
if (sensors2.isParasitePowerMode()) msgInfoString +="ON\"}";
else msgInfoString +="OFF\"}";
msgInfoString.toCharArray(msgInfoChar, (msgInfoString.length()+1));
client.SendTele(msgInfoChar);
msgInfoString = "{\"NumberDevD5\":"+ String(sensors3.getDeviceCount()) + ",\"Parasite\":\"";
if (sensors3.isParasitePowerMode()) msgInfoString +="ON\"}";
else msgInfoString +="OFF\"}";
msgInfoString.toCharArray(msgInfoChar, (msgInfoString.length()+1));
client.SendTele(msgInfoChar);
for (int i=0; i<numsensors1 && i<MAX_ATTACHED_DS18B20; i++) {
sensors1.getAddress(dsaddr[i],i);
}
// Present all sensors to controller + 2 - tyle extra
for (int i=0; i<numsensors1 && i<MAX_ATTACHED_DS18B20; i++) {
msgInfoString = "";
for (uint8_t j = 0; j < 8; j++)
{
if (dsaddr[i][j] < 16) msgInfoString += String(0,HEX);
msgInfoString += String(dsaddr[i][j],HEX);
}
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
msgInfoString = "{\"NewDevID\":" + String(i) + ",\"addr\":\"" + String(msgInfoChar) + "\"}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
msgInfoString = "{\"ID\":" + String(i) + ",\"Res\":" + String(sensors1.getResolution(dsaddr[i]))+ "}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
delay(100);
}
if (sensors2.getDeviceCount() == 1) {
msgInfoString = "";
for (uint8_t j = 0; j < 8; j++)
{
if (dsaddr[numsensors1][j] < 16) msgInfoString += String(0,HEX);
msgInfoString += String(dsaddr[numsensors1][j],HEX);
}
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
msgInfoString = "{\"NewDevID\":" + String(numsensors1) + ",\"addr\":\"" + String(msgInfoChar) + "\"}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
msgInfoString = "{\"ID\":" + String(numsensors1) + ",\"Res\":" + String(sensors2.getResolution(dsaddr[numsensors1]))+ "}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
delay(100);
}
if (sensors3.getDeviceCount() == 1) {
msgInfoString = "";
for (uint8_t j = 0; j < 8; j++)
{
if (dsaddr[numsensors1+1][j] < 16) msgInfoString += String(0,HEX);
msgInfoString += String(dsaddr[numsensors1+1][j],HEX);
}
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
msgInfoString = "{\"NewDevID\":" + String(numsensors1+1) + ",\"addr\":\"" + String(msgInfoChar) + "\"}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
msgInfoString = "{\"ID\":" + String(numsensors1+1) + ",\"Res\":" + String(sensors3.getResolution(dsaddr[numsensors1+1]))+ "}";
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
client.SendTele(msgInfoChar);
delay(100);
}
}
void(* resetFunc) (void) = 0; //declare reset function @ address 0
/*******************************************************************\
* Function which will be called when this client device receives a
* ClientSend command from the Tasmota device. eg. ClientSend ON
\*******************************************************************/
void user_FUNC_RECEIVE(char *data)
{
char response[40];
if (debug) {
sprintf(response,"{\"Received cmd\":\"%s\"}", data);
client.SendTele(response);
}
if (!strcasecmp(data, "DEBUGON")) { // ClientSend DEBUGON
digitalWrite(LED_BUILTIN, HIGH);
debug = true;
sprintf(response,"{\"Debug\":\"On\"}");
client.SendTele(response);
}
else if (!strcasecmp(data, "DEBUGOFF")) { // ClientSend DEBUGOFF
digitalWrite(LED_BUILTIN, LOW);
debug = false;
sprintf(response,"{\"Debug\":\"Off\"}");
client.SendTele(response);
}
else if (!strcasecmp(data, "POMIARVOLTS")) { // ClientSend POMIARVOLTS
int VoltsGate = analogRead(VOLTS_GATE);
sprintf(response,"{\"VoltBrama\":%d}", VoltsGate);
client.SendTele(response);
// oldVoltsGate = VoltsGate;
}
else if (!strcasecmp(data, "POMIARTEMP")) { // ClientSend POMIARTEMP
PomiarTemperatury();
if (successReadTemp == 0) {
if (numFailureRead > 10) {
TempInicijalizacja();
}
else {
numFailureRead++;
sprintf(response,"{\"numFailureRead\":%d}", numFailureRead);
client.SendTele(response);
}
}
else if (numFailureRead > 0) {
numFailureRead=0;
}
}
else if (!strcasecmp(data, "TEMPINIT")) { // ClientSend TEMPINIT
TempInicijalizacja();
}
else if (!strcasecmp(data, "RESETARDUINO")) { // ClientSend RESETARDUINO
sprintf(response,"{\"ResetARDUINO\":\"1s\")");
client.SendTele(response);
delay(1000);
resetFunc();
}
else if (String(data).length() == 16) { // ClientSend DS18XX address ClientSend 28B870580200005E
sprintf(response,"{\"CommandLenght\":\"16\")");
client.SendTele(response);
}
else if (!strcasecmp(data, "STANYDALL")) { // ClientSend STANYDALL
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
oldStanDX[i-12+NUMER_KONTAKTRONS] = digitalRead(i);
sprintf(response,"{\"StanD%d\":%d}", i, oldStanDX[i-12+NUMER_KONTAKTRONS]);
client.SendTele(response);
}
}
else {
sprintf(response,"{\"Unknown cmd\":\"%s\"}", data);
client.SendTele(response);
}
}
/*******************************************************************\
* user_FUNC_JSON creates the JSON which will be sent back to the
* Tasmota device upon receiving a request to do so
\*******************************************************************/
void user_FUNC_JSON(void)
{
char myjson[150];
msgInfoString = "";
char response[200];
int VoltsGate = analogRead(VOLTS_GATE);
msgInfoString += "{\"VoltBrama\":" + String(VoltsGate);
if (debug) {
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
sprintf(response,"{\"PartOfJson\":%s}", msgInfoChar);
client.SendTele(response);
}
// oldVoltsGate = VoltsGate;
//int StanBramy = digitalRead(KONTAKTRON_D12);
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
oldStanDX[i-12+NUMER_KONTAKTRONS] = digitalRead(i);
msgInfoString += ",\"StanD" + String(i)+ "\":" + String(oldStanDX[i-12+NUMER_KONTAKTRONS]);
}
msgInfoString += "}";
if (debug) {
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
sprintf(response,"{\"Full_string\":%s}", msgInfoChar);
client.SendTele(response);
}
msgInfoString.toCharArray(msgInfoChar, msgInfoString.length()+1);
sprintf(myjson,"%s", msgInfoChar);
client.sendJSON(myjson);
TeleTemp = true;
}
void loop() {
// Call the client loop every so often to process any incoming requests
client.loop();
unsigned long timeNow = millis();
char response[40];
if (TeleTemp) { //pomiar temperatur - trigger tele
PomiarTemperatury();
if (successReadTemp == 0) {
if (numFailureRead > 10) {
TempInicijalizacja();
}
else {
numFailureRead++;
sprintf(response,"{\"numFailureRead\":%d}", numFailureRead);
client.SendTele(response);
}
}
else if (numFailureRead > 0) {
numFailureRead=0;
}
TeleTemp = false;
}
// https://forum.mysensors.org/topic/7032/analog-to-digital-how/4
if (timeNow - lastTimeLoop > 1000) {//co sekunde sprawdzamy
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
if (oldStanDX[i-12+NUMER_KONTAKTRONS] != digitalRead(i)) {
oldStanDX[i-12+NUMER_KONTAKTRONS] = digitalRead(i);
sprintf(response,"{\"StanD%d\":%d}", i, oldStanDX[i-12+NUMER_KONTAKTRONS]);
client.SendTele(response);
}
}
lastTimeLoop = timeNow;
}
}
I see what happens "unexpected".
Commenting out line 361 (TeleTemp = true;) will fix it.
To get the messages back at TelePeriod time I suggest you add a new command to Kinowa responding with the TeleTemp data. This command can then be executed by a Tasmota rule triggered by a the default TelePeriod.
I played around a bit. Make this change user_FUNC_RECEIVE
:
else if (!strcasecmp(data, "DEBUGOFF")) { // ClientSend DEBUGOFF
digitalWrite(LED_BUILTIN, LOW);
debug = false;
sprintf(response,"{\"Debug\":\"Off\"}");
client.SendTele(response);
}
else if (!strcasecmp(data, "TELETEMP")) { // ClientSend TELETEMP
TeleTemp = true;
}
else if (!strcasecmp(data, "POMIARVOLTS")) { // ClientSend POMIARVOLTS
adding command ClientSend TELETEMP.
Then add this rule to Tasmota:
rule1 on Tele-TasmotaClient#VoltBrama do ClientSend TELETEMP endon
and enable the rule with command rule1 1
.
That should kind of bring back your previous functionality:
15:54:08.198 TCL: Serial UART1
15:54:08.206 TCL: Enabled
15:54:09.977 TCL: Version 20191129
15:54:26.983 MQT: tele/lolinc3pico1/STATE = {"Time":"2024-11-23T15:54:26","Uptime":"0T00:00:29","UptimeSec":29,"Heap":189,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":1,"Berry":{"HeapUsed":3,"Objects":35},"POWER":"OFF","Dimmer":20,"Color":"033300","HSBColor":"116,100,20","Channel":[1,20,0],"Scheme":0,"Width":1,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"HT40","RSSI":100,"Signal":-32,"LinkCount":1,"Downtime":"0T00:00:04"}}
15:54:27.011 MQT: tele/lolinc3pico1/SENSOR = {"Time":"2024-11-23T15:54:26","TasmotaClient":{"VoltBrama":219,"StanD8":1,"StanD9":1,"StanD10":1,"StanD11":1,"StanD12":1}}
15:54:27.021 RUL: TELE-TASMOTACLIENT#VOLTBRAMA performs 'ClientSend TELETEMP'
15:54:27.022 SRC: Rule
15:54:27.024 CMD: Grp 0, Cmd 'CLIENTSEND', Idx 1, Len 8, Pld -99, Data 'TELETEMP'
15:54:27.027 MQT: stat/lolinc3pico1/RESULT = {"ClientSend":"Done"}
15:54:27.040 MQT: tele/lolinc3pico1/RESULT = {"TasmotaClient":{"numsensors1":0}}
15:54:29.409 MQT: tele/lolinc3pico1/RESULT = {"TasmotaClient":{"NumberDevD3":0,"Parasite":"OFF"}}
15:54:29.423 MQT: tele/lolinc3pico1/RESULT = {"TasmotaClient":{"NumberDevD4":0,"Parasite":"OFF"}}
15:54:29.473 MQT: tele/lolinc3pico1/RESULT = {"TasmotaClient":{"NumberDevD5":0,"Parasite":"OFF"}}
Wow, thanks a lot for your help!
I used the variable TeleTemp because it probably takes too long (likely due to a timeout) to read the temperature from the DS1820:
// Query conversion time and sleep until conversion is completed
int16_t conversionTime = sensors1.millisToWaitForConversion(sensors1.getResolution());
// sleep() call can be replaced by wait() if the node needs to process incoming messages (or if the node is a repeater)
delay(conversionTime);
As a result, I don't get a response at all.
So, during the TelePeriod, I only read the state of the contactrons. My idea was to add a "flag" and mark it as true.
In the loop() function:
if (TeleTemp) { // Trigger temperature measurement
....... read temperature and set to false
TeleTemp = false;
}
Thanks a again for you help. My current solution is: beck to 14.1
Do you know why it stop working ?
Variable
TeleTemp = false;
Never reach this part of the code ?
Even if I correct as you suggest will kontaktron detection still working ?
if (timeNow - lastTimeLoop > 1000) {//co sekunde sprawdzamy
for (int i = 12-NUMER_KONTAKTRONS; i<=12; i++) {
if (oldStanDX[i-12+NUMER_KONTAKTRONS] != digitalRead(i)) {
oldStanDX[i-12+NUMER_KONTAKTRONS] = digitalRead(i);
sprintf(response,"{\"StanD%d\":%d}", i, oldStanDX[i-12+NUMER_KONTAKTRONS]);
client.SendTele(response);
}
}
lastTimeLoop = timeNow;
Never reach this part of the code ?
Simply because another request is outstanding. From 14.2 every second a request is made by the rule engine. Your TeleTemp loop takes seconds to complete so it never gets there. And if it gets there it is immediatle reset by the next rule engine call.
To fix your timeout issue you'll need to provide the TelePeriod data instantly. So you'll need to read the DS1820 way before it can provide it's data. Just poll the DS1820 regulary and store it's value in a variable ready to provide to the TelePeriod request.
No need for TeleTemp then.
Anyway, I close this issue as it is related to your local client code.
Thanks again for explanation
Just looked over your (Kinowa) and my (TasmotaClient) code again and think I have a much easier solution.
As you do not use rules make sure all rules are configured as State OFF. Chk output of command rule0
:
16:00:46.348 CMD: rule0
16:00:46.351 SRC: Serial
16:00:46.354 CMD: Grp 0, Cmd 'RULE', Idx 0, Len 0, Pld -99, Data ''
16:00:46.360 MQT: stat/wemos6/RESULT = {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":0,"Free":511,"Rules":""}}
16:00:46.365 MQT: stat/wemos6/RESULT = {"Rule2":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":0,"Free":511,"Rules":""}}
16:00:46.378 MQT: stat/wemos6/RESULT = {"Rule3":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":0,"Free":511,"Rules":""}}
Now you can keep using your own code. The rules engine doesn't kick-in every second resulting in same behaviour as you noticed in v14.1.0. Se below with TelePeriod 20
as a test:
15:59:47.498 MQT: tele/wemos6/STATE = {"Time":"2024-11-24T15:59:47","Uptime":"0T00:08:53","UptimeSec":533,"Heap":22,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"Wifi":{"AP":2,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"11n","RSSI":100,"Signal":-44,"LinkCount":1,"Downtime":"0T00:00:06"}}
15:59:47.545 MQT: tele/wemos6/SENSOR = {"Time":"2024-11-24T15:59:47","TasmotaClient":{"VoltBrama":360,"StanD8":1,"StanD9":1,"StanD10":1,"StanD11":1,"StanD12":1}}
15:59:47.594 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"numsensors1":0}}
15:59:49.912 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"numsensors2":0}}
15:59:49.994 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD3":0,"Parasite":"OFF"}}
15:59:50.093 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD4":0,"Parasite":"OFF"}}
15:59:50.193 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD5":0,"Parasite":"OFF"}}
16:00:07.497 MQT: tele/wemos6/STATE = {"Time":"2024-11-24T16:00:07","Uptime":"0T00:09:13","UptimeSec":553,"Heap":22,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"Wifi":{"AP":2,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"11n","RSSI":100,"Signal":-42,"LinkCount":1,"Downtime":"0T00:00:06"}}
16:00:27.497 MQT: tele/wemos6/STATE = {"Time":"2024-11-24T16:00:27","Uptime":"0T00:09:33","UptimeSec":573,"Heap":22,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"Wifi":{"AP":2,"SSId":"indebuurt_IoT","BSSId":"18:E8:29:CA:17:C1","Channel":11,"Mode":"11n","RSSI":100,"Signal":-38,"LinkCount":1,"Downtime":"0T00:00:06"}}
16:00:27.547 MQT: tele/wemos6/SENSOR = {"Time":"2024-11-24T16:00:27","TasmotaClient":{"VoltBrama":359,"StanD8":1,"StanD9":1,"StanD10":1,"StanD11":1,"StanD12":1}}
16:00:27.594 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"numsensors1":0}}
16:00:29.920 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"numsensors2":0}}
16:00:29.994 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD3":0,"Parasite":"OFF"}}
16:00:30.094 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD4":0,"Parasite":"OFF"}}
16:00:30.194 MQT: tele/wemos6/RESULT = {"TasmotaClient":{"NumberDevD5":0,"Parasite":"OFF"}}
PROBLEM DESCRIPTION
I'm using Tasmota Client on mine ESP8266(Now testing also on ESP32). It stop working(look like query loop) when upgrade from 14.1.0 (last OK) to 14.2.0(Also just compile latest master). It looks like it trigger tele (void user_FUNCJSON(void)) over and over again - from Arduino perspective. So arduino send to ESP8266 there results of execution this function over and over again. Never stop or/and wait for TelePeriod .
REQUESTED INFORMATION
Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!
Backlog Template; Module; GPIO 255
:Status 0
:TO REPRODUCE
Steps to reproduce the behavior:
EXPECTED BEHAVIOUR
A clear and concise description of what you expected to happen.
SCREENSHOTS
If applicable, add screenshots to help explain your problem.
ADDITIONAL CONTEXT
When working fine (14.1):
When upgrade to newer version:
(Please, remember to close the issue when the problem has been addressed)