Changeset 9b2c65


Ignore:
Timestamp:
06/22/08 12:48:17 (5 years ago)
Author:
Micke Prag <micke.prag@…>
Branches:
('master', '668dd99ac278cfd419d67879b141678facea630a')('windows_service_fixes', 'df6bd2788365991d36d5af2a75833b8de2a5860f')
Children:
3ea649d16ed94ec53afca1c74e041d72503df2bd
Parents:
a5b6430a14834e8d96b9f6a09e554bee4c6dc53c
git-author:
Micke Prag <micke.prag@telldus.se>2008-06-22 10:48:17+00:00
git-committer:
Micke Prag <micke.prag@telldus.se>2008-06-22 10:48:17+00:00
Message:

rfcmd v0.3 with support for IKEA. Thanks to Gudmund Berggren!

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rfcmd/rfcmd.c

    rcff8a1 r9b2c65  
    33 **************************************************************************** 
    44 * 
    5  * rfcmd - utility to control NEXA and other RF remote receivers through a TellStick  
     5 * rfcmd - utility to control NEXA and other RF remote receivers through a TellStick 
    66   USB interface 
    77 * 
     
    1010 * License: GPL v. 2 
    1111 * 
    12  */  
     12 * Authors: 
     13 *   Tord Andersson <tord.o.andersson@gmail.com> 
     14 *   Micke Prag <micke.prag@telldus.se> 
     15 *   Gudmund Berggren 
     16 */ 
     17 
     18/******************************************************************************* 
     19 * Modifications from rfcmd.c ver 0.2 done by Gudmund 
     20 *  Added support for IKEA 
     21 * Note: 
     22 * 1. System code 
     23 * 2. Level 0 == Off (For dimmers and non dimmers) 
     24 *    Level 1== 10%. (for dimmers) 
     25 *     .... 
     26 *    Level 9 == 90 % (for dimmers) 
     27 *    Level 10 == 100 %  (or ON for non dimmers) 
     28 * 3. Command line syntax: 
     29 *    /usr/local/bin/rfcmd  /dev/ttyUSB0  IKEA 0 1 10 1" 
     30 *    Arg 1: device 
     31 *    Arg 2: Protocoll 
     32 *    Arg 3: System code 
     33 *    Arg 4: Device code 
     34 *    Arg 5: Level (0=off, 1 = 10%, 2=20%,...9=90%, 10=100%) 
     35 *    Arg 6: DimStyle (0=instant change, 1=gradually change) 
     36 ******************************************************************************/ 
    1337 
    1438#include <stdio.h> 
     
    2044 
    2145#define PROG_NAME "rfcmd" 
    22 #define PROG_VERSION "0.2" 
     46#define PROG_VERSION "0.3" 
    2347/* #define RFCMD_DEBUG */ 
    2448 
    2549/* Local function declarations */ 
    26 int createNexaString(const char * pHouseStr, const char * pChannelStr,  
    27         const char * pOn_offStr, char * pTxStr, int waveman); 
    28 int createSartanoString(const char * pChannelStr, const char * pOn_offStr,       
    29         char * pTxStr); 
     50int createNexaString(const char * pHouseStr, const char * pChannelStr, 
     51                     const char * pOn_offStr, char * pTxStr, int waveman); 
     52int createSartanoString(const char * pChannelStr, const char * pOn_offStr, 
     53                        char * pTxStr); 
     54int createIkeaString(const char * pSystemStr, const char * pChannelStr, 
     55                     const char * pLevelStr, const char *pDimStyle, 
     56                     char * pStrReturn); 
    3057 
    3158void printUsage(void); 
     
    3562        struct termios tio; 
    3663        int fd = -1; 
    37         char txStr[250]; 
    38  
    39  
     64        char txStr[100]; 
    4065 
    4166        if( (argc == 6) && (strcmp(*(argv+2), "NEXA") == 0)) 
    4267        { 
    43  
    4468                if (createNexaString(*(argv+3), *(argv+4), *(argv+5), txStr, 0) == 0) 
    4569                { 
     
    5983        else if( (argc == 5) && (strcmp(*(argv+2), "SARTANO") == 0)) 
    6084        { 
    61  
    6285                if (createSartanoString(*(argv+3), *(argv+4), txStr) == 0) 
    6386                { 
     
    6790                /* else - a send cmd string was created */ 
    6891        } 
     92        else if ( (argc == 7) && (strcmp(*(argv+2),"IKEA")==0) ) 
     93        { 
     94                //                    System,   Channel,    Level,    DimStyle, TXString 
     95                if ( createIkeaString(*(argv+3), *(argv+4), *(argv+5), *(argv+6),txStr) == 0 ) 
     96                { 
     97                        printUsage(); 
     98                        exit(1); 
     99                } 
     100                /* else - a send cmd string was created */ 
     101        } 
    69102        else /* protocol or parameters not recognized */ 
    70103        { 
     
    72105                exit(1); 
    73106        } 
    74  
    75107 
    76108#ifdef RFCMD_DEBUG 
     
    84116        } 
    85117 
    86  
    87118        if(strlen(txStr) > 0) 
    88119        { 
    89120                /* adjust serial port parameters */ 
    90121                bzero(&tio, sizeof(tio)); /* clear struct for new port settings */ 
    91                 tio.c_cflag = B4800 | CS8 | CLOCAL | CREAD; /* CREAD not used yet */ 
     122                tio.c_cflag = B4800 | CS8 | CLOCAL | CREAD; /* CREAD not used yet */ 
    92123                tio.c_iflag = IGNPAR; 
    93124                tio.c_oflag = 0; 
     
    96127 
    97128                write(fd, txStr, strlen(txStr)); 
    98                 sleep(1); /* one second sleep to avoid device 'choking' */ 
     129 
     130                sleep(1); /* one second sleep to avoid          device 'choking' */ 
     131                close(fd); /* Modified : Close fd to make a clean exit */ 
    99132        } 
    100133        exit(0); 
     
    102135 
    103136 
    104 int createNexaString(const char * pHouseStr, const char * pChannelStr,  
    105         const char * pOn_offStr, char * pTxStr, int waveman) 
     137int createNexaString(const char * pHouseStr, const char * pChannelStr, 
     138                     const char * pOn_offStr, char * pTxStr, int waveman) 
    106139{ 
    107         * pTxStr = '\0'; /* Make sure tx string is empty */  
     140        * pTxStr = '\0'; /* Make sure tx string is empty */ 
    108141        int houseCode; 
    109142        int channelCode; 
     
    131164        else 
    132165        { 
    133                 /* b0..b11 txCode where 'X' will be represented by 1 for simplicity.  
    134                 b0 will be sent first */  
     166                /* b0..b11 txCode where 'X' will be represented by 1 for simplicity. 
     167                   b0 will be sent first */ 
    135168                txCode = houseCode; 
    136169                txCode |= (channelCode <<  4); 
     
    138171                } else { 
    139172                        txCode |= (unknownCode <<  8); 
    140                         txCode |= (on_offCode  << 11);  
    141                 } 
    142                  
     173                        txCode |= (on_offCode  << 11); 
     174                } 
     175 
    143176                /* convert to send cmd string */ 
    144                 strcat(pTxStr,"S");      
     177                strcat(pTxStr,"S"); 
    145178                for(bit=0;bit<12;bit++) 
    146179                { 
     
    159192                } 
    160193                /* add stop/sync bit and command termination char '+'*/ 
    161                 strcat(pTxStr," }+");    
     194                strcat(pTxStr," }+"); 
    162195                /* strcat(pTxStr,"$}+"); */ 
    163196        } 
     
    170203} 
    171204 
    172 int createSartanoString(const char * pChannelStr, const char * pOn_offStr,       
    173         char * pTxStr) 
     205int createSartanoString(const char * pChannelStr, const char * pOn_offStr, 
     206                        char * pTxStr) 
    174207{ 
    175         * pTxStr = '\0'; /* Make sure tx string is empty */  
     208        * pTxStr = '\0'; /* Make sure tx string is empty */ 
    176209        int on_offCode; 
    177210        int bit; 
     
    191224        else 
    192225        { 
    193                 strcat(pTxStr,"S");      
     226                strcat(pTxStr,"S"); 
    194227                for(bit=0;bit<=9;bit++) 
    195228                { 
     
    207240                else 
    208241                        strcat(pTxStr,"$kk$$k$k"); //the "turn off"-code 
    209                  
     242 
    210243                /* add stop/sync bit and command termination char '+'*/ 
    211                 strcat(pTxStr,"$k+");    
     244                strcat(pTxStr,"$k+"); 
    212245        } 
    213246 
     
    217250 
    218251        return strlen(pTxStr); 
    219          
     252 
    220253} 
     254 
     255int createIkeaString( const char * pSystemStr, const char * pChannelStr, const char * pLevelStr, const char *pDimStyle, char * pStrReturn) 
     256{ 
     257        *pStrReturn = '\0'; /* Make sure tx string is empty */ 
     258 
     259        const char STARTCODE[] = "STTTTTTª"; 
     260        const char TT[]  = "TT"; 
     261        const char A[]   = "ª"; 
     262        int systemCode   = atoi(pSystemStr) - 1;   /* System 1..16 */ 
     263        int channelCode  = atoi(pChannelStr);  /* Channel 1..10 */ 
     264        int Level        = atoi(pLevelStr);     /* off,10,20,..,90,on */ 
     265        int DimStyle     = atoi(pDimStyle); 
     266        int intCode      = 0; 
     267        int checksum1    = 0; 
     268        int checksum2    = 0; 
     269        int intFade ; 
     270        int i ; 
     271        int rawChannelCode = 0; 
     272 
     273        /* check converted parameters for validity */ 
     274        if ( (channelCode <= 0) || (channelCode > 10) || 
     275             (systemCode < 0) || (systemCode > 15) || 
     276             (Level < 0) || (Level > 10) || 
     277             (DimStyle < 0) || (DimStyle > 1)) 
     278        { 
     279                return 0; 
     280        } 
     281 
     282        if (channelCode == 10) 
     283        { 
     284                channelCode = 0; 
     285        } 
     286        rawChannelCode = (1<<(9-channelCode)); 
     287 
     288        strcat(pStrReturn, STARTCODE ) ; //Startcode, always like this; 
     289        intCode = (systemCode << 10) | rawChannelCode; 
     290 
     291        for ( i = 13; i >= 0; --i) 
     292        { 
     293                if ((intCode>>i) & 1) 
     294                { 
     295                        strcat(pStrReturn, TT ); 
     296                        if (i % 2 == 0) 
     297                        { 
     298                                checksum2++; 
     299                        } 
     300                        else 
     301                        { 
     302                                checksum1++; 
     303                        } 
     304                } 
     305                else 
     306                { 
     307                        strcat(pStrReturn,A); 
     308                } 
     309        } 
     310 
     311        if (checksum1 %2 == 0) 
     312        { 
     313                strcat(pStrReturn, TT ); 
     314        } 
     315        else 
     316        { 
     317                strcat(pStrReturn, A) ; //1st checksum 
     318        } 
     319 
     320        if (checksum2 %2 == 0) 
     321        { 
     322                strcat(pStrReturn, TT ); 
     323        } 
     324        else 
     325        { 
     326                strcat(pStrReturn, A ) ; //2nd checksum 
     327        } 
     328 
     329        if (DimStyle == 1) 
     330        { 
     331                intFade = 11 << 4; //Smooth 
     332        } 
     333        else 
     334        { 
     335                intFade = 1 << 4; //Instant 
     336        } 
     337 
     338        switch ( Level ) 
     339        { 
     340                case 0 : 
     341                        intCode = (10 | intFade) ; //Concat level and fade 
     342                        break; 
     343                case 1 : 
     344                        intCode = (1 | intFade) ; //Concat level and fade 
     345                        break; 
     346                case 2 : 
     347                        intCode = (2 | intFade) ; //Concat level and fade 
     348                        break; 
     349                case 3 : 
     350                        intCode = (3 | intFade) ; //Concat level and fade 
     351                        break; 
     352                case 4 : 
     353                        intCode = (4 | intFade) ; //Concat level and fade 
     354                        break; 
     355                case 5 : 
     356                        intCode = (5 | intFade) ; //Concat level and fade 
     357                        break; 
     358                case 6 : 
     359                        intCode = (6 | intFade) ; //Concat level and fade 
     360                        break; 
     361                case 7 : 
     362                        intCode = (7 | intFade) ; //Concat level and fade 
     363                        break; 
     364                case 8 : 
     365                        intCode = (8 | intFade) ; //Concat level and fade 
     366                        break; 
     367                case 9 : 
     368                        intCode = (9 | intFade) ; //Concat level and fade 
     369                        break; 
     370                case 10 : 
     371                default : 
     372                        intCode = (0 | intFade) ; //Concat level and fade 
     373                        break; 
     374        } 
     375 
     376        checksum1 = 0; 
     377        checksum2 = 0; 
     378 
     379        for (i = 0; i < 6; ++i) 
     380        { 
     381                if ((intCode>>i) & 1) 
     382                { 
     383                        strcat(pStrReturn, TT); 
     384 
     385                        if (i % 2 == 0) 
     386                        { 
     387                                checksum1++; 
     388                        } 
     389                        else 
     390                        { 
     391                                checksum2++; 
     392                        } 
     393                } 
     394                else 
     395                { 
     396                        strcat(pStrReturn, A ); 
     397                } 
     398        } 
     399 
     400        if (checksum1 %2 == 0) 
     401        { 
     402                strcat(pStrReturn, TT); 
     403        } 
     404        else 
     405        { 
     406                strcat(pStrReturn, A ) ; //2nd checksum 
     407        } 
     408 
     409        if (checksum2 %2 == 0) 
     410        { 
     411                strcat(pStrReturn, TT ); 
     412        } 
     413        else 
     414        { 
     415                strcat(pStrReturn, A ) ; //2nd checksum 
     416        } 
     417 
     418        strcat(pStrReturn, "+"); 
     419 
     420        return strlen(pStrReturn); 
     421} 
     422 
    221423 
    222424void printUsage(void) 
    223425{ 
    224         printf("%s %s - Send RF remote commands\n", PROG_NAME, PROG_VERSION); 
     426        printf("%s v%s - Send RF remote commands\n", PROG_NAME, PROG_VERSION); 
    225427        printf("Usage: rfcmd DEVICE PROTOCOL [PROTOCOL_ARGUMENTS] \n"); 
    226428        printf("\t DEVICE: /dev/ttyUSB[0..n]\n" ); 
    227         printf("\t PROTOCOLS: NEXA, SARTANO, WAVEMAN\n" ); 
    228         printf("\t PROTOCOL ARGUMENTS - NEXA, WAVEMAN: \n"); 
    229         printf("\t\t HOUSE_CODE: A..P\n\t\t CHANNEL: 1..16\n\t\t OFF_ON: 0..1\n" ); 
    230         printf("\t PROTOCOL ARGUMENTS - SARTANO: \n"); 
    231         printf("\t\t CHANNEL: 0000000000..1111111111\n\t\t OFF_ON: 0..1\n" ); 
     429        printf("\t PROTOCOLS: NEXA, SARTANO, WAVEMAN, IKEA\n" ); 
     430        printf("\t PROTOCOL ARGUMENTS - NEXA, WAVEMAN:\n"); 
     431        printf("\t\tHOUSE_CODE: A..P\n\t\tCHANNEL: 1..16\n\t\tOFF_ON: 0..1\n" ); 
     432        printf("\t PROTOCOL ARGUMENTS - SARTANO:\n"); 
     433        printf("\t\tCHANNEL: 0000000000..1111111111\n\t\tOFF_ON: 0..1\n" ); 
     434        printf("\t PROTOCOL ARGUMENTS - IKEA:\n"); 
     435        printf("\t\tSYSTEM: 1..16\n\t\tDEVICE: 1..10\n"); 
     436        printf("\t\tDIM_LEVEL: 0..10\n\t\tDIM_STYLE: 0..1\n" ); 
    232437        printf("Copyright(C) Tord Andersson 2007\r\n"); 
    233438} 
Note: See TracChangeset for help on using the changeset viewer.