Skip to content

Commit

Permalink
Merge pull request #20 from loetmeister/master
Browse files Browse the repository at this point in the history
new device HBW-DIS-Key-4 and some clean-up
  • Loading branch information
ThorstenPferdekaemper committed Oct 9, 2020
2 parents f377ad0 + 3c401e9 commit 2e6b011
Show file tree
Hide file tree
Showing 33 changed files with 2,394 additions and 208 deletions.
54 changes: 8 additions & 46 deletions HBW-CC-DT3-T6/HBW-CC-DT3-T6.ino
Expand Up @@ -13,22 +13,21 @@
// - initial version
// v0.02
// - change to peer: temp (sensor & actuator), removed deltaT virtual Keys (peering conflict)
// v0.30
// - allow deltaT channels peering with external switches (key/actuator peer role)


#define HARDWARE_VERSION 0x01
#define FIRMWARE_VERSION 0x0002
#define FIRMWARE_VERSION 0x001E
#define HMW_DEVICETYPE 0x9C //device ID (make sure to import .xml into FHEM)

#define NUMBER_OF_TEMP_CHAN 6 // input channels - 1-wire temperature sensors
#define ADDRESS_START_CONF_TEMP_CHAN 0x7 // first EEPROM address for temperature sensors configuration
#define NUM_LINKS_TEMP 20 // requires Support_HBWLink_InfoEvent in HBWired.h
#define LINKADDRESSSTART_TEMP 0x100 // step 6
#define LINKADDRESSSTART_TEMP 0x100 // pering start_address for any sensor type peers, address_step has to be 6
#define NUMBER_OF_DELTAT_CHAN 3 // result output channels[, can peer with switch]
#define NUM_LINKS_DELTATX 6 // allow to peer input channels (T1 & T2) with one temperature sensor each
#define LINKADDRESSSTART_DELTATX 0x220 // step 7
//#define NUMBER_OF_KEY_CHAN 3 // input channels - deltaT vKey [pushbutton/switch]
//#define NUM_LINKS_KEY 12 // 3 DELTA_T KEY[, 9 for pushbutton/switch]
//#define LINKADDRESSSTART_KEY 0x100 //0x1A2, only one start address possible for all sensor type peers // step 6


//#define USE_HARDWARE_SERIAL // use hardware serial (USART) for final device - this disables debug output
Expand All @@ -38,10 +37,9 @@

// HB Wired protocol and module
#include <HBWired.h>
//#include <HBWKey.h>
//#include <HBWLinkKey.h>
#include <HBWOneWireTempSensors.h>
#include <HBWLinkInfoEventSensor.h>
//#include <HBWLinkInfoEventSensor.h>
#include "HBWLinkKeyInfoEventSensor.h" // TODO: remove these files and add option to the lib, allowing to combine different LinkSender
#include <HBWLinkInfoEventActuator.h>
#include "HBWDeltaT.h"

Expand All @@ -56,10 +54,6 @@
#define RELAY_1 5
#define RELAY_2 6
#define RELAY_3 7

// #define BUTTON_1 A1
// #define BUTTON_2 A2
// #define BUTTON_3 A3

#define BLOCKED_TWI_SDA A4 // used by I²C - SDA
#define BLOCKED_TWI_SCL A5 // used by I²C - SCL
Expand All @@ -76,10 +70,6 @@
#define RELAY_2 A2
#define RELAY_3 A3 //NOT_A_PIN

// #define BUTTON_1 6
// #define BUTTON_2 NOT_A_PIN
// #define BUTTON_3 NOT_A_PIN

#include "FreeRam.h"
#include <HBWSoftwareSerial.h>
HBWSoftwareSerial rs485(RS485_RXD, RS485_TXD); // RX, TX
Expand Down Expand Up @@ -124,17 +114,12 @@ class HBDTControlDevice : public HBWDevice {
{
d_ow = oneWire;
tempSensorconfig = _tempSensorconfig;
// linkSenderInfo = _linkSenderTemp;
// linkReceiverInfo = _linkReceiverTemp;
};
virtual void afterReadConfig();

private:
OneWire* d_ow;
hbw_config_onewire_temp** tempSensorconfig;

//HBWLinkSender* linkSenderTemp;
//HBWLinkReceiver* linkReceiverTemp;
};

// device specific defaults
Expand All @@ -143,18 +128,6 @@ void HBDTControlDevice::afterReadConfig()
if(hbwconfig.logging_time == 0xFF) hbwconfig.logging_time = 50;

