Changes in / [1:3]


Ignore:
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • /D_RFXCOM.json

    r1 r3  
    106106                    }  
    107107                }, 
    108                  { 
     108                  { 
    109109                      "ControlType": "label", 
    110110                      "Label": { 
     
    151151                          ]  
    152152                      }  
    153                   }                 
     153                  }              
    154154            ]              
    155155        }, 
  • /I_RFXCOM.xml

    r1 r3  
    55  </settings> 
    66  <functions> 
     7     
    78    local RFX_SERVICE = "urn:upnp-esweb-nl:serviceId:rfxcom1" 
    89    socket = require("socket") 
    9       bitw = require("bit") 
    10       startupReady = 0 
    11       startTime = 0 
    12       endTime = 0 
    13       buffer = "" 
    14       RFXmsgTable = {} 
    15       RFXLastMsg = "" 
    16       ipAddress = "" 
    17       ipPortRead = 0 
    18       ipPortSend = 0 
    19       RFXCOM_HAR_Count = 0 
    20     RFXCOM_HAR_Devices = {} 
    21      
     10    bitw = require("bit") 
     11    startupReady = 0 
     12    startTime = 0 
     13    endTime = 0 
     14    buffer = "" 
     15    RFXmsgTable = {} 
     16    RFXLastMsg = "" 
     17    ipAddress = "" 
     18    ipPortRead = 0 
     19    ipPortSend = 0 
     20     
     21    RFXConstants = { 
     22        sensorTypeMotion = "MOTION", 
     23        sensorTypeDoor = "DOOR", 
     24        sensorTypeKeyFob = "KEYFOB", 
     25        sensorTypeWeather = "WEATHER", 
     26        sensorTypeRemote = "REMOTE", 
     27        sensorTypeControler = "CONTROLER", 
     28        sensorTypeWindowCovering = "WINDOWCOVERING", 
     29         
     30        sensorManufacturerX10 = "X10", 
     31        sensorManufacturerHomeEasy = "HOMEEASY", 
     32        sensorManufacturerVisonic = "VISONIC", 
     33        sensorManufacturerOregon = "OREGON", 
     34        sensorManufacturerHarrison = "HARRISON", 
     35             
     36        cmdGroupOn = 1, 
     37        cmdGroupOff = 2, 
     38        cmdOn = 4, 
     39        cmdOff = 8, 
     40        cmdArmAway = 16, 
     41        cmdArmHome = 32, 
     42        cmdDisarm = 64, 
     43        cmdTamper = 128, 
     44        cmdJamming = 256, 
     45        cmdBatteryLow = 512, 
     46        cmdNormal = 1024, 
     47        cmdAlert = 2048 
     48    } 
     49     
    2250    function mainStartup(lul_device) 
    23       THIS_DEVICE = lul_device 
    24      
    25       luup.log("Starting RFXCOM device: " .. tostring(THIS_DEVICE)) 
    26  
    27       local device = luup.devices[THIS_DEVICE] 
    28  
    29       if (device.ip == "") then 
    30           return false, "IP Address attribute must be configured", "rfxcom" 
    31       end 
    32        
    33       ipAddress = device.ip 
    34        
    35         for k, v in pairs(luup.devices) do 
    36           if (v.device_num_parent == lul_device) then 
    37             luup.log( "Found child device, lets save! id " .. tostring(v.id) .. " device " .. tostring(v.device_type)) 
    38                    
    39             if (tostring(v.device_type) == "urn:schemas-micasaverde-com:device:WindowCovering:1") then 
    40               RFXCOM_HAR_Count = RFXCOM_HAR_Count + 1 
    41               RFXCOM_HAR_Devices[RFXCOM_HAR_Count] = v.id 
    42             end 
    43           end 
    44         end 
    45        
    46        
    47       local portList = luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "portRead", lul_device) 
    48       if ((portList or "") == "") then 
    49           portList = "10001" 
    50           luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "portRead", portList, lul_device) 
    51       elseif (portList:find("%d") == nil) then 
    52           return false, "The Port Read parameter must be of the form nnnn.  eg. 10001" 
    53       end        
    54          
    55       ipPortRead = portList 
    56  
    57       local portList = luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "portWrite", lul_device) 
    58       if ((portList or "") == "") then 
    59           portList = "10002" 
    60           luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "portWrite", portList, lul_device) 
    61       elseif (portList:find("%d") == nil) then 
    62           return false, "The Port Write parameter must be of the form nnnn.  eg. 10002" 
    63       end        
    64  
    65       ipPortSend = portList 
    66  
    67       luup.log("Open socket for read " .. ipAddress .. " port " .. ipPortRead ) 
    68        
    69       luup.io.open(THIS_DEVICE, ipAddress, ipPortRead) 
    70  
    71           startupReady = 1 
    72            
    73         return true, "ok", "rfxcom" 
     51        RFXDevicesLS = {} 
     52        RFXCountLS = 0 
     53        RFXDevicesDS = {} 
     54        RFXCountDS = 0 
     55        RFXDevicesMS = {} 
     56        RFXCountMS = 0 
     57        RFXDevicesKF = {} 
     58        RFXCountKF = 0 
     59        RFXCOM_HAR_Count = 0 
     60        RFXCOM_HAR_Devices = {} 
     61         
     62        THIS_DEVICE = lul_device 
     63        luup.log("Starting RFXCOM device: " .. tostring(THIS_DEVICE)) 
     64        local device = luup.devices[THIS_DEVICE] 
     65 
     66        -- Set our device IP number 
     67        if (device.ip == "") then 
     68            return false, "IP Address attribute must be configured", "rfxcom" 
     69        end 
     70        ipAddress = device.ip 
     71 
     72        -- Get defined read and write port. If not set, set the default port numbers 10001 and 10002 
     73        local portList = luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "portRead", lul_device) 
     74        if ((portList or "") == "") then 
     75            portList = "10001" 
     76            luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "portRead", portList, lul_device) 
     77        elseif (portList:find("%d") == nil) then 
     78            return false, "The Port Read parameter must be of the form nnnn.  eg. 10001" 
     79        end 
     80        ipPortRead = portList 
     81       
     82        local portList = luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "portWrite", lul_device) 
     83        if ((portList or "") == "") then 
     84            portList = "10002" 
     85            luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "portWrite", portList, lul_device) 
     86        elseif (portList:find("%d") == nil) then 
     87            return false, "The Port Write parameter must be of the form nnnn.  eg. 10002" 
     88        end      
     89        ipPortSend = portList 
     90 
     91        -- Check if we should create the devices automaticly 
     92        local RFXAutoCreate = luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "AutoCreate", lul_device) 
     93        if ((RFXAutoCreate or "") == "") then 
     94            luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "AutoCreate", "0", lul_device) 
     95        end 
     96         
     97        -- Check all devices if they are childeren. If so, register in 
     98        -- the correct array based on the device type 
     99        for k, v in pairs(luup.devices) do 
     100            -- Look for devices with this device as parent 
     101            if (v.device_num_parent == lul_device) then 
     102                luup.log( "Found child device, lets save! id " .. tostring(v.id) .. " device " .. tostring(v.device_type)) 
     103 
     104                -- Check on door sensors 
     105                if (tostring(v.device_type) == "urn:schemas-micasaverde-com:device:DoorSensor:1") then 
     106                    RFXCountDS = RFXCountDS + 1 
     107                    RFXDevicesDS[RFXCountDS] = v.id 
     108                end 
     109                 
     110                -- Check on motion sensors 
     111                if (tostring(v.device_type) == "urn:schemas-micasaverde-com:device:MotionSensor:1") then 
     112                    RFXCountMS = RFXCountMS + 1 
     113                    RFXDevicesMS[RFXCountMS] = v.id 
     114                end      
     115 
     116                -- Check on keyfobs 
     117                if (tostring(v.device_type) == "urn:schemas-esweb-nl:device:RFXKeyfob:1") then 
     118                    RFXCountKF = RFXCountKF + 1 
     119                    RFXDevicesKF[RFXCountKF] = v.id 
     120                end      
     121 
     122                -- Check on light switches  
     123                if (tostring(v.device_type) == "urn:schemas-upnp-org:device:BinaryLight:1") then 
     124                    RFXCountLS = RFXCountLS + 1 
     125                    RFXDevicesLS[RFXCountLS] = v.id 
     126                end 
     127 
     128                -- Check on Harrison window coverings 
     129                if (tostring(v.device_type) == "urn:schemas-micasaverde-com:device:WindowCovering:1") then 
     130                    RFXCOM_HAR_Count = RFXCOM_HAR_Count + 1 
     131                    RFXCOM_HAR_Devices[RFXCOM_HAR_Count] = v.id 
     132                end 
     133            end 
     134        end 
     135        luup.log("Tree with number child devices:") 
     136        luup.log("    door sensors: " .. RFXCountDS) 
     137        luup.log("  motion sensors: " .. RFXCountMS) 
     138        luup.log("  keyfob sensors: " .. RFXCountKF) 
     139        luup.log("  light switches: " .. RFXCountLS) 
     140        luup.log(" window covering: " .. RFXCOM_HAR_Count) 
     141         
     142        luup.log("Open socket for read " .. ipAddress .. " port " .. ipPortRead ) 
     143        luup.io.open(THIS_DEVICE, ipAddress, ipPortRead) 
     144        startupReady = 1 
     145 
     146        luup.log("Startup RFXCOM ready") 
     147 
     148        return true, "ok", "rfxcom" 
    74149    end 
    75      
    76      
    77     function SendHarrisonCmd( psHouse, psCmd) 
    78       local liMODEHAR = 0x34 
    79  
    80       --luup.log("Connect to rfxtrans ip " .. ipAddress .. " port " .. ipPortSend) 
    81  
    82       local client = socket.connect(ipAddress, ipPortSend) 
    83       client:settimeout(2) 
    84        
    85       --to send a command we need to specify:  F0 CMD F0 CMD    where CMD has special meaning. 
    86       local lsSend = string.char(0xf0) .. string.char(liMODEHAR) .. string.char(0xf0) .. string.char(liMODEHAR) 
    87       --luup.log("send cmd: " .. formattohex(lsSend)) 
    88  
    89       local lsSendStat = client:send(lsSend) 
    90       --luup.log("send cmd result: " .. formattohex(lsSendStat)) 
    91        
    92       -- We will receive an ack with the last byte of the command sent. or a nack 0x5a 
    93       local lsRecvStat=client:receive(1) 
    94       --luup.log("recv result: " .. formattohex(lsRecvStat)) 
    95  
    96       --to send a command we need to specify: [House Code][Command] 
    97       -- House code is 2 bytes. Open up the remote. There are 8 dip switches with a 3 state. 
    98       -- note down the bits where state top = 2 bits: 11, middle = 10, down = 00. 
    99       -- write down the bits starting from switch 1 to 8. 
    100       -- I get the following code of bits:  00 00 11 11 00 10 10 10 
    101       -- This is binary and can be written in hex as follows:  0F2A and there you have the house code 
    102       -- The curtain has three command: open, close, stop: F380, CF80 and FC80 
    103       -- 
    104       if ( psCmd == "OPEN" ) then 
    105         lsSend = psHouse .. "F380" 
    106          
    107         luup.log("send open command for Harrison house code: " .. psHouse) 
    108       elseif ( psCmd == "CLOSE") then 
    109         lsSend = psHouse .. "CF80" 
    110  
    111         luup.log("send close command for Harrison house code: " .. psHouse) 
    112       else 
    113         --stop 
    114         lsSend = psHouse .. "FC80" 
    115  
    116         luup.log("send stop command for Harrison house code: " .. psHouse) 
    117       end 
    118        
    119       lsSend = ToByteString( lsSend ) 
    120  
    121       local lsSendStat = client:send(lsSend) 
    122       --luup.log("send cmd result: " .. formattohex(lsSendStat)) 
    123  
    124       -- We will recieve an ack with the last byte. or a nack 0x5a 
    125       local lsRecvStat=client:receive(1) 
    126       --luup.log("recv result: " .. formattohex(lsRecvStat)) 
    127        
    128       client:close() 
    129       --luup.log("finished: ") 
    130     end 
    131      
     150      
    132151    function ToByteString( psHexString) 
    133152      local resultstr = "" 
    134153 
    135154      if ( psHexString ~= nil ) then 
    136         for teller = 1, string.len(psHexString), 2 do 
    137           local lsHex = string.sub(psHexString, teller, teller+1) 
    138             resultstr = resultstr .. string.char( tonumber( lsHex, 16) ) 
    139         end 
     155        for teller = 1, string.len(psHexString), 2 do 
     156          local lsHex = string.sub(psHexString, teller, teller+1) 
     157          resultstr = resultstr .. string.char( tonumber( lsHex, 16) ) 
     158        end 
    140159      end 
    141160 
     
    147166 
    148167      if ( dataBuf ~= nil ) then 
    149           for teller = 1, string.len(dataBuf) do 
    150               resultstr = resultstr .. string.format("%02X ", string.byte(dataBuf, teller) ) 
    151           end 
     168        for teller = 1, string.len(dataBuf) do 
     169          resultstr = resultstr .. string.format("%02X ", string.byte(dataBuf, teller) ) 
     170        end 
    152171      end 
    153172 
     
    155174    end     
    156175 
    157  
    158176    --Helper function to get a substring that can handle null chars 
    159177    function GetStringPart( psString, piStart, piLen ) 
    160         local lsResult = "" 
    161  
    162         if ( psString ~= nil ) then 
    163           local liStringLength = 1 + #psString 
    164             for teller = piStart, (piStart + piLen - 1) do 
    165               -- if not beyond string length 
    166               if ( liStringLength > teller ) then 
    167                   lsResult = lsResult .. string.sub(psString, teller, teller) 
    168                 end 
    169             end 
    170         end 
    171  
    172         return lsResult 
     178      local lsResult = "" 
     179 
     180      if ( psString ~= nil ) then 
     181        local liStringLength = 1 + #psString 
     182        for teller = piStart, (piStart + piLen - 1) do 
     183          -- if not beyond string length 
     184          if ( liStringLength > teller ) then 
     185            lsResult = lsResult .. string.sub(psString, teller, teller) 
     186          end 
     187        end 
     188      end 
     189 
     190      return lsResult 
    173191    end 
    174  
    175  
    176     function ProcessMessage( psCommand ) 
    177       local lsRFXMSG = "" 
    178  
    179       while ( #RFXmsgTable > 0 ) do 
    180  
    181           psCommand = table.remove( RFXmsgTable, 1) 
    182         --luup.log("Process Msg : " .. formattohex(psCommand)) 
    183  
    184           local liBitLength = bitw.band( string.byte(psCommand, 1), 0x7f) 
    185           psCommand = GetStringPart( psCommand, 2, string.len( psCommand ) -1 ) 
    186           local liCommandLength = string.len(psCommand) 
    187  
    188           if ( liCommandLength == 4 ) then 
    189               --luup.log("trying x10") 
    190             --luup.log("Process Msg : " .. formattohex(psCommand)) 
    191             -- 70 8F 00 FF 
    192  
    193               if ( bitw.bxor( string.byte(psCommand, 1) , string.byte(psCommand, 2) ) == 0xff ) then 
    194                   if ( bitw.bxor( string.byte(psCommand, 3) , string.byte(psCommand, 4) ) == 0xff ) then 
    195  
    196                       local lsX10Coding = "MNOPCDABEFGHKLIJ" 
    197                       local lsX10Message = string.char( string.byte( lsX10Coding, 1 + bitw.rshift( bitw.band( string.byte(psCommand, 1), 0xf0) , 4 ) ) ) 
    198  
    199                       local liCommand = string.byte(psCommand, 3) 
    200                       if ( liCommand == 0x80 ) then 
    201                           lsX10Message = lsX10Message .. "-All lights off" 
    202                         elseif ( liCommand == 0x90 ) then 
    203                             lsX10Message = lsX10Message .. "-All lights on" 
    204                         elseif ( liCommand == 0x88 ) then 
    205                             lsX10Message = lsX10Message .. "-Bright" 
    206                         elseif ( liCommand == 0x98 ) then 
    207                             lsX10Message = lsX10Message .. "-Dim" 
    208                         else 
    209                             local liRecBytes = bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x10), 4) 
    210                             liRecBytes = liRecBytes + bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x8), 2) 
    211                             liRecBytes = liRecBytes + bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x40), 4) 
    212                             liRecBytes = liRecBytes + bitw.lshift( bitw.band( string.byte(psCommand, 3) , 0x4), 1) 
    213                             liRecBytes = liRecBytes + 1 
    214  
    215                             lsX10Message = lsX10Message .. string.format("%02X", liRecBytes) 
    216                             if ( bitw.band( string.byte(psCommand, 3) , 0x1) == 1) then 
    217                                 lsX10Message = lsX10Message .. "-Prog Koppla (non X10)" 
    218                             elseif ( bitw.band( string.byte(psCommand, 3) , 0x20) == 0) then 
    219                                 lsX10Message = lsX10Message .. "-On" 
    220                             else 
    221                                 lsX10Message = lsX10Message .. "-Off" 
    222                             end 
    223                         end 
    224  
    225                         lsRFXMSG = string.format ("[X10: %s]", lsX10Message) 
    226                     end 
    227                 end 
    228             end 
    229  
    230         if ( liCommandLength == 5 ) then 
    231             --luup.log("Process homeeasy Msg : " .. formattohex(psCommand) ) 
    232             --example: 03 A1 C2 9B 80 
    233  
    234             --bits 6 5 
    235             local lnDataM = bitw.rshift( bitw.band( string.byte(psCommand, 4) , 0x30 ), 4 ) 
    236  
    237             --bits 4 3 2 1  
    238             local lnDataU = bitw.band( string.byte(psCommand, 4) , 0x0f ) 
    239  
    240             --bits 8 7 6 5 
    241             local lnDataP = bitw.rshift( bitw.band( string.byte(psCommand, 5) , 0xf0 ), 4 ) 
    242  
    243           --bits 4 3 
    244             local lnDataI = bitw.rshift( bitw.band( string.byte(psCommand, 5) , 0x0c ), 2 ) 
    245  
    246           local lsDevice = string.format("%02X", bitw.rshift(string.byte(psCommand, 1), 6) )  
    247           lsDevice = lsDevice .. string.format("%02X", bitw.bor( bitw.lshift( bitw.band(string.byte(psCommand, 1), 0x3f), 2 ), bitw.rshift(string.byte(psCommand, 2), 6)))  
    248           lsDevice = lsDevice .. string.format("%02X", bitw.bor( bitw.lshift( bitw.band(string.byte(psCommand, 2), 0x3f), 2 ), bitw.rshift(string.byte(psCommand, 3), 6)))  
    249           lsDevice = lsDevice .. string.format("%02X", bitw.bor( bitw.lshift( bitw.band(string.byte(psCommand, 3), 0x3f), 2 ), bitw.rshift(string.byte(psCommand, 4), 6)))  
    250  
    251           local lsHECmd = "" 
    252  
    253           if (lnDataM == 0) then lsHECmd = "off" end 
    254           if (lnDataM == 1) then lsHECmd = "on" end 
    255           if (lnDataM == 2) then lsHECmd = "group off" end 
    256           if (lnDataM == 3) then lsHECmd = "group on" end 
    257  
    258           lsRFXMSG = string.format ("[HOMEEASY: Device: %s Unit: %d Command: %s ( p: %d i: %d )]", lsDevice, lnDataU, lsHECmd, lnDataP, lnDataI) 
    259  
    260           end 
    261  
    262             if ( liCommandLength == 11 ) then 
    263                 --luup.log("trying oregon WGR918") 
    264  
    265                 if ( ( string.byte(psCommand, 1) == 0x3a ) and ( string.byte(psCommand, 2) == 0x0d ) ) then 
    266  
    267                     local liDataDir = string.byte(psCommand, 6) * 10 + bitw.rshift(string.byte(psCommand, 5), 4) 
    268                     local lnDataSpeed = bitw.band( string.byte(psCommand, 8) , 0x0f) * 10 + (string.byte(psCommand, 7) / 10 ) 
    269                     local lnDataSpeedav = string.byte(psCommand, 9) + ( bitw.rshift( string.byte(psCommand, 8), 4) / 10) 
    270  
    271                     local lsDevice = string.format("%02X", string.byte(psCommand, 4) ) 
    272  
    273                     lsRFXMSG = string.format("[OREGONWGR918: WIND3 Device: %s Direction: %3d Speed: %5.2f Speed av: %5.2f]", lsDevice, liDataDir, lnDataSpeed, lnDataSpeedav) 
    274  
    275                 end 
    276             end 
    277  
    278             if ( string.len( lsRFXMSG ) == 0 ) then 
    279                 luup.log("Unknown Msg : " .. formattohex(psCommand) ) 
    280             else 
    281               -- ignore repeated messages. 
    282             if ( RFXLastMsg ~= lsRFXMSG ) then 
    283               luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "Message", lsRFXMSG, THIS_DEVICE) 
    284               luup.log( lsRFXMSG ) 
    285              
    286             end 
    287             end 
    288              
    289             RFXLastMsg = lsRFXMSG 
    290          
    291         end 
    292  
     192     
     193    function SendHarrisonCmd( psHouse, psCmd) 
     194      local liMODEHAR = 0x34 
     195      local liMODERFXCOM = 0x33 
     196      local client = nil 
     197      local lsSend = "" 
     198      local lsSendStat = "" 
     199      local lsRecvStat = "" 
     200           
     201      luup.log("Connect to rfxtrans ip " .. ipAddress .. " port " .. ipPortSend) 
     202      client = socket.connect(ipAddress, ipPortSend) 
     203 
     204      if client ~= nil then 
     205            client:settimeout(2) 
     206 
     207            luup.log("Send cmd " .. psCmd .. " to " .. psID) 
     208 
     209            --to send a command we need to specify:  F0 CMD F0 CMD    where CMD has special meaning. 
     210            lsSend = string.char(0xf0) .. string.char(liMODEHAR) .. string.char(0xf0) .. string.char(liMODEHAR) 
     211            --luup.log("send cmd: " .. formattohex(lsSend)) 
     212 
     213            lsSendStat = client:send(lsSend) 
     214            --luup.log("send cmd result: " .. formattohex(lsSendStat)) 
     215 
     216            -- We will receive an ack with the last byte of the command sent. or a nack 0x5a 
     217            lsRecvStat=client:receive(1) 
     218            --luup.log("recv result: " .. formattohex(lsRecvStat)) 
     219 
     220            --to send a command we need to specify: [House Code][Command] 
     221            -- House code is 2 bytes. Open up the remote. There are 8 dip switches with a 3 state. 
     222            -- note down the bits where state top = 2 bits: 11, middle = 10, down = 00. 
     223            -- write down the bits starting from switch 1 to 8. 
     224            -- I get the following code of bits:  00 00 11 11 00 10 10 10 
     225            -- This is binary and can be written in hex as follows:  0F2A and there you have the house code 
     226            -- The curtain has three command: open, close, stop: F380, CF80 and FC80 
     227            -- 
     228            if ( psCmd == "OPEN" ) then 
     229                lsSend = psHouse .. "F380" 
     230                luup.log("send open command for Harrison house code: " .. psHouse) 
     231            elseif ( psCmd == "CLOSE") then 
     232                lsSend = psHouse .. "CF80" 
     233                luup.log("send close command for Harrison house code: " .. psHouse) 
     234            else 
     235                --stop 
     236                lsSend = psHouse .. "FC80" 
     237                luup.log("send stop command for Harrison house code: " .. psHouse) 
     238            end 
     239 
     240            lsSend = ToByteString( lsSend ) 
     241 
     242            local lsSendStat = client:send(lsSend) 
     243            --luup.log("send cmd result: " .. formattohex(lsSendStat)) 
     244 
     245            -- We will recieve an ack with the last byte. or a nack 0x5a 
     246            local lsRecvStat=client:receive(1) 
     247            --luup.log("recv result: " .. formattohex(lsRecvStat)) 
     248 
     249            -- Close client connection 
     250            client:close() 
     251        else 
     252            return false 
     253        end 
     254        luup.log("finished: ") 
     255    end 
     256  
     257    function SendCmd( psID, psCmd ) 
     258      local liMODEHAR = 0x34 
     259      local liMODERFXCOM = 0x33 
     260      local client = nil 
     261      local lsSend = "" 
     262      local lsSendStat = "" 
     263      local lsRecvStat = "" 
     264       
     265       
     266      luup.log("Connect to rfxtrans ip " .. ipAddress .. " port " .. ipPortSend) 
     267      client = socket.connect(ipAddress, ipPortSend) 
     268 
     269      if client ~= nil then 
     270            client:settimeout(2) 
     271 
     272            luup.log("Send cmd " .. psCmd .. " to " .. psID) 
     273 
     274            --to send a command we need to specify:  F0 CMD F0 CMD    where CMD has special meaning. 
     275            lsSend = string.char(0xf0) .. string.char(liMODERFXCOM) .. string.char(0xf0) .. string.char(liMODERFXCOM) 
     276            if lsSend ~= nil then luup.log("send cmd: " .. formattohex(lsSend)) end 
     277 
     278            lsSendStat = client:send(lsSend) 
     279            if lsSendStat ~= nil then luup.log("send cmd result: " .. formattohex(lsSendStat)) end 
     280 
     281            -- We will receive an ack with the last byte of the command sent. or a nack 0x5a 
     282            lsRecvStat=client:receive(1) 
     283            if lsRecvStat ~= nil then luup.log("recv result: " .. formattohex(lsRecvStat)) end 
     284 
     285            -- Because this is a homeeasy, kaku device, calc the 
     286            -- command to be send based on the ID of the device 
     287             
     288            local psByteID = ToByteString(psID) 
     289            local liBitLength = bitw.band( string.byte(psByteID, 1), 0x7f) 
     290            luup.log("Bit length is " .. liBitLength .. " based on id " .. psID) 
     291             
     292            if liBitLength == 33 then 
     293                lsSend = RecodeHomeEasy33(psByteID,psCmd) 
     294            elseif liBitLength == 34 then 
     295                lsSend = RecodeHomeEasy34(psByteID,psCmd) 
     296            elseif liBitLength == 36 then 
     297                lsSend = RecodeHomeEasy36(psByteID,psCmd) 
     298            elseif liBitLength == 37 then 
     299                lsSend = RecodeHomeEasy37(psByteID,psCmd) 
     300            else 
     301                lsSend = nil 
     302            end 
     303             
     304            if lsSend ~= nil then 
     305                lsSend = ToByteString(lsSend) 
     306                luup.log("send command " .. psCmd .. " as " .. formattohex(lsSend)) 
     307 
     308                lsSendStat = client:send(lsSend) 
     309                if lsSendStat ~= nil then luup.log("send cmd result: " .. formattohex(lsSendStat)) end 
     310 
     311                -- We will recieve an ack with the last byte. or a nack 0x5a 
     312                lsRecvStat=client:receive(1) 
     313                if lsRecvStat ~= nil then luup.log("recv result: " .. formattohex(lsRecvStat)) end 
     314            end 
     315             
     316            -- Close client connection 
     317            client:close() 
     318        else 
     319            return false 
     320        end 
     321        luup.log("finished: ") 
     322    end 
     323 
     324    function RecodeHomeEasy33(psID,psCmd) 
     325        local lbCmd = string.byte(psID, 5) 
     326         
     327        if psCmd == RFXConstants.cmdOff then 
     328            lbCmd = bitw.bor(lbCmd,0x00) 
     329        elseif psCmd == RFXConstants.cmdOn then 
     330            lbCmd = bitw.bor(lbCmd,0x10) 
     331        elseif psCmd == RFXConstants.cmdGroupOff then 
     332            lbCmd = bitw.bor(lbCmd,0x20) 
     333        elseif psCmd == RFXConstants.cmdGroupOn then         
     334            lbCmd = bitw.bor(lbCmd,0x30) 
     335        end 
     336         
     337        return string.format("%02x%02x%02x%02x%02x%02x",string.byte(psID, 1),string.byte(psID, 2),string.byte(psID, 3), 
     338                                string.byte(psID, 4),lbCmd, string.byte(psID, 6)) 
     339    end 
     340     
     341    function RecodeHomeEasy34(psID,psCmd) 
     342        local lbCmd = string.byte(psID, 5) 
     343         
     344        luup.log("Recode homeeasy 34 cmd " .. string.format("%02x",lbCmd)) 
     345        if psCmd == RFXConstants.cmdOff then 
     346            lbCmd = bitw.bor(lbCmd,0x00) 
     347        elseif psCmd == RFXConstants.cmdOn then 
     348            lbCmd = bitw.bor(lbCmd,0x10) 
     349        elseif psCmd == RFXConstants.cmdGroupOff then 
     350            lbCmd = bitw.bor(lbCmd,0x20) 
     351        elseif psCmd == RFXConstants.cmdGroupOn then         
     352            lbCmd = bitw.bor(lbCmd,0x30) 
     353        end 
     354         
     355        return string.format("21%02x%02x%02x%02x%02x",string.byte(psID, 2),string.byte(psID, 3), 
     356                                string.byte(psID, 4),lbCmd, string.byte(psID, 6)) 
     357    end 
     358 
     359    function RecodeHomeEasy36(psID,psCmd) 
     360        return nil 
     361    end 
     362 
     363    ------------------------------------------------------------------------------------             
     364    -- decode X10 commands 
     365    ------------------------------------------------------------------------------------             
     366    function decodeX10(psCommand) 
     367        local liCommandLength = string.len(psCommand) 
     368        local lsRFXMSG = "" 
     369     
     370        if ( liCommandLength == 4 ) then 
     371          luup.log("trying x10") 
     372          luup.log("decode msg : " .. formattohex(psCommand)) 
     373          -- 70 8F 00 FF 
     374 
     375          if ( bitw.bxor( string.byte(psCommand, 1) , string.byte(psCommand, 2) ) == 0xff ) then 
     376            if ( bitw.bxor( string.byte(psCommand, 3) , string.byte(psCommand, 4) ) == 0xff ) then 
     377 
     378              local lsX10Coding = "MNOPCDABEFGHKLIJ" 
     379              local lsX10Message = string.char( string.byte( lsX10Coding, 1 + bitw.rshift( bitw.band( string.byte(psCommand, 1), 0xf0) , 4 ) ) ) 
     380 
     381              local liCommand = string.byte(psCommand, 3) 
     382              if ( liCommand == 0x80 ) then 
     383                lsX10Message = lsX10Message .. "-All lights off" 
     384              elseif ( liCommand == 0x90 ) then 
     385                lsX10Message = lsX10Message .. "-All lights on" 
     386              elseif ( liCommand == 0x88 ) then 
     387                lsX10Message = lsX10Message .. "-Bright" 
     388              elseif ( liCommand == 0x98 ) then 
     389                lsX10Message = lsX10Message .. "-Dim" 
     390              else 
     391                local liRecBytes = bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x10), 4) 
     392                liRecBytes = liRecBytes + bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x8), 2) 
     393                liRecBytes = liRecBytes + bitw.rshift( bitw.band( string.byte(psCommand, 3) , 0x40), 4) 
     394                liRecBytes = liRecBytes + bitw.lshift( bitw.band( string.byte(psCommand, 3) , 0x4), 1) 
     395                liRecBytes = liRecBytes + 1 
     396 
     397                lsX10Message = lsX10Message .. string.format("%02X", liRecBytes) 
     398                if ( bitw.band( string.byte(psCommand, 3) , 0x1) == 1) then 
     399                  lsX10Message = lsX10Message .. "-Prog Koppla (non X10)" 
     400                elseif ( bitw.band( string.byte(psCommand, 3) , 0x20) == 0) then 
     401                  lsX10Message = lsX10Message .. "-On" 
     402                else 
     403                  lsX10Message = lsX10Message .. "-Off" 
     404                end 
     405              end 
     406 
     407              lsRFXMSG = string.format ("[X10: %s]", lsX10Message) 
     408            end 
     409          end 
     410        end 
     411 
     412        return lsRFXMSG 
     413    end 
     414     
     415    ------------------------------------------------------------------------------------             
     416    -- decode homeeasy / kaku commands 
     417    ------------------------------------------------------------------------------------             
     418    function decodeHomeEasy36(psCommand) 
     419        local lsSensorManufacturer = RFXConstants.sensorManufacturerHomeEasy 
     420        local lsSensorType = RFXConstants.sensorTypeControler 
     421        local lsID = "" 
     422        local lsCmd = "" 
     423         
     424        -- Make ID as received bytes minus command 
     425        -- This is not the real ID...just a quick way to send back to RFX 
     426        -- what we received 
     427        lsID = string.format("%02X%02X%02X%02X%02X%02X",string.byte(psCommand, 1),string.byte(psCommand, 2),string.byte(psCommand, 3), 
     428                            string.byte(psCommand, 4),bitw.band(string.byte(psCommand, 5),0xCF),string.byte(psCommand, 6)) 
     429                             
     430        -- Extract on/off/group on/group off command 
     431        local lnDataM = bitw.rshift( bitw.band( string.byte(psCommand, 5) , 0x30 ), 4 ) 
     432        if (lnDataM == 0) then lsCmd = RFXConstants.cmdOff end 
     433        if (lnDataM == 1) then lsCmd = RFXConstants.cmdOn end 
     434        if (lnDataM == 2) then lsCmd = RFXConstants.cmdGroupOff end 
     435        if (lnDataM == 3) then lsCmd =  RFXConstants.cmdGroupOn end 
     436         
     437        -- Make message 
     438        lsRFXMSG = string.format ("[%s:%s ID: %s CMD: %d]", lsSensorManufacturer,lsSensorType, lsID, lsCmd) 
     439         
     440        return lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer 
     441    end 
     442 
     443    function decodeHomeEasy34(psCommand) 
     444        local lsSensorManufacturer = RFXConstants.sensorManufacturerHomeEasy 
     445        local lsSensorType = RFXConstants.sensorTypeControler 
     446        local lsID = "" 
     447        local lsCmd = "" 
     448                 
     449        lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodeHomeEasy36(psCommand) 
     450        return lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer 
     451    end 
     452         
     453    ------------------------------------------------------------------------------------             
     454    -- decode Visonic commands 
     455    ------------------------------------------------------------------------------------             
     456    function decodeVisonic( psCommand ) 
     457        local lsRFXMSG = "" 
     458        local liCommandLength = string.len(psCommand) 
     459        local lsSensorType = "" 
     460        local lsSensorManufacturer = RFXConstants.sensorManufacturerVisonic 
     461        local lsCmd = "" 
     462 
     463        -- First decode ID 
     464        local lsID = string.format("%02X%02X%02X-%d",string.byte(psCommand, 2),string.byte(psCommand, 3),string.byte(psCommand, 6),string.byte(psCommand,2) * 256 + string.byte(psCommand,3))  
     465        local liHsAddr = 0   
     466        --liHsAddr = createhsaddr(psCommand) 
     467         
     468        --if protocol = MODEB32 then 
     469        --  lsRFXMSG = string.format(" addr: %02x%d",string.byte(psCommand, 2),liHsAddr) 
     470        --else 
     471        --  lsRFXMSG = string.format(" addr: %s ID: %d,lsDevice,liHsAddr) 
     472        --end    
     473         
     474        -- Next decode message data 
     475        if string.byte(psCommand, 4) == 0x44 then 
     476            lsSensorType = RFXConstants.sensorTypeDoor 
     477            lsCmd = RFXConstants.cmdAlert + RFXConstants.cmdTamper 
     478        elseif string.byte(psCommand, 4) == 0xC4 then 
     479            lsSensorType = RFXConstants.sensorTypeDoor 
     480            lsCmd = RFXConstants.cmdNormal + RFXConstants.cmdTamper 
     481        elseif string.byte(psCommand, 4) == 0x4 then 
     482            lsSensorType = RFXConstants.sensorTypeDoor 
     483            lsCmd = RFXConstants.cmdAlert    
     484        elseif string.byte(psCommand, 4) == 0x5 then 
     485            lsSensorType = RFXConstants.sensorTypeDoor 
     486            lsCmd = RFXConstants.cmdAlert + RFXConstants.cmdBatteryLow 
     487        elseif string.byte(psCommand, 4) == 0x84 then 
     488            lsSensorType = RFXConstants.sensorTypeDoor 
     489            lsCmd = RFXConstants.cmdNormal   
     490        elseif string.byte(psCommand, 4) == 0x85 then 
     491            lsSensorType = RFXConstants.sensorTypeDoor 
     492            lsCmd = RFXConstants.cmdNormal + RFXConstants.cmdBatteryLow 
     493        elseif string.byte(psCommand, 4) == 0x4C then 
     494            lsSensorType = RFXConstants.sensorTypeMotion 
     495            lsCmd = RFXConstants.cmdAlert + RFXConstants.cmdTamper 
     496        elseif string.byte(psCommand, 4) == 0xCC then 
     497            lsSensorType = RFXConstants.sensorTypeMotion 
     498            lsCmd = RFXConstants.cmdNormal + RFXConstants.cmdTamper 
     499        elseif string.byte(psCommand, 4) == 0x0C then 
     500            lsSensorType = RFXConstants.sensorTypeMotion 
     501            lsCmd = RFXConstants.cmdAlert 
     502        elseif string.byte(psCommand, 4) == 0x0D then 
     503            lsSensorType = RFXConstants.sensorTypeMotion 
     504            lsCmd = RFXConstants.cmdAlert + RFXConstants.cmdBatteryLow 
     505        elseif string.byte(psCommand, 4) == 0x8C then 
     506            lsSensorType = RFXConstants.sensorTypeMotion 
     507            lsCmd = RFXConstants.cmdNormal 
     508        elseif string.byte(psCommand, 4) == 0x8D then 
     509            lsSensorType = RFXConstants.sensorTypeMotion 
     510            lsCmd = RFXConstants.cmdNormal + RFXConstants.cmdBatteryLow 
     511        elseif string.byte(psCommand, 4) == 0xE0 then 
     512            if string.byte(psCommand, 2) == 0xff then 
     513                lsCmd = RFXConstants.cmdJamming -- Master receiver jamming detected 
     514            elseif string.byte(psCommand, 2) == 0x0 then 
     515                lsCmd = RFXConstants.cmdJamming -- Slave receiver jamming detected 
     516            else 
     517                -- Unknown data packet received 
     518            end 
     519        elseif string.byte(psCommand, 4) == 0xF8 then 
     520            if string.byte(psCommand, 2) == 0xff then 
     521                lsCmd = RFXConstants.cmdJamming -- Master receiver jamming detected 
     522            elseif string.byte(psCommand, 2) == 0x0 then 
     523                lsCmd = RFXConstants.cmdJamming -- Slave receiver jamming detected 
     524            else 
     525                -- Unknown command 
     526            end 
     527        elseif string.byte(psCommand, 4) == 0x2 then 
     528            lsSensorType = RFXConstants.sensorTypeKeyFob 
     529            lsCmd = RFXConstants.cmdArmAway  
     530        elseif string.byte(psCommand, 4) == 0xE then 
     531            lsSensorType = RFXConstants.sensorTypeKeyFob 
     532            lsCmd = RFXConstants.cmdArmHome 
     533        elseif string.byte(psCommand, 4) == 0x22 then 
     534            lsSensorType = RFXConstants.sensorTypeKeyFob 
     535            lsCmd = RFXConstants.cmdPanic    
     536        elseif string.byte(psCommand, 4) == 0x42 then 
     537            lsSensorType = RFXConstants.sensorTypeKeyFob 
     538            lsCmd = RFXConstants.cmdGroupOn  
     539        elseif string.byte(psCommand, 4) == 0x82 then 
     540            lsSensorType = RFXConstants.sensorTypeKeyFob 
     541            lsCmd = RFXConstants.cmdDisarm   
     542        else 
     543            -- Unknown data packet received 
     544        end 
     545         
     546        -- Create RFXMSG text 
     547        lsRFXMSG = string.format ("[%s:%s ID: %s CMD: %d]", lsSensorManufacturer,lsSensorType, lsID, lsCmd) 
     548     
     549        return lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer 
     550    end 
     551     
     552     
     553    function createhsaddr(psCommand) 
     554        local liHsAddr = 0 
     555 
     556        if bitw.band(string.byte(psCommand, 1),0x1) ~= 0 then 
     557           liHsAddr = bitw.bor(liHsAddr,0x80) 
     558        end 
     559        if bitw.band(string.byte(psCommand, 1),0x2) ~= 0 then 
     560            liHsAddr = bitw.bor(liHsAddr,0x40) 
     561        end 
     562        if bitw.band(string.byte(psCommand, 1),0x4) ~= 0 then 
     563            liHsAddr = bitw.bor(liHsAddr,0x20) 
     564        end 
     565        if bitw.band(string.byte(psCommand, 1),0x8) ~= 0 then 
     566            liHsAddr = bitw.bor(liHsAddr,0x10) 
     567        end 
     568        if bitw.band(string.byte(psCommand, 1),0x10) ~= 0 then 
     569            liHsAddr = bitw.bor(liHsAddr,0x8) 
     570        end 
     571        if bitw.band(string.byte(psCommand, 1),0x20) ~= 0 then 
     572            liHsAddr = bitw.bor(liHsAddr,0x4) 
     573        end 
     574        if bitw.band(string.byte(psCommand, 1),0x40) ~= 0 then 
     575            liHsAddr = bitw.bor(liHsAddr,0x2) 
     576        end 
     577        if bitw.band(string.byte(psCommand, 1),0x80) ~= 0 then 
     578            liHsAddr = bitw.bor(liHsAddr,0x1) 
     579        end 
     580        if bitw.band(string.byte(psCommand, 2),0x1) ~= 0 then 
     581            liHsAddr = bitw.bor(liHsAddr,0x8000) 
     582        end 
     583        if bitw.band(string.byte(psCommand, 2),0x2) ~= 0 then 
     584            liHsAddr = bitw.bor(liHsAddr,0x4000) 
     585        end 
     586        if bitw.band(string.byte(psCommand, 2),0x4) ~= 0 then 
     587            liHsAddr = bitw.bor(liHsAddr,0x2000) 
     588        end 
     589        if bitw.band(string.byte(psCommand, 2),0x8) ~= 0 then 
     590            liHsAddr = bitw.bor(liHsAddr,0x1000) 
     591        end 
     592        if bitw.band(string.byte(psCommand, 2),0x10) ~= 0 then 
     593            liHsAddr = bitw.bor(liHsAddr,0x800) 
     594        end 
     595        if bitw.band(string.byte(psCommand, 2),0x20) ~= 0 then 
     596            liHsAddr = bitw.bor(liHsAddr,0x400) 
     597        end 
     598        if bitw.band(string.byte(psCommand, 2),0x40) ~= 0 then 
     599            liHsAddr = bitw.bor(liHsAddr,0x200) 
     600        end 
     601        if bitw.band(string.byte(psCommand, 2),0x80) ~= 0 then 
     602            liHsAddr = bitw.bor(liHsAddr,0x100) 
     603        end 
     604         
     605        return liHsAddr 
     606    end 
     607     
     608    function decodex(psCommand) 
     609        local lsRFXMSG = "" 
     610        local lsSensorType = "" 
     611        local lsID = "" 
     612        local lsCmd = "" 
     613        local lsSensorManufacturer = "" 
     614        local liBitLength = bitw.band( string.byte(psCommand, 1), 0x7f) 
     615 
     616        if (bitw.bxor( string.byte(psCommand, 2) , string.byte(psCommand, 3) ) == 0xff and string.byte(psCommand, 2) == 0xee)  then 
     617            luup.log("decoderfremote()") 
     618        end 
     619        if (string.byte(psCommand, 3) == 0 and (bitw.band(string.byte(psCommand, 4),0x0f) == 0)) then 
     620            luup.log("decodeatiplus()") 
     621        end 
     622        if bitw.bxor(string.byte(psCommand, 2),string.byte(psCommand, 3)) == 0xff and bitw.bxor(string.byte(psCommand, 4),string.byte(psCommand, 5)) == 0xff and liBitLength == 32 then 
     623            luup.log("decodex10()") 
     624        end 
     625        if liBitLength == 32 and bitw.bxor(string.byte(psCommand, 2),string.byte(psCommand, 3)) == 0xfe and bitw.bxor(string.byte(psCommand, 4),string.byte(psCommand, 5)) == 0xff then 
     626            luup.log("decodedm10()") 
     627        end 
     628        if string.byte(psCommand, 2) == (bitw.band(string.byte(psCommand, 3),0xf0) + (0x0f - bitw.band(string.byte(psCommand, 3),0x0f))) and bitw.bxor(string.byte(psCommand, 4),string.byte(psCommand, 5)) == 0xff then 
     629            luup.log("decodex10security()") 
     630        end 
     631        if (bitw.bxor(string.byte(psCommand, 4),string.byte(psCommand, 5)) == 0xff) then 
     632            lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodeVisonic(psCommand) 
     633        end 
     634         
     635        return lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer 
    293636    end     
    294      
    295     -- The call back function to process the buffer. 
     637     
     638    -- The call back function to decode the buffer. 
    296639    function endOfData( withdata ) 
    297640 
    298         -- Now loop the buffer and split into messages to process. 
    299         local liCount = 0 
     641      -- Now loop the buffer and split into messages to decode. 
     642      local liCount = 0 
    300643 
    301644      while ( #buffer > 0 ) do 
    302645 
    303           --luup.log("endOfData buffer : " .. tostring(liCount) .. " : " .. formattohex(buffer)) 
    304           liCount = liCount + 1 
     646        luup.log("endOfData buffer : " .. tostring(liCount) .. " : " .. formattohex(buffer)) 
     647        liCount = liCount + 1 
    305648 
    306649        -- we have data, first byte has length and a flag in the first bit to signal if from master or slave function of rfxcom 
    307           -- we are not interested in the flag so strip. Length is in bits so divide by 8 using right shift 3 
    308           local liPacketLength = bitw.rshift( bitw.band( string.byte(buffer, 1), 0x7f), 3) 
    309  
    310             -- We now have the length in bytes but the remainder of the division was lost.  
    311             -- Last three bits had the remainder, if these contain any data then add one byte 
    312             if ( bitw.band( string.byte(buffer, 1), 0x07) > 0 ) then 
    313                 liPacketLength = liPacketLength + 1 
    314             end 
    315  
    316             -- Now isolate message from buffer and shrink buffer accordingly 
    317             -- Unfortunately the string.sub function cannot handle null chars 
    318             local lsCommand = GetStringPart( buffer, 1, 1 + liPacketLength ) 
    319             buffer = GetStringPart( buffer, liPacketLength + 2, #buffer) 
    320  
    321             -- Log found message and process!! 
    322             if ( lsCommand ~= nil and #lsCommand > 0 ) then 
    323               table.insert( RFXmsgTable, lsCommand ) 
    324               luup.call_delay("ProcessMessage", 0 , "none") 
    325             end 
     650        -- we are not interested in the flag so strip. Length is in bits so divide by 8 using right shift 3 
     651        local liPacketLength = bitw.rshift( bitw.band( string.byte(buffer, 1), 0x7f), 3) 
     652 
     653        -- We now have the length in bytes but the remainder of the division was lost.  
     654        -- Last three bits had the remainder, if these contain any data then add one byte 
     655        if ( bitw.band( string.byte(buffer, 1), 0x07) > 0 ) then 
     656          liPacketLength = liPacketLength + 1 
     657        end 
     658 
     659        -- Now isolate message from buffer and shrink buffer accordingly 
     660        -- Unfortunately the string.sub function cannot handle null chars 
     661        local lsCommand = GetStringPart( buffer, 1, 1 + liPacketLength ) 
     662        buffer = GetStringPart( buffer, liPacketLength + 2, #buffer) 
     663 
     664        -- Log found message and decode!! 
     665        if ( lsCommand ~= nil and #lsCommand > 0 ) then 
     666            luup.log("RFX message compleet: " .. formattohex(lsCommand)) 
     667            table.insert( RFXmsgTable, lsCommand ) 
     668            luup.call_delay("processMessage", 0 , "none") 
     669        end 
    326670 
    327671      end 
    328672 
    329         -- Okay Lets flag all is okay for the callback 
     673      -- Okay Lets flag all is okay for the callback 
    330674      return 0 
    331675    end 
     676  
     677    ------------------------------------------------------------------------------------             
     678    -- Main routine to decode and process the received messages 
     679    ------------------------------------------------------------------------------------             
     680    function processMessage(psCommand) 
     681        while ( #RFXmsgTable > 0 ) do 
     682            local lsRFXMSG = "" 
     683            local lsSensorType = "" 
     684            local lsID = "" 
     685            local lsCmd = "" 
     686            local lsSensorManufacturer = "" 
     687 
     688            psCommand = table.remove( RFXmsgTable, 1) 
     689            local liBitLength = bitw.band( string.byte(psCommand, 1), 0x7f) 
     690 
     691            luup.log(string.format("decodeMessage bits:%d data:%s",liBitLength,formattohex(psCommand))) 
     692 
     693            --psCommand = GetStringPart( psCommand, 2, string.len( psCommand ) -1 ) 
     694            --local liCommandLength = string.len(psCommand) 
     695 
     696            -- Decode based on bitlength 
     697            if liBitLength == 12 then 
     698                luup.log("decodeHomeEasyHeater12") 
     699            elseif liBitLength == 13 then 
     700                luup.log("decodeMertikMaxitrol13") 
     701            elseif liBitLength == 20 then 
     702                luup.log("decodeATIRemoteWonder20") 
     703            elseif liBitLength == 22 then 
     704                luup.log("decodeRobocamNinja22") 
     705            elseif liBitLength == 24 then 
     706                luup.log("decodeArc24") 
     707                luup.log("decodeWaveman24") 
     708            elseif liBitLength == 25 then 
     709                luup.log("decodeHarrison25") 
     710            elseif liBitLength == 26 then 
     711                luup.log("decodeIkeaKoppla26") 
     712            elseif liBitLength == 32 then 
     713                luup.log("decodeX1032") 
     714                luup.log("decodeDM1032") 
     715                luup.log("decodePCRemote32") 
     716                luup.log("decodeRFXSensor32")            
     717            elseif liBitLength == 33 then 
     718                luup.log("decodeHomeEasy33")                             
     719            elseif liBitLength == 34  then 
     720                lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodeHomeEasy34(psCommand) 
     721            elseif liBitLength == 36  then 
     722                lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodeHomeEasy36(psCommand) 
     723            elseif liBitLength == 37 then 
     724                luup.log("decodeHomeEasy37")                             
     725            elseif liBitLength == 41 then 
     726                luup.log("decodeX10Security41") 
     727                lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodeVisonic(psCommand) 
     728            elseif liBitLength == 44 then 
     729                luup.log("decodeDigimaxRTS1044")                             
     730            elseif liBitLength == 47 then 
     731                luup.log("decodeCheaperTronics47") 
     732            elseif liBitLength == 56 or liBitLength > 59 then 
     733                luup.log("decodeoregon") 
     734            else 
     735                lsRFXMSG,lsSensorType,lsID,lsCmd,lsSensorManufacturer = decodex(psCommand) 
     736            end 
     737             
     738            if ( string.len( lsRFXMSG ) == 0 ) then 
     739                luup.log("Unknown Msg : " .. formattohex(psCommand) ) 
     740            else 
     741                ------------------------------------------------------------------------------------             
     742                -- ignore repeated messages. 
     743                -- Realy new and decoded messages must be processed. After processing, update 
     744                -- last message variable 
     745                ------------------------------------------------------------------------------------             
     746                if ( RFXLastMsg ~= lsRFXMSG ) then 
     747                    actOnMessage(lsSensorType,lsID,lsCmd)                                
     748                    luup.variable_set("urn:upnp-esweb-nl:serviceId:rfxcom1", "Message", lsRFXMSG, THIS_DEVICE) 
     749                    luup.log( lsRFXMSG ) 
     750                end 
     751            end 
     752             
     753            RFXLastMsg = lsRFXMSG 
     754        end 
     755    end 
     756 
     757      
     758    ------------------------------------------------------------------------ 
     759    -- Act on decoded message 
     760    --  
     761    -- If variable 'AutoCreate' is set to 1 and a received sensor doens't 
     762    -- exsist yet, it's created.  
     763    -- Next execution depends on kind of sensor 
     764    -- Controler (lightswitch): Status variable is set based on cmdOn or cmdOff 
     765    -- Motion Sensor: Tripped status is set 
     766    -- Door Sensor: Tripped status is set 
     767    -- KeyFox: All door and motion sensors are armed or disarmed 
     768    ------------------------------------------------------------------------ 
     769 
     770    function actOnMessage(lsSensorType,lsID,lsCmd) 
     771 
     772        luup.log("Received command " .. lsCmd .. " for " .. lsSensorType .. " with ID " .. lsID)     
     773 
     774        -- Check if we can find a device with the decoded ID and ourself as parent 
     775        local device = findChild(THIS_DEVICE, lsID ) 
     776      
     777        -- If we can't find a device and we have autocreate active, setup a new tree with child devices 
     778        -- and add a new child with the correct type and ID 
     779        if device == nil and luup.variable_get("urn:upnp-esweb-nl:serviceId:rfxcom1", "AutoCreate", lul_device) == "1" then 
     780            luup.log( "device not found and autocreate enabled..." )  
     781             
     782            local child_devices = luup.chdev.start(THIS_DEVICE);   
     783 
     784            ------------------------------------------------------------------------------------             
     785            -- First add all 'old' children to the three 
     786            -- Start with door sensors 
     787            ------------------------------------------------------------------------------------             
     788            for teller = 1, RFXCountDS do 
     789              luup.chdev.append(THIS_DEVICE, child_devices, RFXDevicesDS[teller], "RFX DS sensor #" .. RFXDevicesDS[teller] ,  
     790                "urn:schemas-micasaverde-com:device:DoorSensor:1","D_DoorSensor1.xml","","",false) 
     791            end 
     792            ------------------------------------------------------------------------------------             
     793            -- Next with motion sensors 
     794            ------------------------------------------------------------------------------------             
     795            for teller = 1, RFXCountMS do 
     796              luup.chdev.append(THIS_DEVICE, child_devices, RFXDevicesMS[teller], "RFX MS sensor #" .. RFXDevicesMS[teller] ,  
     797                "urn:schemas-micasaverde-com:device:MotionSensor:1","D_MotionSensor1.xml","","",false) 
     798            end          
     799            ------------------------------------------------------------------------------------             
     800            -- Next with keyfobs 
     801            ------------------------------------------------------------------------------------             
     802            for teller = 1, RFXCountKF do 
     803              luup.chdev.append(THIS_DEVICE, child_devices, RFXDevicesKF[teller], "RFX KF sensor #" .. RFXDevicesKF[teller] ,  
     804                "urn:schemas-ActiveRFID:device:RFIDTransmitter:1","D_RFIDTransmitter.xml","","",false) 
     805            end          
     806            ------------------------------------------------------------------------------------             
     807            -- Next with light switches 
     808            ------------------------------------------------------------------------------------             
     809            for teller = 1, RFXCountLS do 
     810              luup.chdev.append(THIS_DEVICE, child_devices, RFXDevicesLS[teller], "RFX LS #" .. RFXDevicesLS[teller] ,  
     811                "urn:schemas-upnp-org:device:BinaryLight:1","D_BinaryLight1.xml","","",false) 
     812            end          
     813            ------------------------------------------------------------------------------------             
     814            -- Next Harrison window covering 
     815            ------------------------------------------------------------------------------------             
     816            for teller = 1, RFXCOM_HAR_Count do 
     817                luup.chdev.append(THIS_DEVICE, child_devices, RFXCOM_HAR_Devices[teller],  
     818                  "Harrison #" .. RFXCOM_HAR_Devices[teller] , "urn:schemas-micasaverde-com:device:WindowCovering:1", 
     819                  "D_RFXCOMHarrison.xml","","",false) 
     820            end 
     821 
     822            ------------------------------------------------------------------------------------             
     823            -- Now add the new device to the tree depending on the sensor type 
     824            ------------------------------------------------------------------------------------             
     825 
     826            luup.log("Tree buildup, now add " .. lsID .. " with sensortype " .. lsSensorType) 
     827 
     828            ------------------------------------------------------------------------------------             
     829            -- Add if doorsensor 
     830            ------------------------------------------------------------------------------------             
     831            if lsSensorType == RFXConstants.sensorTypeDoor then 
     832                luup.log("CREATING CHILD DEVICE DOOR SENSOR WITH ID " .. lsID) 
     833                luup.chdev.append(THIS_DEVICE, child_devices, lsID, "RFX DS sensor #" .. lsID ,  
     834                  "urn:schemas-micasaverde-com:device:DoorSensor:1","D_DoorSensor1.xml","","",false) 
     835                RFXCountDS = RFXCountDS + 1 
     836                RFXDevicesDS[RFXCountDS] = lsID 
     837            end 
     838            ------------------------------------------------------------------------------------             
     839            -- Add if motionsensor 
     840            ------------------------------------------------------------------------------------             
     841            if lsSensorType == RFXConstants.sensorTypeMotion then 
     842                luup.log("CREATING CHILD DEVICE MOTION SENSOR WITH ID " .. lsID) 
     843                luup.chdev.append(THIS_DEVICE, child_devices, lsID, "RFX MS sensor #" .. lsID ,  
     844                  "urn:schemas-micasaverde-com:device:MotionSensor:1","D_MotionSensor1.xml","","",false) 
     845                RFXCountMS = RFXCountMS + 1 
     846                RFXDevicesMS[RFXCountMS] = lsID 
     847            end 
     848            ------------------------------------------------------------------------------------             
     849            -- Add if keybof 
     850            ------------------------------------------------------------------------------------             
     851            if lsSensorType == RFXConstants.sensorTypeKeyFob then 
     852                luup.log("CREATING CHILD DEVICE KEYFOB WITH ID " .. lsID) 
     853                luup.chdev.append(THIS_DEVICE, child_devices, lsID, "RFX KF sensor #" .. lsID ,  
     854                  "urn:schemas-ActiveRFID:device:RFIDTransmitter:1","D_RFIDTransmitter.xml","","",false) 
     855                RFXCountKF = RFXCountKF + 1 
     856                RFXDevicesKF[RFXCountKF] = lsID 
     857            end 
     858            ------------------------------------------------------------------------------------             
     859            -- Add if lightswitch 
     860            ------------------------------------------------------------------------------------             
     861            if lsSensorType == RFXConstants.sensorTypeControler then 
     862                luup.log("CREATING CHILD DEVICE LIGHT SWITCH WITH ID " .. lsID) 
     863                luup.chdev.append(THIS_DEVICE, child_devices, lsID, "RFX LS #" .. lsID ,  
     864                  "urn:schemas-upnp-org:device:BinaryLight:1","D_BinaryLight1.xml","","",false) 
     865                RFXCountLS = RFXCountLS + 1 
     866                RFXDevicesLS[RFXCountLS] = lsID 
     867            end          
     868            ------------------------------------------------------------------------------------             
     869            -- Add if Harrison window covering 
     870            ------------------------------------------------------------------------------------             
     871            if lsSensorType == RFXConstants.sensorTypeWindowCovering then 
     872                luup.chdev.append(THIS_DEVICE, child_devices, lsID, "Harrison #" .. lsID , 
     873                    "urn:schemas-micasaverde-com:device:WindowCovering:1","D_RFXCOMHarrison.xml","","",false)            
     874                RFXCOM_HAR_Count = RFXCOM_HAR_Count + 1 
     875                RFXCOM_HAR_Devices[RFXCOM_HAR_Count] = lsID 
     876            end  
     877            luup.log("Tree buildup with number child devices:") 
     878            luup.log("     door sensors: " .. RFXCountDS) 
     879            luup.log("   motion sensors: " .. RFXCountMS) 
     880            luup.log("   keyfob sensors: " .. RFXCountKF) 
     881            luup.log("   light switches: " .. RFXCountLS) 
     882            luup.log(" window coverings: " .. RFXCOM_HAR_Count) 
     883             
     884            -- Synch the new tree with the old three 
     885            luup.log("Start sync") 
     886            luup.chdev.sync(THIS_DEVICE, child_devices) 
     887            luup.log("End sync") 
     888            -- Remember the newly added device 
     889            device = findChild(THIS_DEVICE, lsID )         
     890        end 
     891 
     892         
     893        -- If we have found the device with the correct ID, then we have to act on the 
     894        -- command received 
     895        if device ~= nil then 
     896            luup.log("Device found or created, now processing command " .. lsCmd .. " for " .. lsID) 
     897         
     898            -- Execution door sensors same as motion sensors 
     899            if lsSensorType == RFXConstants.sensorTypeDoor or lsSensorType == RFXConstants.sensorTypeMotion then 
     900                local TrippedValue = "0" 
     901                if lsCmd == RFXConstants.cmdAlert then TrippedValue = "1" end 
     902                luup.log( "Set tripped value " .. TrippedValue .. " to device " .. lsID )  
     903                luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", TrippedValue, device) 
     904            end 
     905 
     906            -- Execution for keyfobs 
     907            -- Arm or Disarm all door and motion sensors when keyfob armed or disarmed 
     908            -- Set trip state keyfox as indication home or away 
     909            if lsSensorType == RFXConstants.sensorTypeKeyFob then 
     910                luup.log("KeyFob action: " .. lsCmd)  
     911                 
     912                if lsCmd == RFXConstants.cmdArmAway or lsCmd == RFXConstants.cmdArmHome or lsCmd == RFXConstants.cmdDisarm then 
     913                    ArmDisarmAll(lsCmd) 
     914                elseif lsCmd == RFXConstants.cmdPanic then 
     915                    -- not implemented 
     916                elseif lsCmd == RFXConstants.cmdGroupOn then 
     917                    -- not implemented 
     918                end          
     919            end  
     920 
     921            -- Execution light switches.  
     922            -- Set Status based on cmdOn or cmdOff 
     923            if lsSensorType == RFXConstants.sensorTypeControler then 
     924                local newTargetValue = "0" 
     925                 
     926                if lsCmd == RFXConstants.cmdOn then newTargetValue = "1" end 
     927                 
     928                luup.log("SET TARGET from " .. lsID .. " with value " .. newTargetValue) 
     929                luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",newTargetValue,device) 
     930            end          
     931             
     932        end 
     933 
     934    end 
     935  
     936    ------------------------------------------------------------------------ 
     937    -- Arm or Disarm 
     938    --  
     939    -- Arm or Disarm all motion and door sensors based on command given. 
     940    -- KeyFob sensor gets armed or disarmed also and trip state  
     941    -- is used to indicate home or away status (triped = home) 
     942    ------------------------------------------------------------------------ 
     943     
     944    function ArmDisarmAll(lsCmd) 
     945        local newArmedValue = "1" -- armed 
     946        local newTrippedValue = "1" -- home 
     947         
     948        if lsCmd == RFXConstants.cmdDisarm then  
     949            newArmedValue = "0"  
     950            newTrippedValue = "0" 
     951        end 
     952        if lsCmd == RFXConstants.cmdArmAway then newTrippedValue = "0" end 
     953        luup.log("urn:ActiveRFID:serviceId:RFIDTransmitter1  Action::SetArmed:" .. newArmedValue)  
     954 
     955        -- Iterate all door sensors and set armed value  
     956        for teller = 1, RFXCountDS do 
     957            local lsOtherDevices = findChild(THIS_DEVICE, RFXDevicesDS[teller] ) 
     958             
     959            luup.log("Action::SetArmed: " .. newArmedValue .. " for door sensor device " .. RFXDevicesDS[teller] .. "/" .. lsOtherDevices) 
     960            luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1","Armed",newArmedValue,lsOtherDevices) 
     961        end 
     962 
     963        -- Iterate all  motion sensors and set armed value  
     964        for teller = 1, RFXCountMS do 
     965            local lsOtherDevices = findChild(THIS_DEVICE, RFXDevicesMS[teller] ) 
     966             
     967            luup.log("Action::SetArmed: " .. newArmedValue .. " for motion sensor device " .. RFXDevicesMS[teller] .. "/" .. lsOtherDevices) 
     968            luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1","Armed",newArmedValue,lsOtherDevices) 
     969         
     970        end  
     971 
     972        -- Iterate all keyfobs and set armed value and  
     973        -- set tripped value based on armed-home (1) or armed-away (0) 
     974        for teller = 1, RFXCountKF do 
     975            local lsOtherDevices = findChild(THIS_DEVICE, RFXDevicesKF[teller] ) 
     976             
     977            luup.log("Action::SetArmed: " .. newArmedValue .. "for KeyFob device " .. RFXDevicesKF[teller] .. "/" .. lsOtherDevices) 
     978            luup.log("Action::SetTripped: " .. newTrippedValue .. "for KeyFob device " .. RFXDevicesKF[teller] .. "/" .. lsOtherDevices) 
     979             
     980            luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1","Armed",newArmedValue,lsOtherDevices) 
     981            luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1","Tripped",newTrippedValue,lsOtherDevices)          
     982        end              
     983    end 
     984     
     985  
     986    -- Thanks to guessed for this snippet. 
     987    function findChild(parentDevice, label) 
     988      for k, v in pairs(luup.devices) do 
     989        if (v.device_num_parent == parentDevice and v.id == label) then 
     990          return k 
     991        end 
     992      end 
     993   
     994      -- Dump a copy of the Global Module list for debugging purposes. 
     995      luup.log("findChild cannot find parentDevice: " .. tostring(parentDevice) .. " label: " .. label) 
     996      --for k, v in pairs(luup.devices) do 
     997      --  luup.log("Device Number: " .. k .. 
     998      --           " v.device_type: " .. tostring(v.device_type) .. 
     999      --           " v.device_num_parent: " .. tostring(v.device_num_parent) .. 
     1000      --           " v.id: " .. tostring(v.id) 
     1001      --  ) 
     1002      --end  
     1003    end 
    3321004     
    333     -- Thanks to guessed for this snippet. 
    334       function findChild(parentDevice, label) 
    335         for k, v in pairs(luup.devices) do 
    336           if (v.device_num_parent == parentDevice and v.id == label) then 
    337             return k 
    338           end 
    339         end 
    340      
    341           -- Dump a copy of the Global Module list for debugging purposes. 
    342             luup.log("findChild cannot find parentDevice: " .. tostring(parentDevice) .. " label: " .. label) 
    343             for k, v in pairs(luup.devices) do 
    344         luup.log("Device Number: " .. k .. 
    345                        " v.device_type: " .. tostring(v.device_type) .. 
    346                        " v.device_num_parent: " .. tostring(v.device_num_parent) .. 
    347                        " v.id: " .. tostring(v.id) 
    348               ) 
    349             end  
    350       end 
    351      
    3521005  </functions> 
    3531006 
    3541007  <incoming> 
    3551008    <lua> 
    356             -- When still starting up ignore any data... 
    357             if ( startupReady == 1 ) then 
    358                 local tempdata = tostring(lul_data) 
    359                  
    360                 -- If this is the first byte then create a call back timer to process the data 
    361                 local liStartCallback = 0 
    362                 if ( #buffer == 0 ) then 
    363                   liStartCallback = 1 
    364                 end 
    365                  
    366                 -- and store data in buffer. 
    367                 buffer = buffer .. tempdata 
     1009      -- When still starting up ignore any data... 
     1010      if ( startupReady == 1 ) then 
     1011        local tempdata = tostring(lul_data) 
     1012         
     1013        -- if this is the first byte then create a call back timer to process the data 
     1014        local liStartCallback = 0 
     1015        if ( #buffer == 0 ) then 
     1016          liStartCallback = 1 
     1017        end 
     1018         
     1019        -- and store data in buffer. 
     1020        buffer = buffer .. tempdata 
    3681021 
    3691022        -- do callback 
    3701023        if ( liStartCallback == 1 ) then 
    371                   luup.call_delay("endOfData", 1 , "test delay success") 
    372         end 
    373             end 
    374         </lua> 
     1024          luup.call_delay("endOfData", 1 , "test delay success") 
     1025        end 
     1026      end 
     1027    </lua> 
    3751028  </incoming> 
    3761029 
    3771030  <startup>mainStartup</startup> 
    378   <actionList> 
    379     <action> 
    380       <serviceId>urn:upnp-esweb-nl:serviceId:rfxcom1</serviceId> 
    381       <name>AddHarrisonCurtain</name> 
    382       <run> 
    383          
    384         local lsHouseCode = lul_settings.HouseCode 
    385         luup.log("Add harrison curtain with id: " .. lsHouseCode) 
    386          
    387         local HAR_DEV = findChild(THIS_DEVICE, lsHouseCode ) 
    388  
    389         if HAR_DEV == nil then 
    390           luup.log( "harrison device not found... will create" )     
    391  
    392           local child_devices = luup.chdev.start(THIS_DEVICE);   
    393  
    394             for teller = 1, RFXCOM_HAR_Count do 
    395             luup.chdev.append(THIS_DEVICE, child_devices, RFXCOM_HAR_Devices[teller],  
    396               "Harrison #" .. RFXCOM_HAR_Devices[teller] , "urn:schemas-micasaverde-com:device:WindowCovering:1", 
    397               "D_RFXCOMHarrison.xml","","",false) 
    398             end 
    399  
    400           luup.chdev.append(THIS_DEVICE, child_devices, lsHouseCode,  
    401             "Harrison #" .. lsHouseCode , "urn:schemas-micasaverde-com:device:WindowCovering:1", 
    402             "D_RFXCOMHarrison.xml","","",false) 
    403              
    404             RFXCOM_HAR_Count = RFXCOM_HAR_Count + 1 
    405             RFXCOM_HAR_Devices[RFXCOM_HAR_Count] = lsHouseCode 
    406  
    407               luup.chdev.sync(THIS_DEVICE, child_devices) 
    408  
    409               HAR_DEV = findChild(THIS_DEVICE, lsHouseCode ) 
    410                
    411             else 
    412           luup.log( "harrison device found... nothing to create.." )     
    413  
    414         end 
    415       </run> 
    416     </action> 
    417      <action> 
    418         <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
    419         <name>Stop</name> 
    420         <run> 
    421           local har_id = luup.devices[lul_device].id 
    422           SendHarrisonCmd( har_id, "STOP") 
    423         </run> 
    424       </action> 
    425       <action>      
    426         <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
    427         <name>Up</name> 
    428         <run> 
    429           luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",0,lul_device) 
    430           local har_id = luup.devices[lul_device].id 
    431           SendHarrisonCmd( har_id, "OPEN") 
    432         </run> 
    433       </action> 
    434       <action> 
    435         <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
    436         <name>Down</name> 
    437         <run> 
    438           luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",1,lul_device) 
    439           local har_id = luup.devices[lul_device].id 
    440           SendHarrisonCmd( har_id, "CLOSE") 
    441         </run> 
    442       </action> 
    443  
    444       <action> 
    445         <serviceId>urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1</serviceId> 
    446         <name>SetStatus</name> 
    447         <run> 
    448            luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",lul_settings.newStatusValue,lul_device) 
    449            local har_id = luup.devices[lul_device].id 
    450            if ( lul_settings.newStatusValue == "1" ) then 
    451             SendHarrisonCmd( har_id, "OPEN") 
    452            else 
    453             SendHarrisonCmd( har_id, "CLOSE") 
    454            end 
    455         </run> 
    456       </action> 
    457       <action> 
    458         <serviceId>urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1</serviceId> 
    459         <name>GetStatus</name> 
    460         <run> 
    461            lul_settings.ResultStatus = luup.variable_get("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",lul_device) 
    462         </run> 
    463       </action>       
    464     </actionList> 
    465  
     1031    <actionList> 
     1032        <action> 
     1033            <serviceId>urn:upnp-org:serviceId:SwitchPower1</serviceId> 
     1034            <name>SetTarget</name> 
     1035            <run> 
     1036                local ls_id = luup.devices[lul_device].id 
     1037                local lul_reverse = luup.variable_get("urn:micasaverde-com:serviceId:HaDevice1","ReverseOnOff",lul_device) 
     1038                 
     1039                luup.log("SET TARGET from " .. ls_id .. " with value " .. lul_settings.newTargetValue) 
     1040                 
     1041                if ( lul_settings.newTargetValue == "1"  or (lul_settings.newTargetValue=="0" and lul_reverse=="1") ) then 
     1042                    SendCmd( ls_id,RFXConstants.cmdOn ) 
     1043                else 
     1044                    SendCmd( ls_id,RFXConstants.cmdOff ) 
     1045                end 
     1046                luup.variable_set("urn:upnp-org:serviceId:SwitchPower1","Status",lul_settings.newTargetValue,lul_device) 
     1047            </run> 
     1048        </action> 
     1049 
     1050        <action>  
     1051            <serviceId>urn:micasaverde-com:serviceId:SecuritySensor1</serviceId>  
     1052            <name>SetArmed</name>  
     1053            <run>  
     1054                --debug("Action::SetArmed:"..lul_settings.newArmedValue)  
     1055                luup.variable_set("urn:micasaverde-com:serviceId:SecuritySensor1", "Armed", lul_settings.newArmedValue, lul_device)  
     1056            </run>  
     1057        </action>  
     1058 
     1059        <action>  
     1060            <serviceId>urn:micasaverde-com:serviceId:HaDevice1</serviceId>  
     1061            <name>ToggleState</name>  
     1062            <run>  
     1063                --debug("Action::ToggleState:" .. lul_device)  
     1064            </run>  
     1065        </action>  
     1066           
     1067 
     1068        <action> 
     1069            <serviceId>urn:upnp-esweb-nl:serviceId:rfxcom1</serviceId> 
     1070            <name>AddHarrisonCurtain</name> 
     1071            <run> 
     1072                local lsHouseCode = lul_settings.HouseCode 
     1073                actOnMessage(RFXConstants.sensorTypeWindowCovering,lsHouseCode,"") 
     1074            </run> 
     1075        </action> 
     1076         <action> 
     1077            <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
     1078            <name>Stop</name> 
     1079            <run> 
     1080              local har_id = luup.devices[lul_device].id 
     1081              SendHarrisonCmd( har_id, "STOP") 
     1082            </run> 
     1083          </action> 
     1084          <action>      
     1085            <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
     1086            <name>Up</name> 
     1087            <run> 
     1088              luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",0,lul_device) 
     1089              local har_id = luup.devices[lul_device].id 
     1090              SendHarrisonCmd( har_id, "OPEN") 
     1091            </run> 
     1092          </action> 
     1093          <action> 
     1094            <serviceId>urn:upnp-org:serviceId:WindowCovering1</serviceId> 
     1095            <name>Down</name> 
     1096            <run> 
     1097              luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",1,lul_device) 
     1098              local har_id = luup.devices[lul_device].id 
     1099              SendHarrisonCmd( har_id, "CLOSE") 
     1100            </run> 
     1101          </action> 
     1102 
     1103          <action> 
     1104            <serviceId>urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1</serviceId> 
     1105            <name>SetStatus</name> 
     1106            <run> 
     1107               luup.variable_set("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",lul_settings.newStatusValue,lul_device) 
     1108               local har_id = luup.devices[lul_device].id 
     1109               if ( lul_settings.newStatusValue == "1" ) then 
     1110                SendHarrisonCmd( har_id, "OPEN") 
     1111               else 
     1112                SendHarrisonCmd( har_id, "CLOSE") 
     1113               end 
     1114            </run> 
     1115          </action> 
     1116          <action> 
     1117            <serviceId>urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1</serviceId> 
     1118            <name>GetStatus</name> 
     1119            <run> 
     1120               lul_settings.ResultStatus = luup.variable_get("urn:upnp-esweb-nl:serviceId:RFXCOMHarrison1","CurtainStatus",lul_device) 
     1121            </run> 
     1122          </action> 
     1123    </actionList> 
    4661124</implementation> 
  • /S_RFXCOM.xml

    r1 r3  
    1212      <shortCode>msg</shortCode> 
    1313    </stateVariable> 
     14    <stateVariable allowRepeats="no"> 
     15      <name>Autocreate</name> 
     16      <sendEventsAttribute>no</sendEventsAttribute> 
     17      <dataType>string</dataType> 
     18    </stateVariable>     
    1419  </serviceStateTable> 
    1520  <actionList> 
     
    4247        </argument> 
    4348      </argumentList> 
    44     </action> 
     49    </action>    
    4550  </actionList> 
    4651</scpd> 
Note: See TracChangeset for help on using the changeset viewer.