some more work on states and the rules doc

pull/1/head
Michael Zanetti 2014-04-04 00:10:15 +02:00
parent 30776744c2
commit 6dd81e641c
15 changed files with 856 additions and 5 deletions

View File

@ -0,0 +1,692 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800"
height="450"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Rules_definition.svg"
inkscape:export-filename="/home/micha/Develop/Hive/doc/images/Rules_definition.png"
inkscape:export-xdpi="141.00999"
inkscape:export-ydpi="141.00999">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart"
style="overflow:visible">
<path
id="path4022"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(0.4,0,0,0.4,4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible">
<path
id="path4025"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path4019"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="309.60867"
inkscape:cy="199.52901"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
objecttolerance="20"
guidetolerance="20"
inkscape:window-width="2880"
inkscape:window-height="1726"
inkscape:window-x="-12"
inkscape:window-y="39"
inkscape:window-maximized="1"
fit-margin-left="10"
fit-margin-top="10"
fit-margin-right="10"
fit-margin-bottom="10">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="false"
originx="36px"
originy="-622.40911px" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(36,20.046952)">
<g
id="g3852"
transform="matrix(1.5825382,0,0,1.5825382,0.11188031,78.466151)">
<rect
ry="0.80439985"
rx="1.5232613"
y="114.94991"
x="49.001541"
height="24.088234"
width="88.695778"
id="rect2987"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:0.46546766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3757"
y="131.36218"
x="56"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="131.36218"
x="56"
id="tspan3759"
sodipodi:role="line">State</tspan></text>
</g>
<g
id="g3857"
transform="matrix(1.5825382,0,0,1.5825382,-16.950645,-450.37737)">
<rect
ry="0.80439985"
rx="1.5232613"
y="280.81873"
x="59.783287"
height="24.088234"
width="88.695778"
id="rect2987-2"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:0.46546766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3757-5"
y="297.15192"
x="66.781746"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="297.15192"
x="66.781746"
id="tspan3759-0"
sodipodi:role="line">Event</tspan></text>
</g>
<g
id="g4977">
<path
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
d="m 284.16404,298.62934 c -10.48814,0 -18.99046,-8.50231 -18.99046,-18.99046 0,-10.48812 8.50232,-18.99045 18.99046,-18.99045 l 72.79676,0 c 10.48814,0 18.99046,8.50233 18.99046,18.99045 0,10.48815 -8.50232,18.99046 -18.99046,18.99046 z"
id="path3785"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccscc" />
<text
sodipodi:linespacing="125%"
id="text3787"
y="286.37347"
x="274.68225"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="286.37347"
x="274.68225"
sodipodi:role="line"
id="tspan3253">[&gt;|&lt;|!]=</tspan></text>
</g>
<g
id="g4383">
<path
transform="matrix(1.5825382,0,0,1.5825382,-205.0651,-38.967366)"
d="m 235,136.36218 c 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62741 5.37258,-12 12,-12 6.62742,0 12,5.37259 12,12 z"
sodipodi:ry="12"
sodipodi:rx="12"
sodipodi:cy="136.36218"
sodipodi:cx="223"
id="path3785-8"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3787-3"
y="182.87833"
x="141.82605"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="182.87833"
x="141.82605"
id="tspan3789-3"
sodipodi:role="line">c</tspan></text>
</g>
<g
id="g4395">
<path
transform="matrix(1.5825382,0,0,1.5825382,-205.17377,-113.2888)"
d="m 235,136.36218 c 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62741 5.37258,-12 12,-12 6.62742,0 12,5.37259 12,12 z"
sodipodi:ry="12"
sodipodi:rx="12"
sodipodi:cy="136.36218"
sodipodi:cx="223"
id="path3785-8-9"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3787-3-6"
y="108.36217"
x="144"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="108.36217"
x="144"
id="tspan3789-3-0"
sodipodi:role="line">|</tspan></text>
</g>
<g
id="g5050">
<path
transform="matrix(1.5825382,0,0,1.5825382,155.08925,-107.5011)"
d="m 235,136.36218 c 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62741 5.37258,-12 12,-12 6.62742,0 12,5.37259 12,12 z"
sodipodi:ry="12"
sodipodi:rx="12"
sodipodi:cy="136.36218"
sodipodi:cx="223"
id="path3785-8-0"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3787-3-1"
y="116.36217"
x="499"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="116.36217"
x="499"
id="tspan3789-3-1"
sodipodi:role="line">&amp;</tspan></text>
</g>
<g
transform="matrix(1.5825382,0,0,1.5825382,124.34113,-99.386645)"
id="g3852-5">
<rect
ry="0.80439985"
rx="1.5232613"
y="114.94991"
x="49.001541"
height="24.088234"
width="88.695778"
id="rect2987-5"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:0.46546766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3757-1"
y="131.36218"
x="56"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="131.36218"
x="56"
id="tspan3759-9"
sodipodi:role="line">State</tspan></text>
</g>
<g
id="g4003"
transform="matrix(1.5825382,0,0,1.5825382,338.3813,145.7761)">
<path
d="m 123,84.362183 c 0,6.075132 -12.53603,11 -28,11 -15.463973,0 -28,-4.924868 -28,-11 0,-6.075133 12.536027,-11 28,-11 15.46397,0 28,4.924867 28,11 z"
sodipodi:ry="11"
sodipodi:rx="28"
sodipodi:cy="84.362183"
sodipodi:cx="95"
id="path3997"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3999"
y="88.835815"
x="78.746094"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="88.835815"
x="78.746094"
id="tspan4001"
sodipodi:role="line">value</tspan></text>
</g>
<g
transform="matrix(1.5825382,0,0,1.5825382,172.83338,11.391036)"
id="g3852-5-1">
<rect
ry="0.80439985"
rx="1.5232613"
y="114.94991"
x="49.001541"
height="24.088234"
width="88.695778"
id="rect2987-5-8"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:0.46546766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3757-1-4"
y="131.36218"
x="56"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="131.36218"
x="56"
id="tspan3759-9-5"
sodipodi:role="line">State</tspan></text>
</g>
<g
transform="matrix(1.5825382,0,0,1.5825382,477.37786,-187.5235)"
id="g3852-5-9">
<rect
ry="0.80439985"
rx="1.5232613"
y="114.94991"
x="49.001541"
height="24.088234"
width="88.695778"
id="rect2987-5-4"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:0.46546766;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<text
sodipodi:linespacing="125%"
id="text3757-1-6"
y="131.36218"
x="56"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:12px"
y="131.36218"
x="56"
id="tspan3759-9-4"
sodipodi:role="line">Action</tspan></text>
</g>
<g
id="g5055">
<path
transform="matrix(1.5825382,0,0,1.5825382,273.08925,-66.981752)"
d="m 235,136.36218 c 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62741 5.37258,-12 12,-12 6.62742,0 12,5.37259 12,12 z"
sodipodi:ry="12"
sodipodi:rx="12"
sodipodi:cy="136.36218"
sodipodi:cx="223"
id="path3785-8-0-7"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3787-3-1-2"
y="157.36218"
x="617"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="157.36218"
x="617"
id="tspan3789-3-1-0"
sodipodi:role="line">&amp;</tspan></text>
</g>
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect5099"
width="3.1650765"
height="52.223759"
x="-24.417461"
y="123.70473"
rx="2.4106193"
ry="1.2729934" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect5099-4"
width="3.1650765"
height="52.223759"
x="745.65698"
y="123.70473"
rx="2.4106193"
ry="1.2729934" />
<path
style="fill:none;stroke:#006dff;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M -21.252385,148.54885 124.0481,32.149541"
id="path5139"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#rect5099"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3857"
inkscape:connection-end-point="d4" />
<path
style="fill:#ff0000;stroke:#ff0000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M -21.252385,151.0185 122.74396,260.37878"
id="path5325"
inkscape:connector-type="polyline"
inkscape:connector-curvature="100"
inkscape:connection-start="#rect5099"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 218.02315,13.142224 336.90152,0.254221"
id="path6067"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3857"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852-5-9"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 497.47912,262.21442 615.32811,32.509679"
id="path6071"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4003"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852-5-9"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 642.17758,32.509679 745.65698,148.04962"
id="path6447"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852-5-9"
inkscape:connection-start-point="d4"
inkscape:connection-end="#rect5099-4"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -26,411.11306 c 126.60306,0 126.60306,0 126.60306,0"
id="path7759"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path7772"
d="m -26,382.76382 c 126.60306,0 126.60306,0 126.60306,0"
style="fill:none;stroke:#003fff;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="138.35789"
y="416.35211"
id="text7774"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7776"
x="138.35789"
y="416.35211"
style="font-size:18.99045753px">Trigger path 2</tspan></text>
<text
xml:space="preserve"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="138.35789"
y="388.0029"
id="text7782"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7784"
x="138.35789"
y="388.0029"
style="font-size:18.99045753px">Trigger path 1</tspan></text>
<path
style="fill:none;stroke:#0052ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 183.84092,276.72995 0,-64.55732"
id="path4388"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4383"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#0052ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 183.81315,174.19173 -0.0531,-36.34056"
id="path4400"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4383"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4395"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#0052ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 202.72219,118.71972 35.16575,-0.26113"
id="path4402"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4395"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852-5"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#0052ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 276.60161,136.99771 -76.51506,46.3446"
id="path4404"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852-5"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4383"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#0052ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 183.75533,99.870291 0.0624,-51.369577"
id="path4406"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4395"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3857"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 254.02315,295.87143 47.15054,0.0546"
id="path5001"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4977"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 411.9509,295.87266 68.46109,-0.1451"
id="path5003"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4977"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4003"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 356.56242,247.77539 0,29.22421"
id="path5009"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852-5-1"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4977"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<g
id="g5092">
<path
transform="matrix(1.5825382,0,0,1.5825382,105.82623,-0.2888)"
d="m 235,136.36218 c 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62741 5.37258,-12 12,-12 6.62742,0 12,5.37259 12,12 z"
sodipodi:ry="12"
sodipodi:rx="12"
sodipodi:cy="136.36218"
sodipodi:cx="223"
id="path3785-8-9-9"
style="fill:#fffed5;fill-opacity:1;stroke:#000000;stroke-width:1.26379251;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<text
sodipodi:linespacing="125%"
id="text3787-3-6-8"
y="221.36217"
x="455"
style="font-size:63.30152893px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
style="font-size:22.15553474px"
y="221.36217"
x="455"
id="tspan3789-3-0-9"
sodipodi:role="line">|</tspan></text>
</g>
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 516.6709,278.5124 502.81569,249.04986"
id="path5097"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4003"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5092"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 475.74661,231.4285 -49.00196,-1.11559"
id="path5099"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g5092"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852-5-1"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 543.99527,124.64844 0,0"
id="path5101"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g5050"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5050"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 527.38924,133.86845 390.89158,209.65484"
id="path5103"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g5050"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g3852-5-1"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 526.6827,278.24246 541.86801,143.52108"
id="path5105"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4003"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5050"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 253.66397,47.898394 525.63098,119.79378"
id="path5107"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3857"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5050"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="M 202.50001,189.63153 525.33617,128.19907"
id="path5109"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4383"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5050"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 661.23199,48.860852 0.63865,97.316878"
id="path5297"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g3852-5-9"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g5055"
inkscape:connection-end-point="d4"
transform="translate(-36,-16.351173)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -3,5 +3,92 @@
\title Rules
\annotatedlist rules
\section1 Introduction
Rules define all the logic in guh.
A rule is composed by a set of \l{Event}{Events}, \l{State}{States} and \l{Action}{Actions}.
This diagram shows how rules are composed and interpreted by
the \l{RuleEngine}.
\image Rules_definition.svg "Rules definition"
A basic concept of a \l{Rule} is the trigger path. This is the path that defines when a \l{Rule}
is triggered for evaluation. Each element added on a trigger path (either red or blue) has the possibility to trigger the
\l{RuleEngine} to evaluate the complete rule and ultimately execute the defined \l{Action}{Actions} if the
whole rule evaluates to true. Once the trigger path has been left (i.e. a black arrow is followed),
subsequent elements will still be evaluated when the rule is triggered, but they won't trigger the
evaluation themselves.
There are two mechanisms that can trigger a rule, described by the two trigger paths in the Rules definition figure.
\list
\li State bindings based
\li Event based
\endlist
\section2 Event based rules
Event based rules (trigger path 1) contain either one or more \l{Event}{Events} or are triggered by a \l{State} change (disregarding what
the changed State's value actually is). Such rules may still evaluate \l{States}{State} for a certain value (leaving
Trigger path 1 and re-entering Trigger path 2), however, unless
otherwise explicitly defined, the Rule is not evaluated when such a State change happens (given the Trigger path has been
left by crossing a black arrow). Those rules are only executed for items on trigger path 1.
\section3 Examples
\list
\li This rule will be evaluated and executed whenever Remote_button1 is pressed:
\tt {\span {id="color-blue"} {Event<Remote_button1_pressed>}} \tt {\span {id="color-black"} {-> Action<Toggle_Light>}}
\li This rule will be evaluated and executed whenever Remote_button1 is pressed or or Motion sensor 1 triggers.
\tt {\span {id="color-blue"} {Event<Remote_button1_pressed> | Event<Motion_sensor1_triggered>}} \tt {\span {id="color-black"} {-> Action<Turn_on_Light>}}
\li This rule will be evaluated and executed whenever Remote_button1 is pressed or the temperature changes.
\tt {\span {id="color-blue"} {Event<Remote_button1_pressed> | State<Temperature_changed>}} \tt {\span {id="color-black"} {-> Action<Turn_on_Light>}}
\endlist
\section2 State bindings based rules
State binding rules (Trigger path 2) are rules which only contains \l{State}{States} and \l{Action}{Actions}. Each time
a \l{State} on that path changes, the rule is evaluated. That means, all the States in the Rule are examined. If all
evaluations are fulfilled, the Rule's \l{Actions}{Action} are executed. Please note, that such Rules may only check
if states are equal to, unequal, less than or greater then some value.
\section3 Examples
\list
\li This rule will be evaluated whenever the temperature changes and executed when the temperature equals 10.
\tt {\span {id="color-red"} {State<Temperature>==10}} \tt {\span {id="color-black"} {-> Action<Toggle_Light>}}
\li This rule will be evaluated whenever the temperature changes or the Light sensor changes and executed when the temperature is greater 20 and the light sensor reports values greater 10.
\tt {\span {id="color-blue"} {State<Temperature> >20 & State<Light> >10}} \tt {\span {id="color-black"} {-> Action<OpenWindow>}}
\li This rule will be evaluated whenever the temperature changes or the Light sensor changes and executed when the temperature is greater 20 or the light sensor reports values greater 10..
\tt {\span {id="color-blue"} {State<Temperature> >20 | State<Light> >10}} \tt {\span {id="color-black"} {-> Action<OpenWindow>}}
\endlist
\section2 Mixing rules types
Having both types of triggers in a single rule is only possible by leaving the trigger path 1, crossing a black arrow and
re-entering trigger path 2. This however, converts the rule to an Event based rule which means, only the elements
on trigger path 1 will be able to trigger the rule evaluation.
\section3 Examples
\list
\li This rule will be evaluated whenever the remote button1 is pressed and executed only if the temperature is greater 10.
\tt {\span {id="color-blue"} {Event<Button1_pressed>==10}} \tt {\span {id="color-black"} {->}} \tt {\span {id="color-red"} {State<Temperature> >10}} \tt {\span {id="color-black"} {-> Action<Toggle_Light>}}
\endlist
*/

View File

@ -673,3 +673,6 @@
}
}
/* end of print media */
#color-blue { color: blue }
#color-red { color: red }

