commit 12f2c3eeee08ccb5e1cf941ec0db74fdad41745d Author: Ziver Koc Date: Thu Mar 26 21:22:26 2015 +0000 Initial commit diff --git a/Hal.iml b/Hal.iml new file mode 100644 index 00000000..ccc314b8 --- /dev/null +++ b/Hal.iml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/tellstick-core/Protocol.cpp b/external/tellstick-core/Protocol.cpp new file mode 100644 index 00000000..2a8f00e6 --- /dev/null +++ b/external/tellstick-core/Protocol.cpp @@ -0,0 +1,267 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/Protocol.h" +#include +#include +#include + +#include "client/telldus-core.h" +#include "service/ControllerMessage.h" +#include "service/ProtocolBrateck.h" +#include "service/ProtocolComen.h" +#include "service/ProtocolEverflourish.h" +#include "service/ProtocolFineoffset.h" +#include "service/ProtocolFuhaote.h" +#include "service/ProtocolGroup.h" +#include "service/ProtocolHasta.h" +#include "service/ProtocolIkea.h" +#include "service/ProtocolMandolyn.h" +#include "service/ProtocolNexa.h" +#include "service/ProtocolOregon.h" +#include "service/ProtocolRisingSun.h" +#include "service/ProtocolSartano.h" +#include "service/ProtocolScene.h" +#include "service/ProtocolSilvanChip.h" +#include "service/ProtocolUpm.h" +#include "service/ProtocolWaveman.h" +#include "service/ProtocolX10.h" +#include "service/ProtocolYidong.h" +#include "common/Strings.h" + +class Protocol::PrivateData { +public: + ParameterMap parameterList; + std::wstring model; +}; + +Protocol::Protocol() { + d = new PrivateData; +} + +Protocol::~Protocol(void) { + delete d; +} + +std::wstring Protocol::model() const { + std::wstring strModel = d->model; + // Strip anything after : if it is found + size_t pos = strModel.find(L":"); + if (pos != std::wstring::npos) { + strModel = strModel.substr(0, pos); + } + + return strModel; +} + +void Protocol::setModel(const std::wstring &model) { + d->model = model; +} + +void Protocol::setParameters(const ParameterMap ¶meterList) { + d->parameterList = parameterList; +} + +std::wstring Protocol::getStringParameter(const std::wstring &name, const std::wstring &defaultValue) const { + ParameterMap::const_iterator it = d->parameterList.find(name); + if (it == d->parameterList.end()) { + return defaultValue; + } + return it->second; +} + +int Protocol::getIntParameter(const std::wstring &name, int min, int max) const { + std::wstring value = getStringParameter(name, L""); + if (value == L"") { + return min; + } + std::wstringstream st; + st << value; + int intValue = 0; + st >> intValue; + if (intValue < min) { + return min; + } + if (intValue > max) { + return max; + } + return intValue; +} + +bool Protocol::checkBit(int data, int bitno) { + return ((data >> bitno)&0x01); +} + + +Protocol *Protocol::getProtocolInstance(const std::wstring &protocolname) { + if(TelldusCore::comparei(protocolname, L"arctech")) { + return new ProtocolNexa(); + + } else if (TelldusCore::comparei(protocolname, L"brateck")) { + return new ProtocolBrateck(); + + } else if (TelldusCore::comparei(protocolname, L"comen")) { + return new ProtocolComen(); + + } else if (TelldusCore::comparei(protocolname, L"everflourish")) { + return new ProtocolEverflourish(); + + } else if (TelldusCore::comparei(protocolname, L"fuhaote")) { + return new ProtocolFuhaote(); + + } else if (TelldusCore::comparei(protocolname, L"hasta")) { + return new ProtocolHasta(); + + } else if (TelldusCore::comparei(protocolname, L"ikea")) { + return new ProtocolIkea(); + + } else if (TelldusCore::comparei(protocolname, L"risingsun")) { + return new ProtocolRisingSun(); + + } else if (TelldusCore::comparei(protocolname, L"sartano")) { + return new ProtocolSartano(); + + } else if (TelldusCore::comparei(protocolname, L"silvanchip")) { + return new ProtocolSilvanChip(); + + } else if (TelldusCore::comparei(protocolname, L"upm")) { + return new ProtocolUpm(); + + } else if (TelldusCore::comparei(protocolname, L"waveman")) { + return new ProtocolWaveman(); + + } else if (TelldusCore::comparei(protocolname, L"x10")) { + return new ProtocolX10(); + + } else if (TelldusCore::comparei(protocolname, L"yidong")) { + return new ProtocolYidong(); + + } else if (TelldusCore::comparei(protocolname, L"group")) { + return new ProtocolGroup(); + + } else if (TelldusCore::comparei(protocolname, L"scene")) { + return new ProtocolScene(); + } + + return 0; +} + +std::list Protocol::getParametersForProtocol(const std::wstring &protocolName) { + std::list parameters; + if(TelldusCore::comparei(protocolName, L"arctech")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"brateck")) { + parameters.push_back("house"); + + } else if (TelldusCore::comparei(protocolName, L"comen")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"everflourish")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"fuhaote")) { + parameters.push_back("code"); + + } else if (TelldusCore::comparei(protocolName, L"hasta")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"ikea")) { + parameters.push_back("system"); + parameters.push_back("units"); + // parameters.push_back("fade"); + + } else if (TelldusCore::comparei(protocolName, L"risingsun")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"sartano")) { + parameters.push_back("code"); + + } else if (TelldusCore::comparei(protocolName, L"silvanchip")) { + parameters.push_back("house"); + + } else if (TelldusCore::comparei(protocolName, L"upm")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"waveman")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"x10")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"yidong")) { + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"group")) { + parameters.push_back("devices"); + + } else if (TelldusCore::comparei(protocolName, L"scene")) { + parameters.push_back("devices"); + } + + return parameters; +} + +std::list Protocol::decodeData(const std::string &fullData) { + std::list retval; + std::string decoded = ""; + + ControllerMessage dataMsg(fullData); + if( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) { + decoded = ProtocolNexa::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + decoded = ProtocolWaveman::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + decoded = ProtocolSartano::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"everflourish") ) { + decoded = ProtocolEverflourish::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"fineoffset") ) { + decoded = ProtocolFineoffset::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"mandolyn") ) { + decoded = ProtocolMandolyn::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"oregon") ) { + decoded = ProtocolOregon::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"x10") ) { + decoded = ProtocolX10::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } else if(TelldusCore::comparei(dataMsg.protocol(), L"hasta") ) { + decoded = ProtocolHasta::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + + return retval; +} diff --git a/external/tellstick-core/Protocol.h b/external/tellstick-core/Protocol.h new file mode 100644 index 00000000..a4e7e6cd --- /dev/null +++ b/external/tellstick-core/Protocol.h @@ -0,0 +1,46 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOL_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOL_H_ + +#include +#include +#include +#include "client/telldus-core.h" + +typedef std::map ParameterMap; + +class Controller; + +class Protocol { +public: + Protocol(); + virtual ~Protocol(void); + + static Protocol *getProtocolInstance(const std::wstring &protocolname); + static std::list getParametersForProtocol(const std::wstring &protocolName); + static std::list decodeData(const std::string &fullData); + + virtual int methods() const = 0; + std::wstring model() const; + void setModel(const std::wstring &model); + void setParameters(const ParameterMap ¶meterList); + + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller) = 0; + +protected: + virtual std::wstring getStringParameter(const std::wstring &name, const std::wstring &defaultValue = L"") const; + virtual int getIntParameter(const std::wstring &name, int min, int max) const; + + static bool checkBit(int data, int bit); + +private: + class PrivateData; + PrivateData *d; +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOL_H_ diff --git a/external/tellstick-core/ProtocolBrateck.cpp b/external/tellstick-core/ProtocolBrateck.cpp new file mode 100644 index 00000000..ab03387c --- /dev/null +++ b/external/tellstick-core/ProtocolBrateck.cpp @@ -0,0 +1,53 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolBrateck.h" +#include + +int ProtocolBrateck::methods() const { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; +} + +std::string ProtocolBrateck::getStringForMethod(int method, unsigned char, Controller *) { + const char S = '!'; + const char L = 'V'; + const char B1[] = {L, S, L, S, 0}; + const char BX[] = {S, L, L, S, 0}; + const char B0[] = {S, L, S, L, 0}; + const char BUP[] = {L, S, L, S, S, L, S, L, S, L, S, L, S, L, S, L, S, 0}; + const char BSTOP[] = {S, L, S, L, L, S, L, S, S, L, S, L, S, L, S, L, S, 0}; + const char BDOWN[] = {S, L, S, L, S, L, S, L, S, L, S, L, L, S, L, S, S, 0}; + + std::string strReturn; + std::wstring strHouse = this->getStringParameter(L"house", L""); + if (strHouse == L"") { + return ""; + } + + for( size_t i = 0; i < strHouse.length(); ++i ) { + if (strHouse[i] == '1') { + strReturn.insert(0, B1); + } else if (strHouse[i] == '-') { + strReturn.insert(0, BX); + } else if (strHouse[i] == '0') { + strReturn.insert(0, B0); + } + } + + strReturn.insert(0, "S"); + if (method == TELLSTICK_UP) { + strReturn.append(BUP); + } else if (method == TELLSTICK_DOWN) { + strReturn.append(BDOWN); + } else if (method == TELLSTICK_STOP) { + strReturn.append(BSTOP); + } else { + return ""; + } + strReturn.append("+"); + + return strReturn; +} diff --git a/external/tellstick-core/ProtocolBrateck.h b/external/tellstick-core/ProtocolBrateck.h new file mode 100644 index 00000000..c533308a --- /dev/null +++ b/external/tellstick-core/ProtocolBrateck.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_ + +#include +#include "service/Protocol.h" + +class ProtocolBrateck : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_ diff --git a/external/tellstick-core/ProtocolComen.cpp b/external/tellstick-core/ProtocolComen.cpp new file mode 100644 index 00000000..dfc7d38d --- /dev/null +++ b/external/tellstick-core/ProtocolComen.cpp @@ -0,0 +1,23 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolComen.h" +#include + +int ProtocolComen::methods() const { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); +} + +int ProtocolComen::getIntParameter(const std::wstring &name, int min, int max) const { + if (name.compare(L"house") == 0) { + int intHouse = Protocol::getIntParameter(L"house", 1, 16777215); + // The last two bits must be hardcoded + intHouse <<= 2; + intHouse += 2; + return intHouse; + } + return Protocol::getIntParameter(name, min, max); +} diff --git a/external/tellstick-core/ProtocolComen.h b/external/tellstick-core/ProtocolComen.h new file mode 100644 index 00000000..f43167a8 --- /dev/null +++ b/external/tellstick-core/ProtocolComen.h @@ -0,0 +1,21 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_ + +#include +#include "service/ProtocolNexa.h" + +class ProtocolComen : public ProtocolNexa { +public: + virtual int methods() const; + +protected: + virtual int getIntParameter(const std::wstring &name, int min, int max) const; +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_ diff --git a/external/tellstick-core/ProtocolEverflourish.cpp b/external/tellstick-core/ProtocolEverflourish.cpp new file mode 100644 index 00000000..cc193931 --- /dev/null +++ b/external/tellstick-core/ProtocolEverflourish.cpp @@ -0,0 +1,133 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolEverflourish.h" +#include +#include +#include +#include "service/ControllerMessage.h" + +int ProtocolEverflourish::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; +} + +std::string ProtocolEverflourish::getStringForMethod(int method, unsigned char, Controller *) { + unsigned int deviceCode = this->getIntParameter(L"house", 0, 16383); + unsigned int intCode = this->getIntParameter(L"unit", 1, 4)-1; + unsigned char action; + + if (method == TELLSTICK_TURNON) { + action = 15; + } else if (method == TELLSTICK_TURNOFF) { + action = 0; + } else if (method == TELLSTICK_LEARN) { + action = 10; + } else { + return ""; + } + + const char ssss = 85; + const char sssl = 84; // 0 + const char slss = 69; // 1 + + const char bits[2] = {sssl, slss}; + int i, check; + + std::string strCode; + + deviceCode = (deviceCode << 2) | intCode; + + check = calculateChecksum(deviceCode); + + char preamble[] = {'R', 5, 'T', 114, 60, 1, 1, 105, ssss, ssss, 0}; + strCode.append(preamble); + + for(i = 15; i >= 0; i--) { + strCode.append(1, bits[(deviceCode >> i)&0x01]); + } + for(i = 3; i >= 0; i--) { + strCode.append(1, bits[(check >> i)&0x01]); + } + for(i = 3; i >= 0; i--) { + strCode.append(1, bits[(action >> i)&0x01]); + } + + strCode.append(1, ssss); + strCode.append(1, '+'); + + return strCode; +} + +// The calculation used in this function is provided by Frank Stevenson +unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) { + unsigned int bits[16] = { + 0xf, 0xa, 0x7, 0xe, + 0xf, 0xd, 0x9, 0x1, + 0x1, 0x2, 0x4, 0x8, + 0x3, 0x6, 0xc, 0xb + }; + unsigned int bit = 1; + unsigned int res = 0x5; + int i; + unsigned int lo, hi; + + if ((x & 0x3) == 3) { + lo = x & 0x00ff; + hi = x & 0xff00; + lo += 4; + if (lo>0x100) { + lo = 0x12; + } + x = lo | hi; + } + + for(i = 0; i < 16; i++) { + if (x & bit) { + res = res ^ bits[i]; + } + bit = bit << 1; + } + + return res; +} + +std::string ProtocolEverflourish::decodeData(const ControllerMessage &dataMsg) { + uint64_t allData; + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + allData = dataMsg.getInt64Parameter("data"); + + house = allData & 0xFFFC00; + house >>= 10; + + unit = allData & 0x300; + unit >>= 8; + unit++; // unit from 1 to 4 + + method = allData & 0xF; + + if(house > 16383 || unit < 1 || unit > 4) { + // not everflourish + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:"; + if(method == 0) { + retString << "turnoff;"; + } else if(method == 15) { + retString << "turnon;"; + } else if(method == 10) { + retString << "learn;"; + } else { + // not everflourish + return ""; + } + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolEverflourish.h b/external/tellstick-core/ProtocolEverflourish.h new file mode 100644 index 00000000..ae4abf7c --- /dev/null +++ b/external/tellstick-core/ProtocolEverflourish.h @@ -0,0 +1,24 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolEverflourish : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + static std::string decodeData(const ControllerMessage &dataMsg); + +private: + static unsigned int calculateChecksum(unsigned int x); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_ diff --git a/external/tellstick-core/ProtocolFineoffset.cpp b/external/tellstick-core/ProtocolFineoffset.cpp new file mode 100644 index 00000000..2fd6f5ae --- /dev/null +++ b/external/tellstick-core/ProtocolFineoffset.cpp @@ -0,0 +1,52 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolFineoffset.h" +#include +#include +#include +#include +#include "common/Strings.h" + +std::string ProtocolFineoffset::decodeData(const ControllerMessage &dataMsg) { + std::string data = dataMsg.getParameter("data"); + if (data.length() < 8) { + return ""; + } + + // Checksum currently not used + // uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); + data = data.substr(0, data.length()-2); + + uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); + data = data.substr(0, data.length()-2); + + uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3)); + double temperature = (value & 0x7FF)/10.0; + + value >>= 11; + if (value & 1) { + temperature = -temperature; + } + data = data.substr(0, data.length()-3); + + uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF; + + std::stringstream retString; + retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:"; + + if (humidity <= 100) { + retString << "temperaturehumidity;humidity:" << static_cast(humidity) << ";"; + } else if (humidity == 0xFF) { + retString << "temperature;"; + } else { + return ""; + } + + retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolFineoffset.h b/external/tellstick-core/ProtocolFineoffset.h new file mode 100644 index 00000000..b3bc3ce1 --- /dev/null +++ b/external/tellstick-core/ProtocolFineoffset.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolFineoffset : public Protocol { +public: + static std::string decodeData(const ControllerMessage &dataMsg); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_ diff --git a/external/tellstick-core/ProtocolFuhaote.cpp b/external/tellstick-core/ProtocolFuhaote.cpp new file mode 100644 index 00000000..7254520e --- /dev/null +++ b/external/tellstick-core/ProtocolFuhaote.cpp @@ -0,0 +1,60 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolFuhaote.h" +#include + +int ProtocolFuhaote::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolFuhaote::getStringForMethod(int method, unsigned char, Controller *) { + const char S = 19; + const char L = 58; + const char B0[] = {S, L, L, S, 0}; + const char B1[] = {L, S, L, S, 0}; + const char OFF[] = {S, L, S, L, S, L, L, S, 0}; + const char ON[] = {S, L, L, S, S, L, S, L, 0}; + + std::string strReturn = "S"; + std::wstring strCode = this->getStringParameter(L"code", L""); + if (strCode == L"") { + return ""; + } + + // House code + for(size_t i = 0; i < 5; ++i) { + if (strCode[i] == '0') { + strReturn.append(B0); + } else if (strCode[i] == '1') { + strReturn.append(B1); + } + } + // Unit code + for(size_t i = 5; i < 10; ++i) { + if (strCode[i] == '0') { + strReturn.append(B0); + } else if (strCode[i] == '1') { + strReturn.append(1, S); + strReturn.append(1, L); + strReturn.append(1, S); + strReturn.append(1, L); + } + } + + if (method == TELLSTICK_TURNON) { + strReturn.append(ON); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(OFF); + } else { + return ""; + } + + strReturn.append(1, S); + strReturn.append("+"); + return strReturn; +} + diff --git a/external/tellstick-core/ProtocolFuhaote.h b/external/tellstick-core/ProtocolFuhaote.h new file mode 100644 index 00000000..2618ef86 --- /dev/null +++ b/external/tellstick-core/ProtocolFuhaote.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_ + +#include +#include "service/Protocol.h" + +class ProtocolFuhaote : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_ diff --git a/external/tellstick-core/ProtocolGroup.cpp b/external/tellstick-core/ProtocolGroup.cpp new file mode 100644 index 00000000..4c4d0d15 --- /dev/null +++ b/external/tellstick-core/ProtocolGroup.cpp @@ -0,0 +1,16 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolGroup.h" +#include + +int ProtocolGroup::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_BELL | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_TOGGLE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; +} + +std::string ProtocolGroup::getStringForMethod(int method, unsigned char data, Controller *) { + return ""; +} diff --git a/external/tellstick-core/ProtocolGroup.h b/external/tellstick-core/ProtocolGroup.h new file mode 100644 index 00000000..509c2a3a --- /dev/null +++ b/external/tellstick-core/ProtocolGroup.h @@ -0,0 +1,22 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_ + +#include +#include "service/Protocol.h" + +class ProtocolGroup : public Protocol { +public: + virtual int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_ + + + diff --git a/external/tellstick-core/ProtocolHasta.cpp b/external/tellstick-core/ProtocolHasta.cpp new file mode 100644 index 00000000..786f068b --- /dev/null +++ b/external/tellstick-core/ProtocolHasta.cpp @@ -0,0 +1,201 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolHasta.h" +#include +#include +#include +#include "common/Strings.h" + +int ProtocolHasta::methods() const { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; +} + +std::string ProtocolHasta::getStringForMethod(int method, unsigned char, Controller *) { + if (TelldusCore::comparei(model(), L"selflearningv2")) { + return getStringForMethodv2(method); + } + return getStringForMethodv1(method); +} + +std::string ProtocolHasta::getStringForMethodv1(int method) { + int house = this->getIntParameter(L"house", 1, 65536); + int unit = this->getIntParameter(L"unit", 1, 15); + std::string strReturn; + + strReturn.append(1, 164); + strReturn.append(1, 1); + strReturn.append(1, 164); + strReturn.append(1, 1); + strReturn.append(1, 164); + strReturn.append(1, 164); + + strReturn.append(convertByte( (house & 0xFF) )); + strReturn.append(convertByte( (house>>8) & 0xFF )); + + int byte = unit&0x0F; + + if (method == TELLSTICK_UP) { + byte |= 0x00; + + } else if (method == TELLSTICK_DOWN) { + byte |= 0x10; + + } else if (method == TELLSTICK_STOP) { + byte |= 0x50; + + } else if (method == TELLSTICK_LEARN) { + byte |= 0x40; + + } else { + return ""; + } + strReturn.append(convertByte(byte)); + + strReturn.append(convertByte(0x0)); + strReturn.append(convertByte(0x0)); + + // Remove the last pulse + strReturn.erase(strReturn.end()-1, strReturn.end()); + + return strReturn; +} + +std::string ProtocolHasta::convertByte(unsigned char byte) { + std::string retval; + for(int i = 0; i < 8; ++i) { + if (byte & 1) { + retval.append(1, 33); + retval.append(1, 17); + } else { + retval.append(1, 17); + retval.append(1, 33); + } + byte >>= 1; + } + return retval; +} + +std::string ProtocolHasta::getStringForMethodv2(int method) { + int house = this->getIntParameter(L"house", 1, 65536); + int unit = this->getIntParameter(L"unit", 1, 15); + int sum = 0; + std::string strReturn; + strReturn.append(1, 245); + strReturn.append(1, 1); + strReturn.append(1, 245); + strReturn.append(1, 245); + strReturn.append(1, 63); + strReturn.append(1, 1); + strReturn.append(1, 63); + strReturn.append(1, 1); + strReturn.append(1, 35); + strReturn.append(1, 35); + + strReturn.append(convertBytev2( (house>>8) & 0xFF )); + sum = ((house>>8)&0xFF); + strReturn.append(convertBytev2( (house & 0xFF) )); + sum += (house & 0xFF); + + int byte = unit&0x0F; + + if (method == TELLSTICK_UP) { + byte |= 0xC0; + + } else if (method == TELLSTICK_DOWN) { + byte |= 0x10; + + } else if (method == TELLSTICK_STOP) { + byte |= 0x50; + + } else if (method == TELLSTICK_LEARN) { + byte |= 0x40; + + } else { + return ""; + } + strReturn.append(convertBytev2(byte)); + sum += byte; + + strReturn.append(convertBytev2(0x01)); + sum += 0x01; + + int checksum = ((static_cast(sum/256)+1)*256+1) - sum; + strReturn.append(convertBytev2(checksum)); + strReturn.append(1, 63); + strReturn.append(1, 35); + + return strReturn; +} + +std::string ProtocolHasta::convertBytev2(unsigned char byte) { + std::string retval; + for(int i = 0; i < 8; ++i) { + if (byte & 1) { + retval.append(1, 63); + retval.append(1, 35); + } else { + retval.append(1, 35); + retval.append(1, 63); + } + byte >>= 1; + } + return retval; +} + +std::string ProtocolHasta::decodeData(const ControllerMessage& dataMsg) { + uint64_t allData = dataMsg.getInt64Parameter("data"); + + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + std::string model; + std::string methodstring; + + allData >>= 8; + unit = allData & 0xF; + allData >>= 4; + method = allData & 0xF; + allData >>= 4; + if(TelldusCore::comparei(dataMsg.model(), L"selflearning")) { + // version1 + house = allData & 0xFFFF; + house = ((house << 8) | (house >> 8)) & 0xFFFF; + model = "selflearning"; + if(method == 0) { + methodstring = "up"; + } else if(method == 1) { + methodstring = "down"; + } else if(method == 5) { + methodstring = "stop"; + } else { + return ""; + } + } else { + // version2 + house = allData & 0xFFFF; + + model = "selflearningv2"; + if(method == 12) { + methodstring = "up"; + } else if(method == 1 || method == 8) { // is method 8 correct? + methodstring = "down"; + } else if(method == 5) { + methodstring = "stop"; + } else { + return ""; + } + } + + if(house < 1 || house > 65535 || unit < 1 || unit > 16) { + // not hasta + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:hasta;model:" << model << ";house:" << house << ";unit:" << unit << ";method:" << methodstring << ";"; + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolHasta.h b/external/tellstick-core/ProtocolHasta.h new file mode 100644 index 00000000..7a122bb2 --- /dev/null +++ b/external/tellstick-core/ProtocolHasta.h @@ -0,0 +1,27 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_ + +#include +#include "service/ControllerMessage.h" +#include "service/Protocol.h" + +class ProtocolHasta : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + static std::string decodeData(const ControllerMessage &dataMsg); + +protected: + static std::string convertByte(unsigned char byte); + static std::string convertBytev2(unsigned char byte); + std::string getStringForMethodv1(int method); + std::string getStringForMethodv2(int method); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_ diff --git a/external/tellstick-core/ProtocolIkea.cpp b/external/tellstick-core/ProtocolIkea.cpp new file mode 100644 index 00000000..6b96434a --- /dev/null +++ b/external/tellstick-core/ProtocolIkea.cpp @@ -0,0 +1,151 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolIkea.h" +#include +#include +#include +#include +#include "common/Strings.h" +#ifdef _WINDOWS +#define strtok_r(s, d, p) strtok_s(s, d, p) +#endif + +int ProtocolIkea::methods() const { + if (TelldusCore::comparei(model(), L"selflearning-switch")) { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; + } + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM; +} + +std::string ProtocolIkea::getStringForMethod(int method, unsigned char level, Controller *) { + const char B1[] = {84, 84, 0}; + const char B0[] = {170, 0}; + + int intSystem = this->getIntParameter(L"system", 1, 16)-1; + int intFadeStyle = TelldusCore::comparei(this->getStringParameter(L"fade", L"true"), L"true"); + std::wstring wstrUnits = this->getStringParameter(L"units", L""); + + if (method == TELLSTICK_TURNON) { + level = 255; + } else if (method == TELLSTICK_TURNOFF) { + level = 0; + } else if (method == TELLSTICK_DIM) { + } else { + return ""; + } + + if (wstrUnits == L"") { + return ""; + } + + std::string strUnits(TelldusCore::wideToString(wstrUnits)); + int intUnits = 0; // Start without any units + + char *tempUnits = new char[strUnits.size()+1]; +#ifdef _WINDOWS + strcpy_s(tempUnits, strUnits.size()+1, strUnits.c_str()); +#else + snprintf(tempUnits, strUnits.size()+1, "%s", strUnits.c_str()); +#endif + + char *saveptr; + char *strToken = strtok_r(tempUnits, ",", &saveptr); + do { + int intUnit = atoi(strToken); + if (intUnit == 10) { + intUnit = 0; + } + intUnits = intUnits | ( 1<<(9-intUnit) ); + } while ( (strToken = strtok_r(NULL, ",", &saveptr)) != NULL ); + + delete[] tempUnits; + + std::string strReturn; + strReturn.append(1, 'S'); + strReturn.append(1, 84); + strReturn.append(1, 84); + strReturn.append(1, 84); + strReturn.append(1, 84); + strReturn.append(1, 84); + strReturn.append(1, 84); + strReturn.append(1, 170); + + std::string strChannels = ""; + int intCode = (intSystem << 10) | intUnits; + int checksum1 = 0; + int checksum2 = 0; + for (int i = 13; i >= 0; --i) { + if ((intCode >> i) & 1) { + strChannels.append(B1); + if (i % 2 == 0) + checksum2++; + else + checksum1++; + } else { + strChannels.append(B0); + } + } + strReturn.append(strChannels); // System + Units + + strReturn.append(checksum1 %2 == 0 ? B1 : B0); // 1st checksum + strReturn.append(checksum2 %2 == 0 ? B1 : B0); // 2nd checksum + + int intLevel = 0; + if (level <= 12) { + intLevel = 10; // Level 10 is actually off + } else if (level <= 37) { + intLevel = 1; + } else if (level <= 62) { + intLevel = 2; + } else if (level <= 87) { + intLevel = 3; + } else if (level <= 112) { + intLevel = 4; + } else if (level <= 137) { + intLevel = 5; + } else if (level <= 162) { + intLevel = 6; + } else if (level <= 187) { + intLevel = 7; + } else if (level <= 212) { + intLevel = 8; + } else if (level <= 237) { + intLevel = 9; + } else { + intLevel = 0; // Level 0 is actually full on + } + + int intFade = 0; + if (intFadeStyle == 1) { + intFade = 11 << 4; // Smooth + } else { + intFade = 1 << 4; // Instant + } + + intCode = intLevel | intFade; // Concat level and fade + + checksum1 = 0; + checksum2 = 0; + for (int i = 0; i < 6; ++i) { + if ((intCode >> i) & 1) { + strReturn.append(B1); + if (i % 2 == 0) + checksum1++; + else + checksum2++; + } else { + strReturn.append(B0); + } + } + + strReturn.append(checksum1 %2 == 0 ? B1 : B0); // 1st checksum + strReturn.append(checksum2 %2 == 0 ? B1 : B0); // 2nd checksum + + strReturn.append("+"); + + return strReturn; +} diff --git a/external/tellstick-core/ProtocolIkea.h b/external/tellstick-core/ProtocolIkea.h new file mode 100644 index 00000000..11a18cbf --- /dev/null +++ b/external/tellstick-core/ProtocolIkea.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_ + +#include +#include "service/Protocol.h" + +class ProtocolIkea : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_ diff --git a/external/tellstick-core/ProtocolMandolyn.cpp b/external/tellstick-core/ProtocolMandolyn.cpp new file mode 100644 index 00000000..c37555c0 --- /dev/null +++ b/external/tellstick-core/ProtocolMandolyn.cpp @@ -0,0 +1,46 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolMandolyn.h" +#include +#include +#include +#include +#include "common/Strings.h" + +std::string ProtocolMandolyn::decodeData(const ControllerMessage &dataMsg) { + std::string data = dataMsg.getParameter("data"); + uint32_t value = (uint32_t)TelldusCore::hexTo64l(data); + + // parity not used + // bool parity = value & 0x1; + value >>= 1; + + double temp = static_cast(value & 0x7FFF) - static_cast(6400); + temp = temp/128.0; + value >>= 15; + + uint8_t humidity = (value & 0x7F); + value >>= 7; + + // battOk not used + // bool battOk = value & 0x1; + value >>= 3; + + uint8_t channel = (value & 0x3)+1; + value >>= 2; + + uint8_t house = value & 0xF; + + std::stringstream retString; + retString << "class:sensor;protocol:mandolyn;id:" + << house*10+channel + << ";model:temperaturehumidity;" + << "temp:" << std::fixed << std::setprecision(1) << temp + << ";humidity:" << static_cast(humidity) << ";"; + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolMandolyn.h b/external/tellstick-core/ProtocolMandolyn.h new file mode 100644 index 00000000..8fcd90a5 --- /dev/null +++ b/external/tellstick-core/ProtocolMandolyn.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolMandolyn : public Protocol { +public: + static std::string decodeData(const ControllerMessage &dataMsg); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_ diff --git a/external/tellstick-core/ProtocolNexa.cpp b/external/tellstick-core/ProtocolNexa.cpp new file mode 100644 index 00000000..76cc1efc --- /dev/null +++ b/external/tellstick-core/ProtocolNexa.cpp @@ -0,0 +1,279 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolNexa.h" +#include +#include +#include +#include "service/TellStick.h" +#include "common/Strings.h" + +int ProtocolNexa::lastArctecCodeSwitchWasTurnOff = 0; // TODO(stefan): always removing first turnon now, make more flexible (waveman too) + +int ProtocolNexa::methods() const { + if (TelldusCore::comparei(model(), L"codeswitch")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF); + + } else if (TelldusCore::comparei(model(), L"selflearning-switch")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); + + } else if (TelldusCore::comparei(model(), L"selflearning-dimmer")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_LEARN); + + } else if (TelldusCore::comparei(model(), L"bell")) { + return TELLSTICK_BELL; + } + return 0; +} + +std::string ProtocolNexa::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"codeswitch")) { + return getStringCodeSwitch(method); + } else if (TelldusCore::comparei(model(), L"bell")) { + return getStringBell(); + } + if ((method == TELLSTICK_TURNON) && TelldusCore::comparei(model(), L"selflearning-dimmer")) { + // Workaround for not letting a dimmer do into "dimming mode" + return getStringSelflearning(TELLSTICK_DIM, 255); + } + if (method == TELLSTICK_LEARN) { + std::string str = getStringSelflearning(TELLSTICK_TURNON, data); + + // Check to see if we are an old TellStick (fw <= 2, batch <= 8) + TellStick *ts = reinterpret_cast(controller); + if (!ts) { + return str; + } + if (ts->pid() == 0x0c30 && ts->firmwareVersion() <= 2) { + // Workaround for the bug in early firmwares + // The TellStick have a fixed pause (max) between two packets. + // It is only correct between the first and second packet. + // It seems faster to send two packes at a time and some + // receivers seems picky about this when learning. + // We also return the last packet so Device::doAction() doesn't + // report TELLSTICK_ERROR_METHOD_NOT_SUPPORTED + + str.insert(0, 1, 2); // Repeat two times + str.insert(0, 1, 'R'); + for (int i = 0; i < 5; ++i) { + controller->send(str); + } + } + return str; + } + return getStringSelflearning(method, data); +} + +std::string ProtocolNexa::getStringCodeSwitch(int method) { + std::string strReturn = "S"; + + std::wstring house = getStringParameter(L"house", L"A"); + int intHouse = house[0] - L'A'; + strReturn.append(getCodeSwitchTuple(intHouse)); + strReturn.append(getCodeSwitchTuple(getIntParameter(L"unit", 1, 16)-1)); + + if (method == TELLSTICK_TURNON) { + strReturn.append("$k$k$kk$$kk$$kk$$k+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(this->getOffCode()); + } else { + return ""; + } + return strReturn; +} + +std::string ProtocolNexa::getStringBell() { + std::string strReturn = "S"; + + std::wstring house = getStringParameter(L"house", L"A"); + int intHouse = house[0] - L'A'; + strReturn.append(getCodeSwitchTuple(intHouse)); + strReturn.append("$kk$$kk$$kk$$k$k"); // Unit 7 + strReturn.append("$kk$$kk$$kk$$kk$$k+"); // Bell + return strReturn; +} + +std::string ProtocolNexa::getStringSelflearning(int method, unsigned char level) { + int intHouse = getIntParameter(L"house", 1, 67108863); + int intCode = getIntParameter(L"unit", 1, 16)-1; + return getStringSelflearningForCode(intHouse, intCode, method, level); +} + +std::string ProtocolNexa::getStringSelflearningForCode(int intHouse, int intCode, int method, unsigned char level) { + const unsigned char START[] = {'T', 127, 255, 24, 1, 0}; + // const char START[] = {'T',130,255,26,24,0}; + + std::string strMessage(reinterpret_cast(START)); + strMessage.append(1, (method == TELLSTICK_DIM ? 147 : 132)); // Number of pulses + + std::string m; + for (int i = 25; i >= 0; --i) { + m.append( intHouse & 1 << i ? "10" : "01" ); + } + m.append("01"); // Group + + // On/off + if (method == TELLSTICK_DIM) { + m.append("00"); + } else if (method == TELLSTICK_TURNOFF) { + m.append("01"); + } else if (method == TELLSTICK_TURNON) { + m.append("10"); + } else { + return ""; + } + + for (int i = 3; i >= 0; --i) { + m.append( intCode & 1 << i ? "10" : "01" ); + } + + if (method == TELLSTICK_DIM) { + unsigned char newLevel = level/16; + for (int i = 3; i >= 0; --i) { + m.append(newLevel & 1 << i ? "10" : "01"); + } + } + + // The number of data is odd. + // Add this to make it even, otherwise the following loop will not work + m.append("0"); + + unsigned char code = 9; // b1001, startcode + for (unsigned int i = 0; i < m.length(); ++i) { + code <<= 4; + if (m[i] == '1') { + code |= 8; // b1000 + } else { + code |= 10; // b1010 + // code |= 11; //b1011 + } + if (i % 2 == 0) { + strMessage.append(1, code); + code = 0; + } + } + strMessage.append("+"); + +// for( int i = 0; i < strMessage.length(); ++i ) { +// printf("%i,", (unsigned char)strMessage[i]); +// } +// printf("\n"); + return strMessage; +} + +std::string ProtocolNexa::decodeData(const ControllerMessage& dataMsg) { + uint64_t allData = dataMsg.getInt64Parameter("data"); + + if(TelldusCore::comparei(dataMsg.model(), L"selflearning")) { + // selflearning + return decodeDataSelfLearning(allData); + } else { + // codeswitch + return decodeDataCodeSwitch(allData); + } +} + +std::string ProtocolNexa::decodeDataSelfLearning(uint64_t allData) { + unsigned int house = 0; + unsigned int unit = 0; + unsigned int group = 0; + unsigned int method = 0; + + house = allData & 0xFFFFFFC0; + house >>= 6; + + group = allData & 0x20; + group >>= 5; + + method = allData & 0x10; + method >>= 4; + + unit = allData & 0xF; + unit++; + + if(house < 1 || house > 67108863 || unit < 1 || unit > 16) { + // not arctech selflearning + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:arctech;model:selflearning;house:" << house << ";unit:" << unit << ";group:" << group << ";method:"; + if(method == 1) { + retString << "turnon;"; + } else if(method == 0) { + retString << "turnoff;"; + } else { + // not arctech selflearning + return ""; + } + + return retString.str(); +} + +std::string ProtocolNexa::decodeDataCodeSwitch(uint64_t allData) { + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + method = allData & 0xF00; + method >>= 8; + + unit = allData & 0xF0; + unit >>= 4; + unit++; + + house = allData & 0xF; + + if(house > 16 || unit < 1 || unit > 16) { + // not arctech codeswitch + return ""; + } + + house = house + 'A'; // house from A to P + + if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1) { + lastArctecCodeSwitchWasTurnOff = 0; + return ""; // probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose + // one turnon/bell, but it's better than the alternative... + } + + if(method == 6) { + lastArctecCodeSwitchWasTurnOff = 1; + } + + std::stringstream retString; + retString << "class:command;protocol:arctech;model:codeswitch;house:" << static_cast(house); + + if(method == 6) { + retString << ";unit:" << unit << ";method:turnoff;"; + } else if(method == 14) { + retString << ";unit:" << unit << ";method:turnon;"; + } else if(method == 15) { + retString << ";method:bell;"; + } else { + // not arctech codeswitch + return ""; + } + + return retString.str(); +} + +std::string ProtocolNexa::getCodeSwitchTuple(int intCode) { + std::string strReturn = ""; + for( int i = 0; i < 4; ++i ) { + if (intCode & 1) { // Convert 1 + strReturn.append("$kk$"); + } else { // Convert 0 + strReturn.append("$k$k"); + } + intCode >>= 1; + } + return strReturn; +} + +std::string ProtocolNexa::getOffCode() const { + return "$k$k$kk$$kk$$k$k$k+"; +} diff --git a/external/tellstick-core/ProtocolNexa.h b/external/tellstick-core/ProtocolNexa.h new file mode 100644 index 00000000..82809973 --- /dev/null +++ b/external/tellstick-core/ProtocolNexa.h @@ -0,0 +1,39 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_ + +#ifdef _MSC_VER +typedef unsigned __int64 uint64_t; +#else +#include +#endif +#include +#include "service/ControllerMessage.h" +#include "service/Device.h" + +class ProtocolNexa : public Protocol { +public: + virtual int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + static std::string decodeData(const ControllerMessage &dataMsg); + +protected: + std::string getStringSelflearning(int method, unsigned char data); + std::string getStringCodeSwitch(int method); + std::string getStringBell(); + virtual std::string getOffCode() const; + static std::string getCodeSwitchTuple(int code); + static std::string getStringSelflearningForCode(int house, int unit, int method, unsigned char data); + +private: + static int lastArctecCodeSwitchWasTurnOff; + static std::string decodeDataCodeSwitch(uint64_t allData); + static std::string decodeDataSelfLearning(uint64_t allData); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_ diff --git a/external/tellstick-core/ProtocolOregon.cpp b/external/tellstick-core/ProtocolOregon.cpp new file mode 100644 index 00000000..3fcfe6dc --- /dev/null +++ b/external/tellstick-core/ProtocolOregon.cpp @@ -0,0 +1,347 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolOregon.h" +#include +#include +#include +#include +#include "common/Strings.h" + +std::string ProtocolOregon::decodeData(const ControllerMessage &dataMsg) { + std::string data = dataMsg.getParameter("data"); + + std::wstring model = dataMsg.model(); + if (model.compare(L"0xEA4C") == 0) { + return decodeEA4C(data); + } else if (model.compare(L"0x1A2D") == 0) { + return decode1A2D(data); + } else if (model.compare(L"0xF824") == 0) { + return decodeF824(data); + } else if (model.compare(L"0x1984") == 0 || model.compare(L"0x1994") == 0) { + return decode1984(data, model); + } else if (model.compare(L"0x2914") == 0) { + return decode2914(data); + } else if (model.compare(L"0xC844") == 0 || model.compare(L"0xEC40") == 0) { + // C844 - pool thermometer + return decodeC844(data, model); + } + + return ""; +} + +std::string ProtocolOregon::decodeEA4C(const std::string &data) { + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t checksum = 0xE + 0xA + 0x4 + 0xC; + checksum -= (value & 0xF) * 0x10; + checksum -= 0xA; + value >>= 8; + + uint8_t checksumw = (value >> 4) & 0xF; + bool neg = value & (1 << 3); + int hundred = value & 3; + checksum += (value & 0xF); + value >>= 8; + + uint8_t temp2 = value & 0xF; + uint8_t temp1 = (value >> 4) & 0xF; + checksum += temp2 + temp1; + value >>= 8; + + uint8_t temp3 = (value >> 4) & 0xF; + checksum += (value & 0xF) + temp3; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t address = value & 0xFF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + // channel not used + // uint8_t channel = (value >> 4) & 0x7; + + if (checksum != checksumw) { + return ""; + } + + double temperature = ((hundred * 1000) + (temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:EA4C;id:" << static_cast(address) + << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + + return retString.str(); +} + +std::string ProtocolOregon::decode1984(const std::string &data, const std::wstring &model) { + // wind + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t crcCheck = value & 0xF; // PROBABLY crc + value >>= 4; + uint8_t messageChecksum1 = value & 0xF; + value >>= 4; + uint8_t messageChecksum2 = value & 0xF; + + value >>= 4; + uint8_t avg1 = value & 0xF; + value >>= 4; + uint8_t avg2 = value & 0xF; + value >>= 4; + uint8_t avg3 = value & 0xF; + value >>= 4; + uint8_t gust1 = value & 0xF; + value >>= 4; + uint8_t gust2 = value & 0xF; + value >>= 4; + uint8_t gust3 = value & 0xF; + value >>= 4; + uint8_t unknown1 = value & 0xF; + value >>= 4; + uint8_t unknown2 = value & 0xF; + value >>= 4; + uint8_t direction = value & 0xF; + + value >>= 4; + uint8_t battery = value & 0xF; // PROBABLY battery + value >>= 4; + uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + value >>= 8; + uint8_t channel = value & 0xF; + checksum += unknown1 + unknown2 + avg1 + avg2 + avg3 + gust1 + gust2 + gust3 + direction + battery + channel; + + if (model.compare(L"0x1984") == 0) { + checksum += 0x1 + 0x9 + 0x8 + 0x4; + } else { + checksum += 0x1 + 0x9 + 0x9 + 0x4; + } + + if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) { + // checksum error + return ""; + } + + + double avg = ((avg1 * 100) + (avg2 * 10) + avg3)/10.0; + double gust = ((gust1 * 100) + (gust2 * 10) + gust3)/10.0; + float directiondegree = 22.5 * direction; + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:1984;id:" << static_cast(rollingcode) + << ";winddirection:" << directiondegree + << ";windaverage:" << std::fixed << std::setprecision(1) << avg + << ";windgust:" << std::fixed << std::setprecision(1) << gust << ";"; + + return retString.str(); +} + +std::string ProtocolOregon::decode1A2D(const std::string &data) { + uint64_t value = TelldusCore::hexTo64l(data); + // checksum2 not used yet + // uint8_t checksum2 = value & 0xFF; + value >>= 8; + uint8_t checksum1 = value & 0xFF; + value >>= 8; + + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t hum1 = value & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t neg = value & (1 << 3); + uint8_t hum2 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t temp2 = value & 0xF; + uint8_t temp1 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t temp3 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t address = value & 0xFF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + // channel not used + // uint8_t channel = (value >> 4) & 0x7; + + checksum += 0x1 + 0xA + 0x2 + 0xD - 0xA; + + // TODO(micke): Find out how checksum2 works + if (checksum != checksum1) { + return ""; + } + + double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + int humidity = (hum1 * 10.0) + hum2; + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:1A2D;id:" << static_cast(address) + << ";temp:" << std::fixed << std::setprecision(1) << temperature + << ";humidity:" << humidity << ";"; + + return retString.str(); +} + +std::string ProtocolOregon::decode2914(const std::string &data) { + // rain + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t messageChecksum1 = value & 0xF; + value >>= 4; + uint8_t messageChecksum2 = value & 0xF; + + value >>= 4; + uint8_t totRain1 = value & 0xF; + value >>= 4; + uint8_t totRain2 = value & 0xF; + value >>= 4; + uint8_t totRain3 = value & 0xF; + value >>= 4; + uint8_t totRain4 = value & 0xF; + value >>= 4; + uint8_t totRain5 = value & 0xF; + value >>= 4; + uint8_t totRain6 = value & 0xF; + value >>= 4; + uint8_t rainRate1 = value & 0xF; + value >>= 4; + uint8_t rainRate2 = value & 0xF; + value >>= 4; + uint8_t rainRate3 = value & 0xF; + value >>= 4; + uint8_t rainRate4 = value & 0xF; + + value >>= 4; + uint8_t battery = value & 0xF; // PROBABLY battery + value >>= 4; + uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + value >>= 8; + uint8_t channel = value & 0xF; + checksum += totRain1 + totRain2 + totRain3 + totRain4 + totRain5 + totRain6 + rainRate1 + rainRate2 + rainRate3 + rainRate4 + battery + channel + 0x2 + 0x9 + 0x1 + 0x4; + + if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) { + // checksum error + return ""; + } + + double totRain = ((totRain1 * 100000) + (totRain2 * 10000) + (totRain3 * 1000) + (totRain4 * 100) + (totRain5 * 10) + totRain6)/1000.0*25.4; + double rainRate = ((rainRate1 * 1000) + (rainRate2 * 100) + (rainRate3 * 10) + rainRate4)/100.0*25.4; + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:2914;id:" << static_cast(rollingcode) + << ";raintotal:" << std::fixed << std::setprecision(1) << totRain + << ";rainrate:" << std::fixed << std::setprecision(1) << rainRate << ";"; + return retString.str(); +} + +std::string ProtocolOregon::decodeF824(const std::string &data) { + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t crcCheck = value & 0xF; // PROBABLY crc + value >>= 4; + uint8_t messageChecksum1 = value & 0xF; + value >>= 4; + uint8_t messageChecksum2 = value & 0xF; + value >>= 4; + uint8_t unknown = value & 0xF; + value >>= 4; + uint8_t hum1 = value & 0xF; + value >>= 4; + uint8_t hum2 = value & 0xF; + value >>= 4; + uint8_t neg = value & 0xF; + value >>= 4; + uint8_t temp1 = value & 0xF; + value >>= 4; + uint8_t temp2 = value & 0xF; + value >>= 4; + uint8_t temp3 = value & 0xF; + value >>= 4; + uint8_t battery = value & 0xF; // PROBABLY battery + value >>= 4; + uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + value >>= 8; + uint8_t channel = value & 0xF; + checksum += unknown + hum1 + hum2 + neg + temp1 + temp2 + temp3 + battery + channel + 0xF + 0x8 + 0x2 + 0x4; + + if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) { + // checksum error + return ""; + } + + double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + int humidity = (hum1 * 10.0) + hum2; + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:F824;id:" << static_cast(rollingcode) + << ";temp:" << std::fixed << std::setprecision(1) << temperature + << ";humidity:" << humidity << ";"; + + return retString.str(); +} + +std::string ProtocolOregon::decodeC844(const std::string &data, const std::wstring &model) { + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t messageChecksum1 = value & 0xF; + value >>= 4; + uint8_t messageChecksum2 = value & 0xF; + value >>= 4; + uint8_t neg = value & 0xF; + value >>= 4; + uint8_t temp1 = value & 0xF; + value >>= 4; + uint8_t temp2 = value & 0xF; + value >>= 4; + uint8_t temp3 = value & 0xF; + value >>= 4; + uint8_t battery = value & 0xF; // PROBABLY battery + value >>= 4; + uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + value >>= 8; + uint8_t channel = value & 0xF; + checksum += neg + temp1 + temp2 + temp3 + battery + channel; + + if (model.compare(L"0xC844") == 0) { + checksum += 0xC + 0x8 + 0x4 + 0x4; + } else { + checksum += 0xE + 0xC + 0x4 + 0x0; + } + + if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) { + // checksum error + return ""; + } + + double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:C844;id:" << static_cast(rollingcode) + << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolOregon.h b/external/tellstick-core/ProtocolOregon.h new file mode 100644 index 00000000..cc68fe86 --- /dev/null +++ b/external/tellstick-core/ProtocolOregon.h @@ -0,0 +1,27 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolOregon : public Protocol { +public: + static std::string decodeData(const ControllerMessage &dataMsg); + +protected: + static std::string decodeEA4C(const std::string &data); + static std::string decode1A2D(const std::string &data); + static std::string decodeF824(const std::string &data); + static std::string decode1984(const std::string &data, const std::wstring &model); + static std::string decode2914(const std::string &data); + static std::string decodeC844(const std::string &data, const std::wstring &model); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_ diff --git a/external/tellstick-core/ProtocolRisingSun.cpp b/external/tellstick-core/ProtocolRisingSun.cpp new file mode 100644 index 00000000..c4e9ae0c --- /dev/null +++ b/external/tellstick-core/ProtocolRisingSun.cpp @@ -0,0 +1,115 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolRisingSun.h" +#include +#include "common/Strings.h" + +int ProtocolRisingSun::methods() const { + if (TelldusCore::comparei(model(), L"selflearning")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); + } + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolRisingSun::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"selflearning")) { + return getStringSelflearning(method); + } + return getStringCodeSwitch(method); +} + +std::string ProtocolRisingSun::getStringSelflearning(int method) { + int intHouse = this->getIntParameter(L"house", 1, 33554432)-1; + int intCode = this->getIntParameter(L"code", 1, 16)-1; + + const char code_on[][7] = { + "110110", "001110", "100110", "010110", + "111001", "000101", "101001", "011001", + "110000", "001000", "100000", "010000", + "111100", "000010", "101100", "011100" + }; + const char code_off[][7] = { + "111110", "000001", "101110", "011110", + "110101", "001101", "100101", "010101", + "111000", "000100", "101000", "011000", + "110010", "001010", "100010", "010010" + }; + const char l = 120; + const char s = 51; + + std::string strCode = "10"; + int code = intCode; + code = (code < 0 ? 0 : code); + code = (code > 15 ? 15 : code); + if (method == TELLSTICK_TURNON) { + strCode.append(code_on[code]); + } else if (method == TELLSTICK_TURNOFF) { + strCode.append(code_off[code]); + } else if (method == TELLSTICK_LEARN) { + strCode.append(code_on[code]); + } else { + return ""; + } + + int house = intHouse; + for(int i = 0; i < 25; ++i) { + if (house & 1) { + strCode.append(1, '1'); + } else { + strCode.append(1, '0'); + } + house >>= 1; + } + + std::string strReturn; + for(unsigned int i = 0; i < strCode.length(); ++i) { + if (strCode[i] == '1') { + strReturn.append(1, l); + strReturn.append(1, s); + } else { + strReturn.append(1, s); + strReturn.append(1, l); + } + } + + std::string prefix = "P"; + prefix.append(1, 5); + if (method == TELLSTICK_LEARN) { + prefix.append("R"); + prefix.append( 1, 50 ); + } + prefix.append("S"); + strReturn.insert(0, prefix); + strReturn.append(1, '+'); + return strReturn; +} + +std::string ProtocolRisingSun::getStringCodeSwitch(int method) { + std::string strReturn = "S.e"; + strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"house", 1, 4)-1)); + strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"unit", 1, 4)-1)); + if (method == TELLSTICK_TURNON) { + strReturn.append("e..ee..ee..ee..e+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append("e..ee..ee..e.e.e+"); + } else { + return ""; + } + return strReturn; +} + +std::string ProtocolRisingSun::getCodeSwitchTuple(int intToConvert) { + std::string strReturn = ""; + for(int i = 0; i < 4; ++i) { + if (i == intToConvert) { + strReturn.append( ".e.e" ); + } else { + strReturn.append( "e..e" ); + } + } + return strReturn; +} diff --git a/external/tellstick-core/ProtocolRisingSun.h b/external/tellstick-core/ProtocolRisingSun.h new file mode 100644 index 00000000..ef6262e5 --- /dev/null +++ b/external/tellstick-core/ProtocolRisingSun.h @@ -0,0 +1,24 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_ + +#include +#include "service/Protocol.h" + +class ProtocolRisingSun : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + +protected: + std::string getStringSelflearning(int method); + std::string getStringCodeSwitch(int method); + static std::string getCodeSwitchTuple(int code); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_ diff --git a/external/tellstick-core/ProtocolSartano.cpp b/external/tellstick-core/ProtocolSartano.cpp new file mode 100644 index 00000000..0b33f354 --- /dev/null +++ b/external/tellstick-core/ProtocolSartano.cpp @@ -0,0 +1,108 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolSartano.h" +#ifdef _MSC_VER +typedef unsigned __int16 uint16_t; +#else +#include +#endif +#include +#include +#include + +int ProtocolSartano::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolSartano::getStringForMethod(int method, unsigned char, Controller *) { + std::wstring strCode = this->getStringParameter(L"code", L""); + return getStringForCode(strCode, method); +} + +std::string ProtocolSartano::getStringForCode(const std::wstring &strCode, int method) { + std::string strReturn("S"); + + for (size_t i = 0; i < strCode.length(); ++i) { + if (strCode[i] == L'1') { + strReturn.append("$k$k"); + } else { + strReturn.append("$kk$"); + } + } + + if (method == TELLSTICK_TURNON) { + strReturn.append("$k$k$kk$$k+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append("$kk$$k$k$k+"); + } else { + return ""; + } + + return strReturn; +} + +std::string ProtocolSartano::decodeData(const ControllerMessage &dataMsg) { + uint64_t allDataIn; + uint16_t allData = 0; + unsigned int code = 0; + unsigned int method1 = 0; + unsigned int method2 = 0; + unsigned int method = 0; + + allDataIn = dataMsg.getInt64Parameter("data"); + + uint16_t mask = (1<<11); + for(int i = 0; i < 12; ++i) { + allData >>= 1; + if((allDataIn & mask) == 0) { + allData |= (1<<11); + } + mask >>= 1; + } + + code = allData & 0xFFC; + code >>= 2; + + method1 = allData & 0x2; + method1 >>= 1; + + method2 = allData & 0x1; + + if(method1 == 0 && method2 == 1) { + method = 0; // off + } else if(method1 == 1 && method2 == 0) { + method = 1; // on + } else { + return ""; + } + + if(code > 1023) { + // not sartano + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:sartano;model:codeswitch;code:"; + mask = (1<<9); + for(int i = 0; i < 10; i++) { + if((code & mask) != 0) { + retString << 1; + } else { + retString << 0; + } + mask >>= 1; + } + retString << ";method:"; + + if(method == 0) { + retString << "turnoff;"; + } else { + retString << "turnon;"; + } + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolSartano.h b/external/tellstick-core/ProtocolSartano.h new file mode 100644 index 00000000..d644a0e8 --- /dev/null +++ b/external/tellstick-core/ProtocolSartano.h @@ -0,0 +1,24 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolSartano : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + static std::string decodeData(const ControllerMessage &dataMsg); + +protected: + std::string getStringForCode(const std::wstring &code, int method); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_ diff --git a/external/tellstick-core/ProtocolScene.cpp b/external/tellstick-core/ProtocolScene.cpp new file mode 100644 index 00000000..24ae5318 --- /dev/null +++ b/external/tellstick-core/ProtocolScene.cpp @@ -0,0 +1,16 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolScene.h" +#include + +int ProtocolScene::methods() const { + return TELLSTICK_EXECUTE; +} + +std::string ProtocolScene::getStringForMethod(int method, unsigned char data, Controller *) { + return ""; +} diff --git a/external/tellstick-core/ProtocolScene.h b/external/tellstick-core/ProtocolScene.h new file mode 100644 index 00000000..87f80afe --- /dev/null +++ b/external/tellstick-core/ProtocolScene.h @@ -0,0 +1,22 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_ + +#include +#include "service/Protocol.h" + +class ProtocolScene : public Protocol { +public: + virtual int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_ + + + diff --git a/external/tellstick-core/ProtocolSilvanChip.cpp b/external/tellstick-core/ProtocolSilvanChip.cpp new file mode 100644 index 00000000..ddc20068 --- /dev/null +++ b/external/tellstick-core/ProtocolSilvanChip.cpp @@ -0,0 +1,146 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolSilvanChip.h" +#include +#include "common/Strings.h" + +int ProtocolSilvanChip::methods() const { + if (TelldusCore::comparei(model(), L"kp100")) { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; + } else if (TelldusCore::comparei(model(), L"ecosavers")) { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; + } else if (TelldusCore::comparei(model(), L"displaymatic")) { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; + } + return 0; +} + +std::string ProtocolSilvanChip::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"kp100")) { + std::string preamble; + preamble.append(1, 100); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 100); + + const std::string one = "\xFF\x1\x2E\x2E"; + const std::string zero = "\x2E\xFF\x1\x2E"; + int button = 0; + if (method == TELLSTICK_UP) { + button = 2; + } else if (method == TELLSTICK_DOWN) { + button = 8; + } else if (method == TELLSTICK_STOP) { + button = 4; + } else if (method == TELLSTICK_LEARN) { + button = 1; + } else { + return ""; + } + return this->getString(preamble, one, zero, button); + } else if (TelldusCore::comparei(model(), L"displaymatic")) { + std::string preamble; + preamble.append(1, 0x25); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 0x25); + const std::string one = "\x69\25"; + const std::string zero = "\x25\x69"; + int button = 0; + if (method == TELLSTICK_UP) { + button = 1; + } else if (method == TELLSTICK_DOWN) { + button = 4; + } else if (method == TELLSTICK_STOP) { + button = 2; + } + return this->getString(preamble, one, zero, button); + } else if (TelldusCore::comparei(model(), L"ecosavers")) { + std::string preamble; + preamble.append(1, 0x25); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 0x25); + const std::string one = "\x69\25"; + const std::string zero = "\x25\x69"; + int intUnit = this->getIntParameter(L"unit", 1, 4); + int button = 0; + if (intUnit == 1) { + button = 7; + } else if (intUnit == 2) { + button = 3; + } else if (intUnit == 3) { + button = 5; + } else if (intUnit == 4) { + button = 6; + } + + if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { + button |= 8; + } + return this->getString(preamble, one, zero, button); + } + return ""; +} + +std::string ProtocolSilvanChip::getString(const std::string &preamble, const std::string &one, const std::string &zero, int button) { + int intHouse = this->getIntParameter(L"house", 1, 1048575); + std::string strReturn = preamble; + + for( int i = 19; i >= 0; --i ) { + if (intHouse & (1 << i)) { + strReturn.append(one); + } else { + strReturn.append(zero); + } + } + + for( int i = 3; i >= 0; --i) { + if (button & (1 << i)) { + strReturn.append(one); + } else { + strReturn.append(zero); + } + } + + strReturn.append(zero); + return strReturn; +} diff --git a/external/tellstick-core/ProtocolSilvanChip.h b/external/tellstick-core/ProtocolSilvanChip.h new file mode 100644 index 00000000..188a2d4a --- /dev/null +++ b/external/tellstick-core/ProtocolSilvanChip.h @@ -0,0 +1,22 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_ + +#include +#include "service/Protocol.h" + +class ProtocolSilvanChip : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + +protected: + virtual std::string getString(const std::string &preamble, const std::string &one, const std::string &zero, int button); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_ diff --git a/external/tellstick-core/ProtocolUpm.cpp b/external/tellstick-core/ProtocolUpm.cpp new file mode 100644 index 00000000..4e70b797 --- /dev/null +++ b/external/tellstick-core/ProtocolUpm.cpp @@ -0,0 +1,78 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolUpm.h" +#include + +int ProtocolUpm::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; +} + +std::string ProtocolUpm::getStringForMethod(int method, unsigned char, Controller *) { + const char S = ';'; + const char L = '~'; + const char START[] = {S, 0}; + const char B1[] = {L, S, 0}; + const char B0[] = {S, L, 0}; + // const char BON[] = {S,L,L,S,0}; + // const char BOFF[] = {S,L,S,L,0}; + + int intUnit = this->getIntParameter(L"unit", 1, 4)-1; + std::string strReturn; + + int code = this->getIntParameter(L"house", 0, 4095); + for( size_t i = 0; i < 12; ++i ) { + if (code & 1) { + strReturn.insert(0, B1); + } else { + strReturn.insert(0, B0); + } + code >>= 1; + } + strReturn.insert(0, START); // Startcode, first + + code = 0; + if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { + code += 2; + } else if (method != TELLSTICK_TURNOFF) { + return ""; + } + code <<= 2; + code += intUnit; + + int check1 = 0, check2 = 0; + for( size_t i = 0; i < 6; ++i ) { + if (code & 1) { + if (i % 2 == 0) { + check1++; + } else { + check2++; + } + } + if (code & 1) { + strReturn.append(B1); + } else { + strReturn.append(B0); + } + code >>= 1; + } + + if (check1 % 2 == 0) { + strReturn.append(B0); + } else { + strReturn.append(B1); + } + if (check2 % 2 == 0) { + strReturn.append(B0); + } else { + strReturn.append(B1); + } + + strReturn.insert(0, "S"); + strReturn.append("+"); + return strReturn; +} + diff --git a/external/tellstick-core/ProtocolUpm.h b/external/tellstick-core/ProtocolUpm.h new file mode 100644 index 00000000..9283a408 --- /dev/null +++ b/external/tellstick-core/ProtocolUpm.h @@ -0,0 +1,19 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_ + +#include +#include "service/Protocol.h" + +class ProtocolUpm : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_ diff --git a/external/tellstick-core/ProtocolWaveman.cpp b/external/tellstick-core/ProtocolWaveman.cpp new file mode 100644 index 00000000..9684934b --- /dev/null +++ b/external/tellstick-core/ProtocolWaveman.cpp @@ -0,0 +1,77 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolWaveman.h" +#ifdef _MSC_VER +#else +#include +#endif +#include +#include +#include + +int ProtocolWaveman::lastArctecCodeSwitchWasTurnOff = 0; + +int ProtocolWaveman::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolWaveman::getStringForMethod(int method, unsigned char, Controller *) { + return getStringCodeSwitch(method); +} + +std::string ProtocolWaveman::getOffCode() const { + return "$k$k$k$k$k$k$k$k$k+"; +} + +std::string ProtocolWaveman::decodeData(const ControllerMessage& dataMsg) { + uint64_t allData = 0; + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + allData = dataMsg.getInt64Parameter("data"); + + method = allData & 0xF00; + method >>= 8; + + unit = allData & 0xF0; + unit >>= 4; + unit++; + + house = allData & 0xF; + + if(house > 16 || unit < 1 || unit > 16) { + // not waveman + return ""; + } + + house = house + 'A'; // house from A to P + + if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1) { + lastArctecCodeSwitchWasTurnOff = 0; + return ""; // probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose + // one turnon/bell, but it's better than the alternative... + } + + if(method == 6) { + lastArctecCodeSwitchWasTurnOff = 1; + } + + std::stringstream retString; + retString << "class:command;protocol:waveman;model:codeswitch;house:" << static_cast(house); + + if(method == 0) { + retString << ";unit:" << unit << ";method:turnoff;"; + } else if(method == 14) { + retString << ";unit:" << unit << ";method:turnon;"; + } else { + // not waveman + return ""; + } + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolWaveman.h b/external/tellstick-core/ProtocolWaveman.h new file mode 100644 index 00000000..a6feb394 --- /dev/null +++ b/external/tellstick-core/ProtocolWaveman.h @@ -0,0 +1,26 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_ + +#include +#include "service/ProtocolNexa.h" + +class ProtocolWaveman : public ProtocolNexa { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + static std::string decodeData(const ControllerMessage &dataMsg); + +protected: + virtual std::string getOffCode() const; + +private: + static int lastArctecCodeSwitchWasTurnOff; +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_ diff --git a/external/tellstick-core/ProtocolX10.cpp b/external/tellstick-core/ProtocolX10.cpp new file mode 100644 index 00000000..b3af1230 --- /dev/null +++ b/external/tellstick-core/ProtocolX10.cpp @@ -0,0 +1,185 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "service/ProtocolX10.h" +#ifdef _MSC_VER +#else +#include +#endif +#include +#include +#include + +const unsigned char HOUSES[] = {6, 0xE, 2, 0xA, 1, 9, 5, 0xD, 7, 0xF, 3, 0xB, 0, 8, 4, 0xC}; + +int ProtocolX10::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolX10::getStringForMethod(int method, unsigned char data, Controller *controller) { + const unsigned char S = 59, L = 169; + const char B0[] = {S, S, 0}; + const char B1[] = {S, L, 0}; + const unsigned char START_CODE[] = {'S', 255, 1, 255, 1, 255, 1, 100, 255, 1, 180, 0}; + const unsigned char STOP_CODE[] = {S, 0}; + + std::string strReturn = reinterpret_cast(START_CODE); + std::string strComplement = ""; + + std::wstring strHouse = getStringParameter(L"house", L"A"); + int intHouse = strHouse[0] - L'A'; + if (intHouse < 0) { + intHouse = 0; + } else if (intHouse > 15) { + intHouse = 15; + } + // Translate it + intHouse = HOUSES[intHouse]; + int intCode = getIntParameter(L"unit", 1, 16)-1; + + for( int i = 0; i < 4; ++i ) { + if (intHouse & 1) { + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + intHouse >>= 1; + } + strReturn.append( B0 ); + strComplement.append( B1 ); + + if (intCode >= 8) { + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + strReturn.append( B0 ); + strComplement.append( B1 ); + strReturn.append( B0 ); + strComplement.append( B1 ); + + strReturn.append( strComplement ); + strComplement = ""; + + strReturn.append( B0 ); + strComplement.append( B1 ); + + if (intCode >> 2 & 1) { // Bit 2 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + if (method == TELLSTICK_TURNON) { + strReturn.append(B0); + strComplement.append(B1); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(B1); + strComplement.append(B0); + } else { + return ""; + } + + if (intCode & 1) { // Bit 0 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + if (intCode >> 1 & 1) { // Bit 1 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + for( int i = 0; i < 3; ++i ) { + strReturn.append( B0 ); + strComplement.append( B1 ); + } + + strReturn.append( strComplement ); + strReturn.append( reinterpret_cast(STOP_CODE) ); + strReturn.append("+"); + return strReturn; +} + +std::string ProtocolX10::decodeData(const ControllerMessage& dataMsg) { + uint64_t intData = 0, currentBit = 31; + bool method = 0; + + intData = dataMsg.getInt64Parameter("data"); + + int unit = 0; + int rawHouse = 0; + for(int i = 0; i < 4; ++i) { + rawHouse >>= 1; + if (checkBit(intData, currentBit--)) { + rawHouse |= 0x8; + } + } + + if (checkBit(intData, currentBit--) != 0) { + return ""; + } + + if (checkBit(intData, currentBit--)) { + unit |= (1<<3); + } + + if (checkBit(intData, currentBit--)) { + return ""; + } + if (checkBit(intData, currentBit--)) { + return ""; + } + + currentBit = 14; + + if (checkBit(intData, currentBit--)) { + unit |= (1<<2); + } + if (checkBit(intData, currentBit--)) { + method = 1; + } + if (checkBit(intData, currentBit--)) { + unit |= (1<<0); + } + if (checkBit(intData, currentBit--)) { + unit |= (1<<1); + } + + int intHouse = 0; + for(int i = 0; i < 16; ++i) { + if (HOUSES[i] == rawHouse) { + intHouse = i; + break; + } + } + + std::stringstream retString; + retString << "class:command;protocol:x10;model:codeswitch;"; + retString << "house:" << static_cast('A' + intHouse); + retString << ";unit:" << unit+1; + retString << ";method:"; + if(method == 0) { + retString << "turnon;"; + } else { + retString << "turnoff;"; + } + + return retString.str(); +} diff --git a/external/tellstick-core/ProtocolX10.h b/external/tellstick-core/ProtocolX10.h new file mode 100644 index 00000000..c8cf8422 --- /dev/null +++ b/external/tellstick-core/ProtocolX10.h @@ -0,0 +1,22 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLX10_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLX10_H_ + +#include +#include "service/Protocol.h" +#include "service/ControllerMessage.h" + +class ProtocolX10 : public Protocol { +public: + int methods() const; + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); + + static std::string decodeData(const ControllerMessage &dataMsg); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLX10_H_ diff --git a/external/tellstick-core/ProtocolYidong.cpp b/external/tellstick-core/ProtocolYidong.cpp new file mode 100644 index 00000000..61b9f33f --- /dev/null +++ b/external/tellstick-core/ProtocolYidong.cpp @@ -0,0 +1,31 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include +#include "service/ProtocolYidong.h" + +std::string ProtocolYidong::getStringForMethod(int method, unsigned char, Controller *) { + int intCode = this->getIntParameter(L"unit", 1, 4); + std::wstring strCode = L"111"; + + switch(intCode) { + case 1: + strCode.append(L"0010"); + break; + case 2: + strCode.append(L"0001"); + break; + case 3: + strCode.append(L"0100"); + break; + case 4: + strCode.append(L"1000"); + break; + } + + strCode.append(L"110"); + return getStringForCode(strCode, method); +} diff --git a/external/tellstick-core/ProtocolYidong.h b/external/tellstick-core/ProtocolYidong.h new file mode 100644 index 00000000..c6b628c4 --- /dev/null +++ b/external/tellstick-core/ProtocolYidong.h @@ -0,0 +1,18 @@ +// +// Copyright (C) 2012 Telldus Technologies AB. All rights reserved. +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_ +#define TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_ + +#include +#include "service/ProtocolSartano.h" + +class ProtocolYidong : public ProtocolSartano { +public: + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller); +}; + +#endif // TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_ diff --git a/external/tellstick-driver/DPInst32.exe b/external/tellstick-driver/DPInst32.exe new file mode 100644 index 00000000..86955a2c Binary files /dev/null and b/external/tellstick-driver/DPInst32.exe differ diff --git a/external/tellstick-driver/DPInst64.exe b/external/tellstick-driver/DPInst64.exe new file mode 100644 index 00000000..5fa618ac Binary files /dev/null and b/external/tellstick-driver/DPInst64.exe differ diff --git a/external/tellstick-driver/FTDIBUS.INF b/external/tellstick-driver/FTDIBUS.INF new file mode 100644 index 00000000..bfbb90dc --- /dev/null +++ b/external/tellstick-driver/FTDIBUS.INF @@ -0,0 +1,135 @@ +; FTDIBUS.INF +; +; Copyright © 2000-2013 Future Technology Devices International Limited +; +; USB serial converter driver installation file for Windows 2000, XP, Server 2003, Vista, Server 2008, +; Windows 7, Server 2008 R2 and Windows 8 (x86 and x64). +; +; +; THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED ``AS IS'' AND ANY EXPRESS +; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED +; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +; THE POSSIBILITY OF SUCH DAMAGE. + +; FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS. + +; FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED. + +; IF A CUSTOM VENDOR ID AND/OR PRODUCT ID OR DESCRIPTION STRING ARE USED, IT IS THE RESPONSIBILITY OF +; THE PRODUCT MANUFACTURER TO MAINTAIN ANY CHANGES AND SUBSEQUENT WHQL RE-CERTIFICATION AS A RESULT OF +; MAKING THESE CHANGES. +; + + +[Version] +Signature="$Windows NT$" +DriverPackageType=PlugAndPlay +DriverPackageDisplayName=%DESC% +Class=USB +ClassGUID={36fc9e60-c465-11cf-8056-444553540000} +Provider=%TELLDUS% +CatalogFile=ftdibus.cat +DriverVer=01/18/2013,2.08.28 + +[SourceDisksNames] +1=%DriversDisk%,,, + +[SourceDisksFiles] +ftdibus.sys = 1,i386 +ftbusui.dll = 1,i386 +ftd2xx.dll = 1,i386 +FTLang.Dll = 1,i386 + +[SourceDisksFiles.amd64] +ftdibus.sys = 1,amd64 +ftbusui.dll = 1,amd64 +ftd2xx64.dll = 1,amd64 +ftd2xx.dll = 1,i386 +FTLang.Dll = 1,amd64 + +[DestinationDirs] +FtdiBus.NT.Copy = 10,system32\drivers +FtdiBus.NT.Copy2 = 10,system32 +FtdiBus.NTamd64.Copy = 10,system32\drivers +FtdiBus.NTamd64.Copy2 = 10,system32 +FtdiBus.NTamd64.Copy3 = 10,syswow64 + + +[Manufacturer] +%Telldus%=TelldusHw,NTamd64 + +[TelldusHw] +%USB\VID_1781&PID_0c30.DeviceDesc%=FtdiBus.NT,USB\VID_1781&PID_0c30 +%USB\VID_1781&PID_0c31.DeviceDesc%=FtdiBus.NT,USB\VID_1781&PID_0c31 + +[TelldusHw.NTamd64] +%USB\VID_1781&PID_0c30.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1781&PID_0c30 +%USB\VID_1781&PID_0c31.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1781&PID_0c31 + +[ControlFlags] +ExcludeFromSelect=* + +[FtdiBus.NT] +CopyFiles=FtdiBus.NT.Copy,FtdiBus.NT.Copy2 +AddReg=FtdiBus.NT.AddReg + +[FtdiBus.NTamd64] +CopyFiles=FtdiBus.NTamd64.Copy,FtdiBus.NTamd64.Copy2,FtdiBus.NTamd64.Copy3 +AddReg=FtdiBus.NT.AddReg + +[FtdiBus.NT.Services] +AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService + +[FtdiBus.NTamd64.Services] +AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService + +[FtdiBus.NT.AddService] +DisplayName = %SvcDesc% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %10%\system32\drivers\ftdibus.sys +LoadOrderGroup = Base +AddReg = FtdiBus.NT.AddService.AddReg + +[FtdiBus.NT.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,ftdibus.sys +HKR,,EnumPropPages32,,"ftbusui.dll,FTBUSUIPropPageProvider" + +[FtdiBus.NT.AddService.AddReg] +;HKR,Parameters,"LocIds",1,31,00,00,00,32,00,00,00,00 +;HKR,Parameters,"RetryResetCount",0x10001,50 + + +[FtdiBus.NT.Copy] +ftdibus.sys + +[FtdiBus.NT.Copy2] +ftbusui.dll +ftd2xx.dll +FTLang.dll + +[FtdiBus.NTamd64.Copy] +ftdibus.sys + +[FtdiBus.NTamd64.Copy2] +ftbusui.dll +ftd2xx.dll,ftd2xx64.dll +FTLang.dll + +[FtdiBus.NTamd64.Copy3] +ftd2xx.dll + +[Strings] +Telldus="TELLDUS" +DESC="Telldus Technologies USB-driver" +DriversDisk="Telldus Technologies AB Drivers Disk" +USB\VID_1781&PID_0c30.DeviceDesc="Telldus TellStick" +USB\VID_1781&PID_0c31.DeviceDesc="Telldus TellStick Duo" +SvcDesc="Telldus Technologies USB-driver" +ClassName="USB" diff --git a/external/tellstick-driver/amd64/ftbusui.dll b/external/tellstick-driver/amd64/ftbusui.dll new file mode 100644 index 00000000..b9e28586 Binary files /dev/null and b/external/tellstick-driver/amd64/ftbusui.dll differ diff --git a/external/tellstick-driver/amd64/ftcserco.dll b/external/tellstick-driver/amd64/ftcserco.dll new file mode 100644 index 00000000..f2929154 Binary files /dev/null and b/external/tellstick-driver/amd64/ftcserco.dll differ diff --git a/external/tellstick-driver/amd64/ftd2xx.lib b/external/tellstick-driver/amd64/ftd2xx.lib new file mode 100644 index 00000000..0d68cf79 Binary files /dev/null and b/external/tellstick-driver/amd64/ftd2xx.lib differ diff --git a/external/tellstick-driver/amd64/ftd2xx64.dll b/external/tellstick-driver/amd64/ftd2xx64.dll new file mode 100644 index 00000000..9044b423 Binary files /dev/null and b/external/tellstick-driver/amd64/ftd2xx64.dll differ diff --git a/external/tellstick-driver/amd64/ftdibus.sys b/external/tellstick-driver/amd64/ftdibus.sys new file mode 100644 index 00000000..f13ca478 Binary files /dev/null and b/external/tellstick-driver/amd64/ftdibus.sys differ diff --git a/external/tellstick-driver/amd64/ftlang.dll b/external/tellstick-driver/amd64/ftlang.dll new file mode 100644 index 00000000..66de070d Binary files /dev/null and b/external/tellstick-driver/amd64/ftlang.dll differ diff --git a/external/tellstick-driver/amd64/ftser2k.sys b/external/tellstick-driver/amd64/ftser2k.sys new file mode 100644 index 00000000..9b90f5de Binary files /dev/null and b/external/tellstick-driver/amd64/ftser2k.sys differ diff --git a/external/tellstick-driver/amd64/ftserui2.dll b/external/tellstick-driver/amd64/ftserui2.dll new file mode 100644 index 00000000..fe73f250 Binary files /dev/null and b/external/tellstick-driver/amd64/ftserui2.dll differ diff --git a/external/tellstick-driver/ftdibus.cat b/external/tellstick-driver/ftdibus.cat new file mode 100644 index 00000000..decf3af3 Binary files /dev/null and b/external/tellstick-driver/ftdibus.cat differ diff --git a/external/tellstick-driver/i386/ftbusui.dll b/external/tellstick-driver/i386/ftbusui.dll new file mode 100644 index 00000000..98659a15 Binary files /dev/null and b/external/tellstick-driver/i386/ftbusui.dll differ diff --git a/external/tellstick-driver/i386/ftcserco.dll b/external/tellstick-driver/i386/ftcserco.dll new file mode 100644 index 00000000..3a282692 Binary files /dev/null and b/external/tellstick-driver/i386/ftcserco.dll differ diff --git a/external/tellstick-driver/i386/ftd2xx.dll b/external/tellstick-driver/i386/ftd2xx.dll new file mode 100644 index 00000000..ebd11b59 Binary files /dev/null and b/external/tellstick-driver/i386/ftd2xx.dll differ diff --git a/external/tellstick-driver/i386/ftd2xx.lib b/external/tellstick-driver/i386/ftd2xx.lib new file mode 100644 index 00000000..10cce73b Binary files /dev/null and b/external/tellstick-driver/i386/ftd2xx.lib differ diff --git a/external/tellstick-driver/i386/ftdibus.sys b/external/tellstick-driver/i386/ftdibus.sys new file mode 100644 index 00000000..9538b1a6 Binary files /dev/null and b/external/tellstick-driver/i386/ftdibus.sys differ diff --git a/external/tellstick-driver/i386/ftlang.dll b/external/tellstick-driver/i386/ftlang.dll new file mode 100644 index 00000000..a7b5fa5c Binary files /dev/null and b/external/tellstick-driver/i386/ftlang.dll differ diff --git a/external/tellstick-driver/i386/ftser2k.sys b/external/tellstick-driver/i386/ftser2k.sys new file mode 100644 index 00000000..ff7c63af Binary files /dev/null and b/external/tellstick-driver/i386/ftser2k.sys differ diff --git a/external/tellstick-driver/i386/ftserui2.dll b/external/tellstick-driver/i386/ftserui2.dll new file mode 100644 index 00000000..3e1a5a35 Binary files /dev/null and b/external/tellstick-driver/i386/ftserui2.dll differ diff --git a/external/tellstick-rfcmd/CMakeLists.txt b/external/tellstick-rfcmd/CMakeLists.txt new file mode 100644 index 00000000..af4b4484 --- /dev/null +++ b/external/tellstick-rfcmd/CMakeLists.txt @@ -0,0 +1,88 @@ +cmake_minimum_required(VERSION 2.4) + +INCLUDE_DIRECTORIES( + /usr/src/linux/include +) + +#### Project: rfcmd #### + +PROJECT(rfcmd) + +SET(rfcmd_DESCRIPTION + "Sends RF remote commands through a Telldus TellStick" +) + +SET(rfcmd_SRCS + rfcmd.c +) + +IF(${RFCMD_DEBUG}) + ADD_DEFINITIONS( -DRFCMD_DEBUG ) +ENDIF(${RFCMD_DEBUG}) + +IF (BUILD_RFCMD_WITH_LIBFTDI) + ADD_DEFINITIONS( -DLIBFTDI ) + + SET(rfcmd_SRCS + ${rfcmd_SRCS} + ftdi.c + ) +ENDIF (BUILD_RFCMD_WITH_LIBFTDI) +ADD_EXECUTABLE(rfcmd + ${rfcmd_SRCS} +) + +IF (BUILD_RFCMD_WITH_SEMAPHORES) + FIND_LIBRARY(SEM_LIBRARY rt) + TARGET_LINK_LIBRARIES(rfcmd + ${SEM_LIBRARY} + ) +ELSE (BUILD_RFCMD_WITH_SEMAPHORES) + ADD_DEFINITIONS( -DNO_SEMAPHORES ) +ENDIF (BUILD_RFCMD_WITH_SEMAPHORES) + + + +IF (BUILD_RFCMD_WITH_LIBFTDI) + FIND_LIBRARY(FTDI_LIBRARY ftdi) + + TARGET_LINK_LIBRARIES(rfcmd + ${FTDI_LIBRARY} + ) +ENDIF (BUILD_RFCMD_WITH_LIBFTDI) + +INSTALL(TARGETS rfcmd RUNTIME DESTINATION bin) + +IF (UNIX) + IF (GENERATE_MAN) + ADD_CUSTOM_COMMAND( + TARGET rfcmd + POST_BUILD + COMMAND help2man -n ${rfcmd_DESCRIPTION} ./rfcmd > rfcmd.1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating man file rfcmd.1" + ) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/rfcmd.1 DESTINATION share/man/man1) + ENDIF (GENERATE_MAN) +ENDIF (UNIX) + +#### Project: find_telldus #### + +IF (BUILD_RFCMD_WITH_LIBFTDI) + PROJECT(find_telldus) + + SET(find_telldus_SRCS + find_telldus.c + ) + + ADD_EXECUTABLE(find_telldus + ${find_telldus_SRCS} + ) + + TARGET_LINK_LIBRARIES(find_telldus + ${FTDI_LIBRARY} + ) + + INSTALL(TARGETS find_telldus RUNTIME DESTINATION bin) + +ENDIF (BUILD_RFCMD_WITH_LIBFTDI) diff --git a/external/tellstick-rfcmd/COPYING b/external/tellstick-rfcmd/COPYING new file mode 100644 index 00000000..60549be5 --- /dev/null +++ b/external/tellstick-rfcmd/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/external/tellstick-rfcmd/Makefile b/external/tellstick-rfcmd/Makefile new file mode 100644 index 00000000..4836075a --- /dev/null +++ b/external/tellstick-rfcmd/Makefile @@ -0,0 +1,22 @@ + +SRCS= rfcmd.c ftdi.c +CFLAGS=-O2 -Wall -I/usr/local/include +LFLAGS= -L/usr/local/lib -R/usr/local/lib +#linux:LFLAGS=-Wl,-rpath,/usr/local/lib +LIBS= -lftdi -lusb +PROG= rfcmd +FT= find_telldus +OBJS= $(SRCS:.c=.o) +CC= gcc + +all: $(PROG) $(FT) + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(PROG) $(LFLAGS) $(LIBS) + +rfcmd.o: rfcmd.c + +ftdi.o: ftdi.c + +$(FT): $(FT).c + $(CC) $(CFLAGS) -o $@ $(FT).c $(LFLAGS) $(LIBS) diff --git a/external/tellstick-rfcmd/build.sh b/external/tellstick-rfcmd/build.sh new file mode 100644 index 00000000..fb5100b9 --- /dev/null +++ b/external/tellstick-rfcmd/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +make clean || { echo "Warning: make clean failed"; } +make || { echo "make failed"; exit 1; } +make install || { echo "make install failed"; exit 1; } +echo rfcmd built and installed! diff --git a/external/tellstick-rfcmd/find_telldus.c b/external/tellstick-rfcmd/find_telldus.c new file mode 100644 index 00000000..5c44915e --- /dev/null +++ b/external/tellstick-rfcmd/find_telldus.c @@ -0,0 +1,42 @@ +/* find_all.c + + Example for ftdi_usb_find_all() + + This program is distributed under the GPL, version 2 +*/ + +#include +#include + +int main(int argc, char **argv) +{ + int ret, i; + struct ftdi_context ftdic; + struct ftdi_device_list *devlist, *curdev; + char manufacturer[128], description[128]; + + ftdi_init(&ftdic); + + if((ret = ftdi_usb_find_all(&ftdic, &devlist, 0x1781, 0x0c30)) < 0) { + fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + + printf("Number of FTDI devices (telldus) found: %d\n", ret); + + i = 0; + for (curdev = devlist; curdev != NULL; i++) { + printf("Checking device: %d\n", i); + if((ret = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0) { + fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + printf("Manufacturer: %s, Description: %s\n\n", manufacturer, description); + curdev = curdev->next; + } + + ftdi_list_free(&devlist); + ftdi_deinit(&ftdic); + + return EXIT_SUCCESS; +} diff --git a/external/tellstick-rfcmd/ftdi.c b/external/tellstick-rfcmd/ftdi.c new file mode 100644 index 00000000..c229f2cb --- /dev/null +++ b/external/tellstick-rfcmd/ftdi.c @@ -0,0 +1,110 @@ +/* + * TellStick libftdi libusb version + * tested with 0.15 : http://www.intra2net.com/en/developer/libftdi + */ + +#include +#include +#include +#include + +#define BAUD 4800 + +void ftdiCleanup(struct ftdi_context *ctx) { + ftdi_usb_close( ctx ); + ftdi_deinit( ctx ); +} + +/* + * use libftdi and libusb to send command + * no kernel driver needed + */ +int usbWriteFtdi(char *cmdstr) +{ + struct ftdi_context ctx; + int device=0x0c30, vendor=0x1781; + int retrycnt; + int retval = 0; + + if (ftdi_init( &ctx )) { + char *err = ftdi_get_error_string(&ctx); + fprintf(stderr, "usb - init error: %s\n", err); + return 1; + } + + retval = ftdi_usb_open(&ctx, vendor, device); + if (retval) { + char *err = ftdi_get_error_string(&ctx); + // FreeBSD says -3 when another rfcmd is running... + // Same on other systems? + if(retval == -3) { + fprintf(stderr, "usb - open error: %s. Is it busy?\n", err); + } else { + fprintf(stderr, "usb - open error: %s\n", err); + } + + ftdi_deinit( &ctx ); + return 2; + } + + if (ftdi_usb_reset( &ctx )) { + char *err = ftdi_get_error_string(&ctx); + fprintf(stderr, "usb - reset error: %s\n", err); + retval = 3; + ftdiCleanup(&ctx); + return retval; + } + + if (ftdi_disable_bitbang( &ctx ) || ftdi_set_baudrate(&ctx, BAUD)) { + char *err = ftdi_get_error_string(&ctx); + fprintf(stderr, "usb - init failed: %s\n", err); + ftdiCleanup(&ctx); + return 4; + } + + retval = ftdi_write_data( &ctx, cmdstr, strlen(cmdstr) ); + if (retval < 0) { + char *err = ftdi_get_error_string(&ctx); + fprintf(stderr, "usb - write failed: %s\n", err); + ftdiCleanup(&ctx); + return 5; + } else if(retval != strlen(cmdstr)) { + fprintf(stderr, "usb - warning: %d bytes written instead of %d\n", + retval, (int)strlen(cmdstr)); + } + + /** + * Wait for Tellstick to be done with cmd, read back until we've received + * a \n indicating end of response. + * Wait max 5000 * 1000uS. + * XXX: Can the tellstick report errors? + */ + retval = 0; + retrycnt = 5000; + while (retrycnt--) { + unsigned char inb; + int bytes; + + bytes = ftdi_read_data(&ctx, &inb, 1); + if (bytes == 0) { + usleep(1000); + } else if (bytes > 0) { + // Done when newline is received + if(inb == '\n') { + ftdiCleanup(&ctx); + return retval; + } + } else { + char *err = ftdi_get_error_string(&ctx); + fprintf(stderr, "usb - read error: %s\n", err); + ftdiCleanup(&ctx); + return 6; + } + } + + // if we get here we failed to readback + fprintf(stderr, "usb - warning: never got newline response, giving up on wait\n"); + return retval; +} + + diff --git a/external/tellstick-rfcmd/rfcmd.c b/external/tellstick-rfcmd/rfcmd.c new file mode 100644 index 00000000..76901da5 --- /dev/null +++ b/external/tellstick-rfcmd/rfcmd.c @@ -0,0 +1,663 @@ +/**************************************************************************** + ** rfcmd.c *********************************************************** + **************************************************************************** + * + * rfcmd - utility to control NEXA and other RF remote receivers through a TellStick + * USB interface + * + * Copyright (C) 2007 Tord Andersson + * + * License: GPL v. 2 + * + * Authors: + * Tord Andersson + * Micke Prag + * Gudmund Berggren + * + * Tapani Rintala / userspace libusb / libftdi - version 02-2009 + */ + +/******************************************************************************* + * Modifications from rfcmd.c ver 0.2 done by Gudmund + * Added support for IKEA + * Note: + * 1. System code + * 2. Level 0 == Off (For dimmers and non dimmers) + * Level 1== 10%. (for dimmers) + * .... + * Level 9 == 90 % (for dimmers) + * Level 10 == 100 % (or ON for non dimmers) + * 3. Command line syntax: + * /usr/local/bin/rfcmd /dev/ttyUSB0 IKEA 0 1 10 1" + * Arg 1: device + * Arg 2: Protocoll + * Arg 3: System code + * Arg 4: Device code + * Arg 5: Level (0=off, 1 = 10%, 2=20%,...9=90%, 10=100%) + * Arg 6: DimStyle (0=instant change, 1=gradually change) + ******************************************************************************/ + +/******************************************************************************* + * Modifications to rfcmd.c ver 2.1.0 done by Tord Andersson + * Introduced semaphore protection to avoid problems with simultaneous port + * access from several processes (typically cron jobs). Note! Need rt lib. + ******************************************************************************/ + +/******************************************************************************* + * Modifications from rfcmd.c ver 2.1.0 done by Leo + * Added support for RISINGSUN + * Note: + * 1. Command line syntax: + * /usr/local/bin/rfcmd /dev/ttyUSB0 RISINGSUN 4 1 0" + * Arg 1: device + * Arg 2: protocol + * Arg 3: code + * Arg 4: device number + * Arg 5: Level (0=off, 1 = on) + ******************************************************************************/ + +/******************************************************************************* + * Modifications from rfcmd.c ver 2.1.0 based on marvelous work by Snakehand + * See http://www.telldus.com/forum/viewtopic.php?t=97&start=63 + * Added support for EVERFLOURISH + * Note: + * 1. Command line syntax: + * /usr/local/bin/rfcmd /dev/ttyUSB0 EVERFLOURISH 1 15 + * Arg 1: device + * Arg 2: protocol + * Arg 3: device number (0..65535) + * Arg 4: Level (0=off, 15=on, 10=learn) + ******************************************************************************/ + +/******************************************************************************* + * Modifications from rfcmd ver 2.1.1 done by Johan Ström + * Default disabled semaphores for FreeBSD. + * Added status readback in ftdi.c, instead of wasting time in sleep. + * + * FreeBSD does not have support in the GENERIC kernel semaphore. + * To enable usage of them, you'll have have the following option in your + * kernel configuration: + * + * options P1003_1B_SEMAPHORES + * + * However, on FreeBSD only libftdi seems to be working (at least on my system), + * since the device is not identified as a ucom device. And as we're accessing it + * via libftdi, libftdi makes sure simultaneous access is impossible. + ******************************************************************************/ + + +#include +#include +#include +#include +#include +#include + +#ifndef NO_SEMAPHORES +#include +#endif + +#define PROG_NAME "rfcmd" +#define PROG_VERSION "2.1.1" +/* #define RFCMD_DEBUG */ + +/* Local function declarations */ +int createNexaString(const char * pHouseStr, const char * pChannelStr, + const char * pOn_offStr, char * pTxStr, int waveman); +int createSartanoString(const char * pChannelStr, const char * pOn_offStr, + char * pTxStr); +int createIkeaString(const char * pSystemStr, const char * pChannelStr, + const char * pLevelStr, const char *pDimStyle, + char * pStrReturn); +int createRisingSunString(const char * pCodeStr, const char* pUnitStr, const char * pOn_offStr, + char * pTxStr); +int createEverFlourishString(const char* pUnitStr, const char * pLevelStr, + char * pTxStr); +void printUsage(void); +void printVersion(void); + +#ifdef LIBFTDI +int usbWriteFtdi(char *cmdstr); +#endif + +int main( int argc, char **argv ) +{ + struct termios tio; + int fd = -1; +#ifndef NO_SEMAPHORES + sem_t * portMutex; + char SEM_NAME[]= "RFCMD_SEM"; /* Semaphore for multiple access ctrl */ +#endif + + + char txStr[100]; + + if( (argc == 6) && (strcmp(*(argv+2), "NEXA") == 0)) { + if (createNexaString(*(argv+3), *(argv+4), *(argv+5), txStr, 0) == 0) { + printUsage(); + exit(1); + } + /* else - a send cmd string was created */ + } else if( (argc == 6) && (strcmp(*(argv+2), "WAVEMAN") == 0)) { + if (createNexaString(*(argv+3),*(argv+4), *(argv+5), txStr, 1) == 0) { + printUsage(); + exit(1); + } + } else if( (argc == 5) && (strcmp(*(argv+2), "SARTANO") == 0)) { + if (createSartanoString(*(argv+3), *(argv+4), txStr) == 0) { + printUsage(); + exit(1); + } + /* else - a send cmd string was created */ + } else if ( (argc == 7) && (strcmp(*(argv+2),"IKEA")==0) ) { + // System, Channel, Level, DimStyle, TXString + if ( createIkeaString(*(argv+3), *(argv+4), *(argv+5), *(argv+6),txStr) == 0 ) { + printUsage(); + exit(1); + } + /* else - a send cmd string was created */ + } else if ( (argc == 6) && (strcmp(*(argv+2),"RISINGSUN")==0) ) { + // Code, Unit, Power + if ( createRisingSunString(*(argv+3), *(argv+4), *(argv+5), txStr) == 0 ) { + printUsage(); + exit(1); + } + /* else - a send cmd string was created */ + } else if ( (argc == 5) && (strcmp(*(argv+2),"EVERFLOURISH")==0) ) { + // Unit, Level + if ( createEverFlourishString(*(argv+3), *(argv+4), txStr) == 0 ) { + printUsage(); + exit(1); + } + /* else - a send cmd string was created */ + } else if ( (argc >= 2) && (strcmp(*(argv+1),"--version")==0) ) { + printVersion(); + exit(1); + } else { /* protocol or parameters not recognized */ + printUsage(); + exit(1); + } + +#ifdef RFCMD_DEBUG + printf("txStr: %s\n", txStr); + +#endif + + if(strlen(txStr) > 0) { +#ifndef NO_SEMAPHORES + /* create the semaphore - will reuse an existing one if it exists */ + portMutex = sem_open(SEM_NAME,O_CREAT,0644,1); + if( portMutex == SEM_FAILED) { + fprintf(stderr, "%s - Error creating port semaphore\n", PROG_NAME); + perror("Semaphore open error"); + sem_unlink(SEM_NAME); + exit(1); + } + + /* lock semaphore to protect port from multiple access */ + if(sem_wait(portMutex) != 0) { + fprintf(stderr, "%s - Error aquiring port semaphore\n", PROG_NAME); + sem_unlink(SEM_NAME); + sem_close(portMutex); + exit(1); + } +#endif + + + if (strcmp(*(argv+1), "LIBUSB") != 0) { + if( 0 > ( fd = open( *(argv+1), O_RDWR ) ) ) { +#ifdef __FreeBSD__ + fprintf(stderr, "%s - Error opening %s; You're on a FreeBSD system, you should probably use LIBUSB.\n", PROG_NAME, *(argv+1)); +#else + fprintf(stderr, "%s - Error opening %s\n", PROG_NAME, *(argv+1)); +#endif +#ifndef NO_SEMAPHORES + if(sem_post(portMutex) != 0) { + fprintf(stderr, "%s - Error releasing port semaphore\n", PROG_NAME); + } + sem_unlink(SEM_NAME); + sem_close(portMutex); +#endif + exit(1); + } + + /* adjust serial port parameters */ + bzero(&tio, sizeof(tio)); /* clear struct for new port settings */ + tio.c_cflag = B4800 | CS8 | CLOCAL | CREAD; /* CREAD not used yet */ + tio.c_iflag = IGNPAR; + tio.c_oflag = 0; + tio.c_ispeed = 4800; + tio.c_ospeed = 4800; + tcflush(fd, TCIFLUSH); + tcsetattr(fd,TCSANOW,&tio); + + write(fd, txStr, strlen(txStr)); + + sleep(1); /* one second sleep to avoid device 'choking' */ + close(fd); /* Modified : Close fd to make a clean exit */ + } else { +#ifdef LIBFTDI + usbWriteFtdi( txStr ); +#else + fprintf(stderr, "%s - Support for libftdi is not compiled in, please recompile rfcmd with support for libftdi\n", PROG_NAME); +#endif + } +#ifndef NO_SEMAPHORES + /* Unlock semaphore */ + if (sem_post(portMutex) != 0) { + fprintf(stderr, "%s - Error releasing port semaphore\n", PROG_NAME); + sem_unlink(SEM_NAME); + sem_close(portMutex); + exit(1); + } else { + sem_unlink(SEM_NAME); + sem_close(portMutex); + } +#endif + } + exit(0); +} + + +int createNexaString(const char * pHouseStr, const char * pChannelStr, + const char * pOn_offStr, char * pTxStr, int waveman) +{ + * pTxStr = '\0'; /* Make sure tx string is empty */ + int houseCode; + int channelCode; + int on_offCode; + int txCode = 0; + const int unknownCode = 0x6; + int bit; + int bitmask = 0x0001; + + houseCode = (int)((* pHouseStr) - 65); /* House 'A'..'P' */ + channelCode = atoi(pChannelStr) - 1; /* Channel 1..16 */ + on_offCode = atoi(pOn_offStr); /* ON/OFF 0..1 */ + +#ifdef RFCMD_DEBUG + printf("House: %d, channel: %d, on_off: %d\n", houseCode, channelCode, on_offCode); +#endif + + /* check converted parameters for validity */ + if((houseCode < 0) || (houseCode > 15) || // House 'A'..'P' + (channelCode < 0) || (channelCode > 15) || + (on_offCode < 0) || (on_offCode > 1)) + { + + } else { + /* b0..b11 txCode where 'X' will be represented by 1 for simplicity. + b0 will be sent first */ + txCode = houseCode; + txCode |= (channelCode << 4); + if (waveman && on_offCode == 0) { + } else { + txCode |= (unknownCode << 8); + txCode |= (on_offCode << 11); + } + + /* convert to send cmd string */ + strcat(pTxStr,"S"); + for(bit=0;bit<12;bit++) + { + if((bitmask & txCode) == 0) { + /* bit timing might need further refinement */ + strcat(pTxStr," ` `"); /* 320 us high, 960 us low, 320 us high, 960 us low */ + /* strcat(pTxStr,"$k$k"); *//* 360 us high, 1070 us low, 360 us high, 1070 us low */ + } else { /* add 'X' (floating bit) */ + strcat(pTxStr," `` "); /* 320 us high, 960 us low, 960 us high, 320 us low */ + /*strcat(pTxStr,"$kk$"); *//* 360 us high, 1070 us low, 1070 us high, 360 us low */ + } + bitmask = bitmask<<1; + } + /* add stop/sync bit and command termination char '+'*/ + strcat(pTxStr," }+"); + /* strcat(pTxStr,"$}+"); */ + } + +#ifdef RFCMD_DEBUG + printf("txCode: %04X\n", txCode); +#endif + + return strlen(pTxStr); +} + +int createSartanoString(const char * pChannelStr, const char * pOn_offStr, + char * pTxStr) +{ + * pTxStr = '\0'; /* Make sure tx string is empty */ + int on_offCode; + int bit; + + on_offCode = atoi(pOn_offStr); /* ON/OFF 0..1 */ + +#ifdef RFCMD_DEBUG + printf("Channel: %s, on_off: %d\n", pChannelStr, on_offCode); +#endif + + /* check converted parameters for validity */ + if((strlen(pChannelStr) != 10) || + (on_offCode < 0) || (on_offCode > 1)) { + } else { + strcat(pTxStr,"S"); + for(bit=0;bit<=9;bit++) + { + if(strncmp(pChannelStr+bit, "1", 1) == 0) { //If it is a "1" + strcat(pTxStr,"$k$k"); + } else { + strcat(pTxStr,"$kk$"); + } + } + if (on_offCode >= 1) + strcat(pTxStr,"$k$k$kk$"); //the "turn on"-code + else + strcat(pTxStr,"$kk$$k$k"); //the "turn off"-code + + /* add stop/sync bit and command termination char '+'*/ + strcat(pTxStr,"$k+"); + } + + return strlen(pTxStr); +} + +int createIkeaString( const char * pSystemStr, const char * pChannelStr, const char * pLevelStr, const char *pDimStyle, char * pStrReturn) +{ + *pStrReturn = '\0'; /* Make sure tx string is empty */ + + const char STARTCODE[] = "STTTTTTª"; + const char TT[] = "TT"; + const char A[] = "ª"; + int systemCode = atoi(pSystemStr) - 1; /* System 1..16 */ + int channelCode = atoi(pChannelStr); /* Channel 1..10 */ + int Level = atoi(pLevelStr); /* off,10,20,..,90,on */ + int DimStyle = atoi(pDimStyle); + int intCode = 0; + int checksum1 = 0; + int checksum2 = 0; + int intFade ; + int i ; + int rawChannelCode = 0; + + /* check converted parameters for validity */ + if ( (channelCode <= 0) || (channelCode > 10) || + (systemCode < 0) || (systemCode > 15) || + (Level < 0) || (Level > 10) || + (DimStyle < 0) || (DimStyle > 1)) + { + return 0; + } + + if (channelCode == 10) { + channelCode = 0; + } + rawChannelCode = (1<<(9-channelCode)); + + strcat(pStrReturn, STARTCODE ) ; //Startcode, always like this; + intCode = (systemCode << 10) | rawChannelCode; + + for ( i = 13; i >= 0; --i) { + if ((intCode>>i) & 1) { + strcat(pStrReturn, TT ); + if (i % 2 == 0) { + checksum2++; + } else { + checksum1++; + } + } else { + strcat(pStrReturn,A); + } + } + + if (checksum1 %2 == 0) { + strcat(pStrReturn, TT ); + } else { + strcat(pStrReturn, A) ; //1st checksum + } + + if (checksum2 %2 == 0) { + strcat(pStrReturn, TT ); + } else { + strcat(pStrReturn, A ) ; //2nd checksum + } + + if (DimStyle == 1) { + intFade = 11 << 4; //Smooth + } else { + intFade = 1 << 4; //Instant + } + + switch ( Level ) + { + case 0 : + intCode = (10 | intFade) ; //Concat level and fade + break; + case 1 : + intCode = (1 | intFade) ; //Concat level and fade + break; + case 2 : + intCode = (2 | intFade) ; //Concat level and fade + break; + case 3 : + intCode = (3 | intFade) ; //Concat level and fade + break; + case 4 : + intCode = (4 | intFade) ; //Concat level and fade + break; + case 5 : + intCode = (5 | intFade) ; //Concat level and fade + break; + case 6 : + intCode = (6 | intFade) ; //Concat level and fade + break; + case 7 : + intCode = (7 | intFade) ; //Concat level and fade + break; + case 8 : + intCode = (8 | intFade) ; //Concat level and fade + break; + case 9 : + intCode = (9 | intFade) ; //Concat level and fade + break; + case 10 : + default : + intCode = (0 | intFade) ; //Concat level and fade + break; + } + + checksum1 = 0; + checksum2 = 0; + + for (i = 0; i < 6; ++i) { + if ((intCode>>i) & 1) { + strcat(pStrReturn, TT); + + if (i % 2 == 0) { + checksum1++; + } else { + checksum2++; + } + } else { + strcat(pStrReturn, A ); + } + } + + if (checksum1 %2 == 0) { + strcat(pStrReturn, TT); + } else { + strcat(pStrReturn, A ) ; //2nd checksum + } + + if (checksum2 %2 == 0) { + strcat(pStrReturn, TT ); + } else { + strcat(pStrReturn, A ) ; //2nd checksum + } + + strcat(pStrReturn, "+"); + + return strlen(pStrReturn); +} + +int createRisingSunString(const char * pCodeStr, const char * pUnitStr, const char * pOn_offStr, + char * pTxStr) +{ + * pTxStr = '\0'; /* Make sure tx string is empty */ + int on_offCode; + int unit; + int code; + int i; + + on_offCode = atoi(pOn_offStr); /* ON/OFF 0..1 */ + code = atoi (pCodeStr); + unit = atoi (pUnitStr); + +#ifdef RFCMD_DEBUG + printf("Code: %s, unit: %s, on_off: %d\n", pCodeStr, pUnitStr, on_offCode); +#endif + + /* check converted parameters for validity */ + if((code < 1) || (code > 4) || + (unit < 1) || (unit > 4) || + (on_offCode < 0) || (on_offCode > 1)) { + } else { + strcat(pTxStr,"S.e"); + for (i = 1; i <= 4; ++i) { + if (i == code) { + strcat (pTxStr, ".e.e"); + } else { + strcat (pTxStr, "e..e"); + } + } + for (i = 1; i <= 4; ++i) { + if (i == unit) { + strcat (pTxStr, ".e.e"); + } else { + strcat (pTxStr, "e..e"); + } + } + + if (on_offCode >= 1) { + strcat(pTxStr,"e..ee..ee..ee..e+"); //the "turn on"-code + } else { + strcat(pTxStr,"e..ee..ee..e.e.e+"); //the "turn off"-code + } + } + + return strlen(pTxStr); +} + +unsigned int everflourish_find_code(unsigned int x) { + unsigned int bits[16] = { 0xf ,0xa ,0x7 ,0xe, + 0xf ,0xd ,0x9 ,0x1, + 0x1 ,0x2 ,0x4 ,0x8, + 0x3 ,0x6 ,0xc ,0xb }; + unsigned int bit = 1; + unsigned int res = 0x5; + int i; + unsigned int lo,hi; + + if ((x&0x3)==3) { + lo = x & 0x00ff; + hi = x & 0xff00; + lo += 4; + if (lo>0x100) lo = 0x12; + x = lo | hi; + } + + for(i=0;i<16;i++) { + if (x&bit) { + res = res ^ bits[i]; + } + bit = bit << 1; + } + + return res; +} + + +int createEverFlourishString(const char * pUnitStr, const char * pLevelStr, + char * pTxStr) +{ + int len = 0; + int level; + int unit; + unsigned int check; + int i; + + unit = atoi(pUnitStr); + level = atoi(pLevelStr); /* ON=15, OFF=0, LEARN=10 */ + check = everflourish_find_code(unit); + +#ifdef RFCMD_DEBUG + printf("unit: %d, level: %d\n", unit, level); +#endif + + /* check converted parameters for validity */ + if((unit < 0) || (unit > 0xffff) || + (level < 0) || (level > 15)) { + } else { + const char ssss = 85; + const char sssl = 84; // 0 + const char slss = 69; // 1 + + const char bits[2] = {sssl,slss}; + int i; + + char preamble[] = {'R', 5, 'T', 114,60,1,1,105,ssss,ssss}; + memcpy(pTxStr, preamble, sizeof(preamble)); + len += sizeof(preamble); + + for(i=15;i>=0;i--) pTxStr[len++]=bits[(unit>>i)&0x01]; + for(i=3;i>=0;i--) pTxStr[len++]=bits[(check>>i)&0x01]; + for(i=3;i>=0;i--) pTxStr[len++]=bits[(level>>i)&0x01]; + + pTxStr[len++] = ssss; + pTxStr[len++] = '+'; + } + + pTxStr[len] = '\0'; + return strlen(pTxStr); +} + +void printUsage(void) +{ + printf("Usage: rfcmd DEVICE PROTOCOL [PROTOCOL_ARGUMENTS] \n"); + printf("\n"); +#ifdef LIBFTDI + printf("\t DEVICE: /dev/ttyUSB[0..n] | LIBUSB\n" ); +#else + printf("\t DEVICE: /dev/ttyUSB[0..n]\n" ); +#endif + printf("\t PROTOCOLS: NEXA, SARTANO, WAVEMAN, IKEA, RISINGSUN, EVERFLOURISH\n" ); + printf("\n"); + printf("\t PROTOCOL ARGUMENTS - NEXA, WAVEMAN:\n"); + printf("\t\tHOUSE_CODE: A..P\n\t\tCHANNEL: 1..16\n\t\tOFF_ON: 0..1\n" ); + printf("\n"); + printf("\t PROTOCOL ARGUMENTS - SARTANO:\n"); + printf("\t\tCHANNEL: 0000000000..1111111111\n\t\tOFF_ON: 0..1\n" ); + printf("\n"); + printf("\t PROTOCOL ARGUMENTS - IKEA:\n"); + printf("\t\tSYSTEM: 1..16\n\t\tDEVICE: 1..10\n"); + printf("\t\tDIM_LEVEL: 0..10\n\t\tDIM_STYLE: 0..1\n" ); + printf("\n"); + printf("\t PROTOCOL ARGUMENTS - RISINGSUN:\n"); + printf("\t\tCODE: 1..4\n\t\tDEVICE: 1..4\n"); + printf("\t\tOFF_ON: 0..1\n" ); + printf("\n"); + printf("\t PROTOCOL ARGUMENTS - EVERFLOURISH:\n"); + printf("\t\tDEVICE: 0..65535\n"); + printf("\t\tLEVEL: 0=off, 10=learn, 15=on\n" ); + printf("\n"); + printf("Report bugs to \n"); +} + +void printVersion(void) { + printf("%s v%s\n", PROG_NAME, PROG_VERSION); + printf("\n"); + printf("Copyright (C) Tord Andersson 2007\n"); + printf("\n"); + printf("Written by:\n"); + printf("Tord Andersson, Micke Prag, Gudmund Berggren, Tapani Rintala\n"); + printf("and Johan Ström\n"); +} + diff --git a/lib/RXTXcomm.jar b/lib/RXTXcomm.jar new file mode 100644 index 00000000..e1e75034 Binary files /dev/null and b/lib/RXTXcomm.jar differ diff --git a/lib/librxtxParallel.so b/lib/librxtxParallel.so new file mode 100644 index 00000000..b2e0c903 Binary files /dev/null and b/lib/librxtxParallel.so differ diff --git a/lib/librxtxSerial.so b/lib/librxtxSerial.so new file mode 100644 index 00000000..a921acca Binary files /dev/null and b/lib/librxtxSerial.so differ diff --git a/lib/rxtxParallel.dll b/lib/rxtxParallel.dll new file mode 100644 index 00000000..92666dd4 Binary files /dev/null and b/lib/rxtxParallel.dll differ diff --git a/lib/rxtxSerial.dll b/lib/rxtxSerial.dll new file mode 100644 index 00000000..211e0068 Binary files /dev/null and b/lib/rxtxSerial.dll differ diff --git a/src/se/koc/hal/plugin/tellstick/TellstickParser.java b/src/se/koc/hal/plugin/tellstick/TellstickParser.java new file mode 100644 index 00000000..0e230971 --- /dev/null +++ b/src/se/koc/hal/plugin/tellstick/TellstickParser.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package se.koc.hal.plugin.tellstick; + +import se.koc.hal.plugin.tellstick.protocols.NexaSelfLearning; +import zutil.converters.Converter; + +import java.util.HashMap; + +/** + * Created by Ziver on 2015-02-18. + */ +public class TellstickParser { + private static HashMap> protocolMap; + + static { + registerProtocol(NexaSelfLearning.class); + } + + + + public void decode(String data) { + if (data.startsWith("+W")) { + data = data.substring(2); + HashMap map = new HashMap(); + String[] parameters = data.split(";"); + for (String parameter : parameters) { + String[] keyValue = parameter.split(":"); + map.put(keyValue[0], keyValue[1]); + } + + Class protClass = + getProtocolClass(map.get("protocol"), map.get("model")); + if (protClass != null) { + try { + TellstickProtocol protocol = protClass.newInstance(); + String binData = map.get("data"); + protocol.decode(Converter.hexToByte(binData)); + System.out.println("Decoded: " + protocol); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + System.out.println("Unknown protocol: " + data); + } + } else if (data.startsWith("+S") || data.startsWith("+T")) { + // This is confirmation of send commands + }else { + System.out.println("Unknown prefix: " + data); + } + } + + + + public static void registerProtocol(Class protClass) { + try { + if (protocolMap == null) + protocolMap = new HashMap>(); + TellstickProtocol tmp = protClass.newInstance(); + protocolMap.put( + tmp.getProtocolName() + "-" + tmp.getModelName(), + protClass); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Class getProtocolClass(String protocol, String model) { + return protocolMap.get(protocol + "-" + model); + } +} diff --git a/src/se/koc/hal/plugin/tellstick/TellstickProtocol.java b/src/se/koc/hal/plugin/tellstick/TellstickProtocol.java new file mode 100644 index 00000000..b8ddb121 --- /dev/null +++ b/src/se/koc/hal/plugin/tellstick/TellstickProtocol.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package se.koc.hal.plugin.tellstick; + +/** + * Created by Ziver on 2015-02-18. + */ +public interface TellstickProtocol { + + public String encode(); + public void decode(byte[] data); + + public String getProtocolName(); + public String getModelName(); +} diff --git a/src/se/koc/hal/plugin/tellstick/TwoWaySerialComm.java b/src/se/koc/hal/plugin/tellstick/TwoWaySerialComm.java new file mode 100644 index 00000000..3ec80320 --- /dev/null +++ b/src/se/koc/hal/plugin/tellstick/TwoWaySerialComm.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package se.koc.hal.plugin.tellstick; + +import gnu.io.CommPort; +import gnu.io.CommPortIdentifier; +import gnu.io.SerialPort; +import se.koc.hal.plugin.tellstick.protocols.NexaSelfLearning; + +import java.io.*; + +/** + * This version of the TwoWaySerialComm example makes use of the + * SerialPortEventListener to avoid polling. + */ +public class TwoWaySerialComm extends Thread{ + private BufferedReader in; + private OutputStream out; + private TellstickParser parser = new TellstickParser(); + + public void connect(String portName) throws Exception { + CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); + if (portIdentifier.isCurrentlyOwned()) { + System.out.println("Error: Port is currently in use"); + } else { + CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); + + if (commPort instanceof SerialPort) { + SerialPort serialPort = (SerialPort) commPort; + serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); + + in = new BufferedReader(new InputStreamReader (serialPort.getInputStream())); + out = new BufferedOutputStream(serialPort.getOutputStream()); + + serialPort.disableReceiveTimeout(); + serialPort.enableReceiveThreshold(1); + this.start(); + + } else { + System.out.println("Error: Only serial ports are handled by this example."); + } + } + } + + public void run() { + try { + String data; + while ((data = in.readLine()) != null) { + System.out.println("> "+data); + parser.decode(data); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void write(TellstickProtocol prot) { + write(prot.encode()); + } + + public void write(String data) { + try { + System.out.println("< "+data); + for(int i=0; i= 0; --i) { + m.append( (house & (1 << i)) == 0 ? "01" : "10" ); + } + // Group + m.append("01"); + + // On or OFF + if (enable) + m.append("10"); + else + m.append("01"); + + // Unit + for (int i = 3; i >= 0; --i) { + m.append( (unit & (1 << i)) == 0 ? "01" : "10" ); + } + + // The number of data is odd add this to make it even + m.append("0"); + //01011001101001011010100110010101010101101001011010 01 01 1001011010 0 + + char code = 9; // b1001, startcode + for (int i = 0; i < m.length(); ++i) { + code <<= 4; + if (m.charAt(i) == '1') { + code |= 0x08; // b1000 + } else { + code |= 0x0A; // b1010 + } + if (i % 2 == 0) { + enc.append(code); + code = 0x00; + } + } + + + enc.append("+"); + return enc.toString(); + } + + public void decode(byte[] data){ + // Data positions + // house = 0xFFFFFFC0 + // group = 0x00000020 + // method = 0x00000010 + // unit = 0x0000000F + // ----------------h------------ g m --u- + // 0x2CE81990 - 00101100_11101000_00011001_10 0 1 0000 - ON + // 0x2CE81980 - 00101100_11101000_00011001_10 0 0 0000 - OFF + + house = 0; + house |= (data[3] & 0xFF) << 18; + house |= (data[2] & 0xFF) << 10; + house |= (data[1] & 0xFF) << 2; + house |= (data[0] & 0xC0) >>> 6; + + group = data[0] & 0x20; + group >>>= 5; + + enable = (data[0] & 0x10) != 0; + + unit = data[0] & 0x0F; + unit++; + } + + + public int getHouse() { + return house; + } + public void setHouse(int house) { + this.house = house; + } + public int getGroup() { + return group; + } + public void setGroup(int group) { + this.group = group; + } + public int getUnit() { + return unit; + } + public void setUnit(int unit) { + this.unit = unit; + } + public boolean isEnabled() { + return enable; + } + public void setEnable(boolean enable) { + this.enable = enable; + } + + + @Override + public String getProtocolName() { + return "arctech"; + } + + @Override + public String getModelName() { + return "selflearning"; + } + + + public String toString(){ + return "class:command;protocol:arctech;model:selflearning;" + + "house:"+house+ + ";group:"+group+ + ";unit:"+unit+ + ";method:"+enable; + } +} diff --git a/test/se/koc/hal/plugin/tellstick/protocols/NexaSelfLearningTest.java b/test/se/koc/hal/plugin/tellstick/protocols/NexaSelfLearningTest.java new file mode 100644 index 00000000..daf7d948 --- /dev/null +++ b/test/se/koc/hal/plugin/tellstick/protocols/NexaSelfLearningTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package se.koc.hal.plugin.tellstick.protocols; + +import se.koc.hal.plugin.tellstick.protocols.NexaSelfLearning; +import zutil.converters.Converter; + +import static org.junit.Assert.*; + +public class NexaSelfLearningTest { + + @org.junit.Test + public void testEncode() throws Exception { + NexaSelfLearning nexa = new NexaSelfLearning(); + nexa.setHouse(11772006); + nexa.setUnit(3); + nexa.setEnable(true); + + assertArrayEquals( + new char[]{ + 84, 127, 255, 24, 1, 132, 154, 138, 136, 170, + 136, 168, 170, 138, 136, 168, 168, 170, 136, 170, + 138, 138, 138, 138, 138, 136, 168, 170, 138, 136, + 168, 170, 138, 136, 170, 138, 136, 168, 170, 43}, + nexa.encode().toCharArray() + ); + } + + + @org.junit.Test + public void decode_ON() throws Exception { + NexaSelfLearning nexa = new NexaSelfLearning(); + nexa.decode(Converter.hexToByte("0x2CE81990")); + + assertEquals("House Code", 11772006, nexa.getHouse()); + assertEquals("Unit Code", 1, nexa.getUnit()); + assertTrue("Enabled", nexa.isEnabled()); + } + @org.junit.Test + public void decode_OFF() throws Exception { + NexaSelfLearning nexa = new NexaSelfLearning(); + nexa.decode(Converter.hexToByte("0x2CE81980")); + + assertEquals("House Code", 11772006, nexa.getHouse()); + assertEquals("Unit Code", 1, nexa.getUnit()); + assertFalse("Enabled", nexa.isEnabled()); + } +} \ No newline at end of file