def doDiscoverFound( self, action, inEvent ): # verify webbrick is in the address list od = inEvent.getPayload() if od.has_key("version") and od["version"] >= 6 : adrs = od["ipAdr"] if adrs == WbDefs.DEFAULT_SP_ADR: resetSitePlayer(adrs) elif not self._webbrickConfigs.has_key( adrs ): self._webbrickConfigs[adrs] = None
def handleMinute( self, inEvent ): """ """ #_log.debug( "handleMinute %s" % (self._SpCounters) ) # if entry goes positive then clock needs resetting as getting SS or ST meddages with clock more # then a configurable number of seconds out of step. od = inEvent.getPayload() for tgt in self._SpCounters: self._SpCounters[tgt] = self._SpCounters[tgt] + 1 if self._SpCounters[tgt] > self._resetWebIfTimer: self._SpCounters[tgt] = 0 # webbrick has not sent any UDP events for a period of time resetSitePlayer( tgt ) for tgt in self._ClockCounters.keys(): if self._ClockCounters[tgt] > self._resetClocktimer: # webbrick has not picked up time from RTC or RTC is too far out of step. self._log.info( "SetTime on node %s " % tgt ) cmd = Wb6Commands(tgt) cmd.Login( "password" ) cmd.SetTime( od["day"], od["hour"], od["minute"] ) del self._ClockCounters[tgt]
def handleTimeSignal( self, inEvent ): # If time from webbrick is more than x away from Gateway reset it. od = inEvent.getPayload() if od and od.has_key("ipAdr"): tgt = od["ipAdr"] self._SpCounters[tgt] = 0 # reset site player monitor if od["uptime"] < 5: # minutes _log.info( "Webbrick %s rebooted reason %u" % (tgt, od["resetCode"]) ) if tgt == WbDefs.DEFAULT_IP_ADR: # on default IP address _log.info( "Webbrick %s on default IP address" % (tgt) ) if self._resetOnDefault: resetSitePlayer( tgt ) if tgt == WbDefs.DEFAULT_SP_ADR: # on default Siteplayer IP address _log.info( "Webbrick %s on default siteplayer IP address" % (tgt) ) resetSitePlayer( tgt ) # add to monitor list if od.has_key("hour") and od.has_key("minute") and od.has_key("second"): now = time.time() % 86400 # in seconds today. wbNow = od["second"] + (60 * od["minute"]) + (3600 * od["hour"]) if ( abs(now-wbNow) > self._clockMaxError ): # let the minute handle and system started code handle this. if self._ClockCounters.has_key(tgt): self._ClockCounters[tgt] = self._ClockCounters[tgt] + 1 else: self._ClockCounters[tgt] = 1 _log.info( "Webbrick %s clock error(%i) - %s" % (tgt, self._ClockCounters[tgt], od) ) else: if self._ClockCounters.has_key(tgt): del self._ClockCounters[tgt]
def run(self): # stay in loop reading packets while socket open. self._log.debug( 'enter run' ) seqNrs = dict() try: # bind socket self.WbSkt = getWebBrickSocket() while ( self.running ): # read packet try: data = self.WbSkt.recvfrom(32) if data and self.running: evnt = None adr = str(data[1][0]) if adr == WbDefs.DEFAULT_SP_ADR: resetSitePlayer( adr ) # then events do not get beyond here. else: self._log.debug( 'Receive %s' % str(data) ) # create WbUdpEvents # Wb 6 UDP packets have a length byte in the first position, use to decide on 5 or 6. len = ord(data[0][0]) if len < 32 : if ( ord(data[0][1]) >= 32 ): # lets filter out duplicates # simple approach that only handles duplicates when # appear immediatly. if len >= 13: # contains sequenece number sn = ord(data[0][12]) if (not seqNrs.has_key(adr)) or seqNrs[adr] <> sn: seqNrs[adr] = sn evnt = Wb6Event( data[1], data[0] ) else: self._log.debug( 'Duplicate %i' % sn ) else: evnt = Wb6Event( data[1], data[0] ) else: # len, type, from, seq, sn = ord(data[0][3]) if (not seqNrs.has_key(adr)) or seqNrs[adr] <> sn: seqNrs[adr] = sn evnt = WB6BinaryEvent( data[1], data[0] ) else: self._log.debug( 'Duplicate %i' % sn ) else: evnt = Wb5Event( data[1], data[0] ) # call eventTgt method. if (evnt): self._log.debug( evnt ) self.sendEvent( evnt ) # end if data except socket.error, err: if err[0] == errno.EINTR: continue # ignore error if err[0] == errno.EAGAIN: continue # ignore error if (str(err) != "timed out") and not self.running: self._log.exception( err ) except Exception, ex: self._log.exception( ex )
def updateStatus( self, adrs, newSts ): # now look for changes in all values and generate correct events. if newSts.getOperationalState() == 255: # this is site-player reset value. # siteplayer has been reset, so data not valid. self._log.error( "read from webbrick %s with invalid status data %s" % (adrs, newSts.xmlstr) ) # reset siteplayer. resetSitePlayer( adrs ) return # short circuit out of here oldSts = None if self._webbrickStati.has_key( adrs ) : oldSts = self._webbrickStati[adrs] nnr = self._webbrickConfigs[adrs][0] curCfg = self._webbrickConfigs[adrs][2] typeRoot = "http://id.webbrick.co.uk/events/webbrick/" srcRoot = "webbrick/%s" % nnr if not oldSts or ( oldSts.getLoginState() != newSts.getLoginState() ): # self.sendEvent( Event( typeRoot, srcRoot, {} ) ) pass if not oldSts or ( oldSts.getDate() != newSts.getDate() ): # self.sendEvent( Event( typeRoot, srcRoot, {} ) ) pass ow = newSts.getOneWireBus() for idx in range(WbDefs.TEMPCOUNT): if (ow & (0x01 << idx)) == 0: # sensor not there pass else: if not oldSts or ( oldSts.getTemp( idx ) != newSts.getTemp( idx ) ): if newSts.getTemp( idx ) == -1000.0: self._log.error( "Erroneous Temperature Reading %s %s" % (adrs, newSts.xmlstr) ) self.sendEvent( Event( typeRoot+"ET", "%s/ET/%i" % (srcRoot,idx) , { "fromNode": nnr, "srcChannel": idx, "val": newSts.getTemp( idx ), "curlo": newSts.getTempLowThresh( idx ), "curhi": newSts.getTempHighThresh( idx ), "deflo": curCfg.getTempTriggerLow( idx )["threshold"], "defhi": curCfg.getTempTriggerHigh( idx )["threshold"], } ) ) else: self.sendEvent( Event( typeRoot+"CT", "%s/CT/%i" % (srcRoot,idx) , { "fromNode": nnr, "srcChannel": idx, "val": newSts.getTemp( idx ), "curlo": newSts.getTempLowThresh( idx ), "curhi": newSts.getTempHighThresh( idx ), "deflo": curCfg.getTempTriggerLow( idx )["threshold"], "defhi": curCfg.getTempTriggerHigh( idx )["threshold"], } ) ) for idx in range(WbDefs.AOCOUNT): if not oldSts or ( oldSts.getAnOut( idx ) != newSts.getAnOut( idx ) ): self.sendEvent( Event( typeRoot+"AO", "%s/AO/%i" % (srcRoot,idx), { "fromNode": nnr, "srcChannel": idx, "val": newSts.getAnOut( idx ) } ) ) for idx in range(WbDefs.AICOUNT): if not oldSts or ( oldSts.getAnIn( idx ) != newSts.getAnIn( idx ) ): self.sendEvent( Event( typeRoot+"AI", "%s/AI/%i" % (srcRoot,idx), { "fromNode": nnr, "srcChannel": idx, "val": newSts.getAnIn( idx ), "curlo": newSts.getAnInLowThresh( idx ), "curhi": newSts.getAnInHighThresh( idx ), "deflo": curCfg.getAnalogTriggerLow( idx )["threshold"], "defhi": curCfg.getAnalogTriggerHigh( idx )["threshold"], } ) ) for idx in range(WbDefs.DICOUNT): if not oldSts or ( oldSts.getDigIn( idx ) != newSts.getDigIn( idx ) ): state = 0 if newSts.getDigIn( idx ): state = 1 self.sendEvent( Event( typeRoot+"DI", "%s/DI/%i" % (srcRoot,idx), { "fromNode": nnr, "srcChannel": idx, "state": state } ) ) for idx in range(WbDefs.DOCOUNT+WbDefs.MIMICCOUNT): # dig out 8-15 are the mimics. if not oldSts or ( oldSts.getDigOut( idx ) != newSts.getDigOut( idx ) ): state = 0 if newSts.getDigOut( idx ): state = 1 self.sendEvent( Event( typeRoot+"DO", "%s/DO/%i" % (srcRoot,idx), { "fromNode": nnr, "srcChannel": idx, "state": state } ) ) self._webbrickStati[adrs] = newSts return None