New OTA debugging and logging feature (#913) (#913)

This commit is contained in:
d00616
2017-09-18 20:58:44 +02:00
committed by Henrik Ekblad
parent 0ed558f1d0
commit 8412a3d360
9 changed files with 518 additions and 5 deletions
+74 -4
View File
@@ -47,6 +47,54 @@
*/
//#define MY_DEBUG
/**
* @def MY_DEBUG_OTA
* @brief Define MY_DEBUG_OTA to redirect debug prints to given node ID
*
* With this option debugging messages over serial are disabled. It's not possible to send debug
* messages generated by the radio. All other debug messages redirected to the given Node ID.
* The debug messages are sent unsigned.
*
* This function allocates some additional memory for radio packet preparation and buffering.
* Debug messages are sent to child ID 255 (NODE_SENSOR_ID) as I_LOG_MESSAGE type.
*
* You have to enable the MY_OTA_LOG_RECEIVER_FEATURE on the target node.
* Look into the LogOTAGateway and LogOTANode examples.
*
* The output buffer can be configured via MY_SERIAL_OUTPUT_SIZE
* Transport related debugging is disabled when MY_DEBUG_OTA is enabled.
*
*/
//#define MY_DEBUG_OTA (0)
/**
* @def MY_DEBUG_OTA_DISABLE_ACK
* @brief Define MY_DEBUG_OTA_DISABLE_ACK to send messages with no ACK flag.
*
* This option reduces the latency added by OTA debug messages by sending packages
* only once. You can loose debug messages.
*
*/
//#define MY_DEBUG_OTA_DISABLE_ACK
/**
* @def MY_OTA_LOG_RECEIVER_FEATURE
* @brief Define this to enable printing of OTA logs.
*
* This option requires additional memory for buffering. The buffer size can be configured
* via MY_SERIAL_OUTPUT_SIZE.
*/
//#define MY_OTA_LOG_RECEIVER_FEATURE
/**
* @def MY_OTA_LOG_SENDER_FEATURE
* @brief Define this to enable printing of OTA logs.
*
* This option requires additional memory for buffering. The buffer size can be configured
* via MY_SERIAL_OUTPUT_SIZE.
*/
//#define MY_OTA_LOG_SENDER_FEATURE
/**
* @def MY_SPECIAL_DEBUG
* @brief Define MY_SPECIAL_DEBUG to enable support for I_DEBUG messages.
@@ -80,10 +128,6 @@
*/
//#define MY_SPLASH_SCREEN_DISABLED
#ifdef MY_DISABLED_SERIAL
#undef MY_DEBUG
#endif
/**
* @def MY_BAUD_RATE
* @brief Serial output baud rate (debug prints and serial gateway speed).
@@ -1221,6 +1265,7 @@
#define MY_INCLUSION_BUTTON_PRESSED (LOW)
#endif
/**************************************
* Ethernet Gateway Transport Defaults
***************************************/
@@ -1684,6 +1729,9 @@
#endif
// DEBUG
#if defined(MY_DISABLED_SERIAL) && !defined(MY_DEBUG_OTA)
#undef MY_DEBUG
#endif
#if defined(MY_DEBUG)
// standard debug output
#define MY_DEBUG_VERBOSE_CORE //!< MY_DEBUG_VERBOSE_CORE
@@ -1693,8 +1741,25 @@
#if defined(MY_DEBUG) || defined(MY_DEBUG_VERBOSE_CORE) || defined(MY_DEBUG_VERBOSE_TRANSPORT) || defined(MY_DEBUG_VERBOSE_SIGNING) || defined(MY_DEBUG_VERBOSE_OTA_UPDATE) || defined(MY_DEBUG_VERBOSE_RF24) || defined(MY_DEBUG_VERBOSE_NRF5_ESB) || defined(MY_DEBUG_VERBOSE_RFM69) || defined(MY_DEBUG_VERBOSE_RFM95)
#define DEBUG_OUTPUT_ENABLED //!< DEBUG_OUTPUT_ENABLED
#ifndef MY_DEBUG_OTA
#define DEBUG_OUTPUT(x,...) hwDebugPrint(x, ##__VA_ARGS__) //!< debug
#else
#ifndef MY_OTA_LOG_SENDER_FEATURE
#define MY_OTA_LOG_SENDER_FEATURE
#endif
#ifndef MY_DEBUG_OTA_DISABLE_ACK
#define DEBUG_OUTPUT(x,...) OTALog((MY_DEBUG_OTA), true, x, ##__VA_ARGS__) //!< debug
#else
#define DEBUG_OUTPUT(x,...) OTALog((MY_DEBUG_OTA), false, x, ##__VA_ARGS__) //!< debug
#endif
// disable radio related debugging messages
#undef MY_DEBUG_VERBOSE_RF24
#undef MY_DEBUG_VERBOSE_NRF5_ESB
#undef MY_DEBUG_VERBOSE_RFM69
#undef MY_DEBUG_VERBOSE_RFM69_REGISTERS
#undef MY_DEBUG_VERBOSE_RFM95
#endif
#else
#define DEBUG_OUTPUT(x,...) //!< debug NULL
#endif
@@ -1733,6 +1798,8 @@
#if DOXYGEN
// debug
#define MY_DEBUG
#define MY_DEBUG_OTA
#define MY_DEBUG_OTA_DISABLE_ACK
#define MY_SPECIAL_DEBUG
#define MY_DISABLED_SERIAL
#define MY_SPLASH_SCREEN_DISABLED
@@ -1742,6 +1809,9 @@
// inclusion mode
#define MY_INCLUSION_MODE_FEATURE
#define MY_INCLUSION_BUTTON_FEATURE
// OTA logging and debug
#define MY_OTA_LOG_RECEIVER_FEATURE
#define MY_OTA_LOG_SENDER_FEATURE
// transport
#define MY_PARENT_NODE_IS_STATIC
#define MY_REGISTRATION_CONTROLLER
+10
View File
@@ -45,6 +45,11 @@
#include "core/MySplashScreen.h"
#include "core/MySensorsCore.h"
// OTA Debug, have to defined before HAL
#if defined(MY_OTA_LOG_SENDER_FEATURE) || defined(MY_OTA_LOG_RECEIVER_FEATURE)
#include "core/MyOTALogging.h"
#endif
// HARDWARE
#if defined(ARDUINO_ARCH_ESP8266)
#include "hal/architecture/MyHwESP8266.cpp"
@@ -66,6 +71,11 @@
#include "hal/architecture/MyHwLinuxGeneric.cpp"
#endif
// OTA Debug second part, depends on HAL
#if defined(MY_OTA_LOG_SENDER_FEATURE) || defined(MY_OTA_LOG_RECEIVER_FEATURE)
#include "core/MyOTALogging.cpp"
#endif
#if defined(MY_LEDS_BLINKING_FEATURE)
#error MY_LEDS_BLINKING_FEATURE is now removed from MySensors core,\
define MY_DEFAULT_ERR_LED_PIN, MY_DEFAULT_TX_LED_PIN or\
+166
View File
@@ -0,0 +1,166 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include "MyOTALogging.h"
#ifdef MY_OTA_LOG_SENDER_FEATURE
// global variables
static bool inOTALog = false;
void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... )
{
// Avoid recursion
if (inOTALog==true) {
return;
}
inOTALog = true;
MyMessage msg(NODE_SENSOR_ID, I_LOG_MESSAGE);
char fmtBuffer[MY_SERIAL_OUTPUT_SIZE];
va_list args;
// create message
va_start (args, fmt );
#ifdef vsnprintf_P
int n = vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args);
#else
int n = vsnprintf(fmtBuffer, sizeof(fmtBuffer), fmt, args);
#endif
va_end (args);
// Check number of chars
if (n<1) {
// Nothing to send
inOTALog = false;
return;
}
// Add \n to the end of string
if (n>(int)(sizeof(fmtBuffer)-2)) {
// String is truncated
n = sizeof(fmtBuffer)-2;
}
// add LF if not set
if (fmtBuffer[n-1]!='\n') {
fmtBuffer[n++]='\n';
fmtBuffer[n++]=0;
}
// Configure message
msg.sender = getNodeId();
msg.setDestination(logNode);
mSetCommand(msg, C_INTERNAL);
mSetRequestAck(msg, enableAck);
// Send package
for (int pos = 0; pos<n; pos+=MAX_PAYLOAD) {
uint8_t length = strlen(&fmtBuffer[pos]);
if (length>MAX_PAYLOAD) {
length = MAX_PAYLOAD;
}
(void)_sendRoute(msg.set((char*)&fmtBuffer[pos]));
}
inOTALog = false;
}
#endif
#ifdef MY_OTA_LOG_RECEIVER_FEATURE
// Global variables
char OTALogfmtBuffer[MY_SERIAL_OUTPUT_SIZE];
int OTALogfmtBufferPos = 0;
uint8_t OTALogBufferNode = BROADCAST_ADDRESS;
uint8_t OTALogBufferSensor = 0;
void OTALogPrintPrefix()
{
char prefix[37];
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
#ifdef snprintf_P
snprintf_P(prefix, sizeof(prefix),
PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
#else
snprintf(prefix, sizeof(prefix), PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
#endif
MY_SERIALDEVICE.print(prefix);
}
void OTALogFlushBuffer()
{
OTALogfmtBuffer[0] = 0;
OTALogfmtBufferPos = 0;
OTALogBufferNode = BROADCAST_ADDRESS;
}
inline void OTALogPrint(const MyMessage &message)
{
// Ignore log messages via broadcast
if (message.destination == BROADCAST_ADDRESS) {
return;
}
// FLush buffer, when node id changes
if ((OTALogBufferNode!=BROADCAST_ADDRESS) && ((OTALogBufferNode != message.sender) ||
(OTALogBufferSensor != message.sensor))) {
OTALogPrintPrefix();
MY_SERIALDEVICE.print(OTALogfmtBuffer);
MY_SERIALDEVICE.println("...");
OTALogFlushBuffer();
}
// Add data to buffer
const char *str = message.getString();
strncpy(&OTALogfmtBuffer[OTALogfmtBufferPos], str,
sizeof(OTALogfmtBuffer)-OTALogfmtBufferPos);
OTALogfmtBufferPos += strlen(str);
// Store node ID and sensor ID
OTALogBufferNode = message.sender;
OTALogBufferSensor = message.sensor;
// Print out buffered lines ending with \n
char *EOLpos;
while (EOLpos = strchr(OTALogfmtBuffer,'\n'), EOLpos != NULL) {
// Add end of string
EOLpos[0]=0;
// Print out line
OTALogPrintPrefix();
MY_SERIALDEVICE.println(OTALogfmtBuffer);
// Check if more content in buffer
int lenAfterEOL = (size_t)&OTALogfmtBuffer[OTALogfmtBufferPos]-(size_t)EOLpos-2;
if (lenAfterEOL>0) {
// More lines, move string to the beginning of the buffer
strcpy((char*)&OTALogfmtBuffer[0], (char*)&EOLpos[1]);
// calculate OTALogfmtBufferPos
OTALogfmtBufferPos -= (size_t)EOLpos-(size_t)&OTALogfmtBuffer[0]+2;
// Security check
if ((OTALogfmtBufferPos<=0) || (OTALogfmtBufferPos>=(int)sizeof(OTALogfmtBuffer))) {
MY_SERIALDEVICE.print("Sec:");
MY_SERIALDEVICE.println(OTALogfmtBufferPos);
OTALogFlushBuffer();
}
} else {
// End of message, prepare new one
OTALogFlushBuffer();
}
}
}
#endif
+73
View File
@@ -0,0 +1,73 @@
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
/**
* @file MyOTALogging.h
*
* @brief API declaration for MyOTALogging
* @defgroup MyOTALogginggrp MyOTALogging
* @ingroup internals
* @{
*
* @brief Enables ending and receiving debug messages over the air.
*/
#ifndef MyOTALogging_h
#define MyOTALogging_h
#include "MySensorsCore.h"
#include "MyTransport.h"
/**
* @brief Send a log message to a node
*
* If MY_OTA_LOG_RECEIVER_FEATURE is enabled on the destination node, the given
* message is printed to the serial port. You have to define MY_OTA_LOG_SENDER_FEATURE
* or MY_DEBUG_OTA to enable the OTALog() function.
*
* Output format of each line:
* Node ID;CHILD_NODE_ID;C_INTERNAL;I_LOG_MESSAGE;hwMillis() MESSAGE
*
* You will see the hwMillis() of the receiving node. After each \n character, a
* new debug message line starts. Incomplete messages are ending with '...'
*
* @param logNode Testination node ID
* @param enableAck Enable or disable ACK flag
* @param fmt printf format string
* @param ... arguments
*/
void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... );
/**
* @brief Handles output of OTA log or debug messages
*
* This function is used by MyTransport.cpp
*
* Output format of each line:
* Node ID;CHILD_NODE_ID;C_INTERNAL;I_LOG_MESSAGE;hwMillis() MESSAGE
*
* You will see the hwMillis() of the receiving node. After each \n character, a
* new debug message line starts. Incomplete messages are ending with '...'
*
* @param message Message buffer to use.
*/
inline void OTALogPrint(const MyMessage &message);
#endif /* MyOTALogging_h */
/** @}*/
+2 -1
View File
@@ -381,7 +381,8 @@ static bool skipSign(MyMessage &msg)
msg.type == I_FIND_PARENT_REQUEST || msg.type == I_FIND_PARENT_RESPONSE ||
msg.type == I_HEARTBEAT_REQUEST || msg.type == I_HEARTBEAT_RESPONSE ||
msg.type == I_PING || msg.type == I_PONG ||
msg.type == I_DISCOVER_REQUEST || msg.type == I_DISCOVER_RESPONSE )) {
msg.type == I_DISCOVER_REQUEST || msg.type == I_DISCOVER_RESPONSE ||
msg.type == I_LOG_MESSAGE)) {
ret = true;
} else if (mGetCommand(msg) == C_STREAM &&
(msg.type == ST_SOUND ||
+6
View File
@@ -831,6 +831,12 @@ void transportProcessMessage(void)
TRANSPORT_DEBUG(
PSTR("TSF:MSG:ACK\n")); // received message is ACK, no internal processing, handover to msg callback
}
#if defined(MY_OTA_LOG_RECEIVER_FEATURE)
if ((type == I_LOG_MESSAGE) && (command == C_INTERNAL)) {
OTALogPrint(_msg);
return; // no further processing required
}
#endif //defined(MY_OTA_LOG_RECEIVER_FEATURE)
#if defined(MY_GATEWAY_FEATURE)
// Hand over message to controller
(void)gatewayTransportSend(_msg);
+107
View File
@@ -0,0 +1,107 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
* The ArduinoGateway prints data received from sensors on the serial link.
* The gateway accepts input on seral which will be sent out on radio network.
*
* The GW code is designed for Arduino Nano 328p / 16MHz
*
* Wire connections (OPTIONAL):
* - Inclusion button should be connected between digital pin 3 and GND
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
*
* LEDs (OPTIONAL):
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or recieve crc error
*
* OTA DEBUG MESSAGES
* - Add the OTADebugReceive(message) into receive(const MyMessage &message) on a serial connected node
* - Add '#define MY_DEBUG_OTA (0)' to your Node sketch by replacing (0) with the node id of your serial connected node
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable OTA log display
#define MY_OTA_LOG_RECEIVER_FEATURE
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
#define MY_RF24_PA_LEVEL RF24_PA_LOW
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
}
+74
View File
@@ -0,0 +1,74 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* DESCRIPTION
*
* Example for sending debug messages over the air (OTA).
*
*/
// Enable debug
#define MY_DEBUG
// Enable OTA debugging to Node 0
#define MY_DEBUG_OTA (0)
// Allow sending logs without MY_DEBUG_OTA enabled
#define MY_OTA_LOG_SENDER_FEATURE
// Disable ACK for debug messages
//#define MY_DEBUG_OTA_DISABLE_ACK
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
void setup()
{
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo("DebugSensor", "1.0");
}
// Arduino loop
int c=0;
void loop()
{
// Wait some time
if (sleep(3000)==MY_SLEEP_NOT_POSSIBLE) {
delay(3000);
}
// Count loops
c++;
// A debug message
DEBUG_OUTPUT(PSTR("DEBUG\nc=%" PRId16 "\nmillis=" PRId32 "\n"), c, hwMillis());
// Send a log message with ACK to a node
OTALog(0, true, PSTR("LOG\nc=%" PRId16 "\nmillis=" PRId32 "\n"), c, hwMillis());
}
+6
View File
@@ -56,6 +56,8 @@ MY_PASSIVE_NODE LITERAL1
# debug
MY_DEBUG LITERAL1
MY_DEBUG_OTA LITERAL1
MY_DEBUG_OTA_DISABLE_ACK LITERAL1
MY_SPECIAL_DEBUG LITERAL1
# OTA
@@ -74,6 +76,10 @@ MY_INCLUSION_MODE_FEATURE LITERAL1
MY_INCLUSION_BUTTON_FEATURE LITERAL1
MY_INCLUSION_MODE_BUTTON_PIN LITERAL1
MY_INCLUSION_MODE_DURATION LITERAL1
MY_OTA_LOG_RECEIVER_FEATURE LITERAL1
MY_OTA_LOG_SENDER_FEATURE LITERAL1
MY_DEBUG_OTA LITERAL1
MY_DEBUG_OTA_DISABLE_ACK LITERAL1
# Signing
MY_DEBUG_VERBOSE_SIGNING LITERAL1