Maybe somebody like to write an enigma2 plugin

1 enigma2 plugins

2 ===============

3

4 Enigma2 plugins are always written in python. If you really have to call

5 C/C++ functions from your code, you can supply a python module with it,

6 implementing your functions.

7

8 Let's write a plugin. We call it "OurSmallTest", and it should be a test

9 plugin. Thus we choose "DemoPlugins" as a category. The category is just to

10 organize plugins in the filesystem.

11

12 The simplest plugin looks like the following:

13

14 Plugins/DemoPlugins/OurSmallTest/plugin.py:

15

16 "from Plugins.Plugin import PluginDescriptor

17

18 def main(session, **kwargs):

19 print "Hello world!"

20

21 def Plugins(**kwargs):

22 return PluginDescriptor(

23 name="Our Small Test",

24 description="plugin to test some capabilities",

25 where = PluginDescriptor.WHERE_PLUGINMENU,

26 fnc=main)"

27

28 Basically, you're writing a "python module", which is called

29 Plugins.DemoPlugins.OurSmallTest.plugin. This corresponds to the

30 Plugins/DemoPlugins/OurSmallTest/plugin.py file.

31

32 This module must define a single function called "Plugins". The functions is

33 called for every Plugin, and should return (a list of)

34 PluginDescriptor-Objects. A PluginDescriptor is a simple object, holding the

35 Plugin's name, description, picture etc., and an entry point.

36

37 In the first line, we import that class. It's contained in a module called

38 Plugins.Plugin.

39

40 At the end, we define the "Plugins"-Functions. As said, it returns a

41 constructed PluginDescriptor-object (in fact it can return either one or a

42 list of descriptors, here it returns exactly one). We use keyword arguments

43 to supply the Plugin's information, like the name, the descripttion etc.

44

45 We also supply an entry point, called "fnc". It's set to the "main"

46 function, which is defined before. Our entry point is called with a number

47 of arguments, depending on where the plugin was launched from. In this case,

48 it's a "session" argument. You need the session argument if you want to do

49 graphical output. A session basically connects to "user". There is always

50 one sessions which corresponds to the main screen output, but there can also

51 be other sessions, which yet have to be implemented. (A possible example is a

52 networked remote session.) If you don't need that argument, just ignore it.

53

54 A plugin can decide where it wants to be displayed. A possible example is

55 the plugin menu out of the main menu. In the "where" argument to the

56 descriptor, you can supply one (or a list of) "WHERE_"-identifiers. We use

57 WHERE_PLUGINMENU. There will be other ones, for example for the blue button,

58 or specific other menus.

59

60 Now, if you copy this plugin in-place, it should be listed in the plugin

61 browser in the main menu. You can press "ok" on the plugin, and the "main"

62 function, which was specified as the plugin's entry point, is executed.

63

64 If you want to open a graphical screen, you might want the entry point to

65 look like:

66

67 def main(session):

68 session.open(MyScreen)

69

70 with MyScreen being a GUI screen.

71

72 About the **kwargs:

73 This somewhat special syntax (in fact the name 'kwargs' is arbitrary, but

74 stands for "keyword arguments") collects all addition keyword arguments

75 (i.e. named parameters). For example. the Plugins()-call gets a "path"

76 parameter, and probably more in the future. You must ignore all additional

77 keywords which you don't need!

78

79 skins

80 =====

81

82 Generally, you can include the skin in your Screens by having a static (or

83 non-static, if you really want) variable "skin", for example:

84

85 class OurSmallTestScreen(Screen):

86 skin = "<skin>...</skin>"

87 def __init__(self, session):

88 Screen.__init__(self, session)

89 ...

90

91 However, users can override the skin from their skin.xml. Note that the

92 Screen's name (unless you override this, which is possible) is used for

93 determining which skin is used. Thus, if you're choosing generic skin names

94 like "TheScreen", it's likely to cause namespace clashes.

95

96 Thus, please use skin names (i.e. Screen-names, unless you're overriding the

97 skin name) which are unique enough to not clash. In doubt, prepend the

98 pluginname like in our example.

99

100 autostarting plugins

101 ====================

102

103 you can configure your plugin to automatically start on enigma startup, and

104 end on shutdown.

105

106 you just have to use "WHERE_AUTOSTART". your entry point must (fnc) look

107 like:

108

109 def autostartEntry(raeson, **kwargs):

110 if reason == 0: # startup

111 print "startup"

112 elif reason == 1:

113 print "shutdown"

114

115 autostart plugins should always be configurable, and should default to an

116 OFF state!

117

118 Configuration

119 =============

120

121 Speaking about configuration, plugins must live in

122

123 config.plugins.<PluginName>

124

125 and nowhere else!

126

127 You are, however, free to change settings which are already existing. If you

128

129 Dependencies

130 ============

131

132 Plugin dependencies (one plugin requires another plugin) should generally be

133 avoided, but are possible. If there are dependencies, the .ipk file must

134 list them.

135

136 If possible, make them optional. If your plugin doesn't support one feature

137 because another plugin isn't installed, that's fine (but should be noted in

138 the docs).

139

140 Categories

141 ==========

142

143 Currently defined categories are:

144

145 * DemoPlugins: Plugins fore pure demonstration purposes

146 * Extensions: User interface extensions

147 * SystemPlugins: Hardware specific plugins

148

149 Plugin Names

150 ============

151

152 A plugin name:

153 - should always start with a Uppercase letter,

154 - must not start with the word "Dream",

155 - nor end with "Plugin",

156 - should be unique even across Categories,

157 - must be understandable by english speaking people,

158 (unless it's a geographically restricted plugin)

159 - is not user changeable (that is, the user is not allowed to rename the

160 plugin directory)

161 - shouldn't be a generic word