openhab-addons/bundles/org.openhab.binding.nibehea.../contrib/NibeGW/Arduino/NibeGW/NibeGw.h

131 lines
3.1 KiB
C++

/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* ----------------------------------------------------------------------------
*
* Frame format:
* +----+----+------+-----+-----+----+----+-----+
* | 5C | 00 | ADDR | CMD | LEN | DATA | CHK |
* +----+----+------+-----+-----+----+----+-----+
* |------------ CHK -----------|
*
* Address:
* 0x16 = SMS40
* 0x19 = RMU40
* 0x20 = MODBUS40
*
* Checksum: XOR
*
* When valid data is received (checksum ok),
* ACK (0x06) should be sent to the heat pump.
* When checksum mismatch,
* NAK (0x15) should be sent to the heat pump.
*
* Author: pauli.anttila@gmail.com
*
*/
#ifndef NibeGw_h
#define NibeGw_h
#include <Arduino.h>
#define HARDWARE_SERIAL
//#define ENABLE_NIBE_DEBUG
// state machine states
enum eState
{
STATE_WAIT_START,
STATE_WAIT_DATA,
STATE_OK_MESSAGE_RECEIVED,
STATE_CRC_FAILURE,
};
enum eTokenType
{
READ_TOKEN,
WRITE_TOKEN
};
// message buffer for RS-485 communication. Max message length is 80 bytes + 6 bytes header
#define MAX_DATA_LEN 128
#define NIBE_CALLBACK_MSG_RECEIVED void (*callback_msg_received)(const byte* const data, int len)
#define NIBE_CALLBACK_MSG_RECEIVED_TOKEN int (*callback_msg_token_received)(eTokenType token, byte* data)
#ifdef ENABLE_NIBE_DEBUG
#define NIBE_CALLBACK_MSG_RECEIVED_DEBUG void (*debug)(byte verbose, char* data)
#endif
#define SMS40 0x16
#define RMU40 0x19
#define MODBUS40 0x20
class NibeGw
{
private:
eState state;
boolean connectionState;
byte directionPin;
byte buffer[MAX_DATA_LEN];
byte index;
#ifdef HARDWARE_SERIAL
HardwareSerial* RS485;
#else
Serial_* RS485;
#endif
NIBE_CALLBACK_MSG_RECEIVED;
NIBE_CALLBACK_MSG_RECEIVED_TOKEN;
byte verbose;
boolean ackModbus40;
boolean ackSms40;
boolean ackRmu40;
boolean sendAcknowledge;
int checkNibeMessage(const byte* const data, byte len);
void sendData(const byte* const data, byte len);
void sendAck();
void sendNak();
boolean shouldAckNakSend(byte address);
#ifdef ENABLE_NIBE_DEBUG
NIBE_CALLBACK_MSG_RECEIVED_DEBUG;
char debug_buf[100];
#endif
public:
#ifdef HARDWARE_SERIAL
NibeGw(HardwareSerial* serial, int RS485DirectionPin);
#else
NibeGw(Serial_* serial, int RS485DirectionPin);
#endif
NibeGw& setCallback(NIBE_CALLBACK_MSG_RECEIVED, NIBE_CALLBACK_MSG_RECEIVED_TOKEN);
#ifdef ENABLE_NIBE_DEBUG
NibeGw& setDebugCallback(NIBE_CALLBACK_MSG_RECEIVED_DEBUG);
#endif
void connect();
void disconnect();
boolean connected();
void setVerboseLevel(byte level);
boolean messageStillOnProgress();
void loop();
void setAckModbus40Address(boolean val);
void setAckSms40Address(boolean val);
void setAckRmu40Address(boolean val);
void setSendAcknowledge(boolean val);
};
#endif