Browse Source

Rename some fields; Fetch or create source archive

pull/69/head
squeaky otter 1 year ago
parent
commit
bdc4e30194
Signed by: dashie GPG Key ID: C2D57B325840B755
13 changed files with 88 additions and 78 deletions
  1. +5
    -2
      airwaves_adsb_client.py
  2. +5
    -2
      airwaves_ais_client.py
  3. +4
    -2
      backend/lib/pyairwaves/archive_source.ex
  4. +17
    -5
      backend/lib/pyairwaves/redis_eater.ex
  5. +10
    -0
      backend/priv/repo/migrations/20200223163113_add_source_entrypoint_dataorigin.exs
  6. +2
    -2
      backend/priv/static/js/vehicles/airADSB.js
  7. +2
    -2
      backend/priv/static/js/vehicles/airAIS.js
  8. +3
    -2
      config.py.sample
  9. +6
    -1
      docs/PubSub_structure.md
  10. +9
    -54
      libPyAirwaves/structs.py
  11. +15
    -3
      simulator_adsb_coordinates.py
  12. +5
    -1
      simulator_adsb_real_datas.py
  13. +5
    -2
      simulator_ais_real_datas.py

+ 5
- 2
airwaves_adsb_client.py View File

@ -93,8 +93,11 @@ if __name__ == "__main__":
# AKA a "MSG,3" message and perhaps a "MSG,2" (Surface position)
if adsb_message.has_location():
adsb_message.entryPoint = "airwaves_adsb_client"
adsb_message.src = config.PYAW_HOSTNAME
adsb_message.clientName = config.ADSB_SOURCE["name"]
adsb_message.ourName = config.PYAW_HOSTNAME
adsb_message.srcName = config.ADSB_SOURCE["name"]
adsb_message.srcLat = config.ADSB_SOURCE["lat"]
adsb_message.srcLon = config.ADSB_SOURCE["lon"]
adsb_message.srcPosMode = config.ADSB_SOURCE["posMode"]
adsb_message.dataOrigin = "dump1090"
# Get more datas from SQL


+ 5
- 2
airwaves_ais_client.py View File

@ -26,8 +26,11 @@ def broadcast(msg: pyais.messages.NMEAMessage):
ais_message = AisType()
ais_message.entryPoint = "airwaves_ais_client"
ais_message.src = config.PYAW_HOSTNAME
ais_message.clientName = config.AIS_SOURCE["name"]
ais_message.ourName = config.PYAW_HOSTNAME
ais_message.srcName = config.AIS_SOURCE["name"]
ais_message.srcLat = config.AIS_SOURCE["lat"]
ais_message.srcLon = config.AIS_SOURCE["lon"]
ais_message.srcPosMode = config.AIS_SOURCE["posMode"]
ais_message.dataOrigin = "rtl-ais"
ais_message.raw = msg.raw.decode("utf-8")
ais_message.payload = msg.data.decode("utf-8")


+ 4
- 2
backend/lib/pyairwaves/archive_source.ex View File

@ -7,7 +7,9 @@ defmodule Pyairwaves.ArchiveSource do
schema "archive_source" do
field :name, :string
field :geom, Geo.PostGIS.Geometry
field :position_mode, :integer, default: 0
field :position_mode, :integer, default: 0 # see docs/PubSub_structure srcPosMode list
field :entrypoint, :string
field :data_origin, :string
has_many :archive_ship_messages, Pyairwaves.ArchiveShipMessage
@ -18,7 +20,7 @@ defmodule Pyairwaves.ArchiveSource do
def changeset(aircraft, attrs) do
aircraft
|> cast(attrs, [:name, :geom, :position_mode])
|> validate_required([:name, :geom, :position_mode])
|> validate_required([:name])
|> unique_constraint(:name)
end
end

+ 17
- 5
backend/lib/pyairwaves/redis_eater.ex View File

@ -35,7 +35,17 @@ defmodule Pyairwaves.RedisEater do
end
defp archive_and_enhance_message(%{"type" => "airAIS"} = msg) do
# 1/ Fetch the ship and update if necessary
# 1/ Fetch or create the ArchiveSource
source = %Pyairwaves.ArchiveSource{
name: msg["srcName"],
entrypoint: msg["entryPoint"],
data_origin: msg["dataOrigin"],
position_mode: msg["srcPosMode"]
}
|> Pyairwaves.Utils.put_if(:geom, Pyairwaves.Utils.to_geo_point(msg["lon"], msg["lat"]))
|> Pyairwaves.Repo.insert!(on_conflict: :nothing)
# 2/ Fetch the ship and update if necessary
ship = Pyairwaves.Repo.get_by(Pyairwaves.ArchiveShip, mmsi: msg["mmsi"])
ship =
@ -73,13 +83,15 @@ defmodule Pyairwaves.RedisEater do
# Build a changeset
Pyairwaves.ArchiveShip.changeset(ship, changes)
# Save it
|> Pyairwaves.Repo.insert_or_update!()
|> Pyairwaves.Repo.insert_or_update!(log: false)
# 2/ Archive the rest of the message
# 3/ Archive the rest of the message
%Pyairwaves.ArchiveShipMessage{
mmsi: msg["mmsi"],
raw: msg["raw"],
assembled: msg["isAssembled"]
assembled: msg["isAssembled"],
archive_ship_id: ship.id,
archive_source_id: source.id
}
|> Pyairwaves.Utils.put_if(:geom, Pyairwaves.Utils.to_geo_point(msg["lon"], msg["lat"]))
|> Pyairwaves.Utils.put_if(:position_accuracy, msg["posAcc"])
@ -95,7 +107,7 @@ defmodule Pyairwaves.RedisEater do
|> Pyairwaves.Utils.put_if(:course_over_ground, Pyairwaves.Utils.to_float(msg["courseOverGnd"]))
|> Pyairwaves.Utils.put_if(:turn_rate, Pyairwaves.Utils.to_float(msg["turnRt"]))
|> Pyairwaves.Utils.put_if(:draught, Pyairwaves.Utils.to_float(msg["draught"]))
|> Pyairwaves.Repo.insert!
|> Pyairwaves.Repo.insert!(log: false)
# Return the initial struct
# TODO add missing callsign, dim_*, ship type, etc. if missing


+ 10
- 0
backend/priv/repo/migrations/20200223163113_add_source_entrypoint_dataorigin.exs View File

@ -0,0 +1,10 @@
defmodule Pyairwaves.Repo.Migrations.AddSourceEntrypointDataorigin do
use Ecto.Migration
def change do
alter table("archive_source") do
add :entrypoint, :string
add :data_origin, :string
end
end
end

+ 2
- 2
backend/priv/static/js/vehicles/airADSB.js View File

