ESPHome  2025.3.3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
tormatic_protocol.h
Go to the documentation of this file.
1 #pragma once
2 
4 
47 namespace esphome {
48 namespace tormatic {
49 
50 using namespace esphome::cover;
51 
52 // MessageType is the type of message that follows the MessageHeader.
53 enum MessageType : uint16_t {
54  STATUS = 0x0104,
55  COMMAND = 0x0106,
56 };
57 
58 inline const char *message_type_to_str(MessageType t) {
59  switch (t) {
60  case STATUS:
61  return "Status";
62  case COMMAND:
63  return "Command";
64  default:
65  return "Unknown";
66  }
67 }
68 
69 // MessageHeader appears at the start of every message, both requests and replies.
70 struct MessageHeader {
71  uint16_t seq;
72  uint32_t len;
74 
75  MessageHeader() = default;
76  MessageHeader(MessageType type, uint16_t seq, uint32_t payload_size) {
77  this->type = type;
78  this->seq = seq;
79  // len includes the length of the type field. It was
80  // included in MessageHeader to avoid having to parse
81  // it as part of the payload.
82  this->len = payload_size + sizeof(this->type);
83  }
84 
85  std::string print() {
86  return str_sprintf("MessageHeader: seq %d, len %d, type %s", this->seq, this->len, message_type_to_str(this->type));
87  }
88 
89  void byteswap() {
90  this->len = convert_big_endian(this->len);
91  this->seq = convert_big_endian(this->seq);
92  this->type = convert_big_endian(this->type);
93  }
94 
95  // payload_size returns the amount of payload bytes to be read from the uart
96  // buffer after reading the header.
97  uint32_t payload_size() { return this->len - sizeof(this->type); }
98 } __attribute__((packed));
99 
100 // StatusType denotes which 'page' of information needs to be retrieved.
101 // On my Novoferm 423, only the GATE status type returns values, Unknown
102 // only contains zeroes.
103 enum StatusType : uint16_t {
104  GATE = 0x0A,
105  UNKNOWN = 0x0B,
106 };
107 
108 // GateStatus defines the current state of the gate, received in a StatusReply
109 // and sent in a Command.
110 enum GateStatus : uint8_t {
117 };
118 
120  switch (s) {
121  case OPENING:
123  case CLOSING:
125  case OPENED:
126  case CLOSED:
127  case PAUSED:
128  case VENTILATING:
129  return COVER_OPERATION_IDLE;
130  }
131  return COVER_OPERATION_IDLE;
132 }
133 
134 inline const char *gate_status_to_str(GateStatus s) {
135  switch (s) {
136  case PAUSED:
137  return "Paused";
138  case CLOSED:
139  return "Closed";
140  case VENTILATING:
141  return "Ventilating";
142  case OPENED:
143  return "Opened";
144  case OPENING:
145  return "Opening";
146  case CLOSING:
147  return "Closing";
148  default:
149  return "Unknown";
150  }
151 }
152 
153 // A StatusRequest is sent to request the gate's current status.
156  uint16_t trailer = 0x1;
157 
158  StatusRequest() = default;
159  StatusRequest(StatusType type) { this->type = type; }
160 
161  void byteswap() {
162  this->type = convert_big_endian(this->type);
163  this->trailer = convert_big_endian(this->trailer);
164  }
165 } __attribute__((packed));
166 
167 // StatusReply is received from the unit in response to a StatusRequest.
168 struct StatusReply {
169  uint8_t ack = 0x2;
171  uint8_t trailer = 0x0;
172 
173  std::string print() { return str_sprintf("StatusReply: state %s", gate_status_to_str(this->state)); }
174 
175  void byteswap(){};
176 } __attribute__((packed));
177 
178 // Serialize the given object to a new byte vector.
179 // Invokes the object's byteswap() method.
180 template<typename T> std::vector<uint8_t> serialize(T obj) {
181  obj.byteswap();
182 
183  std::vector<uint8_t> out(sizeof(T));
184  memcpy(out.data(), &obj, sizeof(T));
185 
186  return out;
187 }
188 
189 // Command tells the gate to start or stop moving.
190 // It is echoed back by the unit on success.
192  // The part of the unit to control. For now only the gate is supported.
194  uint8_t pad = 0x0;
195  // The desired state:
196  // PAUSED = stop
197  // VENTILATING = move to ~20% open
198  // CLOSED = close
199  // OPENED = open/high-torque reverse when closing
201 
202  CommandRequestReply() = default;
203  CommandRequestReply(GateStatus state) { this->state = state; }
204 
205  std::string print() { return str_sprintf("CommandRequestReply: state %s", gate_status_to_str(this->state)); }
206 
207  void byteswap() { this->type = convert_big_endian(this->type); }
208 } __attribute__((packed));
209 
210 } // namespace tormatic
211 } // namespace esphome
CommandRequestReply()=default
CoverOperation
Enum encoding the current operation of a cover.
Definition: cover.h:80
StatusRequest()=default
uint16_t seq
The cover is currently closing.
Definition: cover.h:86
const char * gate_status_to_str(GateStatus s)
MessageHeader(MessageType type, uint16_t seq, uint32_t payload_size)
uint32_t payload_size()
std::string str_sprintf(const char *fmt,...)
Definition: helpers.cpp:324
constexpr14 T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order...
Definition: helpers.h:248
std::string print()
uint16_t trailer
std::vector< uint8_t > serialize(T obj)
MessageType type
GateStatus state
const char * message_type_to_str(MessageType t)
MessageHeader()=default
enum esphome::tormatic::StatusType __attribute__
uint8_t pad
uint8_t ack
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
CoverOperation gate_status_to_cover_operation(GateStatus s)
The cover is currently opening.
Definition: cover.h:84