示例#1
0
    def __init__(self, envPath):
        self.logger = log.PythonLoggingObserver(
            "dobozweb.core.components.environments.environmentManager")
        self.path = EnvironmentManager.envPath
        self.idCounter = EnvironmentManager.idCounter

        self._signal_channel = "environment_manager"
        self.signalHandler = SignalHander(self._signal_channel)
示例#2
0
 def __init__(self, parentEnvironment):
     self.logger = log.PythonLoggingObserver(
         "dobozweb.core.components.nodes.nodeManager")
     self.parentEnvironment = parentEnvironment
     self.nodes = {}
     self.lastNodeId = 0
     self._signal_channel = "node_manager"
     self.signalHandler = SignalHander(self._signal_channel)
     self.signal_channel_prefix = "environment_" + str(
         self.parentEnvironment.id)
示例#3
0
 def __init__(self,envPath):
     self.logger=log.PythonLoggingObserver("dobozweb.core.components.environments.environmentManager")
     self.path=EnvironmentManager.envPath
     self.idCounter=EnvironmentManager.idCounter
     
     self._signal_channel="environment_manager"
     self.signalHandler=SignalHander(self._signal_channel)
示例#4
0
    def __init__(self,type="node",name="base_node",description="base node",options={},*args,**kwargs):
        DBObject.__init__(self,**kwargs)
        self.logger=log.PythonLoggingObserver("dobozweb.core.components.nodes.node")
        self.name=name
        self.type=type
        self.description=description
        self.extra_params=options
        
        self.status=NodeStatus()
        self.driver=None 
        
        #################
        self.variables=[]
        self.elements=[]
        self.tools=[]

        
        """this is to ensure no 'asynch clash' occurs when replacing the current driver"""
        self.driverLock=defer.DeferredSemaphore(1)
        #self.rootElement=NodeComponent("root")
        
        self.testElement=None
        self.variable_test()
        #self.link_componentToEndpoint()
        #self.linkedElements=[]
        
        """this is for internal comms handling"""
        self.signal_channel_prefix=str(self.id)
        self._signal_channel="node"+self.signal_channel_prefix+"."+self.name
        self.signalHandler=SignalHander(self._signal_channel)
        self.signalHandler.add_handler(handler=self.variable_get,signal="get")
        self.signalHandler.add_handler(handler=self.variable_set,signal="set")
示例#5
0
 def __init__(self,parentEnvironment):
     self.logger=log.PythonLoggingObserver("dobozweb.core.components.nodes.nodeManager")
     self.parentEnvironment=parentEnvironment
     self.nodes={}
     self.lastNodeId=0
     self._signal_channel="node_manager"
     self.signalHandler=SignalHander(self._signal_channel)
     self.signal_channel_prefix="environment_"+str(self.parentEnvironment.id)
示例#6
0
    def __init__(self, rootUri="http://localhost"):
        DefaultRestHandler.__init__(self, rootUri)
        self.valid_contentTypes.append("application/pollapli.eventList+json")
        self.validGetParams.append('altTimeStamp')

        self._signal_channel = "global_event_listener"
        self.signalHandler = SignalHander(self._signal_channel)
        self.signalHandler.add_handler(channel="driver_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="update_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="environment_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="node_manager",
                                       handler=self._signal_Handler)
        self.lastSignal = DispatchableEvent()

        self.clientHandler = ClientHandler()
示例#7
0
class GlobalEventsHandler(DefaultRestHandler):

    isLeaf = True

    def __init__(self, rootUri="http://localhost"):
        DefaultRestHandler.__init__(self, rootUri)
        self.valid_contentTypes.append("application/pollapli.eventList+json")
        self.validGetParams.append('altTimeStamp')

        self._signal_channel = "global_event_listener"
        self.signalHandler = SignalHander(self._signal_channel)
        self.signalHandler.add_handler(channel="driver_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="update_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="environment_manager",
                                       handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="node_manager",
                                       handler=self._signal_Handler)
        self.lastSignal = DispatchableEvent()

        self.clientHandler = ClientHandler()

    def _signal_Handler(self,
                        signal=None,
                        sender=None,
                        realsender=None,
                        data=None,
                        time=None,
                        *args,
                        **kwargs):
        # log.msg("In rest event handler ", " recieved ",signal," from ",sender, "with data" ,data," addtional ",args,kwargs,logLevel=logging.CRITICAL)
        self.clientHandler.add_event(
            DispatchableEvent(signal, sender, data, realsender, time))

    def render_GET(self, request):
        """
        Handler for GET requests of events
        """
        r = ResponseGenerator(
            request,
            status=200,
            contentType="application/pollapli.eventList+json",
            resource="events",
            rootUri=self.rootUri)
        d = RequestParser(request, "events", self.valid_contentTypes,
                          self.validGetParams).ValidateAndParseParams()
        d.addCallbacks(self.clientHandler.add_delegate,
                       callbackArgs=[d, request],
                       errback=r._build_response)
        request._call = reactor.callLater(0, d.callback, None)

        return NOT_DONE_YET
示例#8
0
    def __init__(self,
                 type="node",
                 name="base_node",
                 description="base node",
                 options={},
                 *args,
                 **kwargs):
        DBObject.__init__(self, **kwargs)
        self.logger = log.PythonLoggingObserver(
            "dobozweb.core.components.nodes.node")
        self.name = name
        self.type = type
        self.description = description
        self.extra_params = options

        self.status = NodeStatus()
        self.driver = None

        #################
        self.variables = []
        self.elements = []
        self.tools = []
        """this is to ensure no 'asynch clash' occurs when replacing the current driver"""
        self.driverLock = defer.DeferredSemaphore(1)
        #self.rootElement=NodeComponent("root")

        self.testElement = None
        self.variable_test()
        #self.link_componentToEndpoint()
        #self.linkedElements=[]
        """this is for internal comms handling"""
        self.signal_channel_prefix = str(self.id)
        self._signal_channel = "node" + self.signal_channel_prefix + "." + self.name
        self.signalHandler = SignalHander(self._signal_channel)
        self.signalHandler.add_handler(handler=self.variable_get, signal="get")
        self.signalHandler.add_handler(handler=self.variable_set, signal="set")
示例#9
0
 def __init__(self,rootUri="http://localhost"):
     DefaultRestHandler.__init__(self,rootUri)  
     self.valid_contentTypes.append("application/pollapli.eventList+json")   
     self.validGetParams.append('altTimeStamp')
     
     
     self._signal_channel="global_event_listener"
     self.signalHandler=SignalHander(self._signal_channel)
     self.signalHandler.add_handler(channel="driver_manager",handler=self._signal_Handler)   
     self.signalHandler.add_handler(channel="update_manager",handler=self._signal_Handler)
     self.signalHandler.add_handler(channel="environment_manager",handler=self._signal_Handler)
     self.signalHandler.add_handler(channel="node_manager",handler=self._signal_Handler)
     self.lastSignal=DispatchableEvent()
     
     self.clientHandler=ClientHandler()
示例#10
0
class GlobalEventsHandler(DefaultRestHandler):
    
    isLeaf=True
    def __init__(self,rootUri="http://localhost"):
        DefaultRestHandler.__init__(self,rootUri)  
        self.valid_contentTypes.append("application/pollapli.eventList+json")   
        self.validGetParams.append('altTimeStamp')
        
        
        self._signal_channel="global_event_listener"
        self.signalHandler=SignalHander(self._signal_channel)
        self.signalHandler.add_handler(channel="driver_manager",handler=self._signal_Handler)   
        self.signalHandler.add_handler(channel="update_manager",handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="environment_manager",handler=self._signal_Handler)
        self.signalHandler.add_handler(channel="node_manager",handler=self._signal_Handler)
        self.lastSignal=DispatchableEvent()
        
        self.clientHandler=ClientHandler()
        

    def _signal_Handler(self,signal=None,sender=None,realsender=None,data=None,time=None,*args,**kwargs):      
       # log.msg("In rest event handler ", " recieved ",signal," from ",sender, "with data" ,data," addtional ",args,kwargs,logLevel=logging.CRITICAL)
        self.clientHandler.add_event(DispatchableEvent(signal,sender,data,realsender,time))


          
    def render_GET(self, request):
        """
        Handler for GET requests of events
        """
        r=ResponseGenerator(request,status=200,contentType="application/pollapli.eventList+json",resource="events",rootUri=self.rootUri)
        d=RequestParser(request,"events",self.valid_contentTypes,self.validGetParams).ValidateAndParseParams()
        d.addCallbacks(self.clientHandler.add_delegate,callbackArgs=[d,request],errback=r._build_response)
        request._call=reactor.callLater(0,d.callback,None)
    
        return NOT_DONE_YET
示例#11
0
class TaskManager(object):
    
    def __init__(self,parentEnvironment):
        self.tasks={}
        self.parentEnvironment=parentEnvironment
        self._signal_channel="task_manager"
        self.signalHandler=SignalHander(self._signal_channel)
    
    @defer.inlineCallbacks
    def setup(self):         
        yield self.load(self.parentEnvironment)
        self.signal_channel_prefix="environment_"+str(self.parentEnvironment.id)    
        defer.returnValue(self)
    
    def _send_signal(self,signal="",data=None):
        prefix=self.signal_channel_prefix+"."
        self.signalHandler.send_message(prefix+signal,self,data)
    
    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of tasks
    """
    
 
    @defer.inlineCallbacks
    def load(self,parentEnvironment=None,taskId=None,taskType=None,*args,**kwargs):
        if taskId is not None:
            """For retrieval of single task"""
            task=yield Task.find(where=['environment_id = ? and task_id=?', parentEnvironment.id,taskId])
            defer.returnValue(task)
        else:
            tasks=yield Task.find(where=['environment_id = ?', parentEnvironment.id])
#            for task in tasks:
#                task.environment.set(parentEnvironment) 
#                yield task.setup()
#                #temp hack           
#                actions=yield PrintAction.find(where=['task_id = ?', task.id])              
#                action=actions[0]
#                
#                actionParams=ast.literal_eval(action.params)
#                action.setup(actionParams)
#                
#                action.task.set(task)
#                action.parentTask=task
#                task.set_action(action)
#                #print("action info ptask",action.parentTask,"filename",action.printFileName)
#                self.tasks[task.id]=task
                
            
                
            defer.returnValue(tasks)
    
    @defer.inlineCallbacks
    def add_task(self,nodeId=None,nodeElement=None,name="task",description="",taskType=None,params={},*args,**kwargs):
        """
        Add a new task to the list of task of the current environment
        Params:
        name: the name of the task
        Desciption: short description of task
        type: the type of the task : very important , as it will be used to instanciate the correct class
        instance
        Connector:the connector to use for this taks
       
        """
        
        """JUST FOR TESTING !!!!
        The finding of nodes and target variables should be done using the normal element.get_subelement(params) API
        """    
        
        targetNode= yield self.parentEnvironment.get_node(1)
        targetVariable=targetNode.testElement
        print("zerzer",targetVariable)
        
        
        task=yield Task(taskType=taskType,extra_params=None).save()
        log.msg("Added  task ",name, logLevel=logging.CRITICAL)
        
        task.add_action(UpdateAndGetVariable_action(targetNode,targetVariable))
        print("Added test action")
        
        task.start()
                
#        task= yield Task(name,description,type,params).save()
#        task.environment.set(self.parentEnvironment)  
#        yield task.setup()
#        
#        action=yield PrintAction(parentTask=task,**params).save()
#        action.task.set(task)
#        task.set_action(action)
#        self.tasks[task.id]=task
#        task.start()
#            
#        print("tasks",self.tasks)
##            capability= yield NodeManager.environmentTypes[type](name,description).save()
##            capability.environment.set(self.parentEnv)
##            capability.environment.set(environment)
##            environment.capability=capability
#            #task.events.OnExited+=self._on_task_exited
#        log.msg("Added  task ",name," of type ",type," with id set to ",str(task.id), logLevel=logging.CRITICAL)
#        defer.returnValue(task)

        
    def get_tasks(self,filter=None):
        """
        Returns the list of tasks, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d=defer.Deferred()
        
        def filter_check(task,filter):
            for key in filter.keys():
                if not getattr(task, key) in filter[key]:
                    return False
            return True
      
        def get(filter,tasksList):
            print("taskList",tasksList)
            if filter:
                
                return WrapperList(data=[task for task in environmentsList if filter_check(task,filter)],rootType="tasks")
            else:               
                return WrapperList(data=tasksList,rootType="tasks")
            
        d.addCallback(get,self.tasks.values())
        reactor.callLater(0.5,d.callback,filter)
        return d
            
    def remove_task(self,id,forceStop=False):
        """Removes the task with id==id 
        Shuts down the task before removing it 
        If forcestop is true, shutdown the task even if it is running
        """
        if forceStop:
            if self.tasks[id].isRunning:
                    self.tasks[id].shutdown()
        del self.tasks[id]
        self.logger.critical ("Task %s Removed ",id)         
       
    def clear_tasks(self,forceStop=False):
        """Clears the task list completely 
        Params: forceStop: if set to true, the current running task gets stopped and removed aswell
        """
        [self.remove_task(task.id, forceStop) for task in self.tasks]
    
    def get_task(self,id):
        """
        returns the task with given id
        """
        return self.tasks[id]
    
    def start_task(self,id):
        """Starts the task in line"""
        try:
            self.logger.critical ("Starting task with id %d",id)
            self.tasks[id].connect(self.connector)
            self.tasks[id].start()
        except Exception as inst:
            self.logger.critical ("Error while starting task %s",str(inst))
   
    def stop_task(self,id):
        """Forcefully Stops the task with the given id """
        if self.tasks[id].isRunning:
            self.tasks[id].shutdown()
                
    def _on_task_exited(self,args,kargs):
        """Handles the event when the task exited (whether force stopped or because it was finished """
        self._task_shutdown()
        self.logger.critical ("Task Finished ,%g remaining tasks",len(self.tasks))
        
    def _task_shutdown(self):
        """helper function for cleaning up after a task ended """
        self.currentTask.disconnect()
        self.currentTask.events.OnExited-=self._on_task_exited
        self.currentTask=None 
        del self.tasks[0]   