View File

@ -124,6 +124,7 @@ void Device::setStateValue(const QUuid &stateTypeId, const QVariant &value)
State newState(stateTypeId, m_id);
newState.setValue(value);
m_states[i] = newState;
emit stateValueChanged(stateTypeId, value);
return;
}
}

View File

@ -48,6 +48,9 @@ public:
QVariant stateValue(const QUuid &stateTypeId) const;
void setStateValue(const QUuid &stateTypeId, const QVariant &value);
signals:
void stateValueChanged(const QUuid &stateTypeId, const QVariant &value);
private:
Device(const QUuid &pluginId, const QUuid &id, const QUuid &deviceClassId, QObject *parent = 0);
Device(const QUuid &pluginId, const QUuid &deviceClassId, QObject *parent = 0);

View File

@ -289,6 +289,15 @@ void DeviceManager::storeConfiguredDevices()
}
}
void DeviceManager::slotDeviceStateValueChanged(const QUuid &stateTypeId, const QVariant &value)
{
Device *device = qobject_cast<Device*>(sender());
if (!device) {
return;
}
emit deviceStateChanged(device, stateTypeId, value);
}
void DeviceManager::radio433SignalReceived(QList<int> rawData)
{
foreach (Device *device, m_configuredDevices) {
@ -344,5 +353,6 @@ bool DeviceManager::setupDevice(Device *device)
return false;
}
connect(device, SIGNAL(stateValueChanged(QUuid,QVariant)), this, SLOT(slotDeviceStateValueChanged(QUuid,QVariant)));
return true;
}

