class AnalogOutput(BaseHandler):
    def __init__(self,eType,eSource,localrouter,wbTarget,aoNum):        
        super(AnalogOutput,self).__init__(localrouter)
        
        self.localrouter = localrouter
        self.wbTarget = wbTarget
        #assume the webbrick node number is equal to the last digit of the ip address
        self.nodeNum = wbTarget.split('.')[3]
        self.targetVal = 0
        self.eType = eType
        self.eSource = eSource
        self.aoNum = str(aoNum)
        
        self.aoCmd = 'AA;' + str(aoNum) + ';%(val)s:'
        self.httpAction = HttpAction(localrouter)
        self.httpAction.configure( self.MakeHttpConfig(eType,eSource,wbTarget) )
        self.httpAction.start()
        self.localrouter.subscribe( 20 , self , 'http://id.webbrick.co.uk/events/webbrick/AO' ,  'webbrick/' + self.nodeNum + '/AO/' + self.aoNum)
            
    def MakeHttpConfig(self,eType,eSource,wbTarget):
        cfg = {}
        cfg['eventtype'] = {}
        cfg['eventtype']['type'] = eType
        cfg['eventtype']['eventsource'] = {}
        cfg['eventtype']['eventsource']['source'] = eSource
        cfg['eventtype']['eventsource']['event'] = {}
        cfg['eventtype']['eventsource']['event']['url'] = {}
        cfg['eventtype']['eventsource']['event']['url']['cmd'] = "GET"
        cfg['eventtype']['eventsource']['event']['url']['uri'] = '/cfg.spi?com=' + self.aoCmd
        cfg['eventtype']['eventsource']['event']['url']['address'] = 'http://' + wbTarget
        cfg['name'] = 'HttpAction'
        cfg['module'] = 'EventHandlers.HttpAction'
        return cfg
    
    def initSubscription(self,status):
        pass
    
    def getUri(self):
        return "ANALOG_OUTPUT/" + self.wbTarget + '/' + self.aoNum 
    
    def SetAO(self,Val):
        if Val >= 0 and Val <= 100:
            newEvent = makeEvent( self.eType,self.eSource , {'val' : str(Val)} )         
            self.localrouter.publish(newEvent.getSource() , newEvent)   
            self.targetVal = int(Val)
        else:
            raise Exception("Warning , analog set point out of range : " + str(Val))        
            
    
    def doHandleEvent(self,handler,inEvent):
        if inEvent.getType() == 'http://id.webbrick.co.uk/events/webbrick/AO':
            if inEvent.getSource() == 'webbrick/' + self.nodeNum + '/AO/' + self.aoNum:
                if inEvent.getPayload()['val'] != self.targetVal:
                    self.SetAO(self.targetVal)
        return makeDeferred(StatusVal.OK)
