Receiving protocols decode according to new standard

This commit is contained in:
Stefan Persson 2011-05-12 14:09:37 +00:00
parent 4d2b80ae11
commit 281621a4ef
10 changed files with 286 additions and 16 deletions

View file

@ -1,6 +1,7 @@
#include "Protocol.h"
#include "../client/telldus-core.h"
#include "ControllerMessage.h"
#include "ProtocolBrateck.h"
#include "ProtocolComen.h"
#include "ProtocolEverflourish.h"
@ -196,21 +197,31 @@ std::list<std::string> Protocol::getParametersForProtocol(const std::wstring &pr
return parameters;
}
std::list<std::string> Protocol::decodeData(const std::wstring &protocolName, const std::string &data) {
std::list<std::string> Protocol::decodeData(const std::string &fullData) {
std::list<std::string> retval;
std::string decoded = "";
if( protocolName.compare(L"everflourish") == 0 ) {
decoded = ProtocolEverflourish::decodeData(data);
ControllerMessage dataMsg(fullData);
if( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) {
decoded = ProtocolNexa::decodeData(dataMsg);
if (decoded != "") {
retval.push_back(decoded);
}
} else if( protocolName.compare(L"x10") == 0 ) {
decoded = ProtocolX10::decodeData(data);
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);
}
}
return retval;
}

View file

@ -18,7 +18,7 @@ public:
static Protocol *getProtocolInstance(const std::wstring &protocolname);
static std::list<std::string> getParametersForProtocol(const std::wstring &protocolName);
static std::list<std::string> decodeData(const std::wstring &protocolname, const std::string &data);
static std::list<std::string> decodeData(const std::string &fullData);
virtual int methods() const = 0;
std::wstring model() const;

View file

@ -1,6 +1,7 @@
#include "ProtocolEverflourish.h"
#include <stdio.h>
#include <sstream>
#include <stdio.h>
#include "ControllerMessage.h"
int ProtocolEverflourish::methods() const {
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN;
@ -86,8 +87,9 @@ unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) {
return res;
}
std::string ProtocolEverflourish::decodeData(const std::string& data)
std::string ProtocolEverflourish::decodeData(ControllerMessage &dataMsg)
{
std::string data = dataMsg.getParameter("data");
unsigned int allData;
unsigned int house = 0;
unsigned int unit = 0;
@ -100,11 +102,17 @@ std::string ProtocolEverflourish::decodeData(const std::string& data)
unit = allData & 0x300;
unit >>= 8;
unit++; //unit from 1 to 4
method = allData & 0xF;
if(house < 0 || house > 16383 || unit < 1 || unit > 4){
//not everflourish
return "";
}
std::stringstream retString;
retString << "class:command;protocol:everflourish;model:selflearning;house:0x" << std::hex << house << std::dec << ";unit:0x" << std::hex << unit << std::dec << ";method:";
retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:";
if(method == 0){
retString << "turnoff;";
}

View file

@ -1,6 +1,7 @@
#ifndef PROTOCOLEVERFLOURISH_H
#define PROTOCOLEVERFLOURISH_H
#include "ControllerMessage.h"
#include "Protocol.h"
class ProtocolEverflourish : public Protocol
@ -8,7 +9,7 @@ class ProtocolEverflourish : public Protocol
public:
int methods() const;
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
static std::string decodeData(const std::string &data);
static std::string decodeData(ControllerMessage &dataMsg);
private:
static unsigned int calculateChecksum(unsigned int x);

View file

@ -1,7 +1,11 @@
#include "ProtocolNexa.h"
#include <sstream>
#include <stdio.h>
#include "TellStick.h"
#include "Strings.h"
int ProtocolNexa::lastArctecCodeSwitchWasTurnOff=0; //TODO, 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);
@ -153,6 +157,113 @@ std::string ProtocolNexa::getStringSelflearningForCode(int intHouse, int intCode
return strMessage;
}
std::string ProtocolNexa::decodeData(ControllerMessage& dataMsg)
{
unsigned long allData = 0;
sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData);
if(dataMsg.getParameter("model") == "selflearning"){
//selflearning
return decodeDataSelfLearning(allData);
}
else{
//codeswitch
return decodeDataCodeSwitch(allData);
}
}
std::string ProtocolNexa::decodeDataSelfLearning(long 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(long 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 < 0 || 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:" << char(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 ) {

View file

@ -1,6 +1,7 @@
#ifndef PROTOCOLNEXA_H
#define PROTOCOLNEXA_H
#include "ControllerMessage.h"
#include "Device.h"
#include <string>
@ -8,6 +9,7 @@ class ProtocolNexa : public Protocol {
public:
virtual int methods() const;
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
static std::string decodeData(ControllerMessage& dataMsg);
protected:
std::string getStringSelflearning(int method, unsigned char data);
@ -16,6 +18,11 @@ protected:
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(long allData);
static std::string decodeDataSelfLearning(long allData);
};
#endif //PROTOCOLNEXA_H

View file

@ -1,4 +1,6 @@
#include "ProtocolSartano.h"
#include <sstream>
#include <stdio.h>
int ProtocolSartano::methods() const {
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
@ -32,3 +34,71 @@ std::string ProtocolSartano::getStringForCode(const std::wstring &strCode, int m
return strReturn;
}
std::string ProtocolSartano::decodeData(ControllerMessage &dataMsg)
{
std::string data = dataMsg.getParameter("data");
signed int allDataIn;
signed int allData = 0;
unsigned int code = 0;
unsigned int method1 = 0;
unsigned int method2 = 0;
unsigned int method = 0;
sscanf(data.c_str(), "%X", &allDataIn);
unsigned long mask = 0b100000000000;
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 < 0 || code > 1023){
//not sartano
return "";
}
std::stringstream retString;
retString << "class:command;protocol:sartano;model:codeswitch;code:";
mask = 0b1000000000;
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();
}

View file

@ -1,6 +1,7 @@
#ifndef PROTOCOLSARTANO_H
#define PROTOCOLSARTANO_H
#include "ControllerMessage.h"
#include "Protocol.h"
class ProtocolSartano : public Protocol
@ -8,6 +9,7 @@ class ProtocolSartano : public Protocol
public:
int methods() const;
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
static std::string decodeData(ControllerMessage &dataMsg);
protected:
std::string getStringForCode(const std::wstring &code, int method);

View file

@ -1,4 +1,8 @@
#include "ProtocolWaveman.h"
#include <sstream>
#include <stdio.h>
int ProtocolWaveman::lastArctecCodeSwitchWasTurnOff=0;
int ProtocolWaveman::methods() const {
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
@ -6,8 +10,60 @@ int ProtocolWaveman::methods() const {
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::getOffCode() const {
return "$k$k$k$k$k$k$k$k$k+";
}
std::string ProtocolWaveman::decodeData(ControllerMessage& dataMsg)
{
unsigned long allData = 0;
unsigned int house = 0;
unsigned int unit = 0;
unsigned int method = 0;
sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData);
method = allData & 0xF00;
method >>= 8;
unit = allData & 0xF0;
unit >>= 4;
unit++;
house = allData & 0xF;
if(house < 0 || 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:" << char(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();
}

View file

@ -7,9 +7,13 @@ class ProtocolWaveman : public ProtocolNexa {
public:
int methods() const;
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
static std::string decodeData(ControllerMessage& dataMsg);
protected:
virtual std::string getOffCode() const;
private:
static int lastArctecCodeSwitchWasTurnOff;
};
#endif //PROTOCOLWAVEMAN_H