示例#12
0
class NodeManager(object):
    """
    Class for managing nodes: works as a container, a handler
    and a central management point for the list of available nodes
    (for future plugin based system)
    
    
     the signal signature for node manager events is as follows: 
     -for example environment_id.node_created : this is for coherence, signal names use underscores, while hierarchy is represented by dots)
    
    """
    nodeTypes = {}

    #nodeTypes["reprap"]=ReprapCapability

    def __init__(self, parentEnvironment):
        self.logger = log.PythonLoggingObserver(
            "dobozweb.core.components.nodes.nodeManager")
        self.parentEnvironment = parentEnvironment
        self.nodes = {}
        self.lastNodeId = 0
        self._signal_channel = "node_manager"
        self.signalHandler = SignalHander(self._signal_channel)
        self.signal_channel_prefix = "environment_" + str(
            self.parentEnvironment.id)

    @defer.inlineCallbacks
    def setup(self):
        @defer.inlineCallbacks
        def addNode(nodes):
            for node in nodes:
                node.environment.set(self.parentEnvironment)
                self.nodes[node.id] = node
                yield node.setup()

        yield Node.all().addCallback(addNode)
        defer.returnValue(None)

    def _send_signal(self, signal="", data=None):
        prefix = self.signal_channel_prefix + "."
        self.signalHandler.send_message(prefix + signal, self, data)

    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of nodes
    """

    @defer.inlineCallbacks
    def add_node(self,
                 name="node",
                 description="",
                 type=None,
                 *args,
                 **kwargs):
        """
        Add a new node to the list of nodes of the current environment
        Params:
        name: the name of the node
        Desciption: short description of node
        type: the type of the node : very important , as it will be used to instanciate the correct class
        instance
        Connector:the connector to use for this node
        Driver: the driver to use for this node's connector
        """

        node = yield Node(name=name, description=description, type=type).save()
        node.environment.set(self.parentEnvironment)
        self.nodes[node.id] = node
        log.msg("Added  node ",
                name,
                " with id set to ",
                str(node.id),
                logLevel=logging.CRITICAL)
        self._send_signal("node_created", node)

        defer.returnValue(node)

    def get_nodes(self, filter=None):
        """
        Returns the list of nodes, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d = defer.Deferred()

        def filter_check(node, filter):
            for key in filter.keys():
                if not getattr(node, key) in filter[key]:
                    return False
            return True

        def get(filter, nodesList):
            if filter:
                return WrapperList(data=[
                    node for node in nodesList if filter_check(node, filter)
                ],
                                   rootType="nodes")
            else:
                return WrapperList(data=nodesList, rootType="nodes")

        d.addCallback(get, self.nodes.values())
        reactor.callLater(0.5, d.callback, filter)
        return d

    def get_node(self, id):
        if not id in self.nodes.keys():
            raise NodeNotFound()
        return self.nodes[id]

    def update_node(self, id, name=None, description=None, *args, **kwargs):
        """Method for node update"""
        node = self.nodes[id]

        @defer.inlineCallbacks
        def _update():
            node.name = name
            node.description = description
            yield node.save()
            self._send_signal("node_updated", node)
            log.msg("updating node ",
                    id,
                    "newname",
                    name,
                    "newdescrption",
                    description,
                    logLevel=logging.CRITICAL)

        _update()

        defer.succeed(node)

        #self.nodes[id].update()

    def delete_node(self, id):
        """
        Remove a node : this needs a whole set of checks, 
        as it would delete an node completely 
        Params:
        id: the id of the node
        """
        @defer.inlineCallbacks
        def _remove(id):
            """
             little "trick" for node deletion : to keep the objects id alive (as it gets removed normally before the event 
             has a chance to be dispatched), the id + data of a node to be deleted gets saved, then the event is dispatched using
              this "fake node"'s data 
            """

            nodeName = self.nodes[id].name
            tmpNode = self.nodes[id]
            tmpId = tmpNode.id
            yield self.nodes[id].delete()
            del self.nodes[id]
            tmpNode.id = tmpId
            self._send_signal("node_deleted", tmpNode)
            log.msg("Removed node ",
                    nodeName,
                    "with id ",
                    id,
                    logLevel=logging.CRITICAL)

        if not id in self.nodes.keys():
            raise NodeNotFound()
        _remove(id)
        defer.succeed(True)

    def clear_nodes(self):
        """
        Removes & deletes ALL the nodes, should be used with care
        """
        @defer.inlineCallbacks
        def _clear():
            for node in self.nodes.values():
                yield self.delete_node(node.id)
            self._send_signal("nodes_cleared", self.nodes)

        _clear()

        defer.succeed(True)

    """
    ####################################################################################
    Helper Methods    
    """

    def set_driver(self, nodeId, **kwargs):
        """Method to set a nodes connector's driver 
        Params:
        nodeId: the id of the node
        WARNING: cheap hack for now, always defaults to serial
        connector
        """
        #real clumsy, will be switched with better dynamic driver instanciation
        driver = None
        if kwargs["type"] == "teacup":
            del kwargs["type"]
            driver = TeacupDriver(**kwargs)
        elif kwargs["type"] == "fived":
            del kwargs["type"]
            driver = FiveDDriver(**kwargs)
        if driver:
            self.nodes[nodeId].connector.set_driver(driver)
            self.logger.critical(
                "Set driver for connector of node %d with params %s", nodeId,
                str(kwargs))
        else:
            raise Exception("unknown driver ")

    def start_node(self, nodeId, **kwargs):
        self.nodes[nodeId].start(**kwargs)

    def stop_node(self, nodeId):
        self.nodes[nodeId].stop()
示例#13
0
class TaskManager(object):
    def __init__(self, parentEnvironment):
        self.tasks = {}
        self.parentEnvironment = parentEnvironment
        self._signal_channel = "task_manager"
        self.signalHandler = SignalHander(self._signal_channel)

    @defer.inlineCallbacks
    def setup(self):
        yield self.load(self.parentEnvironment)
        self.signal_channel_prefix = "environment_" + str(
            self.parentEnvironment.id)
        defer.returnValue(self)

    def _send_signal(self, signal="", data=None):
        prefix = self.signal_channel_prefix + "."
        self.signalHandler.send_message(prefix + signal, self, data)

    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of tasks
    """

    @defer.inlineCallbacks
    def load(self,
             parentEnvironment=None,
             taskId=None,
             taskType=None,
             *args,
             **kwargs):
        if taskId is not None:
            """For retrieval of single task"""
            task = yield Task.find(where=[
                'environment_id = ? and task_id=?', parentEnvironment.id,
                taskId
            ])
            defer.returnValue(task)
        else:
            tasks = yield Task.find(
                where=['environment_id = ?', parentEnvironment.id])
            #            for task in tasks:
            #                task.environment.set(parentEnvironment)
            #                yield task.setup()
            #                #temp hack
            #                actions=yield PrintAction.find(where=['task_id = ?', task.id])
            #                action=actions[0]
            #
            #                actionParams=ast.literal_eval(action.params)
            #                action.setup(actionParams)
            #
            #                action.task.set(task)
            #                action.parentTask=task
            #                task.set_action(action)
            #                #print("action info ptask",action.parentTask,"filename",action.printFileName)
            #                self.tasks[task.id]=task

            defer.returnValue(tasks)

    @defer.inlineCallbacks
    def add_task(self,
                 nodeId=None,
                 nodeElement=None,
                 name="task",
                 description="",
                 taskType=None,
                 params={},
                 *args,
                 **kwargs):
        """
        Add a new task to the list of task of the current environment
        Params:
        name: the name of the task
        Desciption: short description of task
        type: the type of the task : very important , as it will be used to instanciate the correct class
        instance
        Connector:the connector to use for this taks
       
        """
        """JUST FOR TESTING !!!!
        The finding of nodes and target variables should be done using the normal element.get_subelement(params) API
        """

        targetNode = yield self.parentEnvironment.get_node(1)
        targetVariable = targetNode.testElement
        print("zerzer", targetVariable)

        task = yield Task(taskType=taskType, extra_params=None).save()
        log.msg("Added  task ", name, logLevel=logging.CRITICAL)

        task.add_action(UpdateAndGetVariable_action(targetNode,
                                                    targetVariable))
        print("Added test action")

        task.start()

#        task= yield Task(name,description,type,params).save()
#        task.environment.set(self.parentEnvironment)
#        yield task.setup()
#
#        action=yield PrintAction(parentTask=task,**params).save()
#        action.task.set(task)
#        task.set_action(action)
#        self.tasks[task.id]=task
#        task.start()
#
#        print("tasks",self.tasks)
##            capability= yield NodeManager.environmentTypes[type](name,description).save()
##            capability.environment.set(self.parentEnv)
##            capability.environment.set(environment)
##            environment.capability=capability
#            #task.events.OnExited+=self._on_task_exited
#        log.msg("Added  task ",name," of type ",type," with id set to ",str(task.id), logLevel=logging.CRITICAL)
#        defer.returnValue(task)

    def get_tasks(self, filter=None):
        """
        Returns the list of tasks, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d = defer.Deferred()

        def filter_check(task, filter):
            for key in filter.keys():
                if not getattr(task, key) in filter[key]:
                    return False
            return True

        def get(filter, tasksList):
            print("taskList", tasksList)
            if filter:

                return WrapperList(data=[
                    task for task in environmentsList
                    if filter_check(task, filter)
                ],
                                   rootType="tasks")
            else:
                return WrapperList(data=tasksList, rootType="tasks")

        d.addCallback(get, self.tasks.values())
        reactor.callLater(0.5, d.callback, filter)
        return d

    def remove_task(self, id, forceStop=False):
        """Removes the task with id==id 
        Shuts down the task before removing it 
        If forcestop is true, shutdown the task even if it is running
        """
        if forceStop:
            if self.tasks[id].isRunning:
                self.tasks[id].shutdown()
        del self.tasks[id]
        self.logger.critical("Task %s Removed ", id)

    def clear_tasks(self, forceStop=False):
        """Clears the task list completely 
        Params: forceStop: if set to true, the current running task gets stopped and removed aswell
        """
        [self.remove_task(task.id, forceStop) for task in self.tasks]

    def get_task(self, id):
        """
        returns the task with given id
        """
        return self.tasks[id]

    def start_task(self, id):
        """Starts the task in line"""
        try:
            self.logger.critical("Starting task with id %d", id)
            self.tasks[id].connect(self.connector)
            self.tasks[id].start()
        except Exception as inst:
            self.logger.critical("Error while starting task %s", str(inst))

    def stop_task(self, id):
        """Forcefully Stops the task with the given id """
        if self.tasks[id].isRunning:
            self.tasks[id].shutdown()

    def _on_task_exited(self, args, kargs):
        """Handles the event when the task exited (whether force stopped or because it was finished """
        self._task_shutdown()
        self.logger.critical("Task Finished ,%g remaining tasks",
                             len(self.tasks))

    def _task_shutdown(self):
        """helper function for cleaning up after a task ended """
        self.currentTask.disconnect()
        self.currentTask.events.OnExited -= self._on_task_exited
        self.currentTask = None
        del self.tasks[0]
