Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

Is it possible to split plugins into multiple files?

If you have a question or need help, this is the place to be.
WoLpH
Experienced User
Posts: 96
Joined: Mon Dec 10, 2012 3:57 am

Re: Is it possible to split plugins into multiple files?

Post by WoLpH »

Wow, I see what you mean. That's definitely a challenge to maintain in it's current state. Nice plugin though :)

A quick look does show me some dependencies but it looks like you could move all actions to a separate file and import them which should help in maintainability a little bit.

Additionally I would suggest changing code such as "for i in self.monitor_040_mem:" to use a dictionary such as "for i in self.monitor_mem['040']:" so line 679 to 778 could be reduced to:

Code: Select all

for mem in self.monitor_mem.values():
    for monitor in mem.values():
        try:
            eg.scheduler.CancelTask(monitor)
        except Exception:
            pass
It would obviously require a bit more work but that the same idea could apply to a lot of code.
Author of the book Mastering Python. Got Python questions? Perhaps I can help :)
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

hey walter.

I just did up a section of code, i trimmed out about 125 lines. and I think this is a little more readable.

code is below

but on another note. I would set up a folder with a separate file for each hex list with a nice friendly name for the file. and you could make a small class that you would call asking for the name of the file and it would do the import and return the value. that way it will only load what is needed and you wouldn't have to have a heap of imports



but starting at or about line 994 to line 1173

Code: Select all

hexDict = {              
                    ('01', 'FF')      : self.decode_000,
                    ('03',)           : self.decode_003,
                    ('04', '02')      : self.decode_002,
                    ('06', '30', '04'): self.decode_030_1,
                    ('06', '30')      : self.decode_030_0,
                    ('07', '70')      : self.decode_070,
                    ('07', '10')      : self.decode_010,
                    ('07', '16')      : self.decode_016,
                    ('07', '18')      : self.decode_018,
                    ('08', '42')      : self.decode_042,
                    ('08', '50')      : self.decode_050,
                    ('08', '51')      : self.decode_051,
                    ('08', '20')      : self.decode_020,
                    ('09', '57')      : self.decode_057,
                    ('09', '40')      : self.decode_040,
                    ('13',)           : self.decode_013,
                    ('10', '56')      : self.decode_056,
                    ('11', '5a', '01'): self.decode_05A_1,
                    ('11', '5a', '02'): self.decode_05A_2, 
                    ('11', '60', '02'): self.decode_060_02,
                    ('13', '5b')      : self.decode_05B,
                    ('14', '01', '00'): self.decode_14_00,
                    ('14', '01', '01'): self.decode_01d,
                    ('14', '01', '02'): self.decode_02d,
                    ('14', '01', '03'): self.decode_03d,
                    ('14', '01', '04'): self.decode_04d,
                    ('14', '01', 'ff'): self.decode_ff,
                    ('14', '01', '07'): self.decode_14_07,
                    ('15', '60', '01'): self.decode_060_01,
                    ('0a', '52')      : self.decode_052,
                    ('0a', '4e')      : self.decode_04E,
                    ('0a', '4f')      : self.decode_04F, 
                    ('0a', '14', '00'): self.decode_014_00,
                    ('0a', '14', '01'): self.decode_014_01,
                    ('0a', '14', '02'): self.decode_014_02,
                    ('0a', '14', '04'): self.decode_014_02,
                    ('0a', '14', '03'): self.decode_014_03,
                    ('0a', '14', '06'): self.decode_014_06,
                    ('0a', '14', '07'): self.decode_014_07,
                    ('0a', '14', '0d'): self.decode_014_0d,
                    ('0a', '71')      : self.decode_071,
                    ('0b', '55')      : self.decode_055,
                    ('0b', '11')      : self.decode_011,
                    ('0b', '15')      : self.decode_015,
                    ('0d', '54')      : self.decode_054,
                    ('0d', '58')      : self.decode_058,
                    ('0d', '59')      : self.decode_059,
                    ('0d', '01', '00'): self.decode_00d,
                    ('0d', '01', '01'): self.decode_01d,
                    ('0d', '01', '02'): self.decode_02d,
                    ('0d', '01', '03'): self.decode_03d,
                    ('0d', '01', '04'): self.decode_04d,
                    ('0d', '01', 'ff'): self.decode_ff,
                    ('0f', '5c')      : self.decode_05C,
                    ('1c', '21')      : self.decode_021
                }
                if msg[:2] == ['09', '19']:
                    tmpmsg = int(msg[2])
                    if int(msg[2],16) == 11:
                        self.decode_019_B(msg)
                    elif tmpmsg >= 8:
                        self.decode_019_8(msg)
                    elif tmpmsg >= 6:
                        self.decode_019_6(msg)
                    elif  tmpmsg >= 2:
                        self.decode_019_2(msg)
                    elif tmpmsg >= 0:
                        self.decode_019(msg)
                    return
                elif tuple(msg[:3]) in hexDict:
                    hexDixt[tuple(msg[:3])](msg)
                    return

you will have to check this.


but as an example this kind of information can be held elsewhere because it's static

and one other thing. make a changelog.txt file and deep six the 700 line header

lol

but it appears that a whole lot of this code is static information, and coud be put into some kind of database. i am not sure if there is a means to read a function from a file. I don't think pickeling will work. but at any rate even just making the class thing as i mentioned to grab the data

Code: Select all


class DataManager:
    def __init__(self):
        pass
    def __getattr__(self, item):
        mod = __import__('StaticData.' + item)
        attr = getattr(mod, item)
        return attr

Datamanager = DataManager()

testdata = Datamanager.TestData

If you like the work I have been doing then feel free to Image
krambriw
Plugin Developer
Posts: 2570
Joined: Sat Jun 30, 2007 2:51 pm
Location: Stockholm, Sweden
Contact:

Re: Is it possible to split plugins into multiple files?

Post by krambriw »

Thank you both for your nice suggestions!

Best regards, Walter
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

gonna hit ya with a couple more.


trimmed down the __start__ by 25 lines or so.


you can replace all of the self.decode and self.monitor declarations

with this

Code: Select all

decodeHex = (
       		'40, 42, 4E, 4F, 50, 51, 52, 54, 55, 56, 57, 58, 59, 5A_1, 5A_2,'
       		' 5B, 5C, 60_01, 60_02, 70, 71, 10, 11, 13, 14_00, 14_01, 14_02,'
       		' 14_03, 14_06, 17_07, 14_0D, 14_0F, 15, 16, 18_019, 20, 21'
       	)
       	monitorHex = (
        	'40, 42, 4E, 4F, 50, 51, 52, 54, 55, 56, 57, 58, 59, 5A_1, 5A_2,'
        	' 5B, 5C, 60_01, 60_02, 70, 71, 20'
        )

        for decode in decodeHex.split(', '):
        	setattr(self, 'decode_0%s_mem' % decode, dict())

        for monitor in monitorHex.split(', '):
        	setattr(self, 'monitor_0%s_mem' % monitor, dict())

but again I personally like using a class to hand out the information. and if it's a new key then it can make the dict at that point. so there is no need to declare the variables. they are "automatically generate" if you will but this would require replacing the existing variable names.

Code: Select all

class Decode:
	def __getattr__(self, item):
		if item in self.__dict__:
			return self.__dict__[item]
		self.__dict__[item] = attr = dict()
		return attr

Monitor = Decode

class Plugin:
    def __init__(self):
        self.decode = Decode()
        self.monitor = Monitor()

    def SomeMethod(self):
        if 'blah' in self.decode._040_mem:
            runcode

so you wouldn't have to declare all the variables. and if something never gets used it doesn't just sit there empty either. which is nice also. but the first call to that attribute will cause the attribute to be created and returned as an empty dict
If you like the work I have been doing then feel free to Image
WoLpH
Experienced User
Posts: 96
Joined: Mon Dec 10, 2012 3:57 am

Re: Is it possible to split plugins into multiple files?

Post by WoLpH »

Perhaps if we dump it in a github gist we can both take a stab at it :)

I'm curious to see how much we can improve it
Author of the book Mastering Python. Got Python questions? Perhaps I can help :)
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

now that is a fantastic idea. this way Walter can add what he wants to and if more than one person is working on it then that would make sure the code isn't conflicting
If you like the work I have been doing then feel free to Image
WoLpH
Experienced User
Posts: 96
Joined: Mon Dec 10, 2012 3:57 am

