Skip to content

Commit

Permalink
Merge pull request #13 from loetmeister/master
Browse files Browse the repository at this point in the history
New devices and HBWLink_InfoEvent feature
  • Loading branch information
ThorstenPferdekaemper committed May 20, 2019
2 parents f8d9394 + 2799f71 commit 02b5653
Show file tree
Hide file tree
Showing 36 changed files with 3,815 additions and 2,028 deletions.
186 changes: 186 additions & 0 deletions HBW-1W-T10/HBW-1W-T10.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
//*******************************************************************
//
// HBW-1W-T10
//
// Homematic Wired Hombrew Hardware
// Arduino NANO als Homematic-Device
//
// nach einer Vorlage von
// Thorsten Pferdekaemper (thorsten@pferdekaemper.com), Dirk Hoffmann (hoffmann@vmd-jena.de)
//
// http://loetmeister.de/Elektronik/homematic/index.htm#modules
//
//*******************************************************************
// Changes
// v0.01
// - initial version
// v0.02
// - improved startup and error handling (disconnected sensors)
// v0.03
// - validate supported devices (see HBWOneWireTempSensors.h)
// - optimized conversion and measurement sequence to avoid wrong readings


#define HARDWARE_VERSION 0x01
#define FIRMWARE_VERSION 0x0003

#define NUMBER_OF_TEMP_CHAN 10 // input channels - 1-wire temperature sensors
#define ADDRESS_START_CONF_TEMP_CHAN 0x7 // first EEPROM address for temperature sensors configuration
//#define NUM_LINKS_TEMP 30 // requires Support_HBWLink_InfoEvent in HBWired.h
#define LINKADDRESSSTART_TEMP 0xE6 // step 6


#define HMW_DEVICETYPE 0x81 //device ID (make sure to import hbw_1w_t10_v1.xml into FHEM)

//#define USE_HARDWARE_SERIAL // use hardware serial (USART) - this disables debug output


// HB Wired protocol and module
#include <HBWired.h>
#include <HBWOneWireTempSensors.h>
#include <HBWLinkInfoEventSensor.h>


// Pins
#ifdef USE_HARDWARE_SERIAL
#define RS485_TXEN 2 // Transmit-Enable
#define BUTTON A6 // Button fuer Factory-Reset etc.
#define ADC_BUS_VOLTAGE A7 // analog input to measure bus voltage

#define ONEWIRE_PIN 10 // Onewire Bus

#else
#define RS485_RXD 4
#define RS485_TXD 2
#define RS485_TXEN 3 // Transmit-Enable
#define BUTTON 8 // Button fuer Factory-Reset etc.
#define ADC_BUS_VOLTAGE A7 // analog input to measure bus voltage

#define ONEWIRE_PIN 10 // Onewire Bus

#include "FreeRam.h"
#include "HBWSoftwareSerial.h"
// HBWSoftwareSerial can only do 19200 baud
HBWSoftwareSerial rs485(RS485_RXD, RS485_TXD); // RX, TX
#endif //USE_HARDWARE_SERIAL

#define LED LED_BUILTIN // Signal-LED

#define NUMBER_OF_CHAN NUMBER_OF_TEMP_CHAN


struct hbw_config {
uint8_t logging_time; // 0x01
uint32_t central_address; // 0x02 - 0x05
uint8_t direct_link_deactivate:1; // 0x06:0
uint8_t :7; // 0x06:1-7
hbw_config_onewire_temp TempOWCfg[NUMBER_OF_TEMP_CHAN]; // 0x07 - 0x.. (address step 14)
} hbwconfig;


HBWChannel* channels[NUMBER_OF_CHAN]; // total number of channels for the device

// global pointer for OneWire channels
hbw_config_onewire_temp* tempConfig[NUMBER_OF_TEMP_CHAN]; // pointer for config