示例#14
0
 def __init__(self, parentEnvironment):
     self.tasks = {}
     self.parentEnvironment = parentEnvironment
     self._signal_channel = "task_manager"
     self.signalHandler = SignalHander(self._signal_channel)
示例#15
0
class NodeManager(object):
    """
    Class for managing nodes: works as a container, a handler
    and a central management point for the list of available nodes
    (for future plugin based system)
    
    
     the signal signature for node manager events is as follows: 
     -for example environment_id.node_created : this is for coherence, signal names use underscores, while hierarchy is represented by dots)
    
    """
    nodeTypes={}
    #nodeTypes["reprap"]=ReprapCapability
    
    def __init__(self,parentEnvironment):
        self.logger=log.PythonLoggingObserver("dobozweb.core.components.nodes.nodeManager")
        self.parentEnvironment=parentEnvironment
        self.nodes={}
        self.lastNodeId=0
        self._signal_channel="node_manager"
        self.signalHandler=SignalHander(self._signal_channel)
        self.signal_channel_prefix="environment_"+str(self.parentEnvironment.id)
     
    @defer.inlineCallbacks    
    def setup(self):
       
        @defer.inlineCallbacks
        def addNode(nodes):
            for node in nodes:
                node.environment.set(self.parentEnvironment)
                self.nodes[node.id]=node
                yield node.setup()
               
        yield Node.all().addCallback(addNode)
        defer.returnValue(None)
    
    
    def _send_signal(self,signal="",data=None):
        prefix=self.signal_channel_prefix+"."
        self.signalHandler.send_message(prefix+signal,self,data)    
    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of nodes
    """
    @defer.inlineCallbacks
    def add_node(self,name="node",description="",type=None,*args,**kwargs):
        """
        Add a new node to the list of nodes of the current environment
        Params:
        name: the name of the node
        Desciption: short description of node
        type: the type of the node : very important , as it will be used to instanciate the correct class
        instance
        Connector:the connector to use for this node
        Driver: the driver to use for this node's connector
        """
            
        
        node= yield Node(name=name,description=description,type=type).save()
        node.environment.set(self.parentEnvironment)
        self.nodes[node.id]=node
        log.msg("Added  node ",name," with id set to ",str(node.id), logLevel=logging.CRITICAL)
        self._send_signal("node_created", node)
       
        defer.returnValue(node)
        
    
    def get_nodes(self,filter=None):
        """
        Returns the list of nodes, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d=defer.Deferred()
        
        def filter_check(node,filter):
            for key in filter.keys():
                if not getattr(node, key) in filter[key]:
                    return False
            return True
      
        def get(filter,nodesList):
            if filter:
                return WrapperList(data=[node for node in nodesList if filter_check(node,filter)],rootType="nodes")
            else:               
                return WrapperList(data=nodesList,rootType="nodes")
            
        d.addCallback(get,self.nodes.values())
        reactor.callLater(0.5,d.callback,filter)
        return d
    
    def get_node(self,id):
        if not id in self.nodes.keys():
            raise NodeNotFound()
        return self.nodes[id]
    
    
    def update_node(self,id,name=None,description=None,*args,**kwargs):
        """Method for node update"""   
        node=self.nodes[id]
        
        @defer.inlineCallbacks
        def _update():
            node.name=name
            node.description=description
            yield node.save()
            self._send_signal("node_updated", node)
            log.msg("updating node ",id,"newname",name,"newdescrption",description,logLevel=logging.CRITICAL)
        _update()
        
        
        defer.succeed(node)

        #self.nodes[id].update()
    
    
    def delete_node(self,id):
        """
        Remove a node : this needs a whole set of checks, 
        as it would delete an node completely 
        Params:
        id: the id of the node
        """
        @defer.inlineCallbacks
        def _remove(id):
            """
             little "trick" for node deletion : to keep the objects id alive (as it gets removed normally before the event 
             has a chance to be dispatched), the id + data of a node to be deleted gets saved, then the event is dispatched using
              this "fake node"'s data 
            """
           
            nodeName=self.nodes[id].name    
            tmpNode=self.nodes[id]
            tmpId=tmpNode.id
            yield self.nodes[id].delete() 
            del self.nodes[id]
            tmpNode.id=tmpId
            self._send_signal("node_deleted", tmpNode)
            log.msg("Removed node ",nodeName,"with id ",id,logLevel=logging.CRITICAL)
        if not id in self.nodes.keys():
            raise NodeNotFound()
        _remove(id)
        defer.succeed(True)
 
            
    
    def clear_nodes(self):
        """
        Removes & deletes ALL the nodes, should be used with care
        """
        @defer.inlineCallbacks
        def _clear():
            for node in self.nodes.values():
                yield self.delete_node(node.id)  
            self._send_signal("nodes_cleared", self.nodes)   
        _clear();  
             
        defer.succeed(True)     

   
    """
    ####################################################################################
    Helper Methods    
    """
        
    def set_driver(self,nodeId,**kwargs):
        """Method to set a nodes connector's driver 
        Params:
        nodeId: the id of the node
        WARNING: cheap hack for now, always defaults to serial
        connector
        """
        #real clumsy, will be switched with better dynamic driver instanciation
        driver=None
        if kwargs["type"]== "teacup":
            del kwargs["type"]
            driver=TeacupDriver(**kwargs)
        elif kwargs["type"]=="fived":
            del kwargs["type"]
            driver=FiveDDriver(**kwargs)
        if driver:
            self.nodes[nodeId].connector.set_driver(driver)  
            self.logger.critical("Set driver for connector of node %d with params %s",nodeId,str(kwargs))
        else:
            raise Exception("unknown driver ")
        
    def start_node(self,nodeId,**kwargs):
        self.nodes[nodeId].start(**kwargs)
        
    def stop_node(self,nodeId):
        self.nodes[nodeId].stop()
