def __init__(self): self.config={} self.conn=None self.chan=None self.cpoll=0 self.cLastConnAttempt=0 Bus.publish(self,"%llconfig", self.LCONFIG)
def activate (self, shell): """ Called by Rhythmbox when the plugin is activated """ self.active=True self.shell = shell self.sp = shell.get_player() self.db=self.shell.props.db self.sl=shell.props.sourcelist self.plm=shell.get_playlist_manager() ## We might have other signals to connect to in the future self.dbcb = ( #self.db.connect("entry-added", self.on_entry_added), #self.db.connect("entry-deleted", self.on_entry_deleted), #self.db.connect("entry-changed", self.on_entry_changed), self.db.connect("load-complete", self.on_load_complete), ) self.slcb = ( self.sl.connect("drop-received", self.on_drop_received), #self.sl.connect("selected", self.on_selected), ) self.plcb = ( self.plm.connect("playlist-added", self.on_playlist_added), self.plm.connect("playlist-created", self.on_playlist_created), #self.plm.connect("status-changed", self.on_status_changed), ) ## Distribute the vital RB objects around Bus.publish("__pluging__", "rb_shell", self.shell, self.db, self.sp) self.type_song=self.db.entry_type_get_by_name("song")
def _onError(self, e): try: details=self._getDeviceDetails(e.device) self._q.put(["%device-error", details], block=True) Bus.publish(self, "%log", "warning", "Device error: %s" % details) except Exception,e: Bus.publish(self, "%log", "error", "exception whilst attempting to report Phidgets.onError (%s)" % e)
def _hDin(self, serial, pin, value): pname, mval=self.domap(serial, pin, value) #print "_hDin, %s, %s, %s, %s" % (serial, pin, value, pname) if mval is not None: Bus.publish(self, "%state-changed", serial, pname, mval) else: Bus.publish(self, "%state-changed", serial, "din:%s" % pin, mval)
def validateConfig(self, config): """ Validates (as much as possible) the configuration information before handing it off Categories: "States", "Devices" Pins: integer """ pinmap={} try: devices=config.get("Devices", None) or config["devices"] except: self.log("warning", "Configuration file missing 'Devices' section") return try: states=config.get("States", None) or config["states"] except: self.log("warning", "Configuration file missing 'States' section") return pinnames=[] try: for device_name in devices: device=devices[device_name] try: pins = device.get("Pins", None) or device["pins"] except: self.log("warning", "Expecting 'pins' entry for Device(%s) in 'Devices' section" % device_name) return for pin in pins: pname=pins[pin] pinnames.extend([pname]) try: _ipin=int(pin) except: self.log("warning", "Expecting 'integer' value for pin entry, device(%s)" % device) return ## stringify for less headache: normalize type m="%s.%s" % (device_name, pin) pinmap[m] = pname except: self.log("warning", "Error whilst validating 'Devices' section of configuration file") return #print "pinnames: ",pinnames try: for pinname in states: if not pinname in pinnames: self.log("warning", "Pin name(%s) not found in any 'Device' definition" % pinname) except: self.log("warning", "Error whilst validating 'States' section of configuration file") return self.config=config self.log("info", "Successfully validated configuration file(%s)" % self.cpath) Bus.publish(self, "%config-sensors", self.config) Bus.publish(self, "%pin-map", pinmap)
def Devices(self, devices): """ Signal Handler Signal normally issued by Phidgets-Manager """ for device in devices: ddetails=deviceHelper(device) Bus.publish(self, "%device", ddetails)
def processChange(self, iotype, dic): serial=dic["serial"] pin=dic["pin"] value=dic["value"] pname, mval=self.domap(serial, iotype, pin, value) dic.update({"sensor_name": pname, "sensor_state": mval}) if mval is not None: Bus.publish(self, "%state-changed", iotype, dic)
def _doUpdateInfo(self): """ Sends an update on the discovered devices """ devices=self._mng.getAttachedDevices() result=[] for device in devices: details=self._getDeviceDetails(device) result.extend([details]) Bus.publish(self, "%devices", result)
def processMsg(self, data): try: devices=json.loads(data) except Exception,e: Bus.publish(self, "%llog", "%json-decode", "warning", "Error(%s) decoding json object: %s" % (e, data)) return
def on_load_complete(self, *_): """ 'load-complete' signal handler Publishes the filtered list of db entries """ self.load_complete=True Bus.publish("pluging", "load_complete") Bus.publish("pluging", "song_entries", self.song_entries)
def _setup(self): self._mng.setOnAttachHandler(self._onAttach) self._mng.setOnDetachHandler(self._onDetach) self._mng.setOnErrorHandler(self._onError) try: self._mng.openManager() except Exception,e: Bus.publish(self, "%log", "error", "Can't open Phidgets.Manager (%s)" % e) raise RuntimeError("Can't open Phidgets.Manager")
def __init__(self): self._q=Queue() self._mng=None self._info_publish_counter=0 try: self._mng=Manager() self._setup() except Exception,e: Bus.publish(self, "%log", "error", "Can't instantiate Phidgets.Manager (%s)" % e) raise RuntimeError("can't instantiate Phidgets.Manager")
def _hPoll(self, pc): if not self.config: Bus.publish(self, "%config-amqp?") if not self.comm: self.comm=AMQPCommTx(self.config, self.EXCH) self.comm.connect() if not self.comm.isOk(): del self.comm self.comm=None
def setup(self): """ Setup the connection & channel """ Bus.publish(self, "%config-amqp?") try: self.conn=amqp.Connection(insist=True, **self.config) except Exception,e: self.conn=None Bus.publish(self, "%conn-error") self.log("%conn-error", "error", "Failed to connect to AMQP broker. Exception(%s)" % e) return
def on_entry_added(self, _tree, entry): """ 'entry-added' signal handler Filters the db entries based on the 'song' entry type """ type=entry.get_entry_type() if type==self.type_song: if not self.load_complete: id=self.db.entry_get(entry, rhythmdb.PROP_ENTRY_ID) self.song_entries.append(int(id)) Bus.publish("pluging", "entry_added", id, entry)
def _hpoll(self, pc): if self.config is None: Bus.publish(self, "%config-amqp?") if self.comm is not None: if not self.comm.isOk(): del self.comm self.comm=None if self.comm is None: self.comm=AMQPCommTx(self.config, self.EXCH) self.comm.connect()
def on_playing_song_changed (self, sp, entry): """ The event that starts the whole "sync" process """ ## unfortunately, I don't have a better process ## for keeping the "user parameters" synced just yet... Bus.publish("pluging", "config?") self.current_entry = sp.get_playing_entry() details=EntryHelper.track_details(self.shell, entry) if details: track=Track(details=details, entry=self.current_entry) Bus.publish("pluging", "track?", track)
def processMsgQueue(self): while True: msg=self.currentWorker.rxFromWorker() if msg is None: break try: mtype=msg.pop(0) mdata=msg.pop(0) except: Bus.publish(self, "%llog", "%msg-error", "error", "Error whilst decoding message from AMQP exchange 'org.sensors' ") continue ## e.g. "state.io.din" Bus.publish(self, mtype, mdata)
def create_configure_dialog(self, dialog=None): """ This method is called by RB when "configure" button is pressed in the "Edit->Plugins" menu. Note that the dialog *shouldn't* be destroyed but "hidden" when either the "close" or "X" buttons are pressed. """ if not dialog: glade_file_path=self.find_file("config.glade") proxy=ConfigDialog(glade_file_path) dialog=proxy.get_dialog() dialog.present() Bus.publish("pluging", "config?") return dialog
def _hpoll(self, pc): self.cpc=pc if not self.config: Bus.publish(self, "%config-amqp?") self.maybeSpawn() if self.currentWorker is not None: if not self.currentWorker.is_alive(): Bus.publish(self, "%conn-error", "warning", "Connection to AMQP broker failed") del self.currentWorker self.currentWorker = None if self.currentWorker is not None: self.processMsgQueue()
def __init__(self, queue, serial): self.serial=serial self._q=queue self._ic=0 ## digital input count self._oc=0 ## digital output count self._sc=0 ## sensor input count try: self.ifk=InterfaceKit() self._setHooks() self.ifk.openPhidget(int(serial)) except Exception,e: print "*** Exception: ",e w="Can't instantiate a Phidgets.Devices.InterfaceKit" Bus.publish(self, "%log", "warning", w)
def doping(self): if self.gen is None: self.gen=self.iterDevices() try: device=self.gen.next() except: self.inPing=False self.gen=None self.cleanup() return device_serial=device.serial try: device.ping() except: Bus.publish(self, "%log", "warning", "Attempt to `ping` device serial(%s) failed" % device_serial) self.todel.extend([device_serial])
def _hdevice(self, details): """ %device - local message handler """ dtype=details.get("type", None) if dtype!="PhidgetInterfaceKit": return serial=details.get("serial", None) entry=self._devices.get(serial, {}) if not entry: Bus.publish(self, "%log", "Found IFK device, serial(%s)" % serial) Bus.publish(self, "%attached", details) try: device=IfkAgent(self._q, serial) except: device=None if device: self._devices[serial] = device
def activate (self, shell): self.shell = shell sp = shell.get_player() self.db=self.shell.props.db ## We might have other signals to connect to in the future self.cb = ( sp.connect ('playing-song-changed', self.on_playing_song_changed), ) self.dbcb = ( self.db.connect("entry-added", self.on_entry_added), self.db.connect("load-complete", self.on_load_complete), ) ## Distribute the vital RB objects around Bus.publish("pluging", "rb_shell", shell, self.db, sp) self.type_song=self.db.entry_type_get_by_name("song")
def _hpoll(self, *p): """ Pull as much messages as are available from the queue """ while True: try: msg=self._q.get_nowait() except Empty: msg=None if msg is None: break _mtype=msg.pop(0) _dic=msg.pop(0) Bus.publish(self, _mtype, _dic) self._info_publish_counter=self._info_publish_counter+1 if self._info_publish_counter > self.INFO_RATE: self._info_publish_counter=0 self._doUpdateInfo()
def _hllog(self, ltype, *p): c=self.lc.get(ltype, 0)+1 self.lc[ltype]=c try: level, msg = p except: level="info" try: msg = p[0] except: raise RuntimeError("LogLimiter: invalid usage") cdelta=self.map.get(ltype, self.DEFAULT_CDELTA) lpoll=self.st.get(ltype, 0) delta=self.cpoll - lpoll #print "cpoll(%s) ltype(%s) delta(%s) cdelta(%s) msg(%s)" % (self.cpoll, ltype, delta, cdelta, msg) if delta >= cdelta or lpoll==0: self.st[ltype] = self.cpoll Bus.publish(self, "%log", level, "(%s:%s) %s" % (ltype, c, msg))
def publish(self, rkey, msg): try: jmsg=json.dumps(msg) except: self.log("%json-encode", "Error", "Error encoding to JSON: %s" % msg) return msg = amqp.Message(jmsg) msg.properties["delivery_mode"] = 2 msg.content_type="application/json" if not self.chan: Bus.publish(self, "%llog", "%conn-error", "error", "Connection to AMQP broker not opened") return try: #print "AMQPCommTx.publish: rkey(%s) msg(%s)" % (rkey, jmsg) self.chan.basic_publish(msg, exchange=self.exch, routing_key=rkey) except Exception,e: #print "sMsg: rkey(%s) jmsg(%s)" % (rkey, jmsg) self.log("%conn-error", "error", "Failed to send message to AMQP broker: %s" % e) self.closeConn()
def doRefresh(self): try: statinfo=os.stat(self.cpath) except: statinfo=None ## st_mode, st_ino, st_dev, st_nlink, st_uid, ## st_gid, st_size, st_atime, st_mtime, st_ctime if not statinfo: if not self.nConfigPath: self.nConfigPath=True self.log("warning", "Configuration file not found(%s) - using defaults" % self.cpath) self.useDefaults() return mtime=statinfo.st_mtime if self.mtime != mtime: self.log("info", "Configuration file changed, mtime(%s)" % mtime) self.mtime = mtime self.nConfigPath=False self._handleChange() Bus.publish(self, "%config-amqp", self.config)
def _hpoll(self, *p): """ Pull as much messages as are available from the queue """ while True: try: msg=self._q.get_nowait() except Empty: msg=None if msg is None: break _mtype=msg.pop(0) Bus.publish(self, _mtype, *msg) if self.inPing: self.doping() return self.cping=self.cping+1 if self.cping > self.PING_INTERVAL: self.cping=0 self.inPing=True self.doping()
def ping(self): for index in range(0, self._ic): iv=self.ifk.getInputState(index) dic=self.prepareDic(index, iv) Bus.publish(self, "%device-din", dic) for index in range(0, self._oc): iv=self.ifk.getOutputState(index) dic=self.prepareDic(index, iv) Bus.publish(self, "%device-dout", dic) for index in range(0, self._sc): iv=self.ifk.getSensorRawValue(index) dic=self.prepareDic(index, iv) Bus.publish(self, "%device-ain", dic)