Open cjackie opened 7 years ago
Hmm I was just thinking to write structured JSON data to specify the operation. But this one sounds more interesting and make sense to me :) I think there should be a good reference designing this. Let me find one
I came up with a language design borrowing your idea. The format of below specification is based on EBNF.
Device = DeviceName'.'Property ;
Value = String | Number ;
Condition =
Device ('='|'>'|'<') Value ;
Action =
'SET' Device '=' Value ;
IFTTTCommend =
'IF' Condition {('OR'|'AND') Condition} 'THEN' {Action} 'END' ;
And the number of whitespace doesn't care. So we can write like the following as an example:
IF
RPi_1.Button = "On"
AND Gyro.x > 1.56
THEN
SET RPi_1.Relay = 0
SET RPi_2.Power = "Off"
END
What do you hink? BTW, lets start with a simpler way, supporting up to 2 conditions and only one action first.
how do you parse and interpret it?
Parsing? No problem!
import re
# Want explanation? Use https://regex101.com/ . This site will explain MUCH better than me :)
ifttt_re = re.compile(r'IF\s+([\w\W]*)\s+THEN\s+([\w\W]*)\s+END')
condition_1st_re = re.compile(r'(\w+)\.(\w+)\s+(\=|\>|\<)\s+(\"\w*\"|[-+]?\d*\.\d+|[-+]?\d+)')
condition_re = re.compile(r'(AND|OR)\s+(\w+)\.(\w+)\s+(\=|\>|\<)\s+(\"\w*\"|[-+]?\d*\.\d+|[-+]?\d+)')
action_re = re.compile(r'SET\s+(\w+)\.(\w+)\s+(\=|\>|\<)\s+(\"\w*\"|[-+]?\d*\.\d+|[-+]?\d+)')
script = '''IF
RPi_1.Button = "On"
AND Gyro.x > 1.56
THEN
SET RPi_1.Relay = 0
SET RPi_2.Power = "Off"
END'''
ifttt = ifttt_re.match(script)
print(ifttt)
if ifttt:
# Capture condition and action
condition_group = ifttt.group(1)
action_group = ifttt.group(2)
print("==== Condition START ====")
# Get first condition
condition_match = condition_1st_re.match(condition_group)
print("First condtition")
print("\tDevice: ", condition_match.group(1))
print("\tProperty: ", condition_match.group(2))
print("\tComparator: ", condition_match.group(3))
print("\tValue: ", condition_match.group(4))
i = 1
# Capture the rest of conditions
for matched in condition_re.finditer(condition_group):
i += 1
print(i, "th action")
print("\tOperator: ", matched.group(1))
print("\tDevice: ", matched.group(2))
print("\tProperty: ", matched.group(3))
print("\tComparator: ", matched.group(4))
print("\tValue: ", matched.group(5))
print("==== Condition END ====")
# Capture all actions
print("==== Action START ====")
i = 0
for matched in action_re.finditer(action_group):
i += 1
print(i, "th action")
print("\tDevice: ", matched.group(1))
print("\tProperty: ", matched.group(2))
print("\tComparator: ", matched.group(3))
print("\tValue: ", matched.group(4))
print("==== Action END ====")
==== Condition START ====
First condtition
Device: RPi_1
Property: Button
Comparator: =
Value: "On"
2 th action
Operator: AND
Device: Gyro
Property: x
Comparator: >
Value: 1.56
==== Condition END ====
==== Action START ====
1 th action
Device: RPi_1
Property: Relay
Comparator: =
Value: 0
2 th action
Device: RPi_2
Property: Power
Comparator: =
Value: "Off"
==== Action END ====
For execution, I need to think the design yet. But it is almost there. :P
@kbumsik Not sure if this is the right way to solve this problem. I will give my thought.
We need to define a simple language that can be interpreted by the remote server. Something like:
Condition
a statement that can evaluated into
True
orFalse
definitionAction
a statement that can have effects on IoT devices
IFTTT Script
We have a user interface that will generate the script according to this definition, then we have a backend script engine that interpret and execute it.
For example, a script can be
And the backend script engine parses this, and execute it