示例#16
0
class EnvironmentManager(object):
    """
    Class acting as a central access point for all the functionality of environments
    """
    envPath=None
    environments={}
    idCounter=1
    def __init__(self,envPath):
        self.logger=log.PythonLoggingObserver("dobozweb.core.components.environments.environmentManager")
        self.path=EnvironmentManager.envPath
        self.idCounter=EnvironmentManager.idCounter
        
        self._signal_channel="environment_manager"
        self.signalHandler=SignalHander(self._signal_channel)
    
    @classmethod
    @defer.inlineCallbacks
    def setup(cls,*args,**kwargs):
        """Retrieve all existing environments from disk"""
        maxFoundId=1
        for fileDir in os.listdir(EnvironmentManager.envPath): 
            if os.path.isdir(os.path.join(EnvironmentManager.envPath,fileDir)):        
                envName= fileDir
                envPath=os.path.join(EnvironmentManager.envPath,envName)
                dbPath=os.path.join(envPath,envName)+".db"
                if os.path.exists(dbPath):
                    Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",database=dbPath,check_same_thread=False)
                    @defer.inlineCallbacks        
                    def addEnv(env,maxFoundId):
                        EnvironmentManager.environments[env[0].id]=env[0]
                        yield env[0].setup()
                        if env[0].id>maxFoundId:
                            maxFoundId=env[0].id
                        
                        defer.returnValue(maxFoundId)
                    
                    maxFoundId=yield Environment.find().addCallback(addEnv,maxFoundId)
                    EnvironmentManager.idCounter=maxFoundId+1
                    #temporary: this should be recalled from db from within the environments ?
        
        log.msg("Environment manager setup correctly", system="environement manager", logLevel=logging.CRITICAL)
        
    def __getattr__(self, attr_name):
        for env in self.environments.values():
            if hasattr(env, attr_name):
                return getattr(env, attr_name)
        raise AttributeError(attr_name)
        
        
    def stop(self):
        """
        Shuts down the environment manager and everything associated with it : ie EVERYTHING !!
        Should not be called in most cases
        """
        pass

    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of environements
    """
    @defer.inlineCallbacks
    def add_environment(self,name="home_test",description="Add Description here",status="frozen"):
        """
        Add an environment to the list of managed environements : 
        Automatically creates a new folder and launches the new environement auto creation
        Params:
        EnvName: the name of the environment
        description:a short description of the environment
        status: either frozen or live : whether the environment is active or not
        """
        envPath=os.path.join(self.path,name)  
        dbpath=os.path.join(envPath,name)+".db"
        
        #if such an environment does not exist, add it
        doCreate=True
        if name in os.listdir(self.path):
            if os.path.exists(os.path.join(self.path,name,dbpath)):
                doCreate=False
        else:
            os.mkdir(envPath)
        
        if doCreate:
            Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",database=dbpath,check_same_thread=False)
            
            env=Environment(path=envPath,name=name,description=description,status=status)
            yield self._generateDatabase()
            yield env.save()  
            
            """rather horrid hack of sorts, required to have different, sequential id in the different dbs"""
            self.force_id(self.idCounter)  
            Registry.DBPOOL.close()
            Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",database=dbpath,check_same_thread=False)
            
            def addEnv(env):
                self.environments[env[0].id]=env[0]
                self.idCounter+=1
            yield Environment.find().addCallback(addEnv)
            
            env=self.environments[self.idCounter-1]
            self.signalHandler.send_message("environment.created",self,env)
            log.msg("Adding environment named:",name ," description:",description,"with id",env.id, system="environment manager", logLevel=logging.CRITICAL)         
            defer.returnValue(env)
        else:
            raise EnvironmentAlreadyExists()

        defer.returnValue(None) 
    

    def get_environments(self,filter=None):
        """
        Returns the list of environments, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d=defer.Deferred()
        
        def filter_check(env,filter):
            for key in filter.keys():
                if not getattr(env, key) in filter[key]:
                    return False
            return True
      
        def get(filter,envsList):
            if filter:
                #return [env for env in self.environments if getattr(env, "id") in filter["id"]]
                #return [env for env in self.environments if [True for key in filter.keys() if getattr(env, key)in filter[key]]]
              
                return WrapperList(data=[env for env in envsList if filter_check(env,filter)],rootType="environments")
            else:
                return WrapperList(data=envsList,rootType="environments")
            
        d.addCallback(get,self.environments.values())
        reactor.callLater(0.5,d.callback,filter)
        return d
    
    def get_environment(self,envId):      
        env=self.environments.get(envId)
        if env is None:
            raise EnvironmentNotFound()
        return env
    
    def update_environment(self,id,name,description,status):
        #print("updating env",id,name,description,status)
        return self.environments[id].update(name,description,status)
    
    def remove_environment(self,id):
        """
        Remove an environment : this needs a whole set of checks, 
        as it would delete an environment completely (very dangerous)
        Params:
        name: the name of the environment
        """
        d=defer.Deferred()
        def remove(id,envs,path):
            try:
                Registry.DBPOOL.close()
                envName=envs[id].name
                envPath=os.path.join(path,envName)    
                #self.environments[envName].shutdown()
                del envs[id]
                if os.path.isdir(envPath): 
                    shutil.rmtree(envPath)
                            #self.logger.critical("Removed and deleted envrionment: '%s' at : '%s'",envName,envPath) 
                    log.msg("Removed environment ",envName,"with id ",id, system="environment manager",logLevel=logging.CRITICAL)
            except:
                pass
                #should raise  specific exception
                #raise Exception("failed to delete env")
        d.addCallback(remove,self.environments,self.path)
        reactor.callLater(0,d.callback,id)
        return d

        
    @defer.inlineCallbacks
    def clear_environments(self):
        """
        Removes & deletes ALL the environments, should be used with care
        """
        print(self.environments)
        for env in self.environments.values():
            yield self.remove_environment(env.id)        
        defer.returnValue(None)
    """
    ####################################################################################
    Helper Methods    
    """
    @defer.inlineCallbacks
    def force_id(self,id):     
        query=   '''UPDATE environments SET id ='''+str(id)+''' where id=1'''
        yield Registry.DBPOOL.runQuery(query)
        defer.returnValue(None)
    
    @defer.inlineCallbacks
    def _generateMasterDatabase(self):
        yield Registry.DBPOOL.runQuery('''CREATE TABLE environments(
             id INTEGER PRIMARY KEY ,
             name TEXT,
             status TEXT NOT NULL DEFAULT "Live",
             description TEXT
             )''')
    @defer.inlineCallbacks
    def _generateDatabase(self):
        yield Registry.DBPOOL.runQuery('''CREATE TABLE addons(
             id INTEGER PRIMARY KEY,
             name TEXT,
             description TEXT,
             active boolean NOT NULL default true           
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE environments(
             id INTEGER PRIMARY KEY,
             name TEXT,
             description TEXT,
             status TEXT NOT NULL DEFAULT "Live"
             )''')
        
        yield Registry.DBPOOL.runQuery('''CREATE TABLE nodes(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             environment_id INTEGER NOT NULL,
             type TEXT NOT NULL ,
             name TEXT,          
             description TEXT,
             recipe TEXT,
            FOREIGN KEY(environment_id) REFERENCES environments(id) 
             )''')
        
      #FOREIGN KEY(node_id) REFERENCES nodes(id)  
        yield Registry.DBPOOL.runQuery('''CREATE TABLE drivers(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             driverType TEXT NOT NULL,
             deviceType TEXT NOT NULL ,
             deviceId TEXT,
             options BLOB  ,
             FOREIGN KEY(node_id) REFERENCES nodes(id)      
             )''')
        
        yield Registry.DBPOOL.runQuery('''CREATE TABLE tasks(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             environment_id INTEGER NOT NULL,
             name TEXT,          
             description TEXT,
             type TEXT,
             params TEXT,
             FOREIGN KEY(environment_id) REFERENCES environments(id)  
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE actions(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             task_id INTEGER NOT NULL,
             actionType TEXT,          
             params TEXT,
             FOREIGN KEY(task_id) REFERENCES tasks(id)
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE conditions(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             task_id INTEGER NOT NULL,
             name TEXT,          
             description TEXT,
             FOREIGN KEY(task_id) REFERENCES tasks(id)
             )''')
        
       
             
        yield Registry.DBPOOL.runQuery('''CREATE TABLE sensors(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             captureType TEXT NOT NULL,
             captureMode TEXT NOT NULL DEFAULT "Analog",
             type TEXT NOT NULL ,
             realName TEXT NOT NULL,
             name TEXT,
             description TEXT,
             FOREIGN KEY(node_id) REFERENCES nodes(id)
             )''')
        
        yield Registry.DBPOOL.runQuery('''CREATE TABLE readings(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             sensor_id INTEGER NOT NULL,
             data INTEGER NOT NULL,
             dateTime TEXT NOT NULL,
             FOREIGN KEY(node_id) REFERENCES nodes(id),
             FOREIGN KEY(sensor_id) REFERENCES sensors(id)
             )''')
        """this should be in the master db, but will have to do for now (only support for one environment,
        because of the limitations of twistar: one db )"""
        
        yield Registry.DBPOOL.runQuery('''CREATE TABLE updates(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             type TEXT NOT NULL,
             name TEXT NOT NULL,
             description TEXT,
             version TEXT NOT NULL,
             downloadUrl TEXT NOT NULL,
             tags TEXT NOT NULL,
             img TEXT NOT NULL,
             file TEXT NOT NULL,
             fileHash TEXT NOT NULL,
             downloaded TEXT NOT NULL,
             installed TEXT NOT NULL,
             enabled TEXT NOT NULL
             
             )''')
        
        defer.returnValue(None)