View File

@ -69,6 +69,7 @@ public:
signals:
void loaded();
void emitEvent(const Event &event);
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
public slots:
DeviceError executeAction(const Action &action);
@ -78,6 +79,9 @@ private slots:
void loadConfiguredDevices();
void storeConfiguredDevices();
// Only connect this to Devices. It will query the sender()
void slotDeviceStateValueChanged(const QUuid &stateTypeId, const QVariant &value);
void radio433SignalReceived(QList<int> rawData);
void timerEvent();

View File

@ -137,7 +137,13 @@ void DevicePluginMock::executeAction(Device *device, const Action &action)
void DevicePluginMock::setState(const QUuid &stateTypeId, const QVariant &value)
{
qDebug() << "should set state" << stateTypeId << value;
HttpDaemon *daemon = qobject_cast<HttpDaemon*>(sender());
if (!daemon) {
return;
}
Device *device = m_daemons.key(daemon);
device->setStateValue(stateTypeId, value);
}
void DevicePluginMock::triggerEvent(const QUuid &id)

View File

@ -31,6 +31,7 @@
#include "jsonrpcserver.h"
#include "devicemanager.h"
#include "ruleengine.h"
#include "device.h"
#include <QDebug>
@ -78,15 +79,21 @@ GuhCore::GuhCore(QObject *parent) :
qDebug() << "*****************************************";
m_jsonServer = new JsonRPCServer(this);
connect(m_deviceManager, &DeviceManager::emitEvent, this, &GuhCore::gotSignal);
connect(m_deviceManager, &DeviceManager::emitEvent, this, &GuhCore::gotEvent);
connect(m_deviceManager, &DeviceManager::deviceStateChanged, this, &GuhCore::deviceStateChanged);
}
/*! Connected to the DeviceManager's emitEvent signal. Events received in
here will be evaluated by the \l{RuleEngine} and the according \l{Action}{Actions} are executed.*/
void GuhCore::gotSignal(const Event &event)
void GuhCore::gotEvent(const Event &event)
{
foreach (const Action &action, m_ruleEngine->evaluateEvent(event)) {
m_deviceManager->executeAction(action);
}
}
void GuhCore::deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value)
{
m_jsonServer->emitStateChangeNotification(device, stateTypeId, value);
}

