diff --git a/Domain/FSM/FSM.py b/Domain/FSM/FSM.py
new file mode 100644
index 00000000..83cfa4a5
--- /dev/null
+++ b/Domain/FSM/FSM.py
@@ -0,0 +1,239 @@
+#!/usr/bin/env python
+
+"""
+This file contain the FSM class and the SCXMLToFSM function.
+The FSM class allows to model a Finite State Machine and to simulate the transitions.
+The FSM class uses the SCXMLToFSM function to translate a SCXML file into a dictionary compatible with the initFromSCXML FSM class method .
+A FSM instance can be initialized in two diffrent ways:
+
+FSM = FSM('On', {'start':'On', 'target':'Off', 'event':'1', 'send':'1'})
+
+or
+
+FSM = FSM()
+FSM.initFromSCXML('FSM.xml')
+
+The file FSM.xml is exported from the QFSM software only for the free text mode (http://qfsm.sourceforge.net/).
+The next state and the output are obtained using the 'next' method:
+
+FSM.next('1') -> ('Off', '1')
+"""
+
+from lxml import etree
+
+import copy
+import os, sys
+
+__author__ = "Laurent Capocchi"
+__copyright__ = "Copyright 2016, The TIC Project"
+__credits__ = ["Laurent Capocchi"]
+__license__ = "GPL"
+__version__ = "1.0.1"
+__maintainer__ = "Laurent Capocchi"
+__email__ = "capocchi@univ-corse.fr"
+__status__ = "Production"
+
+class FSM():
+ """ Finit State Machine class
+ """
+
+ def __init__(self, initState=None, transitionDict=None):
+ """ Constructor.
+
+ initstate is the inital state of the FSM
+ transititonDcit is the state transition table that defines for all transition:
+ start: the starting state
+ target: the ending state
+ send: the output associated with the transition
+ event: the event that trigger the transition
+ """
+ self._initstate = initState
+ self._transitiondict = transitionDict
+
+ self._currentstate = self._initstate
+ self._currentoutput = None
+ self._states = []
+ self._events = []
+
+ def setTransitionDict(self, val):
+ """ set the state transition table
+ """
+ self._transitiondict = val
+
+ def getTransitionDict(self):
+ """ get the state transition table
+ """
+ return self._transitiondict
+
+ def setInitState(self, val):
+ """ set the init state with the val value
+ """
+ self._initstate = val
+
+ def getInitState(self):
+ """ return the init state
+ """
+ return self._initstate
+
+ def getCurrentState(self):
+ """ return the current state
+ """
+ return self._currentstate
+
+ def setCurrentState(self, s):
+ """ set the current state
+ """
+ self._currentstate = s
+
+ def getCurrentOutput(self):
+ """ return the current output
+ """
+ return self._currentoutput
+
+ def setCurrentOutput(self, val):
+ """ set the current output
+ """
+ self._currentoutput = val
+
+ def getStates(self):
+ """
+ """
+ return self._states
+
+ def setStates(self, states):
+ """
+ """
+ self._states = states
+
+ def setEvents(self, events):
+ """
+ """
+ self._events = events
+
+ def getEvents(self):
+ """
+ """
+ return self._events
+
+ def addStates(self, s):
+ """ Add the state s into the state list
+ """
+ if not s in self._states:
+ self._states.append(s)
+
+ def addEvents(self, evt):
+ """ Add event evt to the event list
+ """
+ if not evt in self._events:
+ self._events.append(s)
+
+ def initFromSCXML(self, scxml):
+ """ Init FSM form scxml exported from QFSM (only for free text FSM)
+ """
+ D = SCXMLtoFSM(scxml)
+ if D:
+ self.setInitState(D['initialstate'])
+ self.setCurrentState(self.getInitState())
+ self.setTransitionDict(D['transitions'])
+ self.setStates(D['states'])
+ self.setEvents(D['events'])
+
+ def isCurrentState(self, s):
+ """ return True if state s is the current state
+ """
+ return self.getCurrentState() == s
+
+ def isInstates(self, s):
+ """ return True if s is in the state list
+ """
+ return s in self.getStates()
+
+ def isInEvents(self, e):
+ """ return True if e is in the event list
+ """
+ return e in self.getEvents()
+
+ def next(self, event=None):
+ """ return the next state if event is received according to the state transition table
+ """
+
+ transitionDict = self.getTransitionDict()
+ currentState = self.getCurrentState()
+ out = []
+
+ if transitionDict:
+ self._currentoutput = None
+ for d in transitionDict:
+ if d['start'] == currentState and d['event'] == event:
+ self.setCurrentState(d['target'])
+ #self.setCurrentOutput(d['send'])
+ out.append(d['send'])
+ #break
+ self.setCurrentOutput(out)
+ return (self.getCurrentState(), self.getCurrentOutput())
+
+def SCXMLtoFSM(scxml):
+ """
+ """
+
+ ### test if the first arg is a file
+ if not os.path.isfile(scxml):
+ sys.stdout.write("first arg is not a file")
+ return None
+ elif not (scxml.endswith("xml") or scxml.endswith("scxml")):
+ sys.stdout.write("arg is not a xml file")
+ return None
+ else:
+ D = {'states':[], 'events':[]}
+ TransitionsList = []
+ tree = etree.parse(scxml)
+ for node in tree.iter():
+ if 'initialstate' in node.attrib.keys():
+ D['initialstate'] = node.attrib['initialstate']
+ else:
+ if type(node.tag) is str:
+ if 'state' in node.tag:
+ s = node.attrib['id']
+ d = {'start':s}
+ D['states'].append(s)
+ elif 'transition' in node.tag:
+ d.update(node.attrib)
+ event = node.attrib['event']
+ if not (event in D['events']):
+ D['events'].append(event)
+ if node.getchildren() == []:
+ d['send']= None
+ TransitionsList.append(copy.copy(d))
+ elif 'send' in node.tag:
+ d['send']=node.attrib['event']
+ TransitionsList.append(copy.copy(d))
+
+ D['transitions'] = TransitionsList
+
+ return D
+
+if __name__ == '__main__':
+
+ print(SCXMLtoFSM("scxml\FSM.xml"))
+
+ FSM1 = FSM()
+ FSM1.initFromSCXML("scxml\FSM.xml")
+ print ("initial state ",FSM1.getCurrentState())
+
+ print ("send 1 ", FSM1.next('1'))
+ print ("send 0 ", FSM1.next('0'))
+ print ("send 0 ", FSM1.next('0'))
+ print ("send 1 ", FSM1.next('1'))
+
+ FSM2 = FSM()
+ FSM2.initFromSCXML("scxml\FSM_SC_DC.xml")
+ print ("initial state ",FSM2.getCurrentState())
+ print ("states ", FSM2.getStates())
+ print ("events ", FSM2.getEvents())
+
+ print(FSM2.getTransitionDict())
+
+ print ("send ON ", FSM2.next('ON'))
+ print ("send OFF ", FSM2.next('OFF'))
+ print ("send DC ", FSM2.next('DC'))
+ print ("send ON ", FSM2.next('ON'))
diff --git a/Domain/FSM/QFSM.amd b/Domain/FSM/QFSM.amd
new file mode 100644
index 00000000..487995fe
Binary files /dev/null and b/Domain/FSM/QFSM.amd differ
diff --git a/Domain/FSM/__init__.py b/Domain/FSM/__init__.py
new file mode 100644
index 00000000..a4a46e78
--- /dev/null
+++ b/Domain/FSM/__init__.py
@@ -0,0 +1,2 @@
+__all__=[
+]
\ No newline at end of file
diff --git a/Domain/FSM/fsm/SC_DC.fsm b/Domain/FSM/fsm/SC_DC.fsm
new file mode 100644
index 00000000..19a877b6
--- /dev/null
+++ b/Domain/FSM/fsm/SC_DC.fsm
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+ On
+ Off
+ DC
+
+ 0
+ 1
+ OFF
+ OFF
+
+
+ 0
+ 0
+ ON
+
+
+
+ 0
+ 2
+ DC
+ DC
+
+
+ 1
+ 0
+ ON
+ ON
+
+
+ 1
+ 1
+ OFF
+
+
+
+ 1
+ 2
+ DC
+ DC
+
+
+ 2
+ 2
+ DC
+
+
+
+ 2
+ 0
+ ON
+ ON
+
+
+ 2
+ 1
+ OFF
+ OFF
+
+
+
diff --git a/Domain/FSM/fsm/SC_DC_e1_e2.fsm b/Domain/FSM/fsm/SC_DC_e1_e2.fsm
new file mode 100644
index 00000000..2d81851e
--- /dev/null
+++ b/Domain/FSM/fsm/SC_DC_e1_e2.fsm
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+ ON
+ OFF
+ DC_ON
+ DC_OFF
+
+ 0
+ 1
+ e1
+ off
+
+
+ 0
+ 1
+ e2
+ off
+
+
+ 0
+ 3
+ e1e2
+ dc_off
+
+
+ 1
+ 2
+ e1e2
+ dc_on
+
+
+ 1
+ 0
+ e2
+ on
+
+
+ 1
+ 0
+ e1
+ on
+
+
+ 2
+ 3
+ e1e2
+ dc_off
+
+
+ 2
+ 1
+ e2
+ off
+
+
+ 2
+ 1
+ e1
+ off
+
+
+ 3
+ 2
+ e1e2
+ dc_on
+
+
+ 3
+ 0
+ e1
+ on
+
+
+ 3
+ 0
+ e2
+ on
+
+
+
diff --git a/Domain/FSM/scxml/FSM.xml b/Domain/FSM/scxml/FSM.xml
new file mode 100644
index 00000000..db4fe30e
--- /dev/null
+++ b/Domain/FSM/scxml/FSM.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Domain/FSM/scxml/FSM_SC_DC.xml b/Domain/FSM/scxml/FSM_SC_DC.xml
new file mode 100644
index 00000000..efedb26f
--- /dev/null
+++ b/Domain/FSM/scxml/FSM_SC_DC.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Domain/__init__.py b/Domain/__init__.py
index 035a3f6d..601f2fdd 100644
--- a/Domain/__init__.py
+++ b/Domain/__init__.py
@@ -1,5 +1,6 @@
__all__ = [
"Basic",
"Generator",
- "Collector"
+ "Collector",
+ 'FSM'
]