示例#17
0
class Node(DBObject):
    """
    Base class for all nodes: a hardware node is a software component handling either a physical device such as a webcam, reprap , arduino etc
    or some software node (pachube etc)
    """
    BELONGSTO = ['environment']
    EXPOSE=["name","description","id","type","status","driver"]
    
    def __init__(self,type="node",name="base_node",description="base node",options={},*args,**kwargs):
        DBObject.__init__(self,**kwargs)
        self.logger=log.PythonLoggingObserver("dobozweb.core.components.nodes.node")
        self.name=name
        self.type=type
        self.description=description
        self.extra_params=options
        
        self.status=NodeStatus()
        self.driver=None 
        
        #################
        self.variables=[]
        self.elements=[]
        self.tools=[]

        
        """this is to ensure no 'asynch clash' occurs when replacing the current driver"""
        self.driverLock=defer.DeferredSemaphore(1)
        #self.rootElement=NodeComponent("root")
        
        self.testElement=None
        self.variable_test()
        #self.link_componentToEndpoint()
        #self.linkedElements=[]
        
        """this is for internal comms handling"""
        self.signal_channel_prefix=str(self.id)
        self._signal_channel="node"+self.signal_channel_prefix+"."+self.name
        self.signalHandler=SignalHander(self._signal_channel)
        self.signalHandler.add_handler(handler=self.variable_get,signal="get")
        self.signalHandler.add_handler(handler=self.variable_set,signal="set")
        
    @defer.inlineCallbacks
    def setup(self):
        self.driver=yield DriverManager.load(parentNode=self)
        
        env= (yield self.environment.get())
        self.signal_channel_prefix="environment_"+str(env.id)+".node_"+str(self.id)
        
        log.msg("Node with id",self.id, "setup successfully",system="Node", logLevel=logging.CRITICAL)
        self.elementsandVarsTest()
        defer.returnValue(None)
        
    def add_command(self,command):  
        log.msg("Node with id",self.id, "recieved command",command,system="Node", logLevel=logging.CRITICAL)
        
        
    def link_componentToEndpoint(self):
        self.tempSensor.set_endPoint(self.driver.endpoints[0])
        self.linkedElements.append(self.tempSensor)
        
    def query_driver(self,sender=None):
        #f sender in self.linkedElements:
        if isinstance(sender,Variable):
           sender.attachedSensors["root"].driverEndpoint.get() 
        
        
    def variable_set(self,sender,varName,*args,**kwargs):
        self.variables[varName].set(*args,**kwargs)
    def variable_get(self,sender,varName,*args,**kwargs):
        self.variables[varName].set(*args,**kwargs)
    
    def variable_test(self):
        temp=Variable(self,"temperature",0,float,"celcius",0,"db")   
        tempSensor=Sensor(type="Sensor",name="temperature sensor",tool="testTool") 
        temp.attach_sensor(tempSensor)
        self.tempSensor=tempSensor
        self.testElement=temp
    
    def elementsandVarsTest(self):
        """test method, for experimental composition of nodes: this creates all the elements for a basic 
        reprap type node"""
        
        """CARTESIAN BOT DEFINITION"""
        """3d Position"""
        pos=Variable(self,"position",Vector(['x','y','z']),"vector","mm",None,"memory",3,True,['x','y','z'])     
        """all the motors/actors controlling the 3d Position"""
        mot1=Actor(type="StepperMotor",name="x_motor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        mot2=Actor(type="StepperMotor",name="y_motor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        mot3=Actor(type="StepperMotor",name="z_motor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        """all the sensors giving feedback on  the 3d Position"""
        endStop1=Sensor(type="end_sensor",name="x_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        endStop2=Sensor(type="end_sensor",name="x_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        endStop3=Sensor(type="end_sensor",name="y_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        endStop4=Sensor(type="end_sensor",name="y_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        endStop5=Sensor(type="end_sensor",name="z_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        endStop6=Sensor(type="end_sensor",name="z_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        """add all these to the current node"""
        self.add_variable(pos)
        self.add_elements([mot1,mot2,mot3,endStop1,endStop2,endStop3,endStop4,endStop5,endStop6])
        pos.attach_sensors([(endStop1,endStop1.channel),(endStop2,endStop2.channel),(endStop3,endStop3.channel),
                            (endStop4,endStop4.channel),(endStop5,endStop5.channel),(endStop6,endStop6.channel)])
        pos.attach_actors([(mot1,mot1.channel),(mot2,mot2.channel),(mot3,mot3.channel)])
        
        """EXTRUDER 1 DEFINITION"""
        """two variables"""
        head_temp=Variable(self,"head_temp",0,"temperature","celcius")
        extrudate_lng=Variable(self,"filament_extrudate",Vector(['e']),"vector","mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot=Actor(type="StepperMotor",name="e_motor1",tool="PrintHead",boundVariable=extrudate_lng,variableChannel='e')
        head_heater=Actor(type="Heater",name="extruder1_heater",tool="PrintHead",boundVariable=head_temp)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor=Sensor(type="temperature_sensor",name="extruder1_temp_sensor",tool="PrintHead",boundVariable=head_temp)
     
        extrudate_lng.attach_actor(extrudMot,'e')
        head_temp.attach_both([(head_heater,None)],[(head_tempSensor,None)])
        
    def elementsandVarsTest2(self):
        """test method, for experimental composition of nodes: this creates all the elements for a basic 
        reprap type node"""
       
        """CARTESIAN BOT DEFINITION"""
        cartesianBot=NodeComponent("cartesian_bot",self.rootElement)
        """3d Position"""
        pos=Variable(self,"3d_position",Vector(['x','y','z']),"vector","mm",None,"memory",3,True,None,None,['x','y','z'])     
        """all the motors/actors controlling the 3d Position"""
        mot1=Actor(type="StepperMotor",name="x_motor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        mot2=Actor(type="StepperMotor",name="y_motor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        mot3=Actor(type="StepperMotor",name="z_motor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        """all the sensors giving feedback on  the 3d Position"""
        endStop1=Sensor(type="end_sensor",name="x_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        endStop2=Sensor(type="end_sensor",name="x_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='x')
        endStop3=Sensor(type="end_sensor",name="y_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        endStop4=Sensor(type="end_sensor",name="y_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='y')
        endStop5=Sensor(type="end_sensor",name="z_startSensor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        endStop6=Sensor(type="end_sensor",name="z_endSensor",tool="cartesianBot",boundVariable=pos,variableChannel='z')
        """add all these to the current tool"""
        cartesianBot.add_child(pos)
        cartesianBot.add_children([mot1,mot2,mot3,endStop1,endStop2,endStop3,endStop4,endStop5,endStop6])
        
        """EXTRUDER 1 DEFINITION"""
        """two variables"""
        extruder1=Tool("extruder1")
        head_temp=Variable(self,"head_temp",0,"temperature","celcius")
        extrudate_lng=Variable(self,"filament_extrudate",Vector(['e']),"vector","mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot=Actor(type="StepperMotor",name="e_motor1",tool="PrintHead",boundVariable=extrudate_lng,variableChannel='e')
        head_heater=Actor(type="Heater",name="extruder1_heater",tool="PrintHead",boundVariable=head_temp)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor=Sensor(type="temperature_sensor",name="extruder1_temp_sensor",tool="PrintHead",boundVariable=head_temp)
     
        extrudate_lng.attach_actor(extrudMot,'e')
        head_temp.attach_both([(head_heater,None)],[(head_tempSensor,None)])
        
        """EXTRUDER 2 DEFINITION"""
        """two variables"""
        extruder2=Tool("extruder2")
        head_temp2=Variable(self,"head_temp",0,"temperature","celcius")
        extrudate_lng2=Variable(self,"filament_extrudate",Vector(['e']),"vector","mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot2=Actor(type="StepperMotor",name="e_motor1",tool="PrintHead",boundVariable=extrudate_lng2,variableChannel='e')
        head_heater2=Actor(type="Heater",name="extruder1_heater",tool="PrintHead",boundVariable=head_temp2)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor=Sensor(type="temperature_sensor",name="extruder1_temp_sensor",tool="PrintHead",boundVariable=head_temp2)
     
        extrudate_lng2.attach_actor(extrudMot2,'e')
        head_temp2.attach_both([(head_heater2,None)],[(head_tempSensor2,None)])
        
        """"""""""""""""""""""""""""""""
        cartesianBot.add_child(extruder1)
        cartesianBot.add_child(extruder2)
        
        
    
           
    def _toDict(self):
        return {"node":{"id":self.id,"name":self.name,"description":self.description,"type":self.type,"driver":{"status":{"connected":True},"type":None,"driver":None},"link":{"rel":"node"}}}
   
    
    @defer.inlineCallbacks
    def set_driver(self,params={},*args,**kwargs):
        """
        Method to set this node's connector 
        Params:
        returns : a driver instance
        connector
        """
        
        @defer.inlineCallbacks
        def update():
            yield self.delete_driver()
            self.driver=yield DriverManager.create(parentNode=self,**kwargs)
            
            log.msg("Set driver of node",self.id," with params ", kwargs,system="Node")
            defer.returnValue(None)
        yield self.driverLock.run(update)
     
        
        defer.returnValue(self.driver)
                    
        
    def get_driver(self):
        if self.driver:
            return self.driver 
        else: 
            raise NoDriverSet()
    
    @defer.inlineCallbacks
    def delete_driver(self):
        if self.driver:
            self.driver.disconnect()    
            DriverManager._unregister_driver(self.driver) 
            yield self.driver.delete()
            self.driver=None         
            log.msg("Disconnected and removed driver", logLevel=logging.CRITICAL,system="Node")
        defer.returnValue(None)
        
    def start(self):
        """
        start this node
        """
        pass
    def stop(self):
        """stop this node
        """
        
    def add_variable(self,variable,*args,**kwarg):
        self.variables.append(variable)
    def remove_variable(self,variable,*args,**kwargs):
        self.variables.remove(variable)
        
    def add_element(self,element,*args,**kwargs):
        self.elements.append(element)
    def add_elements(self,elements,*args,**kwargs):
        for element in elements:
            self.elements.append(element)
    def remove_element(self,element,*args,**kwargs):
        self.elements.remove(elment)
    
    
    def connect(self,*args,**kwargs):
        d=defer.Deferred()
        def doConnect(driver):
            driver.connect(*args,**kwargs)
            return driver
        d.addCallback(doConnect)
        reactor.callLater(0,d.callback,self.driver)
        return d
           
    def disconnect(self):
        d=defer.Deferred()
        def doDisconnect(driver):
            driver.disconnect()
            return driver
        d.addCallback(doDisconnect)
        reactor.callLater(0,d.callback,self.driver)
        return d
示例#18
0
class Node(DBObject):
    """
    Base class for all nodes: a hardware node is a software component handling either a physical device such as a webcam, reprap , arduino etc
    or some software node (pachube etc)
    """
    BELONGSTO = ['environment']
    EXPOSE = ["name", "description", "id", "type", "status", "driver"]

    def __init__(self,
                 type="node",
                 name="base_node",
                 description="base node",
                 options={},
                 *args,
                 **kwargs):
        DBObject.__init__(self, **kwargs)
        self.logger = log.PythonLoggingObserver(
            "dobozweb.core.components.nodes.node")
        self.name = name
        self.type = type
        self.description = description
        self.extra_params = options

        self.status = NodeStatus()
        self.driver = None

        #################
        self.variables = []
        self.elements = []
        self.tools = []
        """this is to ensure no 'asynch clash' occurs when replacing the current driver"""
        self.driverLock = defer.DeferredSemaphore(1)
        #self.rootElement=NodeComponent("root")

        self.testElement = None
        self.variable_test()
        #self.link_componentToEndpoint()
        #self.linkedElements=[]
        """this is for internal comms handling"""
        self.signal_channel_prefix = str(self.id)
        self._signal_channel = "node" + self.signal_channel_prefix + "." + self.name
        self.signalHandler = SignalHander(self._signal_channel)
        self.signalHandler.add_handler(handler=self.variable_get, signal="get")
        self.signalHandler.add_handler(handler=self.variable_set, signal="set")

    @defer.inlineCallbacks
    def setup(self):
        self.driver = yield DriverManager.load(parentNode=self)

        env = (yield self.environment.get())
        self.signal_channel_prefix = "environment_" + str(
            env.id) + ".node_" + str(self.id)

        log.msg("Node with id",
                self.id,
                "setup successfully",
                system="Node",
                logLevel=logging.CRITICAL)
        self.elementsandVarsTest()
        defer.returnValue(None)

    def add_command(self, command):
        log.msg("Node with id",
                self.id,
                "recieved command",
                command,
                system="Node",
                logLevel=logging.CRITICAL)

    def link_componentToEndpoint(self):
        self.tempSensor.set_endPoint(self.driver.endpoints[0])
        self.linkedElements.append(self.tempSensor)

    def query_driver(self, sender=None):
        #f sender in self.linkedElements:
        if isinstance(sender, Variable):
            sender.attachedSensors["root"].driverEndpoint.get()

    def variable_set(self, sender, varName, *args, **kwargs):
        self.variables[varName].set(*args, **kwargs)

    def variable_get(self, sender, varName, *args, **kwargs):
        self.variables[varName].set(*args, **kwargs)

    def variable_test(self):
        temp = Variable(self, "temperature", 0, float, "celcius", 0, "db")
        tempSensor = Sensor(type="Sensor",
                            name="temperature sensor",
                            tool="testTool")
        temp.attach_sensor(tempSensor)
        self.tempSensor = tempSensor
        self.testElement = temp

    def elementsandVarsTest(self):
        """test method, for experimental composition of nodes: this creates all the elements for a basic 
        reprap type node"""
        """CARTESIAN BOT DEFINITION"""
        """3d Position"""
        pos = Variable(self, "position", Vector(['x', 'y', 'z']), "vector",
                       "mm", None, "memory", 3, True, ['x', 'y', 'z'])
        """all the motors/actors controlling the 3d Position"""
        mot1 = Actor(type="StepperMotor",
                     name="x_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='x')
        mot2 = Actor(type="StepperMotor",
                     name="y_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='y')
        mot3 = Actor(type="StepperMotor",
                     name="z_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='z')
        """all the sensors giving feedback on  the 3d Position"""
        endStop1 = Sensor(type="end_sensor",
                          name="x_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='x')
        endStop2 = Sensor(type="end_sensor",
                          name="x_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='x')
        endStop3 = Sensor(type="end_sensor",
                          name="y_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='y')
        endStop4 = Sensor(type="end_sensor",
                          name="y_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='y')
        endStop5 = Sensor(type="end_sensor",
                          name="z_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='z')
        endStop6 = Sensor(type="end_sensor",
                          name="z_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='z')
        """add all these to the current node"""
        self.add_variable(pos)
        self.add_elements([
            mot1, mot2, mot3, endStop1, endStop2, endStop3, endStop4, endStop5,
            endStop6
        ])
        pos.attach_sensors([(endStop1, endStop1.channel),
                            (endStop2, endStop2.channel),
                            (endStop3, endStop3.channel),
                            (endStop4, endStop4.channel),
                            (endStop5, endStop5.channel),
                            (endStop6, endStop6.channel)])
        pos.attach_actors([(mot1, mot1.channel), (mot2, mot2.channel),
                           (mot3, mot3.channel)])
        """EXTRUDER 1 DEFINITION"""
        """two variables"""
        head_temp = Variable(self, "head_temp", 0, "temperature", "celcius")
        extrudate_lng = Variable(self, "filament_extrudate", Vector(['e']),
                                 "vector", "mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot = Actor(type="StepperMotor",
                          name="e_motor1",
                          tool="PrintHead",
                          boundVariable=extrudate_lng,
                          variableChannel='e')
        head_heater = Actor(type="Heater",
                            name="extruder1_heater",
                            tool="PrintHead",
                            boundVariable=head_temp)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor = Sensor(type="temperature_sensor",
                                 name="extruder1_temp_sensor",
                                 tool="PrintHead",
                                 boundVariable=head_temp)

        extrudate_lng.attach_actor(extrudMot, 'e')
        head_temp.attach_both([(head_heater, None)], [(head_tempSensor, None)])

    def elementsandVarsTest2(self):
        """test method, for experimental composition of nodes: this creates all the elements for a basic 
        reprap type node"""
        """CARTESIAN BOT DEFINITION"""
        cartesianBot = NodeComponent("cartesian_bot", self.rootElement)
        """3d Position"""
        pos = Variable(self, "3d_position", Vector(['x', 'y',
                                                    'z']), "vector", "mm",
                       None, "memory", 3, True, None, None, ['x', 'y', 'z'])
        """all the motors/actors controlling the 3d Position"""
        mot1 = Actor(type="StepperMotor",
                     name="x_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='x')
        mot2 = Actor(type="StepperMotor",
                     name="y_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='y')
        mot3 = Actor(type="StepperMotor",
                     name="z_motor",
                     tool="cartesianBot",
                     boundVariable=pos,
                     variableChannel='z')
        """all the sensors giving feedback on  the 3d Position"""
        endStop1 = Sensor(type="end_sensor",
                          name="x_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='x')
        endStop2 = Sensor(type="end_sensor",
                          name="x_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='x')
        endStop3 = Sensor(type="end_sensor",
                          name="y_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='y')
        endStop4 = Sensor(type="end_sensor",
                          name="y_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='y')
        endStop5 = Sensor(type="end_sensor",
                          name="z_startSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='z')
        endStop6 = Sensor(type="end_sensor",
                          name="z_endSensor",
                          tool="cartesianBot",
                          boundVariable=pos,
                          variableChannel='z')
        """add all these to the current tool"""
        cartesianBot.add_child(pos)
        cartesianBot.add_children([
            mot1, mot2, mot3, endStop1, endStop2, endStop3, endStop4, endStop5,
            endStop6
        ])
        """EXTRUDER 1 DEFINITION"""
        """two variables"""
        extruder1 = Tool("extruder1")
        head_temp = Variable(self, "head_temp", 0, "temperature", "celcius")
        extrudate_lng = Variable(self, "filament_extrudate", Vector(['e']),
                                 "vector", "mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot = Actor(type="StepperMotor",
                          name="e_motor1",
                          tool="PrintHead",
                          boundVariable=extrudate_lng,
                          variableChannel='e')
        head_heater = Actor(type="Heater",
                            name="extruder1_heater",
                            tool="PrintHead",
                            boundVariable=head_temp)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor = Sensor(type="temperature_sensor",
                                 name="extruder1_temp_sensor",
                                 tool="PrintHead",
                                 boundVariable=head_temp)

        extrudate_lng.attach_actor(extrudMot, 'e')
        head_temp.attach_both([(head_heater, None)], [(head_tempSensor, None)])
        """EXTRUDER 2 DEFINITION"""
        """two variables"""
        extruder2 = Tool("extruder2")
        head_temp2 = Variable(self, "head_temp", 0, "temperature", "celcius")
        extrudate_lng2 = Variable(self, "filament_extrudate", Vector(['e']),
                                  "vector", "mm")
        """all the actors controlling the extrusion of this print head"""
        extrudMot2 = Actor(type="StepperMotor",
                           name="e_motor1",
                           tool="PrintHead",
                           boundVariable=extrudate_lng2,
                           variableChannel='e')
        head_heater2 = Actor(type="Heater",
                             name="extruder1_heater",
                             tool="PrintHead",
                             boundVariable=head_temp2)
        """all the sensors giving feedback on the extrusion of this print head"""
        head_tempSensor = Sensor(type="temperature_sensor",
                                 name="extruder1_temp_sensor",
                                 tool="PrintHead",
                                 boundVariable=head_temp2)

        extrudate_lng2.attach_actor(extrudMot2, 'e')
        head_temp2.attach_both([(head_heater2, None)],
                               [(head_tempSensor2, None)])
        """""" """""" """""" """""" """""" ""
        cartesianBot.add_child(extruder1)
        cartesianBot.add_child(extruder2)

    def _toDict(self):
        return {
            "node": {
                "id": self.id,
                "name": self.name,
                "description": self.description,
                "type": self.type,
                "driver": {
                    "status": {
                        "connected": True
                    },
                    "type": None,
                    "driver": None
                },
                "link": {
                    "rel": "node"
                }
            }
        }

    @defer.inlineCallbacks
    def set_driver(self, params={}, *args, **kwargs):
        """
        Method to set this node's connector 
        Params:
        returns : a driver instance
        connector
        """
        @defer.inlineCallbacks
        def update():
            yield self.delete_driver()
            self.driver = yield DriverManager.create(parentNode=self, **kwargs)

            log.msg("Set driver of node",
                    self.id,
                    " with params ",
                    kwargs,
                    system="Node")
            defer.returnValue(None)

        yield self.driverLock.run(update)

        defer.returnValue(self.driver)

    def get_driver(self):
        if self.driver:
            return self.driver
        else:
            raise NoDriverSet()

    @defer.inlineCallbacks
    def delete_driver(self):
        if self.driver:
            self.driver.disconnect()
            DriverManager._unregister_driver(self.driver)
            yield self.driver.delete()
            self.driver = None
            log.msg("Disconnected and removed driver",
                    logLevel=logging.CRITICAL,
                    system="Node")
        defer.returnValue(None)

    def start(self):
        """
        start this node
        """
        pass

    def stop(self):
        """stop this node
        """

    def add_variable(self, variable, *args, **kwarg):
        self.variables.append(variable)

    def remove_variable(self, variable, *args, **kwargs):
        self.variables.remove(variable)

    def add_element(self, element, *args, **kwargs):
        self.elements.append(element)

    def add_elements(self, elements, *args, **kwargs):
        for element in elements:
            self.elements.append(element)

    def remove_element(self, element, *args, **kwargs):
        self.elements.remove(elment)

    def connect(self, *args, **kwargs):
        d = defer.Deferred()

        def doConnect(driver):
            driver.connect(*args, **kwargs)
            return driver

        d.addCallback(doConnect)
        reactor.callLater(0, d.callback, self.driver)
        return d

    def disconnect(self):
        d = defer.Deferred()

        def doDisconnect(driver):
            driver.disconnect()
            return driver

        d.addCallback(doDisconnect)
        reactor.callLater(0, d.callback, self.driver)
        return d
示例#19
0
    def __init__(self,port,rootPath,filePath,dataPath):
        #app = Application("PollapliServer")
        self.port=port
        self.rootPath=rootPath
        self.filePath=filePath
        self.dataPath=dataPath
        self.logPath=dataPath
        self.updates_path=os.path.join(dataPath,"updates")
        self.addOnsPath=os.path.join(self.rootPath,"addons")
        self.environmentsPath=os.path.join(self.dataPath,"environments")
        self.depenciesPath=os.path.join(self.rootPath,"dependencies")
        if not os.path.exists(self.rootPath):
            os.makedirs(self.rootPath)
        if not os.path.exists(self.dataPath):
            os.makedirs(self.dataPath)
        if not os.path.exists(self.updates_path):
            os.makedirs(self.updates_path)
        if not os.path.exists(self.addOnsPath):
            os.makedirs(self.addOnsPath)
        if not os.path.exists(self.environmentsPath):
            os.makedirs(self.environmentsPath)
        

        
        """""""""""""""""""""""""""""""""""""""""
        Initialize various subsystems /set correct paths
        """
        UpdateManager._addon_path=self.addOnsPath
        UpdateManager.updates_path=self.updates_path
        EnvironmentManager.envPath=self.environmentsPath
        FileManager.rootDir=self.dataPath        
        FileManager.corePath=os.path.join(self.rootPath,"core")
        
        FileManager.rootPath=self.rootPath    
        FileManager.filePath=self.filePath    
        FileManager.uploadPath=os.path.join(self.dataPath,"uploads")
        FileManager.dataPath=self.dataPath
        FileManager.logPath=self.logPath
        FileManager.updates_path=self.updates_path
        FileManager._addon_path=self.addOnsPath
        FileManager.depenciesPath=self.depenciesPath
        
        if not os.path.exists(FileManager.uploadPath):
            os.makedirs(FileManager.uploadPath)
        
        self.environmentManager=EnvironmentManager(self.dataPath)
        
        """"""""""""""""""""""""""""""""""""""
        exceptionConverter=ExceptionConverter()
        exceptionConverter.add_exception(ParameterParseException,400 ,1,"Params parse error")
        exceptionConverter.add_exception(UnhandledContentTypeException,415 ,2,"Bad content type")
        exceptionConverter.add_exception(EnvironmentAlreadyExists,409 ,3,"Environment already exists")
        exceptionConverter.add_exception(EnvironmentNotFound,404 ,4,"Environment not found")
        exceptionConverter.add_exception(UnknownDeviceType,500 ,5,"Unknown node type")
        exceptionConverter.add_exception(DeviceNotFound,404 ,6,"Node not found")
        exceptionConverter.add_exception(NoDriverSet,404,7,"Node has no connector")
        exceptionConverter.add_exception(UnknownDriver,500,8,"Unknown connector driver type")
        exceptionConverter.add_exception(DeviceHandshakeMismatch,500,9,"Device handshake failed to match the one defined by the driver")
        exceptionConverter.add_exception(InvalidFile,500,10,"Invalid File")
        exceptionConverter.add_exception(DeviceNotConnected,500,11,"Attempting to communicate with not connected device")
        
        self._signal_channel="main_signal_listener"
        self.signalHandler=SignalHander(self._signal_channel)
        self.signalHandler.add_handler(channel="driver_manager")   
        self.signalHandler.add_handler(channel="update_manager")
        self.signalHandler.add_handler(channel="environment_manager")
        self.signalHandler.add_handler(channel="node_manager")
        
        self.setup()
示例#20
0
class MainServer():
    def __init__(self,port,rootPath,filePath,dataPath):
        #app = Application("PollapliServer")
        self.port=port
        self.rootPath=rootPath
        self.filePath=filePath
        self.dataPath=dataPath
        self.logPath=dataPath
        self.updates_path=os.path.join(dataPath,"updates")
        self.addOnsPath=os.path.join(self.rootPath,"addons")
        self.environmentsPath=os.path.join(self.dataPath,"environments")
        self.depenciesPath=os.path.join(self.rootPath,"dependencies")
        if not os.path.exists(self.rootPath):
            os.makedirs(self.rootPath)
        if not os.path.exists(self.dataPath):
            os.makedirs(self.dataPath)
        if not os.path.exists(self.updates_path):
            os.makedirs(self.updates_path)
        if not os.path.exists(self.addOnsPath):
            os.makedirs(self.addOnsPath)
        if not os.path.exists(self.environmentsPath):
            os.makedirs(self.environmentsPath)
        

        
        """""""""""""""""""""""""""""""""""""""""
        Initialize various subsystems /set correct paths
        """
        UpdateManager._addon_path=self.addOnsPath
        UpdateManager.updates_path=self.updates_path
        EnvironmentManager.envPath=self.environmentsPath
        FileManager.rootDir=self.dataPath        
        FileManager.corePath=os.path.join(self.rootPath,"core")
        
        FileManager.rootPath=self.rootPath    
        FileManager.filePath=self.filePath    
        FileManager.uploadPath=os.path.join(self.dataPath,"uploads")
        FileManager.dataPath=self.dataPath
        FileManager.logPath=self.logPath
        FileManager.updates_path=self.updates_path
        FileManager._addon_path=self.addOnsPath
        FileManager.depenciesPath=self.depenciesPath
        
        if not os.path.exists(FileManager.uploadPath):
            os.makedirs(FileManager.uploadPath)
        
        self.environmentManager=EnvironmentManager(self.dataPath)
        
        """"""""""""""""""""""""""""""""""""""
        exceptionConverter=ExceptionConverter()
        exceptionConverter.add_exception(ParameterParseException,400 ,1,"Params parse error")
        exceptionConverter.add_exception(UnhandledContentTypeException,415 ,2,"Bad content type")
        exceptionConverter.add_exception(EnvironmentAlreadyExists,409 ,3,"Environment already exists")
        exceptionConverter.add_exception(EnvironmentNotFound,404 ,4,"Environment not found")
        exceptionConverter.add_exception(UnknownDeviceType,500 ,5,"Unknown node type")
        exceptionConverter.add_exception(DeviceNotFound,404 ,6,"Node not found")
        exceptionConverter.add_exception(NoDriverSet,404,7,"Node has no connector")
        exceptionConverter.add_exception(UnknownDriver,500,8,"Unknown connector driver type")
        exceptionConverter.add_exception(DeviceHandshakeMismatch,500,9,"Device handshake failed to match the one defined by the driver")
        exceptionConverter.add_exception(InvalidFile,500,10,"Invalid File")
        exceptionConverter.add_exception(DeviceNotConnected,500,11,"Attempting to communicate with not connected device")
        
        self._signal_channel="main_signal_listener"
        self.signalHandler=SignalHander(self._signal_channel)
        self.signalHandler.add_handler(channel="driver_manager")   
        self.signalHandler.add_handler(channel="update_manager")
        self.signalHandler.add_handler(channel="environment_manager")
        self.signalHandler.add_handler(channel="node_manager")
        
        self.setup()

        
       # reactor.callLater(2,self.compiler_test)
       # reactor.callLater(2,self.compiler_test2)
        #reactor.callLater(5,self.uploader_test)
        
        #self.formatter_tests()
        #self.usbTest2()
        #reactor.callLater(1,self.gstInspectTest)
        
    def gstInspectTest(self):
        path="C:\\Program Files\\OSSBuild\\GStreamer\\v0.10.6\\bin\gst-inspect.exe"
        scp = SconsProcessProtocol("truc")
        scp.deferred = defer.Deferred()
        cmd = [path]     
       
        p = reactor.spawnProcess(scp, cmd[0], cmd,env=os.environ )
        #p = reactor.spawnProcess(processProtocol=scp, executable=cmd[0],args=cmd,env=os.environ )
        return scp.deferred
    def usbTest_pyusb(self):
        #import pysusb.usb.core
        dev = usb.core.find(find_all=True)
        print("dev ",dev)
    def usbTest(self):
        
        #print("core inst",core.__name__)
        devices= usb.core.find(find_all=True)
        print("total devices",devices)
        try:
            for device in devices:
                print("====DEVICE====")
                _name = usb.util.get_string(device,256,device.iProduct)  #This is where I'm having trouble
                print ("device name=",_name)
                #print ("Device:", device.filename)
                print("descriptor type",device.bDescriptorType)
                print("highest usb type",device.bcdUSB)
                print("class",device.bDeviceClass)
                print("subClass",device.bDeviceSubClass)
                print("vendor id",device.idVendor)
                print("device id",device.idProduct)
                print("bDeviceProtocol",device.bDeviceProtocol)
                print("bcdDevice",device.bcdDevice)
                print("iSerialNumber",device.iSerialNumber)
                print("serialNumber",usb.util.get_string(device,256,device.iSerialNumber))
                print("iManufacturer",device.iManufacturer)
                print("manufacturer",usb.util.get_string(device,256,device.iManufacturer))
                print("iProduct",device.iProduct)
                print("product",usb.util.get_string(device,256,device.iProduct))
                print("configs",device.bNumConfigurations)
                print("   **getting data**")
                
                print("test",usb.util.get_string(device,256,3))
                
                #device.set_configuration(0)
                activeConf=device.get_active_configuration()
                print("active conf", activeConf)
                print("bconfValue", activeConf.bConfigurationValue)
                print("bNumInterfaces", activeConf.bNumInterfaces)
                for interf in activeConf:
                    print("bInterfaceNumber", interf.bInterfaceNumber)
                    print("interfaceInterf", interf.iInterface)
                    print("interfaceBaseClass", interf.bInterfaceClass)
                    print("interfaceSubClass", interf.bInterfaceSubClass)

        except Exception as inst:
            print("error",inst)
                
#        busses = usb.busses()
#        print("busses",busses)
#        for bus in busses:
#            devices = bus.devices
#            for dev in devices:
#                print "Device:", dev.filename
#                _name = usb.util.get_string(device,256,0)  #This is where I'm having trouble
#                print ("device name=",_name)
#                print "  idVendor: %d (0x%04x)" % (dev.idVendor, dev.idVendor)
#                print "  idProduct: %d (0x%04x)" % (dev.idProduct, dev.idProduct)
        reactor.stop()
    def usbTest2(self):
       # import wmi

        c = wmi.WMI()
        
        drivers=c.Win32_PnPSignedDriver()
        for driver in drivers:
            print(driver)
        print("devices")
        devices= c.Win32_USBControllerDevice()
        for dev in devices:
            #print(dev)
            devId=dev.Dependent.DeviceID
            for device in c.Win32_PnPEntity(DeviceID=devId):
                #print(device)
                print(device.DeviceID)
                #print (device.ClassGuid,device.Name,device.DeviceID)
#        dep=devices[0].Dependent 
#        print("Did",dep)
        
#        for device in c.Win32_PnPEntity(DeviceID=dep.DeviceID):
#            print (device)
    def spawn_test(self):
        trucpath=os.path.join("d:\\Progra","arduino-0018","arduino.exe")
        trucpath=os.path.join("d:\\","data","projects","Doboz","pollapli","dependencies","scons","scons.py")

        """
        env = os.environ.copy()
                env['PYTHONPATH'] = os.pathsep.join(sys.path)
                reactor.callLater(0,reactor.spawnProcess, env=env, *self.spawn)
                """
        print('PYTHONPATH',os.environ['PYTHONPATH'])

        scp = SconsProcessProtocol("truc")
        scp.deferred = defer.Deferred()
        print("os environ",os.environ)
        print("sys exect",sys.executable)
        cmd = ["C:\Progra\Python26\python.exe",trucpath]   
        cmd=[sys.executable,trucpath]  
       
        p = reactor.spawnProcess(scp, cmd[0], cmd,env=os.environ )
        #p = reactor.spawnProcess(processProtocol=scp, executable=cmd[0],args=cmd,env=os.environ )
        return scp.deferred
    
    
    def compiler_test3(self):
        testTarget=os.path.join(self.rootPath,"arduinoexample")
        sconsPath=os.path.join(self.depenciesPath,"scons","scons.py")
        shutil.copy2(os.path.join(self.rootPath,"core","components","autocompile","SConstruct"),os.path.join(testTarget,"SConstruct"))
        if os.path.exists(sconsPath):
            print("scons found")
            print("sconsPath",sconsPath)
            scp = SconsProcessProtocol("arduino")
            scp.deferred = defer.Deferred()
            """on linux """
            #cmd = [sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i"]
            """on win32"""
            cmd =[sys.executable,sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i"]
            p = reactor.spawnProcess(scp, cmd[0], cmd,env=os.environ )
            return scp.deferred
        else:
            print("scons not found")
    
    
    def compiler_test(self):
        """todo: add temp file deletion"""
        testTarget=os.path.join(self.addOnsPath,"ArduinoExampleAddOn","arduinoExample" ,"firmware","arduinoexample")
        print(testTarget)
        #print("tutu","\\\?\\")
        ##apparently, max path limitation could get avoided with : "\\\?\\" prefix, causes the build
        ##to fail though
        
        envCopy=os.environ.copy()
        
        sconsPath=os.path.join(self.depenciesPath,"scons","scons.py")
        
        
        def create_dir_struture(source,inTemp=False):
            if inTemp:
                import distutils.dir_util
                targetBuildDir=tempfile.mkdtemp()
                distutils.dir_util.copy_tree(testTarget, targetBuildDir)
            else:
                buildsDir=os.path.join(self.rootPath,"builds")
                if not os.path.exists(buildsDir):
                    os.makedirs(buildsDir)
        
                targetBuildName=str(uuid.uuid4())
                targetBuildDir=os.path.join(buildsDir,targetBuildName)
                shutil.copytree(testTarget, targetBuildDir)
            """rename the pde file"""
            tmp = os.path.basename(testTarget)
            tmpDst=os.path.basename(targetBuildDir)
            shutil.move( os.path.join(targetBuildDir,tmp+".pde"),os.path.join(targetBuildDir,tmpDst+".pde"))
            """copy scons file to folder"""
            shutil.copy2(os.path.join(self.rootPath,"core","components","autocompile","SConstruct"),targetBuildDir)
            return targetBuildDir
        
        testTarget=create_dir_struture(testTarget)
        
        
        if os.path.exists(sconsPath):
            print("scons found")
            print("sconsPath",sconsPath)
            scp = SconsProcessProtocol("arduino",testTarget)
            scp.deferred = defer.Deferred()
            """on linux """
            #cmd = [sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i"]
            """on win32"""
            cmd =[sys.executable,sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i","--diskcheck=none","--cache-disable","--config=force"]
            p = reactor.spawnProcess(scp, cmd[0], cmd,env=envCopy )
            return scp.deferred
        else:
            print("scons not found")
    
    def compiler_test2(self):
        testTarget=os.path.join(self.addOnsPath,"Hydroduino_0_0_1_py2_6","hydroduino" ,"firmware","hydroduino")
        
        sconsPath=os.path.join(self.depenciesPath,"scons.py")  
        scp = SconsProcessProtocol("hydroduino")
        scp.deferred = defer.Deferred()
        cmd = [sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i"]
        p = reactor.spawnProcess(scp, cmd[0], cmd,env=os.environ,usePTY=True )
        return scp.deferred
        
    def uploader_test(self):
        testTarget=os.path.join(self.addOnsPath,"ArduinoExampleAddOn_0_0_1_py2_6","arduinoExample" ,"firmware","arduinoexample")
        
        sconsPath="/home/ckaos/data/Progra/Scons/scons.py"  
        scp = SconsProcessProtocol()
        scp.deferred = defer.Deferred()
        cmd = [sconsPath,"-Y"+testTarget,"TARGETPATH="+testTarget,"-i", "upload"]
        p = reactor.spawnProcess(scp, cmd[0], cmd,env=os.environ,usePTY=True )
        return scp.deferred
        
#        compiler=compiler_uploader(arduinoPath="/home/ckaos/utilz/Progra/arduino-0022/",targetDir=testTarget)
#        compiler.check_boardName()
#        compiler.do_stuff()
#        compiler.check_source_main()
#        compiler.set_flags()
#        compiler._createBuilders()
#        compiler.addArduinoCore()
#        compiler.addArduinoLibs()
#        compiler.do_convert()
#        
#        compiler.build()
        #compiler.tearDown()
        
        #subprocess.call("myProg -arg1 -arg2")
    
    @defer.inlineCallbacks
    def do_stuff(self):
        #filePath="D:\\data\\projects\\Doboz\\add_ons_egg_tests\\virtualDevice\\dist\\VirtualDeviceAddOn-0.0.1-py2.6.egg"
        rootAddonsPath="D:\\data\\projects\\Doboz\\add_ons_egg_tests\\"
        filePath=os.path.join(rootAddonsPath,"virtualDevice\\dist\\VirtualDeviceAddOn-0.0.1-py2.6.egg")
        filePath=os.path.join(rootAddonsPath,"arduinoExample\\dist\\ArduinoExampleAddOn-0.0.1-py2.6.egg")
        #filePath=os.path.join(rootAddonsPath,"reprap\\dist\\ReprapAddOn-0.0.1-py2.6.egg")
        
        hash=yield checksum_tools.generate_hash(filePath)
        print ("md5 hash",hash)
        hashCompare=yield checksum_tools.compare_hash("80e157c0f10baef206ee2de03fae7449",filePath)
        print("md5 compare", hashCompare)
    
    def formatter_tests(self):
        formater=JsonFormater(resource="Tutu",rootUri="http://localhost",ignoredAttrs=["blah","blob"],addedAttrs={"gateaux":75},list=False)
        class subThing(object):
           EXPOSE=["strengh","width","height"]
           def __init__(self,strengh="Max",width=10,height=7):
               self.strengh=strengh
               self.width=width
               self.height=height
        class Thing(object):
            #EXPOSE=["subThings"]
            def __init__(self):
                self.subThings=[]
                self.subThings.append(subThing("truc")) 
                self.subThings.append(subThing("muche")) 
        class OtherThing(object): 
            EXPOSE=["var","subThing1","subThing2"]
            def __init__(self,var="somevalue"):
                self.var=var    
                self.subThing1=subThing()
                self.subThing2=subThing("min")
                
        class Tutu(object):
           id=0
           EXPOSE=["id","thing.subThings"]
           def __init__(self,blob="blob",blib=42,blah="nii"):
               self.blob=blob
               self.blib=blib
               self.blah=blah
               self.id=Tutu.id
               self.name="truc"
               self.thing=Thing()
               Tutu.id+=1
               
        class ThingWithId(object):
            id=0
            EXPOSE=["id","thingy"]
            def __init__(self,thingy="thing"):
                self.id=ThingWithId.id
                ThingWithId.id+=1
                self.thingy=thingy
        print("single item: ",formater.format(OtherThing(),"Otherthing","http://localhost/otherthing"))
        print("single item: ",formater.format(Tutu(),"tutu","http://localhost/tutu"))
        print("multiple items: ",formater.format([subThing("min",0.5,3),subThing()],"kpouer","http://localhost/kpouer"))
        print("multiple items: ",formater.format([ThingWithId(),ThingWithId()],"wobbly","http://localhost/wobbly"))
       
    
    def callbackTests(self):
        d=defer.Deferred() 
        def funct1(result):
            print("in funct1")  
        def funct2(result):
            print("in funct2")
        def funct3(result):
            print("in funct3")  
        d.addCallback(funct1)
        d.addCallback(funct2)
        d.addCallback(funct3)
        d.callback(None)
    
    @defer.inlineCallbacks
    def setup(self):
        """configure all systems """
        from twisted.enterprise import adbapi
        from twistar.registry import Registry
        envPath=os.path.join(EnvironmentManager.envPath,"home")
        dbPath=os.path.join(envPath,"home")+".db"
        Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",database=dbPath,check_same_thread=False)
        """this is a required but very cheap hack: since twistard does not support multiple databases,
        we do not have a "master" database, which causes problems because of the dependencies, and initialization
        order of different elements, so for now, the "home" database is enforced"""
        
        yield UpdateManager.setup()
        yield DriverManager.setup()
        yield EnvironmentManager.setup()
        
        defer.returnValue(None)
        
    def start(self):
        observer = log.PythonLoggingObserver("pollapli.core")
        observer.start()
       # log.startLogging(sys.stdout)
       # logfile=os.path.join(self.logPath,"pollapli.log")
       # log.startLogging(open(logfile, 'w'),setStdout=False)
        
        root = File(self.filePath)
        restRoot=Resource()
        root.putChild("rest",restRoot)
        try:
            restRoot.putChild("config", ConfigHandler("/rest/config"))
            restRoot.putChild("drivertypes", DriverTypesHandler("/rest/drivertypes")) 
            restRoot.putChild("environments", EnvironmentsHandler("/rest/environments",self.environmentManager))

        except Exception as inst:
            log.msg("Error in base rest resources creation",str(inst), system="server", logLevel=logging.CRITICAL)
        
        
        factory = Site(root)
        #self.port=9071#TEMP HACK!!
        reactor.listenTCP(self.port, factory)
        log.msg("Server started!", system="server", logLevel=logging.CRITICAL)
        reactor.run()
示例#21
0
 def __init__(self,parentEnvironment):
     self.tasks={}
     self.parentEnvironment=parentEnvironment
     self._signal_channel="task_manager"
     self.signalHandler=SignalHander(self._signal_channel)
示例#22
0
class EnvironmentManager(object):
    """
    Class acting as a central access point for all the functionality of environments
    """
    envPath = None
    environments = {}
    idCounter = 1

    def __init__(self, envPath):
        self.logger = log.PythonLoggingObserver(
            "dobozweb.core.components.environments.environmentManager")
        self.path = EnvironmentManager.envPath
        self.idCounter = EnvironmentManager.idCounter

        self._signal_channel = "environment_manager"
        self.signalHandler = SignalHander(self._signal_channel)

    @classmethod
    @defer.inlineCallbacks
    def setup(cls, *args, **kwargs):
        """Retrieve all existing environments from disk"""
        maxFoundId = 1
        for fileDir in os.listdir(EnvironmentManager.envPath):
            if os.path.isdir(os.path.join(EnvironmentManager.envPath,
                                          fileDir)):
                envName = fileDir
                envPath = os.path.join(EnvironmentManager.envPath, envName)
                dbPath = os.path.join(envPath, envName) + ".db"
                if os.path.exists(dbPath):
                    Registry.DBPOOL = adbapi.ConnectionPool(
                        "sqlite3", database=dbPath, check_same_thread=False)

                    @defer.inlineCallbacks
                    def addEnv(env, maxFoundId):
                        EnvironmentManager.environments[env[0].id] = env[0]
                        yield env[0].setup()
                        if env[0].id > maxFoundId:
                            maxFoundId = env[0].id

                        defer.returnValue(maxFoundId)

                    maxFoundId = yield Environment.find().addCallback(
                        addEnv, maxFoundId)
                    EnvironmentManager.idCounter = maxFoundId + 1
                    #temporary: this should be recalled from db from within the environments ?

        log.msg("Environment manager setup correctly",
                system="environement manager",
                logLevel=logging.CRITICAL)

    def __getattr__(self, attr_name):
        for env in self.environments.values():
            if hasattr(env, attr_name):
                return getattr(env, attr_name)
        raise AttributeError(attr_name)

    def stop(self):
        """
        Shuts down the environment manager and everything associated with it : ie EVERYTHING !!
        Should not be called in most cases
        """
        pass

    """
    ####################################################################################
    The following are the "CRUD" (Create, read, update,delete) methods for the general handling of environements
    """

    @defer.inlineCallbacks
    def add_environment(self,
                        name="home_test",
                        description="Add Description here",
                        status="frozen"):
        """
        Add an environment to the list of managed environements : 
        Automatically creates a new folder and launches the new environement auto creation
        Params:
        EnvName: the name of the environment
        description:a short description of the environment
        status: either frozen or live : whether the environment is active or not
        """
        envPath = os.path.join(self.path, name)
        dbpath = os.path.join(envPath, name) + ".db"

        #if such an environment does not exist, add it
        doCreate = True
        if name in os.listdir(self.path):
            if os.path.exists(os.path.join(self.path, name, dbpath)):
                doCreate = False
        else:
            os.mkdir(envPath)

        if doCreate:
            Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",
                                                    database=dbpath,
                                                    check_same_thread=False)

            env = Environment(path=envPath,
                              name=name,
                              description=description,
                              status=status)
            yield self._generateDatabase()
            yield env.save()
            """rather horrid hack of sorts, required to have different, sequential id in the different dbs"""
            self.force_id(self.idCounter)
            Registry.DBPOOL.close()
            Registry.DBPOOL = adbapi.ConnectionPool("sqlite3",
                                                    database=dbpath,
                                                    check_same_thread=False)

            def addEnv(env):
                self.environments[env[0].id] = env[0]
                self.idCounter += 1

            yield Environment.find().addCallback(addEnv)

            env = self.environments[self.idCounter - 1]
            self.signalHandler.send_message("environment.created", self, env)
            log.msg("Adding environment named:",
                    name,
                    " description:",
                    description,
                    "with id",
                    env.id,
                    system="environment manager",
                    logLevel=logging.CRITICAL)
            defer.returnValue(env)
        else:
            raise EnvironmentAlreadyExists()

        defer.returnValue(None)

    def get_environments(self, filter=None):
        """
        Returns the list of environments, filtered by  the filter param
        the filter is a dictionary of list, with each key beeing an attribute
        to check, and the values in the list , values of that param to check against
        """
        d = defer.Deferred()

        def filter_check(env, filter):
            for key in filter.keys():
                if not getattr(env, key) in filter[key]:
                    return False
            return True

        def get(filter, envsList):
            if filter:
                #return [env for env in self.environments if getattr(env, "id") in filter["id"]]
                #return [env for env in self.environments if [True for key in filter.keys() if getattr(env, key)in filter[key]]]

                return WrapperList(data=[
                    env for env in envsList if filter_check(env, filter)
                ],
                                   rootType="environments")
            else:
                return WrapperList(data=envsList, rootType="environments")

        d.addCallback(get, self.environments.values())
        reactor.callLater(0.5, d.callback, filter)
        return d

    def get_environment(self, envId):
        env = self.environments.get(envId)
        if env is None:
            raise EnvironmentNotFound()
        return env

    def update_environment(self, id, name, description, status):
        #print("updating env",id,name,description,status)
        return self.environments[id].update(name, description, status)

    def remove_environment(self, id):
        """
        Remove an environment : this needs a whole set of checks, 
        as it would delete an environment completely (very dangerous)
        Params:
        name: the name of the environment
        """
        d = defer.Deferred()

        def remove(id, envs, path):
            try:
                Registry.DBPOOL.close()
                envName = envs[id].name
                envPath = os.path.join(path, envName)
                #self.environments[envName].shutdown()
                del envs[id]
                if os.path.isdir(envPath):
                    shutil.rmtree(envPath)
                    #self.logger.critical("Removed and deleted envrionment: '%s' at : '%s'",envName,envPath)
                    log.msg("Removed environment ",
                            envName,
                            "with id ",
                            id,
                            system="environment manager",
                            logLevel=logging.CRITICAL)
            except:
                pass
                #should raise  specific exception
                #raise Exception("failed to delete env")

        d.addCallback(remove, self.environments, self.path)
        reactor.callLater(0, d.callback, id)
        return d

    @defer.inlineCallbacks
    def clear_environments(self):
        """
        Removes & deletes ALL the environments, should be used with care
        """
        print(self.environments)
        for env in self.environments.values():
            yield self.remove_environment(env.id)
        defer.returnValue(None)

    """
    ####################################################################################
    Helper Methods    
    """

    @defer.inlineCallbacks
    def force_id(self, id):
        query = '''UPDATE environments SET id =''' + str(
            id) + ''' where id=1'''
        yield Registry.DBPOOL.runQuery(query)
        defer.returnValue(None)

    @defer.inlineCallbacks
    def _generateMasterDatabase(self):
        yield Registry.DBPOOL.runQuery('''CREATE TABLE environments(
             id INTEGER PRIMARY KEY ,
             name TEXT,
             status TEXT NOT NULL DEFAULT "Live",
             description TEXT
             )''')

    @defer.inlineCallbacks
    def _generateDatabase(self):
        yield Registry.DBPOOL.runQuery('''CREATE TABLE addons(
             id INTEGER PRIMARY KEY,
             name TEXT,
             description TEXT,
             active boolean NOT NULL default true           
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE environments(
             id INTEGER PRIMARY KEY,
             name TEXT,
             description TEXT,
             status TEXT NOT NULL DEFAULT "Live"
             )''')

        yield Registry.DBPOOL.runQuery('''CREATE TABLE nodes(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             environment_id INTEGER NOT NULL,
             type TEXT NOT NULL ,
             name TEXT,          
             description TEXT,
             recipe TEXT,
            FOREIGN KEY(environment_id) REFERENCES environments(id) 
             )''')

        #FOREIGN KEY(node_id) REFERENCES nodes(id)
        yield Registry.DBPOOL.runQuery('''CREATE TABLE drivers(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             driverType TEXT NOT NULL,
             deviceType TEXT NOT NULL ,
             deviceId TEXT,
             options BLOB  ,
             FOREIGN KEY(node_id) REFERENCES nodes(id)      
             )''')

        yield Registry.DBPOOL.runQuery('''CREATE TABLE tasks(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             environment_id INTEGER NOT NULL,
             name TEXT,          
             description TEXT,
             type TEXT,
             params TEXT,
             FOREIGN KEY(environment_id) REFERENCES environments(id)  
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE actions(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             task_id INTEGER NOT NULL,
             actionType TEXT,          
             params TEXT,
             FOREIGN KEY(task_id) REFERENCES tasks(id)
             )''')
        yield Registry.DBPOOL.runQuery('''CREATE TABLE conditions(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             task_id INTEGER NOT NULL,
             name TEXT,          
             description TEXT,
             FOREIGN KEY(task_id) REFERENCES tasks(id)
             )''')

        yield Registry.DBPOOL.runQuery('''CREATE TABLE sensors(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             captureType TEXT NOT NULL,
             captureMode TEXT NOT NULL DEFAULT "Analog",
             type TEXT NOT NULL ,
             realName TEXT NOT NULL,
             name TEXT,
             description TEXT,
             FOREIGN KEY(node_id) REFERENCES nodes(id)
             )''')

        yield Registry.DBPOOL.runQuery('''CREATE TABLE readings(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             node_id INTEGER NOT NULL,
             sensor_id INTEGER NOT NULL,
             data INTEGER NOT NULL,
             dateTime TEXT NOT NULL,
             FOREIGN KEY(node_id) REFERENCES nodes(id),
             FOREIGN KEY(sensor_id) REFERENCES sensors(id)
             )''')
        """this should be in the master db, but will have to do for now (only support for one environment,
        because of the limitations of twistar: one db )"""

        yield Registry.DBPOOL.runQuery('''CREATE TABLE updates(
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             type TEXT NOT NULL,
             name TEXT NOT NULL,
             description TEXT,
             version TEXT NOT NULL,
             downloadUrl TEXT NOT NULL,
             tags TEXT NOT NULL,
             img TEXT NOT NULL,
             file TEXT NOT NULL,
             fileHash TEXT NOT NULL,
             downloaded TEXT NOT NULL,
             installed TEXT NOT NULL,
             enabled TEXT NOT NULL
             
             )''')

        defer.returnValue(None)