Search code examples
wso2siddhi

Logical Pattern With Sensors


I have two sensors that control lights. when either one detects someone it turns on the light, when both sensors detect nobody it does not show any light. There are two special cases. If someone went to the first sensor and then left without going to the second sensor, it turns off the light. And if someone went from the first sensor to the second sensor. Not leaving

I tried to use Siddhi's Logical Pattern, but I didn't get the expected results.

@App:name("ControllerRightApp")
define stream inputStream(ternateId string,deviceId int,data string);
@sink(type='log',prefix='LOGGER')
define stream  OutputStream(action string);
@info(name='CargoWeightQuery') 
from inputStream[ternateId =='demo'] 
select ternateId,deviceId, data,json:getString(data,'$.eventName') as eventName 
insert into tempStream;
from every ((e1=tempStream)->(e2=tempStream[deviceId==1 and eventName=='out'] and e3=tempStream[deviceId==2 and eventName=='out']))
select "{'deviceId':'3','action':'close'}" as action 
insert into OutputStream;

Solution

  • I am suggesting below solution as catering moving from one sensor to other is sensor areas are not overlapping is bit tricky. Here we are using a periodic trigger to check the sensor state and update bulb state every 5 seconds. Only compromise is this will have a maximum latency of n seconds to turn on/off lights.

    @App:name("ControllerRightApp")
    @App:description("Description of the plan")
    
    define stream inputStream(ternateId string,deviceId int,data string);
    
    @sink(type='log',prefix='LOGGER')
    define stream  OutputStream(action string);
    
    @PrimaryKey('deviceId')
    define table sensorStateTable(deviceId int, state string);
    
    define trigger actionTrigger at every 5 sec;
    
    define trigger populateTrigger at 'start';
    
    from inputStream[ternateId =='demo'] 
    select ternateId,deviceId, json:getString(data,'$.eventName') as eventName
    insert into tempStream;
    
    from tempStream[deviceId == 1 or deviceId == 2]
    select deviceId, eventName as state
    update or insert into sensorStateTable on deviceId == sensorStateTable.deviceId;
    
    --If at least one sensor is in IN state open the switch
    from actionTrigger left outer join sensorStateTable as t1 on (t1.state == 'in')
    select ifThenElse(state is null, "{'deviceId':'3','action':'close'}","{'deviceId':'3','action':'open'}") as action
    insert into OutputStream;
    
    --Queries to add initial state
    from populateTrigger
    select 1 as deviceId, 'out' as state
    insert into sensorStateTable;
    
    from populateTrigger
    select 2 as deviceId, 'out' as state
    insert into sensorStateTable;