From specification to a user friendly visual model

The purpose for this project was to find a way to easely convert technical specifications to user friendly graphical representation.
I considered a smart house type of system for which I have specifications describing the software states of the system.

TECHNOLOGIES, OPERATING SYSTEM

  • Python 2.7
  • Windows
  • Graphviz 2.38
  • Dot
  • Eclipse Neon

Let's consider a "smart home" type of system, mounted inside a house.

Free HTML5 Template by FreeHTML5.co

It will consist mainly of two parts, one will be the hardware part, composed of an alarm mechanism, an air conditioner, a heater, a temperature sensor that will monitor and transmit the temperature and the lights from the inside the house.
The second part of the system will be an application that runs on a embedded platform which monitors and controls the hardware system. Our focus will be on the functionalities of the application.

Some very brief features of the application will be:

  • 1. the user of the system, using the application hosted on the terminal can log in/log off/create an account
  • 2. the logged in user can switch the alarm on or off
  • 3. the logged in user can switch the lights on or off.

  • The application state can be very well described with a state machine.
    All these features should cover the functionalities that the entire system is capable of, without getting into very technical details, mainly it will contain the possible states of the system, the possible transitions from one state to another, the actions that the system will do when a specific state is reached and how the system will react to commands.

    My focus will be to model this states and this transitions in a way that it will be easy to read by everybody that is part of this project and also by the potential customers.

    Having this specifications file:

    <statemachine> <state name="Idle"> <nextState name="Login" command="userLogin" log="Transition to Login screen" imageId="Default"> <nextState name="CreateNewAccount" command="userCreateAccount" log="Transition to CreateNewAccount screen" imageId="Default"> </state> <state name="Login"> <nextState name="CommandScreen" command="submitCredentials" BussinessLogicCall="validateUser() == true" text="User authenticated" imageId="Login_OK"> <nextState name="Idle" command="submitCredentials" BussinessLogicCall="validateUser() == false" text="User failed to authenticate" imageId="Login_NOK"> </state> <state name="CommandScreen"> <nextState name="Armed" command="armSystem" log="Arming system" imageId="Default"> <nextState name="ChangeTemperature" command="changeTemperature" BussinessLogicCall="validatetemperatureSources() == true" imageId="Default"> <nextState name="ConfirmationScreen" command="changeTemperature" BussinessLogicCall="validatetemperatureSources() == false" imageId="NOK"> </state> <state name="ChangeTemperature"> <nextState name="ConfirmationScreen" imageId="OK"> </state> <state name="ConfirmationScreen"> <nextState name="CommandScreen" imageId="Default"> </state> <state name="Armed"> <nextState name="Disarmed" command="disarm_system" BussinessLogicCall="disarmSystem()" text="System disarmed" imageId="Default"> </state> </statemachine>

    Having this specifications in the XML form, we need to create an application that will parse it and eventually display it in a more readable form.
    For this first step, parsing the specifications, I used Python. It is very straight forward to use, it is object oriented and with a very intuitive syntax. The code needs to be kept clean, simple and modular, it is very easy to get ambiguous calls onto objects because you can create them as you go.
    This parser can also encapsulate other specification files like for eg: mapping the screenIds with different screen pictures, or translate the conditions to more technical ones, globalization or anything that you can think of.

    Below a few Python script lines that will parse the XML:

    from xml.dom.minidom import parse from xml.sax import make_parser def readXml(filename): parser = make_parser() xml = parse(filename, parser) rootNode = _readNodes(xml) text = createGraphText(rootNode) writeGraphFiles("graph.gv", text) ..... def _readNodes(xml): nodes = [] stateNodes = xml.getElementsByTagName('state') for stateNode in stateNodes: node = Node() node.name = stateNode.getAttribute('name') node.nextNodes = _readStateTransitions(stateNode) nodes.append(node) return nodes def _readStateTransitions(stateNode): nextNodes = [] nextStateNodes = stateNode.getElementsByTagName('nextState') for nextStateNode in nextStateNodes: nextNode = Node() nextNode.name = nextStateNode.getAttribute('name') nextNode.command = nextStateNode.getAttribute('command') nextNode.BussinessLogicCall = nextStateNode.getAttribute('BussinessLogicCall') nextNode.imageId = nextStateNode.getAttribute('imageId') nextNodes.append(nextNode) return nextNodes

    Now we have all the data in a Node object, that contains nodes data and as a linked list contains a tree shaped information map about all states that are describing the system.
    After the parsing step, we will further use Python in order to generate a .gv(vector graphic) file that will be the base for the new face of our graphical model of the specification XML file.
    So, we have our data in the Node object, we need to use it to create the .gv file. To do this, we will write some simple functions:

    def createGraphText(rootNode): text = writeHeader(rootNode.name) text += createNodesText(rootNode) text += writeFooter() return text def writeHeader(diagramName): text = "" text += 'digraph "%s" {\n' % diagramName text += " rankdir=LR\n" text += " node [shape=Mrecord, color=\"#AAAAAA\", fontname=\"Arial\", fontsize=10, height=0.02, width=0.02]\n" text += " edge [color=pink, len=0.5, penwidth=4.0, fontname=\"Arial\", fontsize=12, fontcolor=\"#AA00CC\"]\n" text += "\n" return text def createNodesText(rootNode): text = "" if rootNode.name: text = ' %s [label=%s]\n' % (rootNode.name, rootNode.name) for node in rootNode.nextNodes: text += createNodesText(node) text += '\n' return text def writeFooter(): return "}\n" def writeGraphFiles(outfile, text): file(outfile, "wb").write(text) for format_ in ("svg",): dot.convertDotGraph(outfile, format_)

    convertDotGraph runs a process that executed dot.exe with filename as params and some flags set, this is configuration related so we don't need too pay much attention here.
    For running it, of course we will need dot.exe, dot.exe is added when installing Graphviz(http://www.graphviz.org/).
    After this step we will have our first graphical form of the XML specifications.

    Free HTML5 Template by FreeHTML5.co

    Get Started

    If you need some guidance in engineering field or you're seeking for some help don't hesitate to write me.

    Let's work together