class HBTempOWDevice : public HBWDevice {
public:
HBTempOWDevice(uint8_t _devicetype, uint8_t _hardware_version, uint16_t _firmware_version,
Stream* _rs485, uint8_t _txen,
uint8_t _configSize, void* _config,
uint8_t _numChannels, HBWChannel** _channels,
Stream* _debugstream, HBWLinkSender* linksender = NULL, HBWLinkReceiver* linkreceiver = NULL,
OneWire* oneWire = NULL, hbw_config_onewire_temp** _tempSensorconfig = NULL) :
HBWDevice(_devicetype, _hardware_version, _firmware_version,
_rs485, _txen, _configSize, _config, _numChannels, ((HBWChannel**)(_channels)),
_debugstream, linksender, linkreceiver)
{
d_ow = oneWire;
tempSensorconfig = _tempSensorconfig;
};
virtual void afterReadConfig();

private:
OneWire* d_ow;
hbw_config_onewire_temp** tempSensorconfig;
};

// device specific defaults
void HBTempOWDevice::afterReadConfig()
{
HBWOneWireTemp::sensorSearch(d_ow, tempSensorconfig, (uint8_t) NUMBER_OF_TEMP_CHAN, (uint8_t) ADDRESS_START_CONF_TEMP_CHAN);
};

HBTempOWDevice* device = NULL;



void setup()
{
// variables for all OneWire channels
OneWire* g_ow = NULL;
uint32_t g_owLastReadTime = 0;
uint8_t g_owCurrentChannel = 255; // always init with 255! used as trigger/reset in channel loop()
g_ow = new OneWire(ONEWIRE_PIN);

// create channels
for(uint8_t i = 0; i < NUMBER_OF_TEMP_CHAN; i++) {
channels[i] = new HBWOneWireTemp(g_ow, &(hbwconfig.TempOWCfg[i]), &g_owLastReadTime, &g_owCurrentChannel);
tempConfig[i] = &(hbwconfig.TempOWCfg[i]);
}


#ifdef USE_HARDWARE_SERIAL // RS485 via UART Serial, no debug (_debugstream is NULL)
Serial.begin(19200, SERIAL_8E1);

device = new HBTempOWDevice(HMW_DEVICETYPE, HARDWARE_VERSION, FIRMWARE_VERSION,
&Serial, RS485_TXEN, sizeof(hbwconfig), &hbwconfig,
NUMBER_OF_CHAN, (HBWChannel**)channels,
NULL,
#if defined(NUM_LINKS_TEMP)
new HBWLinkInfoEventSensor(NUM_LINKS_TEMP,LINKADDRESSSTART_TEMP), NULL,
#else
NULL, NULL,
#endif
g_ow, tempConfig);

device->setConfigPins(BUTTON, LED); // use analog input for 'BUTTON'
//device->setStatusLEDPins(LED, LED); // Tx, Rx LEDs

#else
Serial.begin(19200);
rs485.begin(); // RS485 via SoftwareSerial

device = new HBTempOWDevice(HMW_DEVICETYPE, HARDWARE_VERSION, FIRMWARE_VERSION,
&rs485, RS485_TXEN, sizeof(hbwconfig), &hbwconfig,
NUMBER_OF_CHAN, (HBWChannel**)channels,
&Serial,
#if defined(NUM_LINKS_TEMP)
new HBWLinkInfoEventSensor(NUM_LINKS_TEMP,LINKADDRESSSTART_TEMP), NULL,
#else
NULL, NULL,
#endif
g_ow, tempConfig);

device->setConfigPins(BUTTON, LED); // 8 (button) and 13 (led) is the default
// device->setStatusLEDPins(LED, LED); // Tx, Rx LEDs

hbwdebug(F("B: 2A "));
hbwdebug(freeRam());
hbwdebug(F("\n"));
#endif
}


void loop()
{
device->loop();
};


// check if HBWLinkInfoEvent support is enabled, when links are set
#if !defined(Support_HBWLink_InfoEvent) && defined(NUM_LINKS_TEMP)
#error enable/define Support_HBWLink_InfoEvent in HBWired.h
#endif

