/
dev.txt
245 lines (198 loc) · 10.1 KB
/
dev.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
========================
Development informations
========================
How it work ?
=============
The plugin use clients who send message through operator service.
Operator could be any web service or hardware ``(in future stuff)``
Clients service are register by plugin and communicat with they by internal code.
Header defined in plugin configuration is added at the top of message.
xPL messages
============
No xPL message handle, use only 0MQ
Existing clients service.
=========================
- Sending SMS WEB:
Send SMS using web service phone operator, actually there is 4 french operators handled :
Can use just optional value ``title``
- Bouygues Telecom : file ``bin/smsweb_bouygues.py`` who use web service on
http://www.mobile.service.bbox.bouyguestelecom.fr/services/SMSIHD/sendSMS.phtm
- Free mobile : file ``bin/smsweb_freemobile.py`` who use web service on
https://smsapi.free-mobile.fr/sendmsg?
- Orange : file ``bin/smsweb_orange.py`` who use web service on
http://smsmms1.orange.fr/C/Sms/sms_write.php
- SFR : file ``bin/smsweb_sfr.py`` who use web service on
http://www.sfr.fr/xmscomposer/index.html?todo=compose
- Sending Newtifry for Android:
Send notification using web service phone `Newtifry API <https://newtifry.appspot.com/page/api>`_
Can use all optional value ``title``, ``priority``, ``url``, ``image``
Developing new notification service
==========================================
Plugin offer way to add new client service.
3 step are needed.
1 - Editin JSON file plugin
***************************
Some adding must be necessary to do in info.json file:
- For an SMS web service just add your operator id in ``parameters``, ``operator``, key ``choices`` of ``device_types``, instance ``notify.smsweb``::
......
"notify.smsweb" : {
"description" : "Send SMS using web service phone operator.",
"id" : "notify.smsweb",
"name" : "SMS operator web service",
"commands" : ["send_msg"],
"sensors" : ["msg_status", "error_send"],
"parameters" : [{
"key" : "to",
"xpl": false,
"description" : "Phone number to send SMS.",
"type" : "string"
},{
"key" : "operator",
"xpl": false,
"description" : "Operator service.",
"type" : "enum",
"choices" : {
"Bouygues_sms-web" : "Bouygues service",
"Freemobile_sms-web" : "Freemobile service",
"Orange_sms-web" : "Orange service",
"SFR_sms-web" : "SFR service", # add coma
"My_NEW_OPERATOR" : "NEW service" # add ligne
}
},{
"key" : "login",
"xpl": false,
"description" : "User login service.",
"type" : "string"
},{
"key" : "pwd",
"xpl": false,
"description" : "User password service.",
"type" : "string"
}
]
},
.....
- For a new service or hardware, create your own device_types ::
"notify.mynewservice" : {
"description" : "A simple description of service.",
"id" : "notify.mynewservice",
"name" : "Name service",
"commands" : ["send_extendmsg or send_msg"], # chose type of message
"sensors" : ["msg_status", "error_send"],
"parameters" : [{
"key" : "to", # keep this key, identification of recipient
"xpl": false, # set to false for don't use in xPL message
"description" : "A simple description of recipient.",
"type" : "string"
},{
"key" : "key1", # a optional key needed by service, like user/login/....
"xpl": false, # set to false for don't use in xPL message
"description" : "A simple description of function.",
"type" : "string"
},{
"key" : "key2", # a optional key needed by service, like password/....
"xpl": false, # set to false for don't use in xPL message
"description" : "A simple description of function.",
"type" : "string"
},{
.....
}
]
}
},
2 - Editing clients_devices.py file
***********************************
File ``lib/clients_devices.py`` contains a ``BaseClientService`` python class who handle basic methodes.
You create a new class inherit this base class and overwriting some methodes to get acces of this new service or hardware.
There is 3 thinks to do in this file :
- 1st : Add your new operator id in OPERATORS_SERVICE global variable.
This id is the same than JSON file
::
OPERATORS_SERVICE = ['SFR_sms-web', 'Orange_sms-web', 'Bouygues_sms-web', 'Freemobile_sms-web', 'Newtifry', My_NEW_OPERATOR]
- 2nd : You have to add new client device class reference in ``CreateOperator`` methode. ::
def CreateOperator(params, log = None):
""" Create a device depending of operator, use instance class to get parameters.
- Developer : add your python class derived from DeviceBase class."""
....
elif params['operator'] == 'My_new_service' :
from domogik_packages.plugin_notify.lib.mynewcodefile import MyNewClient
newOperator = MyNewClient(params, log)
....
- 3rd : If you have ceated a new instance_type, you have to add new client getting specifique parameters in ``GetDeviceParams`` methode. ::
def GetDeviceParams(Plugin, device):
""" Return all internal parameters depending of instance_type.
- Developer : add your instance_type proper parameters
@param Plugin : Plugin base class reference for "get_parameter" methods access.
type : object class Plugin
@param device : domogik device data.
type : dict
@return : parameters for creating or update ClientService object.
Value must contain at least keys :
- 'operator' = Selected from OPERATORS_SERVICE
- 'to' = Client reference, the same as global parameter 'to'
type : dict
"""
...
elif device['device_type_id'] == 'newtifry.device':
operator = 'My_NEW_OPERATOR'
id = device['parameters']['to']['value'] # keep this line
valueKey1 = device['parameters']['Key1']['value'] # Get your new device paramaters
valuekey2 = device['parameters']['Key2']['value'] # Get your new device paramaters
valuekey3 = Plugin.get_parameter(device, 'defaulttitle') # Get a Plugin config paramaters if needed
if operator and device["name"] and id and valueKey1 and valuekey3: # check for none optional parameters
# Build a dict with parameters
params = {'name': device["name"] , 'operator' : operator, 'to' : id, 'key1' : valueKey1, 'key2' : valuekey2, 'key3' : valuekey3}
return params # return your own parameters
...
Creating new client class
*************************
In a new python file place in lib :
- Import BaseClientService from plugin lib
::
from client_devices import BaseClientService
- Create your python class
::
class My_New_Client(BaseClientService): # simply new class declaration
def send(self, message): # overwrite methodes class
......
Overwrite ``update`` methode
****************************
This method is called by plugin to update proper parameters, so set your own parameters in::
def update(self, params):
""" Create or update internal data, must be overwrited if others params needed.
@param params : parameters from GetDeviceParams() of domogik device'.
type : dict
"""
BaseClientService.update(self, params) # keep this line to call basic method
self.key1 = params['key1'] # your parameter
self.key2 = params['key2'] if 'key2' in params else None # your parameter
Overwrite ``send`` methode
****************************
This method is called by plugin for sending message on service, She must return a dict with format :
use self._log to log message in plugin log.
::
{
'status' : <A simple text to say sended or not>,
'error' : <Error cause or empty ('') if no error>
}
::
def send(self, message):
""" Send message
@param message : message dict data contain at least keys:
- 'to' : recipient of the message
- 'header' : header for message set in plugin configuration
- 'body" : message
- extra key defined in 'command' json declaration like 'title', priority', ....
@return : dict = {'status' : <Status info>, 'error' : <Error Message>}
"""
...
# write your own code for format message and send it.
# using try / except should avoid failling plugin
try :
...
except :
result = {'status': u"Message not sended", 'error': u"Bad message format : {0}".format(message)}
self._log.warning(u"{0} Message <{1}> not sended. {2}".format(self.to, message, traceback.format_exc())) # use traceback in lo
...
if message_Is_Sended : return {'status': 'Message sended :)', 'error': ''}
else return {'status': 'Message not sended :(', 'error': 'Server not response .....'}