/* * 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 * Copyright (C) 2013-2026 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * Multi message feature added by Constantin Petra * Copyright (C) 2022 Constantin Petra * * 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 MyMultiMessage.h * * @brief API and type declarations for MySensors block object * @defgroup MyMultiMessage Multi-message support * @ingroup publics * @{ * * @brief Block object that enables sending multiple sensor data in one message, * including battery information. * @section MyBlobExample MyMultiMessage usage example * * USE_BLOB is a local define, only for emphasizing the changes needed * for using the blob feature. * * @code * * #define USE_BLOB * * // Initialize general message * #ifdef USE_BLOB * MyMessage msgBlob(0, V_MULTI_MESSAGE); * #else * MyMessage msgTEMPERATURE(CHILD_ID_TEMPERATURE, V_TEMP); * MyMessage msgHUMIDITY(CHILD_ID_HUMIDITY, V_HUM); * #endif * @endcode * * The code below shows a simple humidity/temperature/battery sensor sending everything in one * message: * @code * * #ifdef USE_BLOB * MyMultiMessage blob(&msgBlob); * blob.set(V_TEMP, CHILD_ID_TEMPERATURE , temperature, 1); * blob.set(V_HUM, CHILD_ID_HUMIDITY, humidity, 1); * blob.setBattery(batt_level); * send(msgBlob); * #else * send(msgTEMPERATURE.set(temperature, 1)); * wait(10); // the wait() is needed at least for rfm69, otherwise it takes a long time. * send(msgHUMIDITY.set(humidity, 1)); * wait(10); * #endif * @endcode * * Fitting more messages may become more complex, though: * @todo Add logic in MyMultiMessage to handle sending itself. * @code * * MyMultiMessage blob(&msgBlob); * if (!blob.set(V_TEMP, 0 , temperature, 1)) { * send(msgBlob); * wait(10); * msgBlob.reset(); * blob.set(V_TEMP, 0 , temperature, 1) * } * if (!blob.setBattery(batt_level)) { * send(msgBlob); * wait(10); * msgBlob.reset(); * blob.setBattery(batt_level) * } * * @endcode */ #ifndef MYMULTIMESSAGE_H #define MYMULTIMESSAGE_H #include "MyMessage.h" /** * @brief A collection of APIs that convert a MyMessage object to a message group. */ class MyMultiMessage { private: // A pointer to the "real" message MyMessage *_msg; // Current offset inside the message size_t _offset; // Common setup, returns a pointer to the next area that can be used, NULL if no more room void *common(uint8_t type, uint8_t sensor, uint8_t ptype, uint8_t size, uint8_t cmd); public: /** * Constructor * @param msg A MyMessage pointer, the type should be V_MULTI_MESSAGE */ explicit MyMultiMessage(MyMessage *msg); /** * @brief Set payload to unsigned 8-bit integer value * @param messageType * @param sensorId * @param value (0 to 255) * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, uint8_t value); /** * @brief Set payload to unsigned 16-bit integer value * @param messageType * @param sensorId * @param value (0 to 65535) * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, uint16_t value); /** * @brief Set payload to signed 16-bit integer value * @param messageType * @param sensorId * @param value (–32768 to 32767) * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, int16_t value); /** * @brief Set payload to unsigned 32-bit integer value * @param messageType * @param sensorId * @param value (0 to 4294967295) * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, uint32_t value); /** * @brief Set payload to signed 32-bit integer value * @param messageType * @param sensorId * @param value (–2147483648 to 2147483647) * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, int32_t value); /** * @brief Set payload to decimal number * @param messageType * @param sensorId * @param value float * @param decimals number of decimals to include * @return false if the message won't fit, true if the message was added successfuly */ bool set(uint8_t messageType, uint8_t sensorId, float value, uint8_t decimals); /** * @brief Reset the message contents, so that in can be reused after send() */ void reset(); /** * @brief Set battery level * @param value battery level */ bool setBattery(uint8_t value); /** * @brief get next message from the blob * @param m MyMessage reference */ bool getNext(MyMessage &m); ~MyMultiMessage(); }; #endif /** @}*/