164 changes: 164 additions & 0 deletions HBW-1W-T10/hbw_1w_t10_v1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<device version="12" eep_size="1024">
<supported_types>
<type name="RS485 One Wire 10 Channel Temperature Module" id="HBW-1W-T10" priority="2">
<parameter index="0" size="1" const_value="0x81"/><!--HMW_DEVICETYPE-->
<parameter index="1" size="1" const_value="1"/><!--HARDWARE_VERSION-->
<parameter const_value="0x0002" size="2" cond_op="GE" index="2"/><!--min FIRMWARE_VERSION-->
</type>
</supported_types>

<paramset type="MASTER" id="HBW-1W-T10_dev_master">
<parameter id="CENTRAL_ADDRESS" hidden="true">
<logical type="integer"/>
<physical type="integer" size="4" interface="eeprom">
<address index="0x0002"/>
</physical>
</parameter>
<parameter id="DIRECT_LINK_DEACTIVATE" hidden="true">
<logical type="boolean" default="false"/>
<physical interface="eeprom" size="0.1" type="integer">
<address index="0x0006"/>
</physical>
</parameter>
<enforce id="CENTRAL_ADDRESS" value="1"/>
<enforce id="DIRECT_LINK_DEACTIVATE" value="true"/>
</paramset>

<frames>
<frame id="LEVEL_GET" direction="to_device" type="#S" channel_field="10"/>
<frame id="INFO_LEVEL" direction="from_device" event="true" type="#i" channel_field="10">
<parameter type="integer" signed="true" index="11.0" size="2.0" param="TEMPERATURE"/>
</frame>
</frames>

