xaal.lib 0.7.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xaal/__init__.py +1 -0
- xaal/lib/__init__.py +23 -0
- xaal/lib/__main__.py +2 -0
- xaal/lib/aioengine.py +388 -0
- xaal/lib/aiohelpers.py +38 -0
- xaal/lib/aionetwork.py +74 -0
- xaal/lib/bindings.py +98 -0
- xaal/lib/cbor.py +62 -0
- xaal/lib/config.py +53 -0
- xaal/lib/core.py +308 -0
- xaal/lib/devices.py +285 -0
- xaal/lib/engine.py +231 -0
- xaal/lib/exceptions.py +20 -0
- xaal/lib/helpers.py +80 -0
- xaal/lib/messages.py +336 -0
- xaal/lib/network.py +100 -0
- xaal/lib/test.py +140 -0
- xaal/lib/tools.py +130 -0
- xaal.lib-0.7.2.dist-info/METADATA +131 -0
- xaal.lib-0.7.2.dist-info/RECORD +22 -0
- xaal.lib-0.7.2.dist-info/WHEEL +5 -0
- xaal.lib-0.7.2.dist-info/top_level.txt +1 -0
xaal/lib/network.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2014, Jérôme Colin, Jérôme Kerdreux, Philippe Tanguy,
|
|
3
|
+
# Telecom Bretagne.
|
|
4
|
+
#
|
|
5
|
+
# This file is part of xAAL.
|
|
6
|
+
#
|
|
7
|
+
# xAAL is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# xAAL is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with xAAL. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
import socket
|
|
22
|
+
import struct
|
|
23
|
+
import select
|
|
24
|
+
import logging
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
import time
|
|
29
|
+
from enum import Enum
|
|
30
|
+
|
|
31
|
+
class NetworkState(Enum):
|
|
32
|
+
disconnected = 0
|
|
33
|
+
connected = 1
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class NetworkConnector(object):
|
|
37
|
+
UDP_MAX_SIZE = 65507
|
|
38
|
+
|
|
39
|
+
def __init__(self, addr, port, hops,bind_addr='0.0.0.0'):
|
|
40
|
+
self.addr = addr
|
|
41
|
+
self.port = port
|
|
42
|
+
self.hops = hops
|
|
43
|
+
self.bind_addr = bind_addr
|
|
44
|
+
self.state = NetworkState.disconnected
|
|
45
|
+
|
|
46
|
+
def connect(self):
|
|
47
|
+
try:
|
|
48
|
+
self.__connect()
|
|
49
|
+
except Exception as e:
|
|
50
|
+
self.network_error(e)
|
|
51
|
+
|
|
52
|
+
def __connect(self):
|
|
53
|
+
logger.info("Connecting to %s:%s" % (self.addr, self.port))
|
|
54
|
+
|
|
55
|
+
self.__sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP)
|
|
56
|
+
self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
|
57
|
+
# #formac os ???
|
|
58
|
+
#self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
59
|
+
self.__sock.bind((self.bind_addr, self.port))
|
|
60
|
+
mreq = struct.pack("=4s4s",socket.inet_aton(self.addr),socket.inet_aton(self.bind_addr))
|
|
61
|
+
self.__sock.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,mreq)
|
|
62
|
+
self.__sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,self.hops)
|
|
63
|
+
self.state = NetworkState.connected
|
|
64
|
+
|
|
65
|
+
def disconnect(self):
|
|
66
|
+
logger.info("Disconnecting from the bus")
|
|
67
|
+
self.state = NetworkState.disconnected
|
|
68
|
+
self.__sock.close()
|
|
69
|
+
|
|
70
|
+
def is_connected(self):
|
|
71
|
+
return self.state == NetworkState.connected
|
|
72
|
+
|
|
73
|
+
def receive(self):
|
|
74
|
+
packt = self.__sock.recv(self.UDP_MAX_SIZE)
|
|
75
|
+
return packt
|
|
76
|
+
|
|
77
|
+
def __get_data(self):
|
|
78
|
+
r = select.select([self.__sock, ], [], [], 0.02)
|
|
79
|
+
if r[0]:
|
|
80
|
+
return self.receive()
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
def get_data(self):
|
|
84
|
+
if not self.is_connected(): self.connect()
|
|
85
|
+
try:
|
|
86
|
+
return self.__get_data()
|
|
87
|
+
except Exception as e:
|
|
88
|
+
self.network_error(e)
|
|
89
|
+
|
|
90
|
+
def send(self,data):
|
|
91
|
+
if not self.is_connected(): self.connect()
|
|
92
|
+
try:
|
|
93
|
+
self.__sock.sendto(data, (self.addr, self.port))
|
|
94
|
+
except Exception as e:
|
|
95
|
+
self.network_error(e)
|
|
96
|
+
|
|
97
|
+
def network_error(self, msg):
|
|
98
|
+
self.disconnect()
|
|
99
|
+
logger.info("Network error, reconnect..%s" % msg)
|
|
100
|
+
time.sleep(5)
|
xaal/lib/test.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import xaal.lib
|
|
4
|
+
from xaal.lib import tools
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
ADDR="b8bec7ca-f955-11e6-9031-82ed25e6aaaa"
|
|
11
|
+
ADDR=tools.get_random_uuid()
|
|
12
|
+
|
|
13
|
+
def dump_hex(name,data):
|
|
14
|
+
print("%s : " % name,end='=')
|
|
15
|
+
for k in data:
|
|
16
|
+
if type(k) == int:
|
|
17
|
+
print("%x"%k,end=' ')
|
|
18
|
+
else:
|
|
19
|
+
print("%x"%ord(k),end=' ')
|
|
20
|
+
print()
|
|
21
|
+
|
|
22
|
+
def test_pysodium():
|
|
23
|
+
from xaal.lib import messages
|
|
24
|
+
import pysodium
|
|
25
|
+
|
|
26
|
+
payload = "FooBar".encode("utf-8")
|
|
27
|
+
ad = '[]'
|
|
28
|
+
|
|
29
|
+
data = messages.build_timestamp()
|
|
30
|
+
nonce = messages.build_nonce(data)
|
|
31
|
+
key = tools.pass2key("My Friend Goo")
|
|
32
|
+
|
|
33
|
+
dump_hex("Payload",payload)
|
|
34
|
+
dump_hex("Key",key)
|
|
35
|
+
|
|
36
|
+
ciph = pysodium.crypto_aead_chacha20poly1305_encrypt(payload, ad, nonce, key)
|
|
37
|
+
dump_hex("Ciph",ciph)
|
|
38
|
+
|
|
39
|
+
pjson = pysodium.crypto_aead_chacha20poly1305_decrypt(ciph, ad, nonce, key)
|
|
40
|
+
print(pjson)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_device():
|
|
44
|
+
from xaal.lib.devices import Device
|
|
45
|
+
addr = ADDR
|
|
46
|
+
dev = Device("foo.basic",addr)
|
|
47
|
+
dev.vendor_id = "ACME"
|
|
48
|
+
dev.url="http://acmefactory.blogspot.fr/"
|
|
49
|
+
dev.hw_id = "0x201"
|
|
50
|
+
print(dev.getDescription())
|
|
51
|
+
return dev
|
|
52
|
+
|
|
53
|
+
def test_msg():
|
|
54
|
+
from xaal.lib.messages import Message
|
|
55
|
+
msg = Message()
|
|
56
|
+
addr = ADDR
|
|
57
|
+
msg.targets = [addr,]
|
|
58
|
+
msg.dump()
|
|
59
|
+
|
|
60
|
+
def test_encode():
|
|
61
|
+
from xaal.lib.messages import MessageFactory
|
|
62
|
+
key = tools.pass2key("FooBar")
|
|
63
|
+
factory = MessageFactory(key)
|
|
64
|
+
m2 = factory.build_msg()
|
|
65
|
+
print(factory.decode_msg(m2))
|
|
66
|
+
|
|
67
|
+
def test_log():
|
|
68
|
+
logger = logging.getLogger(__name__)
|
|
69
|
+
logger.info("This is an INFO msg")
|
|
70
|
+
logger.debug("This is an DEBUG msg")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_engine():
|
|
74
|
+
from xaal.lib.core import Engine
|
|
75
|
+
engine = Engine()
|
|
76
|
+
engine.run()
|
|
77
|
+
|
|
78
|
+
def test_alive():
|
|
79
|
+
addr = ADDR
|
|
80
|
+
dev = xaal.lib.Device("test.basic",addr)
|
|
81
|
+
eng = xaal.lib.Engine()
|
|
82
|
+
eng.add_devices([dev,])
|
|
83
|
+
eng.run()
|
|
84
|
+
|
|
85
|
+
def test_crypto_decoding_error():
|
|
86
|
+
addr = ADDR
|
|
87
|
+
dev = xaal.lib.Device("test.basic",addr)
|
|
88
|
+
eng = xaal.lib.Engine()
|
|
89
|
+
eng.add_devices([dev,])
|
|
90
|
+
eng.msg_factory.cipher_key = tools.pass2key("FakeKey")
|
|
91
|
+
eng.start()
|
|
92
|
+
eng.loop()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_attr():
|
|
96
|
+
dev = xaal.lib.Device("test.basic",ADDR)
|
|
97
|
+
dev.url = "http://linux.org"
|
|
98
|
+
dev.vendor_id = "ACME"
|
|
99
|
+
dev.product_id = "Full Fake Device"
|
|
100
|
+
dev.info = "FooBar"
|
|
101
|
+
dev.hw_id = "ffd0001"
|
|
102
|
+
#dev.alive_period = 100
|
|
103
|
+
|
|
104
|
+
attr0 = dev.new_attribute("attr0",10)
|
|
105
|
+
attr1 = dev.new_attribute("attr1",False)
|
|
106
|
+
|
|
107
|
+
eng = xaal.lib.Engine()
|
|
108
|
+
eng.add_devices([dev,])
|
|
109
|
+
|
|
110
|
+
def update():
|
|
111
|
+
attr0.value = attr0.value + 1
|
|
112
|
+
|
|
113
|
+
eng.add_timer(update,60)
|
|
114
|
+
|
|
115
|
+
#eng.loop()
|
|
116
|
+
eng.run()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def run():
|
|
121
|
+
|
|
122
|
+
logger = tools.get_logger(__name__,logging.DEBUG,"%s.log" % __name__)
|
|
123
|
+
#test_pysodium()
|
|
124
|
+
#test_device()
|
|
125
|
+
#test_msg()
|
|
126
|
+
#test_encode()
|
|
127
|
+
#test_log()
|
|
128
|
+
#test_alive()
|
|
129
|
+
#test_crypto_decoding_error()
|
|
130
|
+
test_attr()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if __name__ == '__main__':
|
|
135
|
+
try:
|
|
136
|
+
run()
|
|
137
|
+
except KeyboardInterrupt:
|
|
138
|
+
print("Bye bye...")
|
|
139
|
+
|
|
140
|
+
|
xaal/lib/tools.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2014, Jérôme Colin, Jérôme Kerdreux, Philippe Tanguy,
|
|
3
|
+
# Telecom Bretagne.
|
|
4
|
+
#
|
|
5
|
+
# This file is part of xAAL.
|
|
6
|
+
#
|
|
7
|
+
# xAAL is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# xAAL is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with xAAL. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
import pysodium
|
|
25
|
+
|
|
26
|
+
import sys
|
|
27
|
+
import functools
|
|
28
|
+
from configobj import ConfigObj
|
|
29
|
+
|
|
30
|
+
from . import config
|
|
31
|
+
from .bindings import UUID
|
|
32
|
+
|
|
33
|
+
XAAL_DEVTYPE_PATTERN = '^[a-zA-Z][a-zA-Z0-9_-]*\.[a-zA-Z][a-zA-Z0-9_-]*$'
|
|
34
|
+
|
|
35
|
+
def get_cfg_filename(name, cfg_dir=config.conf_dir):
|
|
36
|
+
if name.startswith('xaal.'):
|
|
37
|
+
name = name[5:]
|
|
38
|
+
filename = '%s.ini' % name
|
|
39
|
+
if not os.path.isdir(cfg_dir):
|
|
40
|
+
print("Your configuration directory doesn't exist: [%s]" % cfg_dir)
|
|
41
|
+
return os.path.join(cfg_dir, filename)
|
|
42
|
+
|
|
43
|
+
def load_cfg_file(filename):
|
|
44
|
+
""" load .ini file and return it as dict"""
|
|
45
|
+
if os.path.isfile(filename):
|
|
46
|
+
return ConfigObj(filename,indent_type=' ',encoding="utf8")
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
def load_cfg(app_name):
|
|
50
|
+
filename = get_cfg_filename(app_name)
|
|
51
|
+
return load_cfg_file(filename)
|
|
52
|
+
|
|
53
|
+
def load_cfg_or_die(app_name):
|
|
54
|
+
cfg = load_cfg(app_name)
|
|
55
|
+
if not cfg:
|
|
56
|
+
print("Unable to load config file %s" % get_cfg_filename(app_name))
|
|
57
|
+
sys.exit(-1)
|
|
58
|
+
return cfg
|
|
59
|
+
|
|
60
|
+
def new_cfg(app_name):
|
|
61
|
+
filename = get_cfg_filename(app_name)
|
|
62
|
+
cfg = ConfigObj(filename,indent_type=' ')
|
|
63
|
+
cfg['config'] = {}
|
|
64
|
+
cfg['config']['addr']=get_random_uuid().str
|
|
65
|
+
return cfg
|
|
66
|
+
|
|
67
|
+
def get_random_uuid():
|
|
68
|
+
return UUID.random()
|
|
69
|
+
|
|
70
|
+
def get_random_base_uuid(digit=2):
|
|
71
|
+
return UUID.random_base(digit)
|
|
72
|
+
|
|
73
|
+
def get_uuid(val):
|
|
74
|
+
if isinstance(val,UUID):
|
|
75
|
+
return val
|
|
76
|
+
if isinstance(val,str):
|
|
77
|
+
return str_to_uuid(val)
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def str_to_uuid(val):
|
|
81
|
+
""" return an xAAL address for a given string"""
|
|
82
|
+
try:
|
|
83
|
+
return UUID(val)
|
|
84
|
+
except ValueError:
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
def bytes_to_uuid(val):
|
|
88
|
+
try:
|
|
89
|
+
return UUID(bytes=val)
|
|
90
|
+
except ValueError:
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
def is_valid_uuid(val):
|
|
94
|
+
return isinstance(val,UUID)
|
|
95
|
+
|
|
96
|
+
def is_valid_address(val):
|
|
97
|
+
return is_valid_uuid(val)
|
|
98
|
+
|
|
99
|
+
@functools.lru_cache(maxsize=128)
|
|
100
|
+
def is_valid_dev_type(val):
|
|
101
|
+
if not isinstance(val,str):
|
|
102
|
+
return False
|
|
103
|
+
if re.match(XAAL_DEVTYPE_PATTERN,val):
|
|
104
|
+
return True
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
def pass2key(passphrase):
|
|
108
|
+
"""Generate key from passphrase using libsodium
|
|
109
|
+
crypto_pwhash_scryptsalsa208sha256 func
|
|
110
|
+
salt: buffer of zeros
|
|
111
|
+
opslimit: crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE
|
|
112
|
+
memlimit: crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE
|
|
113
|
+
"""
|
|
114
|
+
buf = passphrase.encode('utf-8')
|
|
115
|
+
KEY_BYTES = pysodium.crypto_pwhash_scryptsalsa208sha256_SALTBYTES #32
|
|
116
|
+
# this should be:
|
|
117
|
+
# salt = bytes(KEY_BYTES)
|
|
118
|
+
# but due to bytes() stupid stuff in py2 we need this awfull stuff
|
|
119
|
+
salt = ('\00' * KEY_BYTES).encode('utf-8')
|
|
120
|
+
opslimit = pysodium.crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE
|
|
121
|
+
memlimit = pysodium.crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE
|
|
122
|
+
key = pysodium.crypto_pwhash_scryptsalsa208sha256(KEY_BYTES, buf, salt, opslimit, memlimit)
|
|
123
|
+
return key
|
|
124
|
+
|
|
125
|
+
@functools.lru_cache(maxsize=128)
|
|
126
|
+
def reduce_addr(addr):
|
|
127
|
+
"""return a string based addred without all digits"""
|
|
128
|
+
tmp = addr.str
|
|
129
|
+
return tmp[:5] + '..' + tmp[-5:]
|
|
130
|
+
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: xaal.lib
|
|
3
|
+
Version: 0.7.2
|
|
4
|
+
Summary: xaal.lib is the official Python stack of xAAL protocol dedicated to home automation systems
|
|
5
|
+
Author-email: Jerome Kerdreux <Jerome.Kerdreux@imt-atlantique.fr>
|
|
6
|
+
License: GPL License
|
|
7
|
+
Keywords: xaal,home-automation
|
|
8
|
+
Classifier: Programming Language :: Python
|
|
9
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
10
|
+
Description-Content-Type: text/x-rst
|
|
11
|
+
Requires-Dist: cbor2 ==5.4.2
|
|
12
|
+
Requires-Dist: pysodium
|
|
13
|
+
Requires-Dist: configobj
|
|
14
|
+
Requires-Dist: coloredlogs
|
|
15
|
+
Requires-Dist: decorator
|
|
16
|
+
Requires-Dist: tabulate
|
|
17
|
+
Requires-Dist: aioconsole
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
xaal.lib
|
|
21
|
+
========
|
|
22
|
+
**xaal.lib** is the official Python stack to develop home-automation devices and gateways
|
|
23
|
+
with the xAAL protocol. For a full description of the protocol check out
|
|
24
|
+
http://recherche.imt-atlantique.fr/xaal/
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Dependencies
|
|
28
|
+
~~~~~~~~~~~~
|
|
29
|
+
xaal.lib depends on :
|
|
30
|
+
* cbor2
|
|
31
|
+
* pysodium
|
|
32
|
+
* configobj
|
|
33
|
+
* coloredlogs
|
|
34
|
+
* decorator
|
|
35
|
+
* tabulate
|
|
36
|
+
* aioconsole
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Install
|
|
40
|
+
~~~~~~~
|
|
41
|
+
Please refer to the official `full documentation to install the lib in a virtualenv
|
|
42
|
+
<https://redmine.telecom-bretagne.eu/svn/xaal/code/Python/branches/0.7/README.html>`_
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
Usage
|
|
46
|
+
~~~~~
|
|
47
|
+
The main goal of xaal.lib is to provide an API to easily develop devices & gateways.
|
|
48
|
+
**xaal.lib.Engine send / receive / parse to|from xAAL Bus**.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
To receive / parse / display incoming xAAL messages, you can simply try something like
|
|
52
|
+
this:
|
|
53
|
+
|
|
54
|
+
.. code-block:: python
|
|
55
|
+
|
|
56
|
+
from xaal.lib import Engine
|
|
57
|
+
|
|
58
|
+
def display(msg):
|
|
59
|
+
print(msg)
|
|
60
|
+
|
|
61
|
+
eng = Engine()
|
|
62
|
+
eng.subscribe(display)
|
|
63
|
+
eng.run()
|
|
64
|
+
|
|
65
|
+
The Engine will call the display function every time it receive a xAAL message.
|
|
66
|
+
|
|
67
|
+
Let's take a look at a simple lamp device :
|
|
68
|
+
|
|
69
|
+
.. code-block:: python
|
|
70
|
+
|
|
71
|
+
from xaal.lib import Device,Engine,tools
|
|
72
|
+
|
|
73
|
+
# create and configure the lamp device, with a random address
|
|
74
|
+
dev = Device("lamp.basic", tools.get_random_uuid())
|
|
75
|
+
dev.product_id = 'Dummy Lamp'
|
|
76
|
+
dev.url = 'http://www.acme.org'
|
|
77
|
+
dev.info = 'My fake lamp'
|
|
78
|
+
|
|
79
|
+
# add an xAAL attribute 'light'
|
|
80
|
+
light = dev.new_attribute('light')
|
|
81
|
+
|
|
82
|
+
# declare two device methods ON & OFF
|
|
83
|
+
def on():
|
|
84
|
+
light.value = True
|
|
85
|
+
|
|
86
|
+
def off():
|
|
87
|
+
light.value = False
|
|
88
|
+
|
|
89
|
+
dev.add_method('turn_on',on)
|
|
90
|
+
dev.add_method('turn_off',off)
|
|
91
|
+
|
|
92
|
+
# last step, create an engine and register the lamp
|
|
93
|
+
eng = Engine()
|
|
94
|
+
eng.add_device(dev)
|
|
95
|
+
eng.run()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
FAQ
|
|
99
|
+
~~~
|
|
100
|
+
The core engine run forever so how can I use it in webserver, GUI or to develop device
|
|
101
|
+
with IO. The whole API is absolutely not thread safe, so **don't use threads** unless you
|
|
102
|
+
exactly know what's going on. Anyways, you have several options to fix this issue:
|
|
103
|
+
|
|
104
|
+
* You can use you own loop and periodically call *eng.loop()*
|
|
105
|
+
for example, you can do something like this:
|
|
106
|
+
|
|
107
|
+
.. code:: python
|
|
108
|
+
|
|
109
|
+
while 1:
|
|
110
|
+
do_some_stuff()
|
|
111
|
+
eng.loop()
|
|
112
|
+
|
|
113
|
+
* You can use a engine timer, to perform some stuff.
|
|
114
|
+
|
|
115
|
+
.. code:: python
|
|
116
|
+
|
|
117
|
+
def read_io():
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
# call the read_io function every 10 sec
|
|
121
|
+
eng.add_timer(read_io,10)
|
|
122
|
+
eng.run()
|
|
123
|
+
|
|
124
|
+
* Use the **AsyncEngine**. Python version > 3.8 provides async programming with **asyncio** package.
|
|
125
|
+
*AsyncEngine* use the same API as *Engine*, but it is a **asynchronous** engine. You can use
|
|
126
|
+
*coroutines* in device methods, timers functions and callbacks. It provides additionals features
|
|
127
|
+
like the *on_start* and *on_stop* callbacks.
|
|
128
|
+
|
|
129
|
+
* Use an alternate coroutine lib, you can use **gevent** or **greenlet** for example. Look at
|
|
130
|
+
apps/rest for a simple greenlet example.
|
|
131
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
xaal/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
|
|
2
|
+
xaal/lib/__init__.py,sha256=MMXBicq9vNn6yCzBPcqZfTXk329NEL-qTM95jXUMymE,471
|
|
3
|
+
xaal/lib/__main__.py,sha256=xsVqqoIh3UeJIXxeexSfmGSUP4YxUcibdZExjEzk4lE,30
|
|
4
|
+
xaal/lib/aioengine.py,sha256=3MTG9aGKekVvsWhYaehZqZem6YmPng4UqGfDoRTaC2E,13100
|
|
5
|
+
xaal/lib/aiohelpers.py,sha256=2a310wSXzbg9SGYzrTfcHbaZ8PWEe9rLteDmS2i62kU,1007
|
|
6
|
+
xaal/lib/aionetwork.py,sha256=pH-5kf8o4FHsbvs-oFf5guAgYaEu0aosyTuI3k8xt2M,2484
|
|
7
|
+
xaal/lib/bindings.py,sha256=EkDJJ_iBQbC7UzsjHfoXAjpGSwC613hrIm5ubrkcw4k,1994
|
|
8
|
+
xaal/lib/cbor.py,sha256=hWE-mfwhzYQVZ1-JWyx2vy0Sl96Pv6KV7qaN_nf_DxE,1666
|
|
9
|
+
xaal/lib/config.py,sha256=jNAEXCswWsKrVab3hycupQn4aYt4c61eq628ow_I2ZI,1736
|
|
10
|
+
xaal/lib/core.py,sha256=VfaisNREUse-zMrilJuKf6NLVO9HugL1U_I4M7BFzKQ,10806
|
|
11
|
+
xaal/lib/devices.py,sha256=ZDNVNVmJ26W2atuNkzB7xtYZQAT3dWTrQCvMCDMSVWA,9574
|
|
12
|
+
xaal/lib/engine.py,sha256=p2of6IPQB0It0RNu5fkJHHp615K_2rgzHfuWOpvJ6Is,7539
|
|
13
|
+
xaal/lib/exceptions.py,sha256=ZKDKGlm_F48K_0NlaV1fa0Z-a4ZnOxT7NU8c8MKSJAc,504
|
|
14
|
+
xaal/lib/helpers.py,sha256=mXxVxv7fTV9O9xO1BROhVYBTmdviMl6qx3Il8q1ox8w,2679
|
|
15
|
+
xaal/lib/messages.py,sha256=cLwplLp_0qmlgZi6ByohvLEcmuxpWK7liE5dpqyV9AM,11552
|
|
16
|
+
xaal/lib/network.py,sha256=3HWuQ0afQ-X6_-En2rFeqYJ0Scy5IEHfd0qTldxxCFo,3130
|
|
17
|
+
xaal/lib/test.py,sha256=laVbgG4HtQquxDzixAG-Cka-HO4kpb7YUsLL267mGPU,3006
|
|
18
|
+
xaal/lib/tools.py,sha256=SnXmOkeTd4eTN8yWn-GyCkV5mYiG-MX4hkF39KnogLE,3841
|
|
19
|
+
xaal.lib-0.7.2.dist-info/METADATA,sha256=nOxqYAIqm40VUe4t2-22728LE5yL_PfxRlXjbQaI_X0,3545
|
|
20
|
+
xaal.lib-0.7.2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
21
|
+
xaal.lib-0.7.2.dist-info/top_level.txt,sha256=UZ2WDkN02ztkh1OrsjrW8Kmj4n3WqC0BQxaEYOYfWa0,5
|
|
22
|
+
xaal.lib-0.7.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
xaal
|