Skip to content

Commit

Permalink
Start of ZiBlue RFPlayer implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gizmocuz committed Oct 10, 2016
1 parent 289b09a commit e625b8a
Show file tree
Hide file tree
Showing 14 changed files with 1,117 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ hardware/Winddelen.cpp
hardware/WOL.cpp
hardware/Wunderground.cpp
hardware/YouLess.cpp
hardware/ZiBlueBase.cpp
hardware/ZiBlueSerial.cpp
hardware/ZiBlueTCP.cpp
hardware/ZWaveBase.cpp
notifications/NotificationBase.cpp
notifications/NotificationEmail.cpp
Expand Down
309 changes: 309 additions & 0 deletions hardware/ZiBlueBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@

#include "stdafx.h"
#include "ZiBlueBase.h"
#include "../main/Logger.h"
#include "../main/Helper.h"
#include "../main/RFXtrx.h"
#include "hardwaretypes.h"
#include "../main/localtime_r.h"

#include "../main/mainworker.h"
#include "../main/WebServer.h"
#include "../webserver/cWebem.h"
#include "../json/json.h"

#include "ziblue_usb_frame_api.h"

#ifdef _DEBUG
#define ENABLE_LOGGING
#endif

struct _tZiBlueStringIntHelper
{
std::string szType;
int gType;
};

const _tZiBlueStringIntHelper ziblue_switches[] =
{
{ "X10", sSwitchTypeX10 },
//{ "Kaku", sSwitchTypeARC },
{ "Blyss", sSwitchTypeBlyss },
{ "RTS", sSwitchTypeRTS },
{ "", -1 }
};

const _tZiBlueStringIntHelper rfswitchcommands[] =
{
{ "ON", gswitch_sOn },
{ "OFF", gswitch_sOff },
{ "DIM", gswitch_sDim },
{ "", -1 }
};

const _tZiBlueStringIntHelper rfblindcommands[] =
{
{ "UP", blinds_sOpen },
{ "DOWN", blinds_sClose },
{ "STOP", blinds_sStop },
{ "CONFIRM", blinds_sConfirm },
{ "LIMIT", blinds_sLimit },
{ "", -1 }
};



int GetGeneralZiBlueFromString(const _tZiBlueStringIntHelper *pTable, const std::string &szType)
{
int ii = 0;
while (pTable[ii].gType!=-1)
{
if (pTable[ii].szType == szType)
return pTable[ii].gType;
ii++;
}
return -1;
}

std::string GetGeneralZiBlueFromInt(const _tZiBlueStringIntHelper *pTable, const int gType)
{
int ii = 0;
while (pTable[ii].gType!=-1)
{
if (pTable[ii].gType == gType)
return pTable[ii].szType;
ii++;
}
return "";
}

CZiBlueBase::CZiBlueBase()
{
Init();
}

CZiBlueBase::~CZiBlueBase()
{
}

void CZiBlueBase::Init()
{
m_rfbufferpos = 0;
m_State = ZIBLUE_STATE_ZI_1;
memset(&m_rfbuffer, 0, sizeof(m_rfbuffer));
}

void CZiBlueBase::OnConnected()
{
Init();
}

void CZiBlueBase::OnDisconnected()
{
Init();
}


#define round(a) ( int ) ( a + .5 )

bool CZiBlueBase::WriteToHardware(const char *pdata, const unsigned char length)
{
return false;
}

bool CZiBlueBase::SendSwitchInt(const int ID, const int switchunit, const int BatteryLevel, const std::string &switchType, const std::string &switchcmd, const int level)
{
int intswitchtype = GetGeneralZiBlueFromString(ziblue_switches, switchType);
if (intswitchtype == -1)
{
_log.Log(LOG_ERROR, "ZiBlue: Unhandled switch type: %s", switchType.c_str());
return false;
}

int cmnd = GetGeneralZiBlueFromString(rfswitchcommands, switchcmd);

int svalue=level;
if (cmnd==-1) {
if (switchcmd.compare(0, 10, "SET_LEVEL=") == 0 ){
cmnd=gswitch_sSetLevel;
std::string str2 = switchcmd.substr(10);
svalue=atoi(str2.c_str());
_log.Log(LOG_STATUS, "ZiBlue: %d level: %d", cmnd, svalue);
}
}

if (cmnd==-1)
{
_log.Log(LOG_ERROR, "ZiBlue: Unhandled switch command: %s", switchcmd.c_str());
return false;
}

_tGeneralSwitch gswitch;
gswitch.subtype = intswitchtype;
gswitch.id = ID;
gswitch.unitcode = switchunit;
gswitch.cmnd = cmnd;
gswitch.level = svalue; //level;
gswitch.battery_level = BatteryLevel;
gswitch.rssi = 12;
gswitch.seqnbr = 0;
sDecodeRXMessage(this, (const unsigned char *)&gswitch, NULL, BatteryLevel);
return true;
}