<channels>
<channel index="0" type="MAINTENANCE" ui_flags="internal" class="maintenance" count="1">
<paramset type="MASTER" id="maint_ch_master"/>
<paramset type="VALUES" id="maint_ch_values">
<parameter id="UNREACH" operations="read,event" ui_flags="service">
<logical type="boolean"/>
<physical type="integer" interface="internal" value_id="UNREACH"/>
</parameter>
<parameter id="STICKY_UNREACH" operations="read,write,event" ui_flags="service">
<logical type="boolean"/>
<physical type="integer" interface="internal" value_id="STICKY_UNREACH"/>
</parameter>
<parameter id="CONFIG_PENDING" operations="read,event" ui_flags="service">
<logical type="boolean"/>
<physical type="integer" interface="internal" value_id="CONFIG_PENDING"/>
</parameter>
</paramset>
</channel>
<channel index="1" count="10" physical_index_offset="-1" type="TEMPSENSOR">
<link_roles>
<source name="TEST"/>
</link_roles>
<paramset type="MASTER" id="hmw_input_ch_master" address_step="14" address_start="0x07">
<parameter id="SEND_DELTA_TEMP">
<logical type="float" unit="&#x2103;" default="0.5" min="0.1" max="25.0">
<special_value id="NOT_USED" value="0"/>
</logical>
<physical size="1.0" type="integer" interface="eeprom">
<address index="0.0"/>
</physical>
<conversion type="float_integer_scale" factor="10"/>
<conversion type="integer_integer_map">
<value_map to_device="false" from_device="true" parameter_value="5" device_value="0xff"/>
</conversion>
</parameter>
<parameter id="OFFSET">
<logical type="integer" min="-127" max="127" unit="&#x2103;"/>
<physical type="integer" size="1" interface="eeprom">
<address index="+1.0"/>
</physical>
<conversion type="integer_integer_scale" offset="127" factor="100"/>
<conversion type="integer_integer_map">
<value_map to_device="false" from_device="true" parameter_value="127" device_value="0xff"/>
</conversion>
</parameter>
<parameter id="SEND_MIN_INTERVAL">
<logical type="integer" unit="s" default="10" min="5" max="3600">
<special_value id="NOT_USED" value="0"/>
</logical>
<physical size="2.0" type="integer" interface="eeprom" endian="little">
<address index="+2.0"/>
</physical>
<conversion type="integer_integer_map">
<value_map to_device="false" from_device="true" parameter_value="10" device_value="0xffff"/>
</conversion>
</parameter>
<parameter id="SEND_MAX_INTERVAL">
<logical type="integer" unit="s" default="150" min="5" max="3600">
<special_value id="NOT_USED" value="0"/>
</logical>
<physical size="2.0" type="integer" interface="eeprom" endian="little">
<address index="+4.0"/>
</physical>
<conversion type="integer_integer_map">
<value_map to_device="false" from_device="true" parameter_value="150" device_value="0xffff"/>
</conversion>
</parameter>
<parameter id="ONEWIRE_TYPE">
<logical type="option">
<option id="NOT_USED" default="true"/>
<option id="DS18B20"/>
<option id="DS18S20"/>
<option id="DS1822"/>
<option id="REMOVE_DEVICE"/>
</logical>
<physical size="1.0" type="integer" interface="eeprom">
<address index="+6.0"/>
</physical>
<conversion type="option_integer">
<value_map to_device="true" from_device="true" parameter_value="0" device_value="0xFF"/>
<value_map to_device="true" from_device="true" parameter_value="1" device_value="0x28"/>
<value_map to_device="true" from_device="true" parameter_value="2" device_value="0x10"/>
<value_map to_device="true" from_device="true" parameter_value="3" device_value="0x22"/>
<value_map to_device="true" from_device="false" parameter_value="4" device_value="0xFF"/>
</conversion>
</parameter>
<!-- not working like this... <parameter id="ONEWIRE_ADDRESS">
<logical type="address"/>
<physical type="array">
<physical type="integer" size="4.0" interface="eeprom">
<address index="+6"/>
</physical>
<physical type="integer" size="4.0" interface="eeprom">
<address index="+10"/>
</physical>
</physical>
</parameter>-->
</paramset>
<paramset type="LINK" id="hmw_input_ch_link" peer_param="ACTUATOR" channel_param="CHANNEL" count="30" address_start="0xE6" address_step="6">
<parameter id="CHANNEL" operations="none" hidden="true">
<logical type="integer" min="0" max="255" default="255"/>
<physical type="integer" size="1.0" interface="eeprom">
<address index="+0"/>
</physical>
</parameter>
<parameter id="ACTUATOR" operations="none" hidden="true">
<logical type="address"/>
<physical type="array">
<physical type="integer" size="4.0" interface="eeprom">
<address index="+1"/>
</physical>
<physical type="integer" size="1.0" interface="eeprom">
<address index="+5"/>
</physical>
</physical>
</parameter>
</paramset>
<paramset type="VALUES" id="hmw_analog_input_values">
<parameter id="TEMPERATURE" operations="read,event">
<logical type="float" min="-273.15" max="327.67" unit="&#x2103;"/>
<physical type="integer" interface="command" value_id="TEMPERATURE">
<get request="LEVEL_GET" response="INFO_LEVEL"/>
<event frame="INFO_LEVEL"/>
</physical>
<conversion type="float_integer_scale" factor="100"/>
</parameter>
</paramset>
</channel>
</channels>
</device>
34 changes: 34 additions & 0 deletions HBW-1W-T10/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Homematic Wired Homebrew 10 Channel OneWire Temperature Module
==============================================================

Am Modul HBW-1W-T10 k�nnen bis zu 10 OneWire Temperatursensoren angeschlossen werden.
Basis ist ein Arduino NANO mit RS485-Interface.

Unterst�tzte 1-Wire� Temperatursensoren:
DS18S20 Ger�tecode 0x10
DS18B20 Ger�tecode 0x28
DS1822 Ger�tecode 0x22


Damit FHEM das Homebrew-Device richtig erkennt, muss die hbw_1w_t10_v1.xml Datei in den Ordner FHEM/lib/HM485/Devices/xml kopiert werden (Das Device gibt sich als HW-Typ 0x81 aus).



Standard-Pinbelegung:
(Seriell �ber USART - #define USE_HARDWARE_SERIAL)
0 - Rx RS485
1 - Tx RS485
2 - RS485 Enable
13 - Status LED
A6 - Bedientaster (Reset)
10 - OneWire Bus (parasit�re Stromversorgung)



"Debug"-Pinbelegung:
4 - Rx RS485
2 - Tx RS485
3 - RS485 Enable
13 - Status LED
8 - Bedientaster (Reset)
10 - OneWire Bus (parasit�re Stromversorgung)
Loading

0 comments on commit 02b5653

Please sign in to comment.