Merge pull request #1 from daniviga/feedback

Make operations sync and use bidirectional socket instead of MQTT
This commit is contained in:
2021-12-31 11:48:22 +01:00
committed by GitHub
13 changed files with 117 additions and 72 deletions

0
daemons/__init__.py Normal file
View File

44
daemons/net-to-serial.py Normal file
View File

@@ -0,0 +1,44 @@
import serial
import asyncio
class SerialDaemon:
def __init__(self):
self.ser = serial.Serial('/dev/pts/7') # WIP
self.ser.baudrate = 115200
def __del__(self):
try:
self.ser.close()
except AttributeError:
pass
async def handle_echo(self, reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print(f"Received {message!r} from {addr!r}")
self.ser.write(data)
response = self.read_until()
print(f"Send: {response!r}")
writer.write(response)
await writer.drain()
print("Close the connection")
writer.close()
async def main():
sd = SerialDaemon()
server = await asyncio.start_server(
sd.handle_echo, '127.0.0.1', 2560) # WIP
addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
print(f'Serving on {addrs}')
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -1,42 +0,0 @@
import serial
import logging
import socket
import asyncio
import time
import paho.mqtt.client as mqtt
from asyncio_mqtt import Client
MQTT_HOST = "127.0.0.1"
MQTT_PORT = 1883
async def mqtt_broker(ser):
async with Client(MQTT_HOST, port=MQTT_PORT) as client:
await client.subscribe("dcc/commands")
async with client.unfiltered_messages() as messages:
async for message in messages:
print(message.payload.decode())
# ser.write(message.payload)
def main():
client = mqtt.Client()
# ser = serial.Serial('/dev/pts/7')
# ser.baudrate = 9600
ser = None # remove me
while True:
try:
client.connect(MQTT_HOST, MQTT_PORT)
break
except (socket.gaierror, ConnectionRefusedError):
logging.warning('Broker not available')
time.sleep(5)
logging.info('Broker subscribed')
client.disconnect()
asyncio.run(mqtt_broker(ser))
# ser.close()
if __name__ == "__main__":
main()

View File

@@ -39,6 +39,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'django_countries',
'solo',
'rest_framework',
'dcc',
'driver',

View File

@@ -1,3 +1,6 @@
from django.contrib import admin
from solo.admin import SingletonModelAdmin
# Register your models here.
from driver.models import DriverConfiguration
admin.site.register(DriverConfiguration, SingletonModelAdmin)

View File

@@ -1,22 +1,27 @@
import paho.mqtt.client as mqtt
import socket
from driver.models import DriverConfiguration
class Connector:
MQTT_HOST = "127.0.0.1"
MQTT_PORT = 1883
@classmethod
def __mqtt_pub(self, message):
def __init__(self):
config = DriverConfiguration.get_solo()
self.remote_host = config.remote_host
self.remote_port = config.remote_port
def __send_data(self, message):
# to be encoded
client = mqtt.Client()
client.connect(self.MQTT_HOST, self.MQTT_PORT)
client.publish("dcc/commands", payload=message)
client.disconnect()
print(message)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((self.remote_host, self.remote_port))
sock.sendall(message)
resp = sock.recv(1024)
print(resp)
return True
def passthrough(self, data):
self.__mqtt_pub(data)
self.__send_data(data)
def ops(self, address, data, function=False):
if function:
@@ -25,7 +30,7 @@ class Connector:
else:
message = "<t 1 {0} {1} {2}>".format(address, data['speed'],
data['direction'])
self.__mqtt_pub(message)
self.__send_data(message)
return True
def infra(self, data):
@@ -36,9 +41,9 @@ class Connector:
track = ""
if power:
self.__mqtt_pub('<1{}>'.format(track))
self.__send_data('<1{}>'.format(track))
else:
self.__mqtt_pub('<0{}>'.format(track))
self.__send_data('<0{}>'.format(track))
def emergency(self):
self.__mqtt_pub('<!>')
self.__send_data('<!>')

View File

@@ -0,0 +1,25 @@
# Generated by Django 4.0 on 2021-12-31 10:41
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DriverConfiguration',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('remote_host', models.GenericIPAddressField(default='192.168.4.1', protocol='IPv4')),
('remote_port', models.SmallIntegerField(default=2560)),
],
options={
'verbose_name': 'Driver Configuration',
},
),
]

View File

@@ -1,3 +1,14 @@
from django.db import models
from solo.models import SingletonModel
# Create your models here.
class DriverConfiguration(SingletonModel):
remote_host = models.GenericIPAddressField(
protocol="IPv4", default="192.168.4.1")
remote_port = models.SmallIntegerField(default=2560)
def __str__(self):
return "Driver Configuration"
class Meta:
verbose_name = "Driver Configuration"

View File

@@ -8,11 +8,8 @@ class CabSerializer(serializers.ModelSerializer):
manufacturer = ManufacturerSerializer()
decoder = DecoderSerializer()
company = CompanySerializer()
# manufacturer = serializers.StringRelatedField()
# decoder = serializers.StringRelatedField()
# company = serializers.StringRelatedField()
class Meta:
model = Cab
fields = "__all__"
read_only_fields = ("identifier", "creation_time", "updated_time")
read_only_fields = ("creation_time", "updated_time")

View File

@@ -1,27 +1,27 @@
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateAPIView
from rest_framework.generics import ListAPIView, RetrieveAPIView
from roster.models import Cab
from roster.serializers import CabSerializer
class RosterList(ListCreateAPIView):
class RosterList(ListAPIView):
queryset = Cab.objects.all()
serializer_class = CabSerializer
class RosterGet(RetrieveUpdateAPIView):
class RosterGet(RetrieveAPIView):
queryset = Cab.objects.all()
serializer_class = CabSerializer
lookup_field = 'uuid'
class RosterAddress(RetrieveUpdateAPIView):
class RosterAddress(RetrieveAPIView):
queryset = Cab.objects.all()
serializer_class = CabSerializer
lookup_field = 'address'
class RosterIdentifier(RetrieveUpdateAPIView):
class RosterIdentifier(RetrieveAPIView):
queryset = Cab.objects.all()
serializer_class = CabSerializer
lookup_field = 'identifier'

View File

@@ -1,8 +1,9 @@
pytz
Django
djangorestframework
django-solo
django-health-check
# psycopg2-binary
paho-mqtt
asyncio-mqtt
# paho-mqtt
# asyncio-mqtt
pySerial