void CZiBlueBase::ParseData(const char *data, size_t len)
{
size_t ii = 0;
while (ii < len)
{
switch (m_State)
{
case ZIBLUE_STATE_ZI_1:
if (data[ii] == SYNC1_CONTAINER_CONSTANT)
m_State = ZIBLUE_STATE_ZI_2;
break;
case ZIBLUE_STATE_ZI_2:
if (data[ii] != SYNC2_CONTAINER_CONSTANT)
m_State = ZIBLUE_STATE_ZI_1;
else
m_State = ZIBLUE_STATE_SDQ;
break;
case ZIBLUE_STATE_SDQ:
m_SDQ = data[ii];
m_State = ZIBLUE_STATE_QL_1;
break;
case ZIBLUE_STATE_QL_1:
m_QL_1 = data[ii];
m_State = ZIBLUE_STATE_QL_2;
break;
case ZIBLUE_STATE_QL_2:
m_QL_2 = data[ii];
m_Length = (m_QL_2 << 8) + m_QL_1;
if (m_Length >= 1000)
{
m_State = ZIBLUE_STATE_ZI_1;
}
else
{
m_rfbufferpos = 0;
m_State = ZIBLUE_STATE_DATA;
}
break;
case ZIBLUE_STATE_DATA:
m_rfbuffer[m_rfbufferpos++] = data[ii];
if (m_rfbufferpos == m_Length)
{
ParseBinary(m_SDQ, (const uint8_t*)&m_rfbuffer, m_Length);
m_State = ZIBLUE_STATE_ZI_1;
}
else if (m_rfbufferpos >= m_Length)
{
m_State = ZIBLUE_STATE_ZI_1;
}
break;
}
ii++;
continue;
}
}

