rfcmd v0.3 with support for IKEA. Thanks to Gudmund Berggren!
This commit is contained in:
parent
a5b6430a14
commit
9b2c653fcd
1 changed files with 243 additions and 38 deletions
225
rfcmd/rfcmd.c
225
rfcmd/rfcmd.c
|
@ -9,8 +9,32 @@
|
||||||
*
|
*
|
||||||
* License: GPL v. 2
|
* License: GPL v. 2
|
||||||
*
|
*
|
||||||
|
* Authors:
|
||||||
|
* Tord Andersson <tord.o.andersson@gmail.com>
|
||||||
|
* Micke Prag <micke.prag@telldus.se>
|
||||||
|
* Gudmund Berggren
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -19,7 +43,7 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#define PROG_NAME "rfcmd"
|
#define PROG_NAME "rfcmd"
|
||||||
#define PROG_VERSION "0.2"
|
#define PROG_VERSION "0.3"
|
||||||
/* #define RFCMD_DEBUG */
|
/* #define RFCMD_DEBUG */
|
||||||
|
|
||||||
/* Local function declarations */
|
/* Local function declarations */
|
||||||
|
@ -27,6 +51,9 @@ int createNexaString(const char * pHouseStr, const char * pChannelStr,
|
||||||
const char * pOn_offStr, char * pTxStr, int waveman);
|
const char * pOn_offStr, char * pTxStr, int waveman);
|
||||||
int createSartanoString(const char * pChannelStr, const char * pOn_offStr,
|
int createSartanoString(const char * pChannelStr, const char * pOn_offStr,
|
||||||
char * pTxStr);
|
char * pTxStr);
|
||||||
|
int createIkeaString(const char * pSystemStr, const char * pChannelStr,
|
||||||
|
const char * pLevelStr, const char *pDimStyle,
|
||||||
|
char * pStrReturn);
|
||||||
|
|
||||||
void printUsage(void);
|
void printUsage(void);
|
||||||
|
|
||||||
|
@ -34,13 +61,10 @@ int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
char txStr[250];
|
char txStr[100];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( (argc == 6) && (strcmp(*(argv+2), "NEXA") == 0))
|
if( (argc == 6) && (strcmp(*(argv+2), "NEXA") == 0))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (createNexaString(*(argv+3), *(argv+4), *(argv+5), txStr, 0) == 0)
|
if (createNexaString(*(argv+3), *(argv+4), *(argv+5), txStr, 0) == 0)
|
||||||
{
|
{
|
||||||
printUsage();
|
printUsage();
|
||||||
|
@ -58,7 +82,6 @@ int main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
else if( (argc == 5) && (strcmp(*(argv+2), "SARTANO") == 0))
|
else if( (argc == 5) && (strcmp(*(argv+2), "SARTANO") == 0))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (createSartanoString(*(argv+3), *(argv+4), txStr) == 0)
|
if (createSartanoString(*(argv+3), *(argv+4), txStr) == 0)
|
||||||
{
|
{
|
||||||
printUsage();
|
printUsage();
|
||||||
|
@ -66,13 +89,22 @@ int main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
/* else - a send cmd string was created */
|
/* 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 /* protocol or parameters not recognized */
|
else /* protocol or parameters not recognized */
|
||||||
{
|
{
|
||||||
printUsage();
|
printUsage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef RFCMD_DEBUG
|
#ifdef RFCMD_DEBUG
|
||||||
printf("txStr: %s\n", txStr);
|
printf("txStr: %s\n", txStr);
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,7 +115,6 @@ int main( int argc, char **argv )
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(strlen(txStr) > 0)
|
if(strlen(txStr) > 0)
|
||||||
{
|
{
|
||||||
/* adjust serial port parameters */
|
/* adjust serial port parameters */
|
||||||
|
@ -95,7 +126,9 @@ int main( int argc, char **argv )
|
||||||
tcsetattr(fd,TCSANOW,&tio);
|
tcsetattr(fd,TCSANOW,&tio);
|
||||||
|
|
||||||
write(fd, txStr, strlen(txStr));
|
write(fd, txStr, strlen(txStr));
|
||||||
|
|
||||||
sleep(1); /* one second sleep to avoid device 'choking' */
|
sleep(1); /* one second sleep to avoid device 'choking' */
|
||||||
|
close(fd); /* Modified : Close fd to make a clean exit */
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -219,15 +252,187 @@ int createSartanoString(const char * pChannelStr, const char * pOn_offStr,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printUsage(void)
|
void printUsage(void)
|
||||||
{
|
{
|
||||||
printf("%s %s - Send RF remote commands\n", PROG_NAME, PROG_VERSION);
|
printf("%s v%s - Send RF remote commands\n", PROG_NAME, PROG_VERSION);
|
||||||
printf("Usage: rfcmd DEVICE PROTOCOL [PROTOCOL_ARGUMENTS] \n");
|
printf("Usage: rfcmd DEVICE PROTOCOL [PROTOCOL_ARGUMENTS] \n");
|
||||||
printf("\t DEVICE: /dev/ttyUSB[0..n]\n" );
|
printf("\t DEVICE: /dev/ttyUSB[0..n]\n" );
|
||||||
printf("\t PROTOCOLS: NEXA, SARTANO, WAVEMAN\n" );
|
printf("\t PROTOCOLS: NEXA, SARTANO, WAVEMAN, IKEA\n" );
|
||||||
printf("\t PROTOCOL ARGUMENTS - NEXA, WAVEMAN:\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("\t\tHOUSE_CODE: A..P\n\t\tCHANNEL: 1..16\n\t\tOFF_ON: 0..1\n" );
|
||||||
printf("\t PROTOCOL ARGUMENTS - SARTANO:\n");
|
printf("\t PROTOCOL ARGUMENTS - SARTANO:\n");
|
||||||
printf("\t\tCHANNEL: 0000000000..1111111111\n\t\tOFF_ON: 0..1\n" );
|
printf("\t\tCHANNEL: 0000000000..1111111111\n\t\tOFF_ON: 0..1\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("Copyright(C) Tord Andersson 2007\r\n");
|
printf("Copyright(C) Tord Andersson 2007\r\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue