[chirp_devel] [PATCH] [RFC] Dynamic driver registration
# HG changeset patch # User Dan Smith dsmith@danplanet.com # Date 1329428169 28800 # Node ID cfbdca8031730005d3c61613bdce6b1798d4872d # Parent 0786ddcd02c395ffcfc3a99f9605ffa87102ebd8 [RFC] Dynamic driver registration
This patch gets rid of the big silly static definition of the driver directory and replaces it with one that is populated dynamically. When multiple people are working on a driver, it's often the case that patches will conflict because they both made edits to the directory listing. Further, it makes it harder to add/remove a module during development because you have to edit the directory.
This patch introduces a "register" decorator in the directory module. Any driver claiming to implement a radio driver can decorate that class and have it automatically included in the directory. Thus, simply placing mydriver.py in the chirp module folder will cause it to be included.
Two example radios (Yaesu FT-7800 and Icom IC-2200) are implemented here for demonstration.
I've been wanting to do this for a looooong time.
Thoughts? Comments?
diff -r 0786ddcd02c3 -r cfbdca803173 chirp/__init__.py --- a/chirp/__init__.py Thu Feb 16 13:00:30 2012 -0800 +++ b/chirp/__init__.py Thu Feb 16 13:36:09 2012 -0800 @@ -14,3 +14,14 @@ # along with this program. If not, see http://www.gnu.org/licenses/.
CHIRP_VERSION="0.1.13dev" + +import os +import sys +from glob import glob + +module_dir = os.path.dirname(sys.modules["chirp"].__file__) +__all__ = [] +for i in glob(os.path.join(module_dir, "*.py")): + name = os.path.basename(i)[:-3] + if not name.startswith("__"): + __all__.append(name) diff -r 0786ddcd02c3 -r cfbdca803173 chirp/directory.py --- a/chirp/directory.py Thu Feb 16 13:00:30 2012 -0800 +++ b/chirp/directory.py Thu Feb 16 13:36:09 2012 -0800 @@ -16,92 +16,22 @@ import os import tempfile
-from chirp import id800, id880, ic2820, ic2200, ic9x, icx8x, ic2100, ic2720 -from chirp import icq7, icomciv, idrp, icf, ic9x_icf, icw32, ict70 -from chirp import vx3, vx5, vx6, vx7, vx8, ft2800, ft7800, ft50, ft60, ft817, ft857 -from chirp import kenwood_live, tmv71, thd72 -from chirp import alinco -from chirp import wouxun -from chirp import xml, chirp_common, generic_csv, util, rfinder, errors +from chirp import icf +from chirp import chirp_common, util, rfinder, errors
-DRV_TO_RADIO = { - # Virtual/Generic - "csv" : generic_csv.CSVRadio, - "xml" : xml.XMLRadio, +def register(cls): + global DRV_TO_RADIO + ident = cls.VENDOR + cls.MODEL + cls.VARIANT + if ident in DRV_TO_RADIO.keys(): + raise Exception("Duplicate radio driver id `%s'" % ident) + DRV_TO_RADIO[ident] = cls + RADIO_TO_DRV[cls] = ident + print "Registered %s = %s" % (ident, cls.__name__)
- # Icom - "ic2720" : ic2720.IC2720Radio, - "ic2820" : ic2820.IC2820Radio, - "ic2200" : ic2200.IC2200Radio, - "ic2100" : ic2100.IC2100Radio, - "ic9x" : ic9x.IC9xRadio, - "id800" : id800.ID800v2Radio, - "id880" : id880.ID880Radio, - "icx8x" : icx8x.ICx8xRadio, - "idrpx000v" : idrp.IDRPx000V, - "icq7" : icq7.ICQ7Radio, - "icw32" : icw32.ICW32ARadio, - "ict70" : ict70.ICT70Radio, - "icom7200" : icomciv.Icom7200Radio, - "ic9xicf" : ic9x_icf.IC9xICFRadio, + return cls
- # Yaesu - "vx3" : vx3.VX3Radio, - "vx5" : vx5.VX5Radio, - "vx6" : vx6.VX6Radio, - "vx7" : vx7.VX7Radio, - "vx8" : vx8.VX8Radio, - "vx8d" : vx8.VX8DRadio, - "ft2800" : ft2800.FT2800Radio, - "ft7800" : ft7800.FT7800Radio, - "ft8800" : ft7800.FT8800Radio, - "ft8900" : ft7800.FT8900Radio, - #"ft50" : ft50.FT50Radio, - "ft60" : ft60.FT60Radio, - "ft817" : ft817.FT817Radio, - "ft817nd" : ft817.FT817NDRadio, - "ft817nd-us" : ft817.FT817ND_US_Radio, - "ft857" : ft857.FT857Radio, - "ft857-us" : ft857.FT857_US_Radio, - - # Kenwood - "thd7" : kenwood_live.THD7Radio, - "thd7g" : kenwood_live.THD7GRadio, - "thd72" : thd72.THD72Radio, - "tm271" : kenwood_live.TM271Radio, - "tmd700" : kenwood_live.TMD700Radio, - "tmd710" : kenwood_live.TMD710Radio, - "tmv7" : kenwood_live.TMV7RadioSub, - "thk2" : kenwood_live.THK2Radio, - "thf6" : kenwood_live.THF6ARadio, - "thf7" : kenwood_live.THF7ERadio, - "v71a" : kenwood_live.TMV71Radio, - - # Jetstream - "jt220m" : alinco.JT220MRadio, - - # Alinco - "dr03" : alinco.DR03Radio, - "dr06" : alinco.DR06Radio, - "dr135" : alinco.DR135Radio, - "dr235" : alinco.DR235Radio, - "dr435" : alinco.DR435Radio, - "dj596" : alinco.DJ596Radio, - - # Wouxun - "kguvd1p" : wouxun.KGUVD1PRadio, - - # Puxing - "px777" : wouxun.Puxing777Radio, - "px2r" : wouxun.Puxing2RRadio, - - # Baofeng - "uv3r" : wouxun.UV3RRadio, -} - +DRV_TO_RADIO = {} RADIO_TO_DRV = {} -for __key, __val in DRV_TO_RADIO.items(): - RADIO_TO_DRV[__val] = __key
def get_radio(driver): if DRV_TO_RADIO.has_key(driver): diff -r 0786ddcd02c3 -r cfbdca803173 chirp/ft7800.py --- a/chirp/ft7800.py Thu Feb 16 13:00:30 2012 -0800 +++ b/chirp/ft7800.py Thu Feb 16 13:36:09 2012 -0800 @@ -14,7 +14,7 @@ # along with this program. If not, see http://www.gnu.org/licenses/.
import time -from chirp import chirp_common, yaesu_clone, memmap +from chirp import chirp_common, yaesu_clone, memmap, directory from chirp import bitwise, util, errors
ACK = chr(0x06) @@ -370,6 +370,7 @@ banks.append(bank) return banks
+@directory.register class FT7800Radio(FTx800Radio): MODEL = "FT-7800"
diff -r 0786ddcd02c3 -r cfbdca803173 chirp/ic2200.py --- a/chirp/ic2200.py Thu Feb 16 13:00:30 2012 -0800 +++ b/chirp/ic2200.py Thu Feb 16 13:36:09 2012 -0800 @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/.
-from chirp import chirp_common, icf, util +from chirp import chirp_common, icf, util, directory from chirp import bitwise
mem_format = """ @@ -83,6 +83,7 @@ chirp_common.PowerLevel("MidLow", watts=10), chirp_common.PowerLevel("Low", watts=5)]
+@directory.register class IC2200Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): VENDOR = "Icom" MODEL = "IC-2200H" diff -r 0786ddcd02c3 -r cfbdca803173 chirpw --- a/chirpw Thu Feb 16 13:00:30 2012 -0800 +++ b/chirpw Thu Feb 16 13:36:09 2012 -0800 @@ -98,6 +98,7 @@ # Python >=2.6, use normal gettext behavior lang.install()
+from chirp import * from chirpui import mainapp, config
a = mainapp.ChirpMain()
Hi Dan
Thoughts? Comments?
I like it.
I think we must comment the magic of this decoration so people in future have a trace of the effect of "@directory.register" in chirp.
Eg. we can add in front of the register definition
# Any driver claiming to implement a radio driver can decorate that # class with @directory.register and have it automatically included in # the directory. # Thus, simply placing mydriver.py in the chirp module folder will # cause it to be included.
and near the @directory.register in each driver
# this will automatically include our driver in the directory # see register definition in directory.py
73 de IZ3GME Marco
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
I think we must comment the magic of this decoration so people in future have a trace of the effect of "@directory.register" in chirp.
Indeed, yes.
and near the @directory.register in each driver
Well, I think that might be a bit much, but ... I know that a couple people have asked for a "template driver" -- something that doesn't implement anything, other than the bare minimum to be a driver in CHIRP. Something they can take and copy to make into a driver. It would be good to put a comment in that driver, explaining what it does...
I've got a couple other things to work out with it, but I'll put it in soon.
Thanks!
- -- Dan Smith www.danplanet.com KK7DS
participants (2)
-
Dan Smith
-
IZ3GME Marco