2 # -*- coding: utf-8 -*-
5 Slixmpp: The Slick XMPP Library
6 Implementation of xeps for Internet of Things
7 http://wiki.xmpp.org/web/Tech_pages/IoT_systems
8 Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se
9 This file is part of Slixmpp.
11 See the file LICENSE for copying permission.
16 # This can be used when you are in a test environment and need to make paths right
17 sys
.path
=['/Users/jocke/Dropbox/06_dev/Slixmpp']+sys
.path
25 from os
.path
import splitext
, basename
, join
as pjoin
26 from optparse
import OptionParser
27 from urllib
import urlopen
30 # Python versions before 3.0 do not use UTF-8 encoding
31 # by default. To ensure that Unicode is handled properly
32 # throughout Slixmpp, we will set the default encoding
34 if sys
.version_info
< (3, 0):
35 from slixmpp
.util
.misc_ops
import setdefaultencoding
36 setdefaultencoding('utf8')
40 from slixmpp
.plugins
.xep_0323
.device
import Device
42 #from slixmpp.exceptions import IqError, IqTimeout
44 class IoT_TestDevice(slixmpp
.ClientXMPP
):
47 A simple IoT device that can act as server or client
49 def __init__(self
, jid
, password
):
50 slixmpp
.ClientXMPP
.__init
__(self
, jid
, password
)
51 self
.add_event_handler("session_start", self
.session_start
)
52 self
.add_event_handler("message", self
.message
)
58 def datacallback(self
,from_jid
,result
,nodeId
=None,timestamp
=None,fields
=None,error_msg
=None):
60 This method will be called when you ask another IoT device for data with the xep_0323
61 se script below for the registration of the callback
63 logging
.debug("we got data %s from %s",str(result
),from_jid
)
65 def beClientOrServer(self
,server
=True,clientJID
=None ):
71 self
.clientJID
=clientJID
73 def testForRelease(self
):
77 def doReleaseMe(self
):
81 def addDevice(self
, device
):
84 def session_start(self
, event
):
87 # tell your preffered friend that you are alive
88 self
.send_message(mto
='jocke@jabber.sust.se', mbody
=self
.boundjid
.bare
+' is now online use xep_323 stanza to talk to me')
90 if not(self
.beServer
):
91 session
=self
['xep_0323'].request_data(self
.boundjid
.full
,self
.clientJID
,self
.datacallback
)
93 def message(self
, msg
):
94 if msg
['type'] in ('chat', 'normal'):
95 logging
.debug("got normal chat message" + str(msg
))
96 ip
=urlopen('http://icanhazip.com').read()
97 msg
.reply("Hi I am " + self
.boundjid
.full
+ " and I am on IP " + ip
).send()
99 logging
.debug("got unknown message type %s", str(msg
['type']))
101 class TheDevice(Device
):
103 This is the actual device object that you will use to get information from your real hardware
104 You will be called in the refresh method when someone is requesting information from you
106 def __init__(self
,nodeId
):
107 Device
.__init
__(self
,nodeId
)
110 def refresh(self
,fields
):
112 the implementation of the refresh method
114 self
._set
_momentary
_timestamp
(self
._get
_timestamp
())
115 self
.counter
+=self
.counter
116 self
._add
_field
_momentary
_data
(self
, "Temperature", self
.counter
)
118 if __name__
== '__main__':
120 # Setup the command line arguments.
122 # This script can act both as
123 # "server" an IoT device that can provide sensorinformation
124 # python IoT_TestDevice.py -j "serverjid@yourdomain.com" -p "password" -n "TestIoT" --debug
126 # "client" an IoT device or other party that would like to get data from another device
128 optp
= OptionParser()
130 # Output verbosity options.
131 optp
.add_option('-q', '--quiet', help='set logging to ERROR',
132 action
='store_const', dest
='loglevel',
133 const
=logging
.ERROR
, default
=logging
.INFO
)
134 optp
.add_option('-d', '--debug', help='set logging to DEBUG',
135 action
='store_const', dest
='loglevel',
136 const
=logging
.DEBUG
, default
=logging
.INFO
)
137 optp
.add_option('-v', '--verbose', help='set logging to COMM',
138 action
='store_const', dest
='loglevel',
139 const
=5, default
=logging
.INFO
)
140 optp
.add_option('-t', '--pingto', help='set jid to ping',
141 action
='store', type='string', dest
='pingjid',
144 # JID and password options.
145 optp
.add_option("-j", "--jid", dest
="jid",
147 optp
.add_option("-p", "--password", dest
="password",
148 help="password to use")
151 optp
.add_option("-c", "--sensorjid", dest
="sensorjid",
152 help="Another device to call for data on", default
=None)
153 optp
.add_option("-n", "--nodeid", dest
="nodeid",
154 help="I am a device get ready to be called", default
=None)
156 opts
, args
= optp
.parse_args()
159 logging
.basicConfig(level
=opts
.loglevel
,
160 format
='%(levelname)-8s %(message)s')
163 opts
.jid
= raw_input("Username: ")
164 if opts
.password
is None:
165 opts
.password
= getpass
.getpass("Password: ")
168 xmpp
= IoT_TestDevice(opts
.jid
,opts
.password
)
169 xmpp
.register_plugin('xep_0030')
170 #xmpp['xep_0030'].add_feature(feature='urn:xmpp:iot:sensordata',
173 xmpp
.register_plugin('xep_0323')
174 xmpp
.register_plugin('xep_0325')
178 # xmpp['xep_0030'].add_feature(feature='urn:xmpp:sn',
180 # jid=xmpp.boundjid.full)
182 myDevice
= TheDevice(opts
.nodeid
);
183 # myDevice._add_field(name="Relay", typename="numeric", unit="Bool");
184 myDevice
._add
_field
(name
="Temperature", typename
="numeric", unit
="C");
185 myDevice
._set
_momentary
_timestamp
("2013-03-07T16:24:30")
186 myDevice
._add
_field
_momentary
_data
("Temperature", "23.4", flags
={"automaticReadout": "true"});
188 xmpp
['xep_0323'].register_node(nodeId
=opts
.nodeid
, device
=myDevice
, commTimeout
=10);
189 xmpp
.beClientOrServer(server
=True)
190 while not(xmpp
.testForRelease()):
192 xmpp
.process(block
=True)
193 logging
.debug("lost connection")
195 logging
.debug("will try to call another device for data")
196 xmpp
.beClientOrServer(server
=False,clientJID
=opts
.sensorjid
)
198 xmpp
.process(block
=True)
199 logging
.debug("ready ending")
202 print "noopp didn't happen"