Refactor communication to daemon

This commit is contained in:
2022-01-03 22:19:01 +01:00
parent 31b9afb5c1
commit 850e8e5f6f
5 changed files with 68 additions and 34 deletions

View File

@@ -4,41 +4,45 @@ from driver.models import DriverConfiguration
class Connector:
def __init__(self):
self.config = DriverConfiguration.get_solo()
def __send_data(self, message):
# to be encoded
resp = b''
# convert to binary if str is received
if isinstance(message, str):
message = message.encode()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.config.remote_host, self.config.remote_port))
sock.settimeout(self.config.timeout / 1000) # milliseconds
sock.sendall(message)
resp = sock.recv(1024)
print(resp)
return True
while True:
try:
resp += sock.recv(1024)
except socket.timeout:
break
return resp
def passthrough(self, data):
self.__send_data(data)
return self.__send_data(data)
def ops(self, address, data, function=False):
if function:
message = "<F {0} {1} {2}>".format(address, data['function'],
data['state'])
message = "<F {0} {1} {2}>".format(
address, data['function'], data['state'])
else:
message = "<t 1 {0} {1} {2}>".format(address, data['speed'],
data['direction'])
message = "<t 1 {0} {1} {2}>".format(
address, data['speed'], data['direction'])
self.__send_data(message)
return True
def infra(self, data):
power = data['power']
if "track" in data:
track = " {}".forma(data['track'].upper())
track = " {}".format(data["track"].upper())
else:
track = ""
if power:
if data["power"]:
self.__send_data('<1{}>'.format(track))
else:
self.__send_data('<0{}>'.format(track))

View File

@@ -0,0 +1,22 @@
# Generated by Django 4.0 on 2022-01-03 19:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('driver', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='driverconfiguration',
options={'verbose_name': 'Configuration'},
),
migrations.AddField(
model_name='driverconfiguration',
name='timeout',
field=models.SmallIntegerField(default=250),
),
]

View File

@@ -6,9 +6,10 @@ class DriverConfiguration(SingletonModel):
remote_host = models.GenericIPAddressField(
protocol="IPv4", default="192.168.4.1")
remote_port = models.SmallIntegerField(default=2560)
timeout = models.SmallIntegerField(default=250)
def __str__(self):
return "Driver Configuration"
return "Configuration"
class Meta:
verbose_name = "Driver Configuration"
verbose_name = "Configuration"

View File

@@ -13,5 +13,6 @@ class CabSerializer(serializers.Serializer):
class InfraSerializer(serializers.Serializer):
power = serializers.BooleanField(required=True)
track = serializers.ChoiceField(choices=('main', 'prog', 'join'),
track = serializers.ChoiceField(
choices=('main', 'prog', 'join', 'MAIN', 'PROG', 'JOIN'),
required=False)

View File

@@ -1,7 +1,6 @@
from django.views import View
from django.http import HttpResponse, Http404
from django.http import Http404
from django.utils.decorators import method_decorator
from rest_framework import status
from rest_framework import status, serializers
from rest_framework.views import APIView
from rest_framework.response import Response
@@ -11,8 +10,6 @@ from driver.serializers import (
FunctionSerializer, CabSerializer, InfraSerializer)
from roster.models import Cab as CabModel
conn = Connector()
def addresschecker(f):
def addresslookup(request, address, *args):
@@ -29,8 +26,15 @@ class SendCommand(APIView):
def put(self, request):
data = request.data
conn.passthrough(data)
return Response(data,
if not data:
raise serializers.ValidationError({
"error": "a string is expected"})
cmd = data.decode().strip()
if not (cmd.startswith("<") and cmd.endswith(">")):
raise serializers.ValidationError({
"error": "please provide a valid command"})
response = Connector().passthrough(cmd)
return Response({"response": response.decode()},
status=status.HTTP_202_ACCEPTED)
@@ -39,7 +43,7 @@ class Function(APIView):
def put(self, request, address):
serializer = FunctionSerializer(data=request.data)
if serializer.is_valid():
conn.ops(address, serializer.data, function=True)
Connector().ops(address, serializer.data, function=True)
return Response(serializer.data,
status=status.HTTP_202_ACCEPTED)
@@ -52,7 +56,7 @@ class Cab(APIView):
def put(self, request, address):
serializer = CabSerializer(data=request.data)
if serializer.is_valid():
conn.ops(address, serializer.data)
Connector().ops(address, serializer.data)
return Response(serializer.data,
status=status.HTTP_202_ACCEPTED)
@@ -64,7 +68,7 @@ class Infra(APIView):
def put(self, request):
serializer = InfraSerializer(data=request.data)
if serializer.is_valid():
conn.infra(serializer.data)
Connector().infra(serializer.data)
return Response(serializer.data,
status=status.HTTP_202_ACCEPTED)
@@ -72,11 +76,13 @@ class Infra(APIView):
status=status.HTTP_400_BAD_REQUEST)
class Emergency(View):
class Emergency(APIView):
def put(self, request):
conn.emergency()
return HttpResponse()
Connector().emergency()
return Response({"response": "emergency stop"},
status=status.HTTP_202_ACCEPTED)
def get(self, request):
conn.emergency()
return HttpResponse()
Connector().emergency()
return Response({"response": "emergency stop"},
status=status.HTTP_202_ACCEPTED)