HBWOneWireTemp::sensorSearch(d_ow, tempSensorconfig, (uint8_t) NUMBER_OF_TEMP_CHAN, (uint8_t) ADDRESS_START_CONF_TEMP_CHAN);


//static const uint16_t sAddr = 0x100;
//hbwdebug(F("EE@ 0x100"));hbwdebug(F("\n"));
//static const uint8_t Esize = 64;
//byte eeFoo[Esize];
//readEEPROM(eeFoo, sAddr, Esize);
//for(byte i = 0; i < Esize; i++) {
//hbwdebughex(eeFoo[i]);
//if (i % 6 == 0 && i != 0) hbwdebug(F("\n"));
//} hbwdebug(F("\n"));

};

HBDTControlDevice* device = NULL;
Expand Down Expand Up @@ -185,11 +158,6 @@ void setup()
channels[i +NUMBER_OF_TEMP_CHAN + NUMBER_OF_DELTAT_CHAN *2] = deltaTxCh[i +NUMBER_OF_DELTAT_CHAN];
}

// static const uint8_t buttonPin[NUMBER_OF_KEY_CHAN] = {BUTTON_1, BUTTON_2, BUTTON_3}; // assing pins
// for(uint8_t i = 0; i < NUMBER_OF_KEY_CHAN; i++) {
// channels[i +NUMBER_OF_TEMP_CHAN +NUMBER_OF_DELTAT_CHAN *3] = new HBWKey(buttonPin[i], &(hbwconfig.KeyCfg[i]));
// }


#ifdef USE_HARDWARE_SERIAL // RS485 via UART Serial, no debug (_debugstream is NULL)
Serial.begin(19200, SERIAL_8E1);
Expand All @@ -198,12 +166,9 @@ void setup()
&Serial, RS485_TXEN, sizeof(hbwconfig), &hbwconfig,
NUMBER_OF_CHAN, (HBWChannel**)channels,
NULL,
// new HBWLinkKey(NUM_LINKS_KEY + NUM_LINKS_TEMP,LINKADDRESSSTART_TEMP), NULL,
new HBWLinkInfoEventSensor<NUM_LINKS_TEMP, LINKADDRESSSTART_TEMP>(),
new HBWLinkKeyInfoEventSensor<NUM_LINKS_TEMP, LINKADDRESSSTART_TEMP>(),
new HBWLinkInfoEventActuator<NUM_LINKS_DELTATX, LINKADDRESSSTART_DELTATX>(),
g_ow, tempConfig
// , new HBWLinkInfoEventSensor(NUM_LINKS_TEMP + NUM_LINKS_KEY,LINKADDRESSSTART_TEMP),
// new HBWLinkInfoEventActuator(NUM_LINKS_DELTATX,LINKADDRESSSTART_DELTATX)
);

device->setConfigPins(BUTTON, LED); // use analog input for 'BUTTON'
Expand All @@ -216,12 +181,9 @@ void setup()
&rs485, RS485_TXEN, sizeof(hbwconfig), &hbwconfig,
NUMBER_OF_CHAN, (HBWChannel**)channels,
&Serial,
// new HBWLinkKey(NUM_LINKS_KEY + NUM_LINKS_TEMP,LINKADDRESSSTART_TEMP), NULL,
new HBWLinkInfoEventSensor<NUM_LINKS_TEMP, LINKADDRESSSTART_TEMP>(),
new HBWLinkKeyInfoEventSensor<NUM_LINKS_TEMP, LINKADDRESSSTART_TEMP>(),
new HBWLinkInfoEventActuator<NUM_LINKS_DELTATX, LINKADDRESSSTART_DELTATX>(),
g_ow, tempConfig
// , new HBWLinkInfoEventSensor(NUM_LINKS_TEMP + NUM_LINKS_KEY,LINKADDRESSSTART_TEMP),
// new HBWLinkInfoEventActuator(NUM_LINKS_DELTATX,LINKADDRESSSTART_DELTATX)
);