View File

@ -27,6 +27,7 @@
class JsonRPCServer;
class DeviceManager;
class RuleEngine;
class Device;
class GuhCore : public QObject
{
@ -46,7 +47,8 @@ private:
RuleEngine *m_ruleEngine;
private slots:
void gotSignal(const Event &event);
void gotEvent(const Event &event);
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
};

View File

@ -85,6 +85,23 @@ JsonRPCServer::JsonRPCServer(QObject *parent):
registerHandler(new RulesHandler(this));
}
void JsonRPCServer::emitStateChangeNotification(Device *device, const QUuid &stateTypeId, const QVariant &value)
{
QVariantMap notification;
notification.insert("notification", "Device.StateChanged");
QVariantMap params;
params.insert("deviceId", device->id());
params.insert("stateTypeId", stateTypeId);
params.insert("value", value);
notification.insert("params", params);
QJsonDocument jsonDoc = QJsonDocument::fromVariant(notification);
m_tcpServer->sendData(m_clients.keys(true), jsonDoc.toJson());
}
QString JsonRPCServer::name() const
{
return QStringLiteral("JSONRPC");
@ -92,6 +109,8 @@ QString JsonRPCServer::name() const
QVariantMap JsonRPCServer::Introspect(const QVariantMap &params) const
{
Q_UNUSED(params)
QVariantMap data;
data.insert("types", JsonTypes::allTypes());
QVariantMap methods;
@ -105,6 +124,8 @@ QVariantMap JsonRPCServer::Introspect(const QVariantMap &params) const
QVariantMap JsonRPCServer::Version(const QVariantMap &params) const
{
Q_UNUSED(params)
QVariantMap data;
data.insert("version", "0.0.0");
return data;
@ -137,12 +158,14 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonDat
int commandId = message.value("id").toInt(&success);
if (!success) {
qWarning() << "Error parsing command. Missing \"id\":" << jsonData;
sendErrorResponse(clientId, commandId, "Error parsing command. Missing 'id'");
return;
}
QStringList commandList = message.value("method").toString().split('.');
if (commandList.count() != 2) {
qWarning() << "Error parsing method.\nGot:" << message.value("method").toString() << "\nExpected: \"Namespace.method\"";
sendErrorResponse(clientId, commandId, QString("Error parsing method. Got: '%1'', Expected: 'Namespace.method'").arg(message.value("method").toString()));
return;
}

View File

@ -41,6 +41,8 @@ class JsonRPCServer: public JsonHandler
public:
JsonRPCServer(QObject *parent = 0);
void emitStateChangeNotification(Device *device, const QUuid &stateTypeId, const QVariant &value);
// JsonHandler API implementation
QString name() const;
Q_INVOKABLE QVariantMap Introspect(const QVariantMap &params) const;

View File

@ -18,6 +18,8 @@
#include "mocktcpserver.h"
#include <QUuid>
QList<MockTcpServer*> MockTcpServer::s_allServers;
MockTcpServer::MockTcpServer(QObject *parent):
@ -36,6 +38,13 @@ void MockTcpServer::sendData(const QUuid &clientId, const QByteArray &data)
emit outgoingData(clientId, data);
}
void MockTcpServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
{
foreach (const QUuid &clientId, clients) {
sendData(clientId, data);
}
}
QList<MockTcpServer *> MockTcpServer::servers()
{
return s_allServers;

View File

@ -31,6 +31,7 @@ public:
~MockTcpServer();
void sendData(const QUuid &clientId, const QByteArray &data);
void sendData(const QList<QUuid> &clients, const QByteArray &data);
/************** Used for testing **************************/
static QList<MockTcpServer*> servers();

View File

@ -3,6 +3,7 @@
if test -z $5; then
echo "usage: $0 host sourceDevice eventTypeId targetDeviceId actionTypeId"
else
(echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$3'", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234
(echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "$3", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234
# (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$3'", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234
# (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$2'", "deviceId":"'$3'", "params":{"power":"false"}}, "actions": [ { "deviceId":"'$4'", "name":"rule 1", "params":{"power":"false"}},{ "deviceId":"'$5'", "name":"rule 1", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234
fi