bluetooth_drone/client.py
Daniel Pollithy 1904e850d1 d3 update
2017-08-31 20:04:34 +02:00

198 lines
6.3 KiB
Python

import bluetooth
import time
import json
from subprocess import Popen, PIPE
import settings
from drone_poller import notify_website
settings.activate_bluetooth_discovery()
bt_mac = settings.get_own_bt_address()
print('This devices bluetooth address is: {}'.format(bt_mac))
def protocol(address):
payload = json.dumps({'addr': settings.CLIENT_ETHEREUM_ADDRESS})
assert len(payload) < 1024
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
bt_addr = address
port = 0x1001
print("trying to connect to %s on PSM 0x%X" % (bt_addr, port))
sock.connect((bt_addr, port))
print("connected. Sending: ", payload)
sock.send(payload)
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'state': 'landing approach',
'station': ''
}))
notify_website()
# THE SERVER WILL ONLY REPLY WHEN THE BLUETOOTH DISTANCE IS CLOSE ENOUGH
# BUT THE SOCKET STAYS OPEN
data = sock.recv(1024)
print("Data received:", str(data))
try:
data = json.loads(data)
assert 'accepted' in data
connection_accepted = data['accepted']
if connection_accepted:
assert 'addr' in data
server_ethereum_address = data['addr'].lower()
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'status': 'landing accepted',
'station': server_ethereum_address
}))
notify_website()
else:
server_ethereum_address = False
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'status': 'landing denied',
'station': ''
}))
notify_website()
except AssertionError:
print('Json is missing data')
sock.close()
raise StandardError
except:
print('Error reading json from the data')
sock.close()
raise StandardError
if not connection_accepted:
print('The server has not accepted the drone')
print('Closing connection.')
sock.close()
print('Connection accepted')
print('calling ethereum network')
# ETHEREUM
# now start the transaction
if not settings.DEMO:
print('node start_charging.js {} {}'.format(settings.CLIENT_ETHEREUM_ADDRESS, server_ethereum_address))
p = Popen(
[
'node',
'start_charging.js',
settings.CLIENT_ETHEREUM_ADDRESS,
server_ethereum_address
],
stdin=PIPE,
stdout=PIPE,
stderr=PIPE
)
output, err = p.communicate()
returncode = p.returncode
else:
returncode = 0
if returncode != 0:
sock.send(json.dumps({'start_charging': False}))
print('Not starting charging logic (no reservation or blockchain problem)')
print('Closing connection.')
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'status': 'charging denied',
'station': server_ethereum_address
}))
notify_website()
# wait for remote closing
data = sock.recv(1024)
# sock.close()
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'status': 'start charging',
'station': server_ethereum_address
}))
notify_website()
sock.send(json.dumps({'start_charging': True}))
# the server will activate the relais now
# the loading will take time and there could be some information exchanged here in the future
data = sock.recv(1024)
print("Data received:", str(data))
try:
data = json.loads(data)
assert 'electricity' in data
electricity = data['electricity']
except AssertionError:
print('Json is missing data')
sock.close()
raise StandardError
except:
print('Error reading json from the data')
sock.close()
raise StandardError
print('Energy consumption as hangar says: {}'.format(electricity))
print('Transaction done.')
with open('connection_state.txt', 'w') as inp:
inp.write(json.dumps({
'status': 'charging ended',
'station': server_ethereum_address
}))
notify_website()
sock.close()
def run():
connecting = True
while connecting:
nearby_devices = bluetooth.discover_devices(duration=settings.BT_DISCOVERY_DURATION, flush_cache=False)
print("found %d devices" % len(nearby_devices))
for address in nearby_devices:
print(" %s " % (address))
if address.lower() == settings.PEER_BT_ADDRESS:
print("PEERING PARTNER FOUND")
try:
protocol(address.lower())
except bluetooth.BluetoothError as e:
print('e')
print(e)
print('errno')
print(e.errno)
print('args')
print(e.args)
print('msg')
print(e.message)
print('__repr__()')
print(e.__repr__())
if e.__repr__() == "(104, 'Connection reset by peer')":
print('Connection reset by peer')
print('That is o.k. I make a break and then we keep on')
time.sleep(settings.DRONE_REJECTED_RESTART_TIME)
elif e.message == "(112, 'Host is down')":
print('The host is down. :(')
print('Try to reconnect')
elif e.message == "(9, 'Bad file descriptor')":
print('Closing connection because booking is unconfirmed')
print('No booking in blockchain')
elif e.message == "(104, 'Connection reset by peer')":
print('Peer closed connection')
print('No booking in blockchain')
else:
print('This error is not known. I stop connecting')
print(e)
# connecting = False
time.sleep(settings.BT_SLEEP)
if __name__ == '__main__':
run()