C'est s_rae. J'étudie la programmation dur.
En tant que pratique de développement d'applications, j'ai créé une interface permettant de faire fonctionner le robot. https://github.com/samanthanium/dullahan_local Vous pouvez voir le code source sur.
Poursuivant le post précédent, cette fois, je vais expliquer un peu la source. Dernière fois: https://qiita.com/s_rae/items/d808c3eccd8e173dc55b
Comme il a été fait à des fins de passe-temps, j'omettrai la gestion des erreurs.
Nous utilisons cette technologie pour ce projet.
Django servait principalement des pages Web via HTTP, gérait les utilisateurs en sessions et travaillait sur la base de données sqlite.
Soit dit en passant, le projet Django se compose de plusieurs «applications» (code qui peut être réutilisé pour d’autres projets).
Ce projet --dullahan (application principale du projet) --pages (pour les pages Web Accueil, À propos, Connexion) --control_system (page d'envoi de commandes et d'enregistrement des périphériques) --bluetooth_interface (y compris le consommateur et la fonction du périphérique Bluetooth)
Il est composé de «app».
La raison pour laquelle j'ai utilisé Django est qu'il a de nombreuses fonctions et peut être créé rapidement. Je voulais aussi pratiquer Python.
Django Channels Django Channels est une bibliothèque créée pour le framework Django. Il est possible d'ajouter des fonctionnalités telles que Websocket au framework Django.
Channels est un mécanisme qui utilise la classe «Consommateur» pour traiter les messages WebSocket. Il peut exécuter des fonctions similaires à la vue du framework Django.
Pybluez Pybluez est une bibliothèque créée pour utiliser la fonction Bluetooth du système en Python. Je n'expliquerai pas le code Pybluez ici, mais vous pouvez écrire le code de la même manière que le module socket.
L'utilisateur se connecte dans> Ajouter un appareil-> Envoyer la commande à l'appareil J'expliquerai le flux des sentiments.
pages/views.py
#...
def log_in(req):
form = AuthenticationForm()
if req.method == 'POST':
form = AuthenticationForm(data=req.POST)
if form.is_valid():
login(req, form.get_user())
return redirect(reverse('get_home'))
else:
return render(req, 'login.html', {'form': form})
return render(req, 'login.html', {'form': form})
#...
def sign_up(req):
form = UserCreationForm()
if req.method == 'POST':
form = UserCreationForm(data=req.POST)
if form.is_valid():
form.save()
return redirect(reverse('log_in'))
else:
print(form.errors)
return render(req, 'signup.html', {'form': form})
Voici la fonction de connexion utilisateur. Vous pouvez facilement vous connecter en utilisant la méthode "form.get_user" incluse dans Django's Forms.
Après ça
@login_required
Vous pouvez vérifier l'utilisateur actuel en utilisant le décorateur de dans la vue.
Vient ensuite l'écran pour rechercher et enregistrer les périphériques Bluetooth environnants.
control_system/views.py
from bluetooth_interface import bt_functions as bt
#...
@login_required
def device_search_ajax(req):
try:
if req.method == "GET":
nearby_devices = json.dumps(bt.search())
return JsonResponse({'nearby_devices':nearby_devices}, status=200)
else:
#...
except:
#Poignée d'erreur
#...
Lorsque vous recherchez des appareils Bluetooth autour de vous, utilisez la requête Ajax.
bt.search est une fonction de recherche d'appareils Bluetooth à l'aide de Pybluez.
Ce Kawa utilise Websocket au lieu de HTTP pour échanger des messages avec le robot.
control_system/consumers.py
#...
class CommandConsumer(WebsocketConsumer):
def connect(self):
#Trouver le modèle de l'appareil sélectionné par l'utilisateur
self.device_id = self.scope['url_route']['kwargs']['device_id']
self.device_group_name = 'command_%s' % self.device_id
device = Device.objects.get(id=self.device_id)
#Autoriser le consommateur pour Bluetooth à communiquer en série avec l'appareil
async_to_sync(self.channel_layer.send)('bt-process', {
'type': 'bt_connect',
'group_name': self.device_group_name,
'uuid': device.uuid,
'device' : device.id,
}
)
#Ajouter un utilisateur au groupe
async_to_sync(self.channel_layer.group_add)(
self.device_group_name,
self.channel_name
)
self.accept()
#...
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
device_id = text_data_json['device']
#Envoyer des commandes à l'appareil
async_to_sync(self.channel_layer.send)('bt-process', {
'type': 'bt_send_serial',
'device': device_id,
'message': message,
}
)
#...
#Enregistrer et transférer les messages de réponse reçus des appareils Bluetooth
def command_message(self, event):
message = event['message']
device_id = event['device']
#Enregistrer dans le modèle d'appareil avec horodatage
device = Device.objects.get(id=device_id)
new_history = CommandHistory(device=device, command=message )
new_history.save()
command_history = {}
all_history = device.history.all()
for command in all_history:
command_history[command.timestamp.strftime('%H:%M:%S')] = command.command + '\n'
#Envoyer l'historique des commandes à l'utilisateur
self.send(text_data=json.dumps({
'message': command_history,
'device': device_id
}))
C'est un peu compliqué, mais pour l'expliquer brièvement
--Connect ouvre la communication Websocket avec l'utilisateur et active la communication avec le périphérique Bluetooth. «Processus Bt» fait référence au consommateur des appareils Bluetooth actuellement exécutés en arrière-plan. J'ai envie d'essayer d'utiliser «bt_connect» de «bt-process».
--Receive envoie une commande à l'appareil contenu dans le message au robot lorsque l'utilisateur envoie un message à l'aide de la page Web. Cela envoie également un message à «bt-process» de la même manière que ci-dessus.
--command_message enregistre la réponse reçue du robot dans le modèle de base de données du robot. Le message a une relation plusieurs-à-un avec le modèle de robot. C'est un formulaire qui est connecté en utilisant l'identifiant du robot.
Vient ensuite la classe consommateur pour communiquer avec le robot.
bluetooth_interface/consumers.py
#...
from bluetooth_interface import bt_functions
#...
class BTConsumer(SyncConsumer):
def bt_connect(self, message):
#N'oubliez pas de pouvoir envoyer un message à l'utilisateur
self.device_group_name = message['group_name']
self.sock = {}
#Numéro de port de communication Bluetooth
self.port_num = 1
#Créer une prise de communication
sock, msg = bt_functions.connect(message['uuid'], self.port_num)
#Prise d'enregistrement avec identifiant de l'appareil
if sock != 1:
self.sock = {message['device']:[sock, self.port_num]}
#Envoyer l'état de la communication à l'utilisateur
async_to_sync(self.channel_layer.group_send)(
self.device_group_name,
{
'type': 'command_message',
'device': message['device'],
'message': msg,
}
)
#...
def bt_send_serial(self, event):
#Prenez l'identifiant de l'appareil et le message demandé par l'utilisateur
device_id = int(event['device'])
message = event['message']
#Sélectionnez une prise pour communiquer avec l'appareil et envoyer un message
if device_id in self.sock.keys():
result = bt_functions.send_serial(self.sock[device_id][0], message)
#Envoyer un message de réponse à l'utilisateur
async_to_sync(self.channel_layer.group_send)(
self.device_group_name,
{
'type': 'command_message',
'device': device_id,
'message': result,
}
)
#...
J'étais assez confus sur la façon de le faire ici. Par conséquent
--Créez un consommateur qui permet au robot d'envoyer des messages (données de capteur, réponses aux commandes, etc.) à tout moment
Je l'ai rendu possible.
Django Channels utilise la couche Channels pour permettre la communication entre les classes et les processus Consumer.
Ainsi, même si l'utilisateur se déconnecte ou effectue un autre travail, il est toujours connecté au robot dans un autre processus.
Je ne l'ai pas encore créé, mais je peux toujours obtenir des données de capteur à partir de robots et d'appareils IoT de cette manière.
Consultez la documentation des canaux Django pour plus de détails. https://channels.readthedocs.io/en/latest/topics/channel_layers.html https://channels.readthedocs.io/en/latest/topics/worker.html
Je pense qu'il aurait été plus facile de créer un projet avec Node.js, qui est facile à utiliser avec Async.
Cependant, j'ai utilisé Django et Django Channels car je voulais utiliser les nombreuses fonctionnalités de Django (sécurité, gestion des utilisateurs, formulaires, etc.).
Il a fallu environ 2 semaines pour arriver à ce point. Il y avait beaucoup de nouveautés, il était donc surtout temps de lire et d'étudier des documents.
Merci d'avoir lu cette fois aussi.