ESPHome 2026.2.1
Loading...
Searching...
No Matches
tormatic_protocol.h
Go to the documentation of this file.
1#pragma once
47namespace esphome {
48namespace tormatic {
49
50using namespace esphome::cover;
51
52// MessageType is the type of message that follows the MessageHeader.
53enum MessageType : uint16_t {
54 STATUS = 0x0104,
55 COMMAND = 0x0106,
56};
57
58// Max string length: 7 ("Unknown"/"Command"). Update print() buffer sizes if adding longer strings.
59inline const char *message_type_to_str(MessageType t) {
60 switch (t) {
61 case STATUS:
62 return "Status";
63 case COMMAND:
64 return "Command";
65 default:
66 return "Unknown";
67 }
68}
69
70// MessageHeader appears at the start of every message, both requests and replies.
72 uint16_t seq;
73 uint32_t len;
75
76 MessageHeader() = default;
78 this->type = type;
79 this->seq = seq;
80 // len includes the length of the type field. It was
81 // included in MessageHeader to avoid having to parse
82 // it as part of the payload.
83 this->len = payload_size + sizeof(this->type);
84 }
85
86 std::string print() {
87 // 64 bytes: "MessageHeader: seq " + uint16 + ", len " + uint32 + ", type " + type + safety margin
88 char buf[64];
89 buf_append_printf(buf, sizeof(buf), 0, "MessageHeader: seq %d, len %d, type %s", this->seq, this->len,
90 message_type_to_str(this->type));
91 return buf;
92 }
93
94 void byteswap() {
95 this->len = convert_big_endian(this->len);
96 this->seq = convert_big_endian(this->seq);
97 this->type = convert_big_endian(this->type);
98 }
99
100 // payload_size returns the amount of payload bytes to be read from the uart
101 // buffer after reading the header.
102 uint32_t payload_size() { return this->len - sizeof(this->type); }
103} __attribute__((packed));
104
105// StatusType denotes which 'page' of information needs to be retrieved.
106// On my Novoferm 423, only the GATE status type returns values, Unknown
107// only contains zeroes.
108enum StatusType : uint16_t {
109 GATE = 0x0A,
110 UNKNOWN = 0x0B,
112
113// GateStatus defines the current state of the gate, received in a StatusReply
114// and sent in a Command.
123
125 switch (s) {
126 case OPENING:
128 case CLOSING:
130 case OPENED:
131 case CLOSED:
132 case PAUSED:
133 case VENTILATING:
135 }
137}
138
139// Max string length: 11 ("Ventilating"). Update print() buffer sizes if adding longer strings.
140inline const char *gate_status_to_str(GateStatus s) {
141 switch (s) {
142 case PAUSED:
143 return "Paused";
144 case CLOSED:
145 return "Closed";
146 case VENTILATING:
147 return "Ventilating";
148 case OPENED:
149 return "Opened";
150 case OPENING:
151 return "Opening";
152 case CLOSING:
153 return "Closing";
154 default:
155 return "Unknown";
156 }
157}
158
159// A StatusRequest is sent to request the gate's current status.
162 uint16_t trailer = 0x1;
163
164 StatusRequest() = default;
166
167 void byteswap() {
168 this->type = convert_big_endian(this->type);
169 this->trailer = convert_big_endian(this->trailer);
170 }
171} __attribute__((packed));
172
173// StatusReply is received from the unit in response to a StatusRequest.
175 uint8_t ack = 0x2;
177 uint8_t trailer = 0x0;
178
179 std::string print() {
180 // 48 bytes: "StatusReply: state " (19) + state (11) + safety margin
181 char buf[48];
182 buf_append_printf(buf, sizeof(buf), 0, "StatusReply: state %s", gate_status_to_str(this->state));
183 return buf;
184 }
185
186 void byteswap(){};
187} __attribute__((packed));
188
189// Serialize the given object to a new byte vector.
190// Invokes the object's byteswap() method.
191template<typename T> std::vector<uint8_t> serialize(T obj) {
192 obj.byteswap();
193
194 std::vector<uint8_t> out(sizeof(T));
195 memcpy(out.data(), &obj, sizeof(T));
196
197 return out;
198}
199
200// Command tells the gate to start or stop moving.
201// It is echoed back by the unit on success.
203 // The part of the unit to control. For now only the gate is supported.
205 uint8_t pad = 0x0;
206 // The desired state:
207 // PAUSED = stop
208 // VENTILATING = move to ~20% open
209 // CLOSED = close
210 // OPENED = open/high-torque reverse when closing
212
215
216 std::string print() {
217 // 56 bytes: "CommandRequestReply: state " (27) + state (11) + safety margin
218 char buf[56];
219 buf_append_printf(buf, sizeof(buf), 0, "CommandRequestReply: state %s", gate_status_to_str(this->state));
220 return buf;
221 }
222
223 void byteswap() { this->type = convert_big_endian(this->type); }
224} __attribute__((packed));
225
226} // namespace tormatic
227} // namespace esphome
enum esphome::cover::CoverOperation __attribute__
CoverOperation
Enum encoding the current operation of a cover.
Definition cover.h:79
@ COVER_OPERATION_OPENING
The cover is currently opening.
Definition cover.h:83
@ COVER_OPERATION_CLOSING
The cover is currently closing.
Definition cover.h:85
@ COVER_OPERATION_IDLE
The cover is currently idle (not moving)
Definition cover.h:81
CoverOperation gate_status_to_cover_operation(GateStatus s)
std::vector< uint8_t > serialize(T obj)
const char * message_type_to_str(MessageType t)
const char * gate_status_to_str(GateStatus s)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
Definition helpers.h:584
MessageHeader(MessageType type, uint16_t seq, uint32_t payload_size)