class DigitalOutput(BaseHandler):
    
    def __init__(self,eType,eSource,localrouter,wbTarget,doNum):        
        super(DigitalOutput,self).__init__(localrouter)              
        self.localrouter = localrouter
        self.wbTarget = wbTarget
        #assume the node number is equal to the last digit of the ip address
        self.nodeNum = wbTarget.split('.')[3]        
        self.eType = eType
        self.eOnSource = eSource + '/on'
        self.eOffSource = eSource + '/off'
        self.eDwellSource = eSource + '/dwell'
        self.doNum = str(doNum)
        self.onCmd = 'DO;' + str(doNum) + ';N:'
        self.offCmd = 'DO;' + str(doNum) + ';F:'
        self.dwellCmd = 'DO;' + str(doNum) + ';D;%(val)s:'
        self.httpAction = HttpAction(localrouter)
        self.httpAction.configure( self.MakeHttpConfig() )
        self.httpAction.start()
        self.dwellTime = -1
        self.localrouter.subscribe( 20 , self , 'http://id.webbrick.co.uk/events/webbrick/DO' ,  'webbrick/' + self.nodeNum + '/DO/' + self.doNum)
        
    def MakeHttpConfig(self):
        cfg = {}
        cfg['eventtype'] = [{},{},{}]
        cfg['eventtype'][0]['type'] = self.eType
        cfg['eventtype'][0]['eventsource'] = {}
        cfg['eventtype'][0]['eventsource']['source'] = self.eOnSource
        cfg['eventtype'][0]['eventsource']['event'] = {}
        cfg['eventtype'][0]['eventsource']['event']['url'] = {}
        cfg['eventtype'][0]['eventsource']['event']['url']['cmd'] = 'GET'
        cfg['eventtype'][0]['eventsource']['event']['url']['uri'] = '/cfg.spi?com=' + self.onCmd
        cfg['eventtype'][0]['eventsource']['event']['url']['address'] = self.wbTarget
        
        cfg['eventtype'][1]['type'] = self.eType
        cfg['eventtype'][1]['eventsource'] = {}
        cfg['eventtype'][1]['eventsource']['source'] = self.eOffSource
        cfg['eventtype'][1]['eventsource']['event'] = {}
        cfg['eventtype'][1]['eventsource']['event']['url'] = {}
        cfg['eventtype'][1]['eventsource']['event']['url']['cmd'] = 'GET'
        cfg['eventtype'][1]['eventsource']['event']['url']['uri'] = '/cfg.spi?com=' + self.offCmd
        cfg['eventtype'][1]['eventsource']['event']['url']['address'] = self.wbTarget
        
        cfg['eventtype'][2]['type'] = self.eType
        cfg['eventtype'][2]['eventsource'] = {}
        cfg['eventtype'][2]['eventsource']['source'] = self.eDwellSource
        cfg['eventtype'][2]['eventsource']['event'] = {}
        cfg['eventtype'][2]['eventsource']['event']['url'] = {}
        cfg['eventtype'][2]['eventsource']['event']['url']['cmd'] = 'GET'
        cfg['eventtype'][2]['eventsource']['event']['url']['uri'] = '/cfg.spi?com=' + self.dwellCmd
        cfg['eventtype'][2]['eventsource']['event']['url']['address'] = self.wbTarget
        
        cfg['name'] = 'HttpAction'
        cfg['module'] = 'EventHandlers.HttpAction'
        return cfg
    
    def initSubscription(self,status):
        pass
    
    def getUri(self):
        return "DIGITAL_OUTPUT/" + self.wbTarget + '/' + self.doNum 
        
    def turnOn(self,dwell = 0):
        if dwell > 8:
            #TODO deal with this better somehow
            #dwell must be above 8 seconds as below that are the dwell presets
            newEvent = makeEvent (self.eType,self.eDwellSource,{'val':str(int(dwell))} )
            self.dwellAmount = dwell
            self.dwellTime = time.time() + dwell
        else:
            newEvent = makeEvent( self.eType, self.eOnSource,  {} )      
            self.dwellTime = 0    
            self.dwellAmount = 0  
        self.targetVal = '1' 
        self.localrouter.publish(newEvent.getSource() , newEvent)
    
    def turnOff(self):
        newEvent = makeEvent( self.eType,self.eOffSource , {} )         
        self.localrouter.publish(newEvent.getSource() , newEvent)   
        self.targetVal = '0'
        
    def doHandleEvent(self,handler,inEvent):
        if inEvent.getType() == 'http://id.webbrick.co.uk/events/webbrick/DO':
            if inEvent.getSource() == 'webbrick/' + self.nodeNum + '/DO/' + self.doNum:
                if inEvent.getPayload()['state'] != self.targetVal:
                    if self.targetVal == '0':          
                        self._log.error("Webbrick DO not at target value is off , should be on")
                        self.turnOff()
                    elif self.targetVal == '1':
                        #check if we were dwelling
                        if self.dwellAmount:
                            if self.dwellTime < time.time():
                                #dwell time has expired being off is fine
                                self.targetVal = '0'
                            else:
                                #dwell not expired , dwell must have failed to set
                                self._log.error("Webbrick DO not at target value is off , should be on for %i seconds" %self.dwellTime)
                                self.turnOn(self.dwellAmount)
                        else:                    
                            self._log.error("Webbrick DO not at target value is off , should be on")
                            self.turnOn()
        return makeDeferred(StatusVal.OK)