Skip to content

Commit cdb8b65

Browse files
committed
Add multi-message support (#1515)
1 parent aa76d26 commit cdb8b65

File tree

7 files changed

+432
-1
lines changed

7 files changed

+432
-1
lines changed

MySensors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs
440440

441441
#include "core/MyCapabilities.h"
442442
#include "core/MyMessage.cpp"
443+
#include "core/MyBlob.cpp"
443444
#include "core/MySplashScreen.cpp"
444445
#include "core/MySensorsCore.cpp"
445446

core/MyBlob.cpp

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*
2+
* The MySensors Arduino library handles the wireless radio link and protocol
3+
* between your home built sensors/actuators and HA controller of choice.
4+
* The sensors forms a self healing radio network with optional repeaters. Each
5+
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
6+
* network topology allowing messages to be routed to nodes.
7+
*
8+
* Created by Constnatin Petra <constantin.petra@gmail.com>
9+
* Copyright (C) 2022 Constantin Petra
10+
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
11+
*
12+
* Documentation: http://www.mysensors.org
13+
* Support Forum: http://forum.mysensors.org
14+
*
15+
* This program is free software; you can redistribute it and/or
16+
* modify it under the terms of the GNU General Public License
17+
* version 2 as published by the Free Software Foundation.
18+
*/
19+
20+
#include "Version.h"
21+
#include "MyConfig.h"
22+
#include "MyEepromAddresses.h"
23+
#include "MyMessage.h"
24+
#include "MyBlob.h"
25+
#include "stddef.h"
26+
27+
#define SET_PAYLOAD_TYPE(u, type) BF_SET(u, type, V2_MYS_HEADER_CEP_PAYLOADTYPE_POS, \
28+
V2_MYS_HEADER_CEP_PAYLOADTYPE_SIZE)
29+
#define GET_PAYLOAD_TYPE(u) BF_GET(u, V2_MYS_HEADER_CEP_PAYLOADTYPE_POS, \
30+
V2_MYS_HEADER_CEP_PAYLOADTYPE_SIZE)
31+
#define SET_COMMAND(u, command) BF_SET(u, command, V2_MYS_HEADER_CEP_COMMAND_POS, \
32+
V2_MYS_HEADER_CEP_COMMAND_SIZE)
33+
#define GET_COMMAND(u) BF_GET(u, V2_MYS_HEADER_CEP_COMMAND_POS, \
34+
V2_MYS_HEADER_CEP_COMMAND_SIZE)
35+
#define SET_LENGTH(u, finalLength) BF_SET(u, finalLength, V2_MYS_HEADER_VSL_LENGTH_POS, \
36+
V2_MYS_HEADER_VSL_LENGTH_SIZE)
37+
#define GET_LENGTH(u) BF_GET(u, V2_MYS_HEADER_VSL_LENGTH_POS, \
38+
V2_MYS_HEADER_VSL_LENGTH_SIZE)
39+
#define SET_VERSION(u) BF_SET(u, V2_MYS_HEADER_PROTOCOL_VERSION, \
40+
V2_MYS_HEADER_VSL_VERSION_POS, V2_MYS_HEADER_VSL_VERSION_SIZE);
41+
42+
#define MAX_BLOB_SIZE (MAX_PAYLOAD_SIZE)
43+
44+
// replicates part of the MyMesgage structure related to a single sensor data.
45+
typedef struct {
46+
uint8_t command_echo_payload;
47+
uint8_t type;
48+
uint8_t sensor;
49+
union {
50+
uint8_t bValue;
51+
uint16_t uiValue;
52+
int16_t iValue;
53+
uint32_t ulValue;
54+
int32_t lValue;
55+
struct {
56+
float fValue;
57+
uint8_t fPrecision;
58+
};
59+
} __attribute__((packed));
60+
} __attribute__((packed)) blob;
61+
62+
MyBlob::~MyBlob()
63+
{
64+
65+
}
66+
67+
MyBlob::MyBlob(MyMessage *msg)
68+
{
69+
_msg = msg;
70+
_offset = 0;
71+
_msg->setPayloadType(P_CUSTOM);
72+
}
73+
74+
void *MyBlob::common(uint8_t messageType, uint8_t sensor, uint8_t ptype, uint8_t size, uint8_t cmd)
75+
{
76+
blob *b;
77+
if (_offset + size >= MAX_BLOB_SIZE) {
78+
return NULL;
79+
}
80+
b = (blob *)(_msg->data + _offset);
81+
SET_PAYLOAD_TYPE(b->command_echo_payload, ptype);
82+
SET_COMMAND(b->command_echo_payload, cmd);
83+
b->type = messageType;
84+
b->sensor = sensor;
85+
_offset += size;
86+
SET_LENGTH(_msg->version_length, _offset);
87+
SET_VERSION(_msg->version_length);
88+
return b;
89+
}
90+
91+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, uint8_t value)
92+
{
93+
blob *b = (blob *)common(messageType, sensor, P_BYTE, 4, C_SET);
94+
if (b == NULL) {
95+
return false;
96+
}
97+
b->bValue = value;
98+
return true;
99+
}
100+
101+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, uint16_t value)
102+
{
103+
blob *b = (blob *)common(messageType, sensor, P_UINT16, 5, C_SET);
104+
if (b == NULL) {
105+
return false;
106+
}
107+
b->uiValue = value;
108+
return true;
109+
}
110+
111+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, int16_t value)
112+
{
113+
blob *b = (blob *)common(messageType, sensor, P_INT16, 5, C_SET);
114+
if (b == NULL) {
115+
return false;
116+
}
117+
b->uiValue = value;
118+
return true;
119+
}
120+
121+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, uint32_t value)
122+
{
123+
blob *b = (blob *)common(messageType, sensor, P_ULONG32, 7, C_SET);
124+
if (b == NULL) {
125+
return false;
126+
}
127+
b->ulValue = value;
128+
return true;
129+
}
130+
131+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, int32_t value)
132+
{
133+
blob *b = (blob *)common(messageType, sensor, P_LONG32, 7, C_SET);
134+
135+
if (b == NULL) {
136+
return false;
137+
}
138+
b->lValue = value;
139+
return true;
140+
}
141+
142+
bool MyBlob::set(uint8_t messageType, uint8_t sensor, float value, uint8_t decimals)
143+
{
144+
blob *b = (blob *)common(messageType, sensor, P_FLOAT32, 8, C_SET);
145+
146+
if (b == NULL) {
147+
return false;
148+
}
149+
b->fValue = value;
150+
b->fPrecision = decimals;
151+
return true;
152+
}
153+
154+
bool MyBlob::setBattery(uint8_t value)
155+
{
156+
blob *b = (blob *)common(I_BATTERY_LEVEL, NODE_SENSOR_ID, P_BYTE, 4, C_INTERNAL);
157+
158+
if (b == NULL) {
159+
return false;
160+
}
161+
b->bValue = value;
162+
return true;
163+
}
164+
165+
166+
bool MyBlob::getNext(MyMessage &m)
167+
{
168+
uint8_t size = GET_LENGTH(_msg->version_length);
169+
uint8_t type;
170+
171+
blob *b;
172+
if (_offset >= size) {
173+
return false;
174+
}
175+
176+
m.last = _msg->last;
177+
m.sender = _msg->sender;
178+
m.destination = _msg->destination;
179+
m.version_length = _msg->version_length;
180+
181+
b = (blob *)(_msg->data + _offset);
182+
m.type = b->type;
183+
m.sensor = b->sensor;
184+
185+
type = GET_PAYLOAD_TYPE(b->command_echo_payload);
186+
m.command_echo_payload = b->command_echo_payload;
187+
188+
if (type == P_BYTE) {
189+
m.bValue = b->bValue;
190+
_offset += 4;
191+
return true;
192+
} else if (type == P_UINT16) {
193+
m.uiValue = b->uiValue;
194+
_offset += 5;
195+
return true;
196+
} else if (type == P_INT16) {
197+
m.iValue = b->iValue;
198+
_offset += 5;
199+
return true;
200+
} else if (type == P_ULONG32) {
201+
m.ulValue = b->ulValue;
202+
_offset += 7;
203+
return true;
204+
} else if (type == P_LONG32) {
205+
m.lValue = b->lValue;
206+
_offset += 7;
207+
return true;
208+
} else if (type == P_FLOAT32) {
209+
m.fValue = b->fValue;
210+
m.fPrecision = b->fPrecision;
211+
_offset += 8;
212+
return true;
213+
}
214+
return false;
215+
}
216+
217+
void MyBlob::reset()
218+
{
219+
_offset = 0;
220+
SET_LENGTH(_msg->version_length, _offset);
221+
}

0 commit comments

Comments
 (0)