@classmethod<EOL><INDENT>def decode(cls, _data: str) -> '<STR_LIT>':<DEDENT>
<EOL>data = DataIterator(_data)<EOL>_LOGGER.debug("<STR_LIT>", _data)<EOL>start = data.take_hex()<EOL>address = None<EOL>if has_address(start, len(_data)):<EOL><INDENT>address = data.take_hex(half=is_user_interface_req(start))<EOL><DEDENT>length = data.take_hex()<EOL>data_length = length & <NUM_LIT><EOL>seq = length >> <NUM_LIT:7><EOL>command = CommandType(data.take_hex())<EOL>msg_data = data.take_bytes(data_length,<EOL>half=is_user_interface_req(start))<EOL>timestamp = None<EOL>if has_timestamp(start):<EOL><INDENT>timestamp = decode_timestamp(data.take_bytes(<NUM_LIT:6>))<EOL><DEDENT>checksum = data.take_hex()  <EOL>if not data.is_consumed():<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return Packet(<EOL>is_user_interface_resp=(is_user_interface_resp(start) and<EOL>command == CommandType.USER_INTERFACE),<EOL>address=address,<EOL>seq=seq,<EOL>command=command,<EOL>data=msg_data,<EOL>timestamp=timestamp,<EOL>)<EOL>
Packets are ASCII encoded data. Packet layout is as follows:

+---------------------------------------------------------------------------+
| start | address | length | command | data | timestamp | checksum | finish |
| hex   | hex     | hex    | hex     | str  | dec       | hex      | crlf   |
| 1     | 1       | 1      | 1       | n    | 6         | 1        |        |
+---------------------------------------------------------------------------+

Timestamp:
    Timestamps are formatted in the following format, where each field is
    decimal encoded:

    YY MM DD HH MM SS

Checksum:
    Calculated by...?

Since data is ASCII encoded, each byte uses 2 ASCII character to be
represented. However, we cannot simply do a hex decode on the entire
message, since the timestamp and data fields are represented using a
non-hex representation and therefore must be manually decoded.