@ -203,7 +203,7 @@ Aircraft.prototype.createTableEntry = function () {
</tr>\
<tr>\
<td class="tblHeader">Data src.</td>\
<td class="tblCell" colspan=3>' + this.lastClientName + ' -&gt; ' + this.lastSrc + '</td>\
<td class="tblCell" colspan=3>' + this.srcName + ' -&gt; ' + this.ourName + '</td>\
</tr>\
' + ((aSquawkMetaStr == null) ? '' : aSquawkMetaStr) + '\
' + ((this.regMetaStr == null) ? '' : this.regMetaStr) + '\
@ -311,7 +311,7 @@ Aircraft.prototype.updateTableEntry = function () {
</tr>\
<tr>\
<td class="tblHeader">Data src.</td>\
<td class="tblCell" colspan=3>' + this.lastClientName + ' -&gt; ' + this.lastSrc + '</td>\
<td class="tblCell" colspan=3>' + this.srcName + ' -&gt; ' + this.ourName + '</td>\
</tr>\
' + ((aSquawkMetaStr == null) ? '' : aSquawkMetaStr) + '\
' + ((this.regMetaStr == null) ? '' : this.regMetaStr));

+ 2
- 2
backend/priv/static/js/vehicles/airAIS.js View File

@ -147,7 +147,7 @@ Ship.prototype.createTableEntry = function () {
</tr>\
<tr>\
<td class="tblHeader">Data src.</td>\
<td class="tblCell" colspan=3>' + this.lastClientName + ' -&gt; ' + this.lastSrc + '</td>\
<td class="tblCell" colspan=3>' + this.srcName + ' -&gt; ' + this.ourName + '</td>\
</tr>\
</tbody></table>\
</td>\
@ -273,7 +273,7 @@ Ship.prototype.updateTableEntry = function () {
</tr>\
<tr>\
<td class="tblHeader">Data src.</td>\
<td class="tblCell" colspan=3>' + this.lastClientName + ' -&gt; ' + this.lastSrc + '</td>\
<td class="tblCell" colspan=3>' + this.srcName + ' -&gt; ' + this.ourName + '</td>\
</tr>\
</tbody></table>\
</td>\


+ 3
- 2
config.py.sample View File

@ -10,8 +10,9 @@ PYAW_HOSTNAME = 'potato'
# Sources for ADS-B and AIS, PLEASE NOTE that currently only one source is handled for each !
# Port for ADSB (dump1090) needs to be 30003 (SBS BaseStation)
# Port for AIS (rtl-ais) needs to be 10110
ADSB_SOURCE = {"host": "patate", "port": 30003, "name": "patate", "reconnect_delay": 5, "thread_timeout": 30}
AIS_SOURCE = {'host': 'patate', 'port': 10110, "name": "patate", "reconnect_delay": 5, "thread_timeout": 30}
# See docs/PubSub_structure.md for the value of (src)PosMode
ADSB_SOURCE = {"host": "patate", "port": 30003, "name": "patate", "posMode": 0, "lon": None, "lat": None, "reconnect_delay": 5, "thread_timeout": 30}
AIS_SOURCE = {'host': 'patate', 'port': 10110, "name": "patate", "posMode": 0, "lon": None, "lat": None, "reconnect_delay": 5, "thread_timeout": 30}
# Do not touch that
SQLALCHEMY_RECORD_QUERIES = False

+ 6
- 1
docs/PubSub_structure.md View File

@ -4,7 +4,12 @@
|name|type|used by frontend|required|description|
|----|----|----------------|--------|-----------|
|srcPosMode|integer enum-like|no|no|How the source position is determined.|
|srcLat|float|no|no|Latitude of the source|
|srcLon|float|no|no|Longitude of the source|
|srcName|string|yes|required|Name for the source giving out datas|
|ourName|string|yes|required|Name for the server gathering the clients datas|
|entryPoint|string|no|yes|Name of the script/tool used to push datas to the redis pubsub (ie airwaves_ais_client)|
|dataOrigin|string|no|yes|how is the data gathered ? (ie rtl-ais,...)|
## ADSB
## AIS


+ 9
- 54
libPyAirwaves/structs.py View File

@ -49,21 +49,14 @@ class AdsbType(DefaultType):
# Date/time stamp data hits system or is generated
self.dts: datetime = None
# Name of source host.
self._src: str = None
# Equals to src
self.lastSrc: str = None
# Raw data frame.
self.data: str = None
# I don't know, probably unused
self._clientName: str = None
# Equals to clientName
self.lastClientName: str = None
# Name for the source giving out datas
self.srcName: str = None
# Is srcPos available
self.srcPos: bool = False
# Name for the server gathering the clients datas
self.ourName: str = None
# Data source latitude
self.srcLat: float = None
@ -138,25 +131,6 @@ class AdsbType(DefaultType):
else:
return False
# Setters and Getters
def set_src(self, value):
self._src = value
self.lastSrc = value
def get_src(self):
return self._src
def set_client_name(self, value):
self._clientName = value
self.lastClientName = value
def get_client_name(self):
return self._clientName
src = property(get_src, set_src)
clientName = property(get_client_name, set_client_name)
class AisType(DefaultType):
"""
@ -177,10 +151,11 @@ class AisType(DefaultType):
# Date/time stamp data hits system or is generated
self.dts: datetime = None
# Name of source host.
self._src: str = None
# Equals to src
self.lastSrc: str = None
# Name for the source giving out datas
self.srcName: str = None
# Name for the server gathering the clients datas
self.ourName: str = None
# vdm[vdm] Raw data frame.
self.data: str = None
@ -310,7 +285,6 @@ class AisType(DefaultType):
self.maneuver = message["maneuver"].numerator
self.raim = message["raim"]
self.radioStatus = message["radio"]
self.srcPos = False # TODO add source position support
# Extract MMSI Datas
mmsiMeta = self.__getMMSIMeta()
@ -529,22 +503,3 @@ class AisType(DefaultType):
return True
else:
return False
# Setters and Getters
def set_src(self, value):
self._src = value
self.lastSrc = value
def get_src(self):
return self._src
def set_client_name(self, value):
self._clientName = value
self.lastClientName = value
def get_client_name(self):
return self._clientName
src = property(get_src, set_src)
clientName = property(get_client_name, set_client_name)

+ 15
- 3
simulator_adsb_coordinates.py View File

@ -31,7 +31,11 @@ try:
adsb_msg = AdsbType()
adsb_msg.populate_from_list(msg)
adsb_msg.entryPoint = "simulator"
adsb_msg.src = cfg.PYAW_HOSTNAME
adsb_msg.ourName = cfg.PYAW_HOSTNAME
adsb_msg.srcName = cfg.ADSB_SOURCE["name"]
adsb_msg.srcLat = cfg.ADSB_SOURCE["lat"]
adsb_msg.srcLon = cfg.ADSB_SOURCE["lon"]
adsb_msg.srcPosMode = cfg.ADSB_SOURCE["posMode"]
adsb_msg.clientName = "sim_host"
adsb_msg.dataOrigin = "dump1090"
redis.publish("room:vehicles", json.dumps(adsb_msg.to_dict()))
@ -48,7 +52,11 @@ try:
adsb_msg = AdsbType()
adsb_msg.populate_from_list(msg)
adsb_msg.entryPoint = "simulator"
adsb_msg.src = cfg.PYAW_HOSTNAME
adsb_msg.ourName = cfg.PYAW_HOSTNAME
adsb_msg.srcName = cfg.ADSB_SOURCE["name"]
adsb_msg.srcLat = cfg.ADSB_SOURCE["lat"]
adsb_msg.srcLon = cfg.ADSB_SOURCE["lon"]
adsb_msg.srcPosMode = cfg.ADSB_SOURCE["posMode"]
adsb_msg.clientName = "sim_host"
adsb_msg.dataOrigin = "dump1090"
redis.publish("room:vehicles", json.dumps(adsb_msg.to_dict()))
@ -65,7 +73,11 @@ try:
adsb_msg = AdsbType()
adsb_msg.populate_from_list(msg)
adsb_msg.entryPoint = "simulator"
adsb_msg.src = cfg.PYAW_HOSTNAME
adsb_msg.ourName = cfg.PYAW_HOSTNAME
adsb_msg.srcName = cfg.ADSB_SOURCE["name"]
adsb_msg.srcLat = cfg.ADSB_SOURCE["lat"]
adsb_msg.srcLon = cfg.ADSB_SOURCE["lon"]
adsb_msg.srcPosMode = cfg.ADSB_SOURCE["posMode"]
adsb_msg.clientName = "sim_host"
adsb_msg.dataOrigin = "dump1090"
redis.publish("room:vehicles", json.dumps(adsb_msg.to_dict()))


+ 5
- 1
simulator_adsb_real_datas.py View File

@ -21,7 +21,11 @@ try:
adsb_msg = AdsbType()
adsb_msg.populate_from_string(msg)
adsb_msg.entryPoint = "simulator"
adsb_msg.src = cfg.PYAW_HOSTNAME
adsb_msg.ourName = cfg.PYAW_HOSTNAME
adsb_msg.srcName = cfg.ADSB_SOURCE["name"]
adsb_msg.srcLat = cfg.ADSB_SOURCE["lat"]
adsb_msg.srcLon = cfg.ADSB_SOURCE["lon"]
adsb_msg.srcPosMode = cfg.ADSB_SOURCE["posMode"]
adsb_msg.clientName = "sim_host"
adsb_msg.dataOrigin = "dump1090"


+ 5
- 2
simulator_ais_real_datas.py View File

@ -24,8 +24,11 @@ try:
print("invalid message")
continue
ais_msg.entryPoint = "simulator"
ais_msg.src = cfg.PYAW_HOSTNAME
ais_msg.clientName = "sim_host"
ais_msg.ourName = cfg.PYAW_HOSTNAME
ais_msg.srcName = cfg.AIS_SOURCE["name"]
ais_msg.srcLat = cfg.AIS_SOURCE["lat"]
ais_msg.srcLon = cfg.AIS_SOURCE["lon"]
ais_msg.srcPosMode = cfg.AIS_SOURCE["posMode"]
ais_msg.dataOrigin = "rtl-ais"
redis.publish("room:vehicles", json.dumps(ais_msg.to_dict()))


Loading…
Cancel
Save