Re: Is it possible to split plugins into multiple files?

Post by WoLpH »

Ok, here's a start :)

https://gist.github.com/WoLpH/3b15e0e54 ... 75aeb8e7db

I think we will have to split the files since github is refusing to diff a file with 20k lines
Author of the book Mastering Python. Got Python questions? Perhaps I can help :)
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

hey Walter, you ok with your plugin being up on the git???
If you like the work I have been doing then feel free to Image
krambriw
Plugin Developer
Posts: 2570
Joined: Sat Jun 30, 2007 2:51 pm
Location: Stockholm, Sweden
Contact:

Re: Is it possible to split plugins into multiple files?

Post by krambriw »

Yes, of course :)
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

well I have an update, I have all of the hex codes already seperated into a database of sorts.

i have done some code adjustment

and i am going to be able to shrink this bad larry by at least 10K lines

I made up a nice ActionMixin to do all the Configure dirty work.

and i made a script up to parse all of the hex data from the original code file and write all the independent files with the hex code in them. and put in the original the means to access the data simple one liner kinda stuff


i think with some good brain storming we could get this thing down to a nice manageable 4K lines

but we don't want to go to crazy with the voodoo code because its hard to follow. but the import mechanism for the HexCodes works almost exactly like the EG mechanism. because this plugin is so large think i would also like to use the same mechanism to import the code for a specific action upon use and not upon the loading of the plugin. this should be pretty easy to accomplish using classtype to make a wrapper. and using the __name__ for the class when either the __call__ or the Configure classes are called to import and redirect the call to the appropriate module. doing up all of the actions are going to take a while because of the amount of work that has to be done for each one and the number of them.

but progress!!!

once i get this thing broken down far enough so github doesn't have heartattack i will put it up there
If you like the work I have been doing then feel free to Image
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

well here is the github of the source for the RFXtrx plugin

https://github.com/kdschlosser/EventGhost-RFXtrx

now I know it's not running at the moment and still has work to be done. but it's a start and has been separated into a manageable file structure
If you like the work I have been doing then feel free to Image
krambriw
Plugin Developer
Posts: 2570
Joined: Sat Jun 30, 2007 2:51 pm
Location: Stockholm, Sweden
Contact:

Re: Is it possible to split plugins into multiple files?

Post by krambriw »

Dear kgschlosser,

Cool, this looks much, much better organized! You know the original just grow as a wild tree, it was not that high in the beginning....

Best regards, Walter
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

Oh I have no doubt. my Vera plugin started to grow like that. and then i learned how to split across multiple files. my personal copy of the Vera plugin is HUGE i think it's over the 20K lines you have for the RFXtrx. byt my person copy contains mostly GUI stuff for having any of the data from my lighting controller be able to come up onto the screen more like an OSD Control system. I started to separate the OSD system from the Vera Plugin. and got a good bit done but I have decided in lieu of trying to reinvent the wheel with it i need to learn more on how the wx stuff works. I have learned a great deal. and now know how to do what it is what i would like to do to make the code accept input from other sources and make it in a way that has a core drawing routine and different widgets. the thing is so damned complex i really need to make some kind of a layout designer where it will load a specific OSD Overlay and allow the person integrating to set specific callbacks that way the plugin passing the data to it doesn't have to be aware of if and when a menu is called. it only needs to hand the data to it if it's asked to.
If you like the work I have been doing then feel free to Image
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Is it possible to split plugins into multiple files?

Post by kgschlosser »

but your plugin has also given me a lot of ideas on how to handle the use of the different modules. I am going to spend an hour or so writing the Action Handler I am curious to see if i can dynamically import the actions at time of use. without EG throwing a fit. because I know it stores the plugin and it's actions in an object container but it doesn't look for some things at time of install only when you try to run something. and I am not sure if I can manipulate the class dynamically like that but we will see
If you like the work I have been doing then feel free to Image
WoLpH
Experienced User
Posts: 96
Joined: Mon Dec 10, 2012 3:57 am

Re: Is it possible to split plugins into multiple files?

Post by WoLpH »

Yep, that's always the problem. It starts out very small but it grows to an unmanageable size if you don't refractor regularly.

The new structure looks quite a bit better indeed
Author of the book Mastering Python. Got Python questions? Perhaps I can help :)
Post Reply