device->setConfigPins(BUTTON, LED); // 8 (button) and 13 (led) is the default
Expand Down
24 changes: 12 additions & 12 deletions HBW-CC-DT3-T6/HBWDeltaT.cpp
Expand Up @@ -17,10 +17,11 @@ HBWDeltaT::HBWDeltaT(uint8_t _pin, HBWDeltaTx* _delta_t1, HBWDeltaTx* _delta_t2,
deltaT2(_delta_t2)
{
deltaT = 0xFF;
outputChangeLastTime = DELTA_CALCULATION_WAIT_TIME;
outputChangeLastTime = 0;
deltaCalcLastTime = MIN_CHANGE_WAIT_TIME; // wait some time to get input values
clearFeedback();
stateFlags.byte = 0;
keyPressNum = 1;
initDone = false;
};

Expand All @@ -39,11 +40,11 @@ void HBWDeltaT::afterReadConfig()
if (initDone == false)
{
// All off on init, but consider inverted setting
initDone = true;
digitalWrite(pin, config->n_inverted ? LOW : HIGH); // 0=inverted, 1=not inverted
pinMode(pin,OUTPUT);
currentState = OFF;
nextState = currentState; //(if key support for HBWDeltaT; TODO: reset peered actors???)
initDone = true;
}
else {
// Do not reset outputs on config change (EEPROM re-reads), but update its state
Expand Down Expand Up @@ -129,7 +130,7 @@ void HBWDeltaT::loop(HBWDevice* device, uint8_t channel)
#ifdef DEBUG_OUTPUT
hbwdebug(F(" ch: ")); hbwdebug(channel);
hbwdebug(F(" deltaT: ")); hbwdebug(deltaT);
hbwdebug("\n");
hbwdebug(F("\n"));
#endif
}

Expand All @@ -153,15 +154,14 @@ bool HBWDeltaT::setOutput(HBWDevice* device, uint8_t channel)
if (currentState == nextState) return false; // no change - quit

digitalWrite(pin, (!nextState ^ config->n_inverted)); // set local output
// TODO: check if peering is needed/useful. Currently not reliable...
//if (device->busIsIdle()) {
// don't continue if bus is not idle. sendKeyEvent would probably fail
//keyPressNum++;
//device->sendKeyEvent(channel, keyPressNum, currentState); // peering (ignore inversion... can be done in peering)
//return false?;
//}

// allow peering with external switches
if (device->sendKeyEvent(channel, keyPressNum, !nextState) != HBWDevice::BUS_BUSY) {
keyPressNum++;
currentState = nextState; // TODO: check if this ok, as it will result into retries, as long as the bus is busy (retry interval: MIN_CHANGE_WAIT_TIME)
}

currentState = nextState;
// currentState = nextState;
stateFlags.element.status = currentState;

// set trigger to send info/notify message in loop()
Expand All @@ -184,7 +184,7 @@ bool HBWDeltaT::calculateNewState()
// check if valid temp is available
// T1
int16_t t1 = deltaT1->currentTemperature;
if (t1 <= ERROR_TEMP || t1 > config->maxT1) {
if (t1 <= ERROR_TEMP || t1 >= config->maxT1) {
nextState = OFF;
return false;
}
Expand Down
11 changes: 11 additions & 0 deletions HBW-CC-DT3-T6/HBWLinkKeyInfoEventSensor.cpp
@@ -0,0 +1,11 @@
/*
** HBWLinkKeyInfoEventSensor
**
** Einfache direkte Verknuepfung (Peering), vom Sensor ausgehend
** Ein Link-Objekt steht immer fuer alle (direkt aufeinander folgenden) Verknuepfungen
** des entsprechenden Typs.
**
*/


#include "HBWLinkKeyInfoEventSensor.h"
29 changes: 29 additions & 0 deletions HBW-CC-DT3-T6/HBWLinkKeyInfoEventSensor.h
@@ -0,0 +1,29 @@
/*
** HBWLinkKeyInfoEventSensor
**
** Einfache direkte Verknuepfung (Peering), vom Sensor ausgehend
** Ein Link-Objekt steht immer fuer alle (direkt aufeinander folgenden) Verknuepfungen
** des entsprechenden Typs.
**
*/

// TODO: remove these files and add option to the lib, allowing to combine different LinkSender

#ifndef HBWLinkKeyInfoEventSensor_h
#define HBWLinkKeyInfoEventSensor_h

#include "HBWired.h"


template<uint8_t numLinks, uint16_t eepromStart>
class HBWLinkKeyInfoEventSensor : public HBWLinkSender {
public:
HBWLinkKeyInfoEventSensor();
void sendInfoEvent(HBWDevice* device, uint8_t srcChan, uint8_t length, uint8_t const * const data);
void sendKeyEvent(HBWDevice* device, uint8_t srcChan, uint8_t keyPressNum, boolean longPress);
private:
static const uint8_t EEPROM_SIZE = 6; // "address_step" in XML
};

#include "HBWLinkKeyInfoEventSensor.hpp"
#endif
76 changes: 76 additions & 0 deletions HBW-CC-DT3-T6/HBWLinkKeyInfoEventSensor.hpp
@@ -0,0 +1,76 @@
/*
** HBWLinkKeyInfoEventSensor
**
** Einfache direkte Verknuepfung (Peering), vom Sensor ausgehend
** Ein Link-Objekt steht immer fuer alle (direkt aufeinander folgenden) Verknuepfungen
** des entsprechenden Typs.
**
*/


#ifdef Support_HBWLink_InfoEvent
template<uint8_t numLinks, uint16_t eepromStart>
HBWLinkKeyInfoEventSensor<numLinks, eepromStart>::HBWLinkKeyInfoEventSensor() {
}


// TODO: Der Beginn aller Verknuepfungen ist gleich. Eigentlich koennte man
// das meiste in einer gemeinsamen Basisklasse abhandeln
template<uint8_t numLinks, uint16_t eepromStart>
void HBWLinkKeyInfoEventSensor<numLinks, eepromStart>::sendInfoEvent(HBWDevice* device, uint8_t srcChan,
uint8_t length, uint8_t const * const data) {
uint8_t channelEEPROM;
uint32_t addrEEPROM;
// care for peerings
for(int i = 0; i < numLinks; i++) {
// get channel number
device->readEEPROM(&channelEEPROM, eepromStart + EEPROM_SIZE * i, 1);
// valid peering?
// TODO: Really like that? This always goes through all possible peerings
if(channelEEPROM == 0xFF) continue;
// channel is key?
if(channelEEPROM != srcChan) continue;
// get address and channel of actuator
device->readEEPROM(&addrEEPROM, eepromStart + EEPROM_SIZE * i + 1, 4, true);
device->readEEPROM(&channelEEPROM, eepromStart + EEPROM_SIZE * i +5, 1);
// own address? -> internal peering
if(addrEEPROM == device->getOwnAddress()) {
device->receiveInfoEvent(addrEEPROM, srcChan, channelEEPROM, length, data);
}else{
// external peering
// TODO: If bus busy, then try to repeat. ...aber zuerst feststellen, wie das die Original-Module machen (bzw. hier einfach so lassen)
/* byte result = */
device->sendInfoEvent(srcChan, length, data, addrEEPROM, channelEEPROM, !NEED_IDLE_BUS, 1); // free/idle bus was checked before calling sendInfoEvent. Send peer message only once
};
};
}

template<uint8_t numLinks, uint16_t eepromStart>
void HBWLinkKeyInfoEventSensor<numLinks, eepromStart>::sendKeyEvent(HBWDevice* device, uint8_t srcChan,
uint8_t keyPressNum, boolean longPress) {
uint8_t channelEEPROM;
uint32_t addrEEPROM;
// care for peerings
for(int i = 0; i < numLinks; i++) {
// get channel number
device->readEEPROM(&channelEEPROM, eepromStart + EEPROM_SIZE * i, 1);
// valid peering?
// TODO: Really like that? This always goes through all possible peerings
if(channelEEPROM == 0xFF) continue;
// channel is key?
if(channelEEPROM != srcChan) continue;
// get address and channel of actuator
device->readEEPROM(&addrEEPROM, eepromStart + EEPROM_SIZE * i + 1, 4, true);
device->readEEPROM(&channelEEPROM, eepromStart + EEPROM_SIZE * i +5, 1);
// own address? -> internal peering
if(addrEEPROM == device->getOwnAddress()) {
device->receiveKeyEvent(addrEEPROM, srcChan, channelEEPROM, keyPressNum, longPress);
}else{
// external peering
// TODO: If bus busy, then try to repeat. ...aber zuerst feststellen, wie das die Original-Module machen (bzw. hier einfach so lassen)
/* byte result = */
device->sendKeyEvent(srcChan, keyPressNum, longPress, addrEEPROM, channelEEPROM, !NEED_IDLE_BUS, 1); // free/idle bus was checked before calling sendKeyEvent - by broadcast message. Send peer message only once
};
};
}
#endif

0 comments on commit 2e6b011

Please sign in to comment.