bool CZiBlueBase::ParseBinary(const uint8_t SDQ, const uint8_t *data, size_t len)
{
m_LastReceivedTime = mytime(NULL);

uint8_t reserved = (SDQ & 0x80) >> 7;
uint8_t vtype = (SDQ & 0x70) >> 4; //0x0 = binary, 0x4 = ascii
if (vtype != 0)
return false;

uint8_t SourceDest = SDQ & 0x0F;

if (SourceDest > 1)
return false; //not supported

//0 = MUX Management
//1 = 433 / 868

int dlen = len - 8;

REGULAR_INCOMING_RF_TO_BINARY_USB_FRAME_HEADER *pIncomming = (REGULAR_INCOMING_RF_TO_BINARY_USB_FRAME_HEADER*)data;

_log.Log(LOG_NORM, "ZiBlue: Received Info Type: %d, %s", pIncomming->infoType, (pIncomming->dataFlag == 0) ? "433" : "868");
switch (pIncomming->infoType)
{
case INFOS_TYPE0:
// used by X10 / Domia Lite protocols
break;
case INFOS_TYPE1:
// Used by X10 (32 bits ID) and CHACON
break;
case INFOS_TYPE2:
// Used by VISONIC /Focus/Atlantic/Meian Tech
if (dlen == sizeof(INCOMING_RF_INFOS_TYPE2))
{
INCOMING_RF_INFOS_TYPE2 *pSen = (INCOMING_RF_INFOS_TYPE2*)(data + 8);
int DevID = (pSen->idMsb << 16) + pSen->idLsb;
if (pSen->subtype == 0)
{
//detector/sensor( PowerCode device)
uint8_t Tamper_Flag = (pSen->qualifier & 0x01) != 0;
uint8_t Alarm_Flag = (pSen->qualifier & 0x02) != 0;
uint8_t LowBat_Flag = (pSen->qualifier & 0x04) != 0;
uint8_t Supervisor_Frame_Flag = (pSen->qualifier & 0x08) != 0;
if (Supervisor_Frame_Flag != 0)
return false;
}
else
{
//remote control (CodeSecure device)
uint8_t Key_Id = pSen->qualifier;//values : 0x08, 0x10, 0x20, 0x40. (Nota : D0:7 of the id always set to 0)
}
}
break;
case INFOS_TYPE3:
// Used by RFY PROTOCOL
break;
case INFOS_TYPE4:
// Used by Scientific Oregon protocol ( thermo/hygro sensors)
if (dlen == sizeof(INCOMING_RF_INFOS_TYPE4))
{
INCOMING_RF_INFOS_TYPE4 *pSen = (INCOMING_RF_INFOS_TYPE4*)(data + 8);
if (pSen->hygro>0)
SendTempHumSensor(pSen->idPHY, (pSen->qualifier & 0x01) ? 0 : 100, float(pSen->temp) / 10.0f, pSen->hygro, "Temp+Hum");
else
SendTempSensor(pSen->idPHY, (pSen->qualifier & 0x01) ? 0 : 100, float(pSen->temp) / 10.0f, "Temp+Hum");
}
break;
case INFOS_TYPE5:
// Used by Scientific Oregon protocol ( Atmospheric pressure sensors)
if (dlen == sizeof(INCOMING_RF_INFOS_TYPE5))
{
INCOMING_RF_INFOS_TYPE5 *pSen = (INCOMING_RF_INFOS_TYPE5*)(data + 8);
SendTempHumBaroSensor(pSen->idPHY, (pSen->qualifier & 0x01) ? 0 : 100, float(pSen->temp) / 10.0f, pSen->hygro, pSen->pressure, 0, "Temp+Hum+Baro");
}
break;
case INFOS_TYPE6:
// Used by Scientific Oregon protocol (Wind sensors)
break;
case INFOS_TYPE7:
// Used by Scientific Oregon protocol ( UV sensors)
break;
case INFOS_TYPE8:
// Used by OWL ( Energy/power sensors)
break;
case INFOS_TYPE9:
// Used by OREGON ( Rain sensors)
break;
case INFOS_TYPE10:
// Used by Thermostats X2D protocol
break;
case INFOS_TYPE11:
// Used by Alarm/remote control devices X2D protocol
break;
case INFOS_TYPE12:
// deprecated // Used by DIGIMAX TS10 protocol
break;
}

return true;
}
48 changes: 48 additions & 0 deletions hardware/ZiBlueBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include <vector>
#include "ASyncSerial.h"
#include "DomoticzHardware.h"

#define ZiBlue_READ_BUFFER_SIZE 5*1024

class CZiBlueBase: public CDomoticzHardwareBase
{
friend class CZiBlueSerial;
friend class CZiBlueTCP;
enum _eZiBlueState
{
ZIBLUE_STATE_ZI_1=0,
ZIBLUE_STATE_ZI_2,
ZIBLUE_STATE_SDQ,
ZIBLUE_STATE_QL_1,
ZIBLUE_STATE_QL_2,
ZIBLUE_STATE_DATA
};
public:
CZiBlueBase();
~CZiBlueBase();
bool WriteToHardware(const char *pdata, const unsigned char length);
virtual bool WriteInt(const std::string &sendString) = 0;
bool m_bTXokay;
std::string m_Version;
private:
void Init();
void OnConnected();
void OnDisconnected();
void ParseData(const char *data, size_t len);
bool ParseBinary(const uint8_t SDQ, const uint8_t *data, size_t len);
bool SendSwitchInt(const int ID, const int switchunit, const int BatteryLevel, const std::string &switchType, const std::string &switchcmd, const int level);
unsigned char m_rfbuffer[ZiBlue_READ_BUFFER_SIZE];
int m_rfbufferpos;
int m_retrycntr;
time_t m_LastReceivedTime;

//
_eZiBlueState m_State;
uint8_t m_SDQ;
uint8_t m_QL_1;
uint8_t m_QL_2;
uint16_t m_Length;
};

Loading

0 comments on commit e625b8a

Please sign in to comment.