diff --git a/trackdirect-apache.dockerfile b/Dockerfile
similarity index 87%
rename from trackdirect-apache.dockerfile
rename to Dockerfile
index 44d045222378bbc71dca97e56354d60d5ee8f5c9..f948dd8ade4bb881ff089d965f2cab1bbda6d3dd 100644
--- a/trackdirect-apache.dockerfile
+++ b/Dockerfile
@@ -21,3 +21,7 @@ RUN chmod a+rx / && chmod a+rx -R /root
 RUN chmod 777 /root/trackdirect/htdocs/public/symbols
 RUN chmod 777 /root/trackdirect/htdocs/public/heatmaps
 
+VOLUME /root/trackdirect/config
+VOLUME /root/trackdirect/htdocs/public/heatmaps
+
+EXPOSE 80
diff --git a/aprsc.dockerfile b/aprsc.dockerfile
deleted file mode 100644
index da2e51c9cda8d9b4fe0540c63ee05de25b690db0..0000000000000000000000000000000000000000
--- a/aprsc.dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM ubuntu:20.04
-
-RUN apt-get update && apt-get install -y \
-  gnupg \
-  && rm -rf /var/lib/apt/lists/*
-
-RUN printf "deb http://aprsc-dist.he.fi/aprsc/apt focal main" >> /etc/apt/sources.list
-RUN gpg --keyserver keyserver.ubuntu.com --recv C51AA22389B5B74C3896EF3CA72A581E657A2B8D
-RUN gpg --export C51AA22389B5B74C3896EF3CA72A581E657A2B8D | apt-key add -
-
-RUN apt-get update && apt-get install -y \
-  aprsc \
-  && rm -rf /var/lib/apt/lists/*
-
-EXPOSE 10152
-EXPOSE 14580
-EXPOSE 10155
-EXPOSE 14501
-
-WORKDIR /opt/aprsc
-USER aprsc
-
-CMD /opt/aprsc/sbin/aprsc -c /opt/aprsc/etc/aprsc.conf
diff --git a/config/aprsc.conf b/config/aprsc.conf
deleted file mode 100755
index 48d5927d5a10a43f1a8a4b2a21fb86698268a9dd..0000000000000000000000000000000000000000
--- a/config/aprsc.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-# Note that server id and passcode needs to be changed
-ServerId   MY-SERVER-ID
-PassCode   11111
-
-MyAdmin    "My Name, MySignal"
-MyEmail    me@domain.com
-
-disallow_unverified	false
-RunDir 				data
-LogRotate 			10 5
-UpstreamTimeout		15s
-ClientTimeout		48h
-
-Listen "Full feed"					fullfeed tcp 	::  10152
-Listen "Client-Defined Filters"		igate tcp 		::  14580
-Listen "Duplicate packets"			dupefeed tcp 	::  10155
-
-### Select aprs source (only one)
-Uplink "Core rotate" ro tcp rotate.aprs.net 10152
-#Uplink "Core rotate" ro tcp cwop.aprs.net 10152
-#Uplink "Core rotate" ro tcp aprs.glidernet.org 10152
-
-HTTPStatus 0.0.0.0 14501
-HTTPStatusOptions ShowEmail=1
-
-### Operator attention span qualification run ###########
-# After configuring the rest of the settings, remove this bad command
-# from the configuration file. It's here only to avoid starting the
-# server up accidentally with an invalid configuration.
-MagicBadness	42.7
diff --git a/config/trackdirect.ini b/config/trackdirect.ini
index 0a38d5e28f0ea18eaecbecf1736b81f87a6db73b..073c45edeb8c1114389a1f34a5fe6863161d684d 100644
--- a/config/trackdirect.ini
+++ b/config/trackdirect.ini
@@ -4,9 +4,9 @@
 
 [website]
 
-title="APRS Track Direct"
-owner_name="Unknown"
-owner_email="no@name.com"
+title="Digipex Hub"
+owner_name="Jeffrey Phillips Freeman (WI2ARD)"
+owner_email="the@JeffreyFreeman.me"
 
 ;maptiler_key="<insert map key here if you want to activate maptiler for vector tiles>"
 ;google_key="<insert google key here if you want to activate google maps>"
@@ -32,18 +32,18 @@ coverage_percentile="95"
 
 ;; Basic database settings
 ;; If using docker, set host to "db"
-host="127.0.0.1"
-database="trackdirect"
+host="swarm-db-default-postgres.cjvkhc5ajvev.us-east-1.rds.amazonaws.com"
+database="digipex_hub"
 ;; If using docker, activate username and set to "root"
-;username="username"
-password="foobar"
+username="digipex_hub_user"
+password=""
 port="5432"
 
 ;; Settings for the remover script
-days_to_save_position_data="10"
-days_to_save_station_data="30"
-days_to_save_weather_data="10"
-days_to_save_telemetry_data="10"
+days_to_save_position_data="10000"
+days_to_save_station_data="30000"
+days_to_save_weather_data="10000"
+days_to_save_telemetry_data="10000"
 
 ;; If this setting is enabled, OGN stations that we are not allowed to reveal the identity of will be given a random name similar to "UNKNOWN123"
 ;; If disabled we will drop all packets regarding stations that we should not reveal the identity of.
@@ -73,7 +73,7 @@ frequency_limit="0"
 ;; First APRS IS server for the websocket server to connect to.
 ;; Important: Please set up your own APRS IS server, do not use a public server.
 ;; If using docker, set aprs_host1 to "aprsc"
-aprs_host1="127.0.0.1"
+aprs_host1="igate.digipex.io"
 aprs_port1="14580"
 
 ;; Important that you set the correct source, otherwise it might be handled incorrect
@@ -92,7 +92,7 @@ aprs_source_id1="1"
 
 ;; Allow time travel
 ;; Use this settings to disable/enable data requests with a time interval (this must be disabled for the OGN network)
-allow_time_travel="0"
+allow_time_travel="1"
 
 ;; Max default time in minutes (how old packets that will be included in the response)
 ;; This setting should be no more than 1440 for for the OGN network.
@@ -103,7 +103,7 @@ max_default_time="1440"
 max_filter_time="1440"
 
 ;; Time in minutes until idle client is disconnected
-max_client_idle_time="60"
+max_client_idle_time="20160"
 
 ;; Max age in seconds for real time packets waiting to be sent to client (dropping packets if limit is excceded)
 max_queued_realtime_packets="30"
@@ -112,7 +112,7 @@ max_queued_realtime_packets="30"
 [collector0]
 
 ;; If using docker, set host to "aprsc"
-host="127.0.0.1"
+host="igate.digipex.io"
 port_full="10152"
 port_filtered="14580"
 
@@ -125,21 +125,21 @@ port_filtered="14580"
 source_id="1"
 
 ;; Your callsign and passcode
-callsign="NOCALL"
-passcode="-1"
+callsign="DIGIHUB"
+passcode="31415"
 
 ;; Database inserts is done in batches
 numbers_in_batch="50"
 
 ;; Packets received more frequently than the configured frequency limit will not be shown on map (limit is specified in seconds)
 ;; Set to "0" to disable the frequency limit (note that the limit must be 20s or more when receiving data from OGN network)).
-frequency_limit="5"
+frequency_limit="0"
 
 ;; If save_fast_packets is set to "0", packets that is received to frequently will not be saved (useful for OGN, but not recommended for APRS-IS).
 save_fast_packets="1"
 
 ;; If detect_duplicates is set to "1" we will try to detect duplicates and ignore them.
-detect_duplicates="1"
+detect_duplicates="0"
 
 ;; Collector error log
 error_log="~/trackdirect/server/log/collector.log"
diff --git a/db.dockerfile b/db.dockerfile
deleted file mode 100644
index 4d037867d41ea4f65c982eac29d00658f642c1d3..0000000000000000000000000000000000000000
--- a/db.dockerfile
+++ /dev/null
@@ -1,3 +0,0 @@
-FROM postgres
-COPY misc/database/tables/* /docker-entrypoint-initdb.d/
-VOLUME /var/lib/postgresql/data
diff --git a/docker-compose.yml b/docker-compose.yml
index ac2d8fd60fcb3497cbfb5d1ad921af1449008625..758c366f7d3f6758014da180153f988f3ea13622 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,60 +1,28 @@
 version: "3.9"
 services:
-  aprsc:
-    build:
-      context: .
-      dockerfile: aprsc.dockerfile
-    ports:
-      - "10152:10152"
-      - "14580:14580"
-      - "10155:10155"
-      - "14501:14501"
-    volumes:
-      - $PWD/config/aprsc.conf:/opt/aprsc/etc/aprsc.conf
-
   collector:
+    image: 'registry.qoto.org/digipex/hub:latest'
     build:
       context: .
-      dockerfile: trackdirect-python.dockerfile
+      dockerfile: collector.dockerfile
     volumes:
       - $PWD/config/trackdirect.ini:/root/trackdirect/config/trackdirect.ini
-    command: /root/trackdirect/server/scripts/collector.sh trackdirect.ini 0
-    depends_on:
-      - "db"
-      - "aprsc"
 
   websocket:
     build:
       context: .
-      dockerfile: trackdirect-python.dockerfile
+      dockerfile: websocket.dockerfile
     volumes:
       - $PWD/config/trackdirect.ini:/root/trackdirect/config/trackdirect.ini
-    command: /root/trackdirect/server/scripts/wsserver.sh trackdirect.ini
     ports:
       - "9000:9000"
-    depends_on:
-      - "db"
-      - "aprsc"
 
   web:
     build:
       context: .
-      dockerfile: trackdirect-apache.dockerfile
+      dockerfile: web.dockerfile
     volumes:
       - $PWD/config/trackdirect.ini:/root/trackdirect/config/trackdirect.ini
       - $PWD/heatmaps:/root/trackdirect/htdocs/public/heatmaps
     ports:
       - "80:80"
-    depends_on:
-      - "db"
-
-  db:
-    build:
-      context: .
-      dockerfile: db.dockerfile
-    environment:
-      POSTGRES_USER: root
-      POSTGRES_PASSWORD: foobar
-      POSTGRES_DB: trackdirect
-    volumes:
-      - $PWD/db:/var/lib/postgresql/data
diff --git a/misc/database/tables/01_map.sql b/misc/database/tables/01_map.sql
deleted file mode 100644
index 840056becd91d912189e88be33d88ccae29651ca..0000000000000000000000000000000000000000
--- a/misc/database/tables/01_map.sql
+++ /dev/null
@@ -1,22 +0,0 @@
-create table map (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-insert into map(id, name) values(1, 'Show on map');
-insert into map(id, name) values(2, 'Hide, same position as newer packet');
-insert into map(id, name) values(3, 'Hide, duplicate packet');
-insert into map(id, name) values(4, 'Hide, failed to find marker id');
-insert into map(id, name) values(5, 'Hide, faulty gps position');
-insert into map(id, name) values(6, 'Hide, packet received to late');
-insert into map(id, name) values(7, 'Hide, moves to fast');
-insert into map(id, name) values(8, 'Hide, packet is less than 5 seconds after previous');
-insert into map(id, name) values(9, 'Hide, abnormal position');
-insert into map(id, name) values(10, 'Hide, has no position');
-insert into map(id, name) values(11, 'Hide, unsupported format');
-insert into map(id, name) values (12, 'Hide, same position as newer packet (but later date)');
-insert into map(id, name) values (13, 'Hide, same position as newer packet (and faulty gps position)');
-insert into map(id, name) values (14, 'Hide, killed object/item');
-insert into map(id, name) values (15, 'Stealth/No tracking');
-insert into map(id, name) values (16, 'Faulty network, APRS packet digipeated by a CWOP-station');
diff --git a/misc/database/tables/02_marker.sql b/misc/database/tables/02_marker.sql
deleted file mode 100644
index 42b103adb1ff06d425b390c525933d1155c32957..0000000000000000000000000000000000000000
--- a/misc/database/tables/02_marker.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE SEQUENCE marker_seq INCREMENT BY 1 MINVALUE 2;
diff --git a/misc/database/tables/03_ogn_address_type.sql b/misc/database/tables/03_ogn_address_type.sql
deleted file mode 100644
index 48f0364649ed3ff8f1eadb605b1f342d3edbb60e..0000000000000000000000000000000000000000
--- a/misc/database/tables/03_ogn_address_type.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-create table ogn_address_type (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-insert into ogn_address_type(id, name) values(1, 'ICAO');
-insert into ogn_address_type(id, name) values(2, 'FLARM');
-insert into ogn_address_type(id, name) values(3, 'OGN');
diff --git a/misc/database/tables/04_ogn_aircraft_type.sql b/misc/database/tables/04_ogn_aircraft_type.sql
deleted file mode 100644
index f5089435359834777044d6593632c9f50394d0ad..0000000000000000000000000000000000000000
--- a/misc/database/tables/04_ogn_aircraft_type.sql
+++ /dev/null
@@ -1,22 +0,0 @@
-create table ogn_aircraft_type (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-insert into ogn_aircraft_type(id, name) values(1, 'Glider');
-insert into ogn_aircraft_type(id, name) values(2, 'Tow Plane');
-insert into ogn_aircraft_type(id, name) values(3, 'Helicopter');
-insert into ogn_aircraft_type(id, name) values(4, 'Parachute');
-insert into ogn_aircraft_type(id, name) values(5, 'Drop Plane');
-insert into ogn_aircraft_type(id, name) values(6, 'Hang Glider');
-insert into ogn_aircraft_type(id, name) values(7, 'Para Glider');
-insert into ogn_aircraft_type(id, name) values(8, 'Powered Aircraft');
-insert into ogn_aircraft_type(id, name) values(9, 'Jet Aircraft');
-insert into ogn_aircraft_type(id, name) values(10, 'UFO');
-insert into ogn_aircraft_type(id, name) values(11, 'Balloon');
-insert into ogn_aircraft_type(id, name) values(12, 'Airship');
-insert into ogn_aircraft_type(id, name) values(13, 'UAV');
-insert into ogn_aircraft_type(id, name) values(14, '');
-insert into ogn_aircraft_type(id, name) values(15, 'Static Object');
-
diff --git a/misc/database/tables/05_ogn_device.sql b/misc/database/tables/05_ogn_device.sql
deleted file mode 100644
index 22e01e03a04829941f8b454975c6a44440ecaa4a..0000000000000000000000000000000000000000
--- a/misc/database/tables/05_ogn_device.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-create table if not exists ogn_device (
-    "device_type" text not null,
-    "device_id" text not null,
-    "aircraft_model" text not null,
-    "registration" text not null,
-    "cn" text not null,
-    "tracked" text not null,
-    "identified" text not null,
-    "ddb_aircraft_type" text not null
-);
diff --git a/misc/database/tables/06_ogn_hidden_station.sql b/misc/database/tables/06_ogn_hidden_station.sql
deleted file mode 100644
index 0b311556fab2ba46eb7b4697bf85c043f7a1aaf4..0000000000000000000000000000000000000000
--- a/misc/database/tables/06_ogn_hidden_station.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-create table ogn_hidden_station (
-    "id" bigserial not null,
-    "hashed_name" text not null,
-    primary key (id)
-);
-
-create index ogn_hidden_station_hashed_name_idx on ogn_hidden_station(hashed_name);
diff --git a/misc/database/tables/07_packet_type.sql b/misc/database/tables/07_packet_type.sql
deleted file mode 100644
index c72b01c4769193e2cd02cc83fa72cf68ff1dfbcf..0000000000000000000000000000000000000000
--- a/misc/database/tables/07_packet_type.sql
+++ /dev/null
@@ -1,18 +0,0 @@
-create table packet_type (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-
-insert into packet_type(id, name) values(1, 'position');
-insert into packet_type(id, name) values(2, 'direction');
-insert into packet_type(id, name) values(3, 'weather');
-insert into packet_type(id, name) values(4, 'object');
-insert into packet_type(id, name) values(5, 'item');
-insert into packet_type(id, name) values(6, 'telemetry');
-insert into packet_type(id, name) values(7, 'message');
-insert into packet_type(id, name) values(8, 'query');
-insert into packet_type(id, name) values(9, 'response');
-insert into packet_type(id, name) values(10, 'status');
-insert into packet_type(id, name) values(11, 'other');
diff --git a/misc/database/tables/08_sender.sql b/misc/database/tables/08_sender.sql
deleted file mode 100644
index d042c3172fbd0a7013b243b531fb9c1d484dec32..0000000000000000000000000000000000000000
--- a/misc/database/tables/08_sender.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-create table sender (
-    "id" bigserial not null,
-    "name" text not null,
-    primary key (id)
-);
-
-create index sender_name_idx on sender(name);
diff --git a/misc/database/tables/09_source.sql b/misc/database/tables/09_source.sql
deleted file mode 100644
index 42bac07a5a4dc94366c99db00876cb890c43e543..0000000000000000000000000000000000000000
--- a/misc/database/tables/09_source.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-create table source (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-
-insert into source(id, name) values(1, 'APRS');
-insert into source(id, name) values(2, 'CWOP');
-insert into source(id, name) values(3, 'CBAPRS');
-insert into source(id, name) values(4, 'HUBHAB');
-insert into source(id, name) values(5, 'OGN');
diff --git a/misc/database/tables/10_station_type.sql b/misc/database/tables/10_station_type.sql
deleted file mode 100644
index 8ca498462120633440c4ed893698f247a96f3af5..0000000000000000000000000000000000000000
--- a/misc/database/tables/10_station_type.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-create table station_type (
-    "id" smallint not null,
-    "name" text not null,
-    primary key (id)
-);
-
-
-insert into station_type(id, name) values(1, 'Station');
-insert into station_type(id, name) values(2, 'Object');
diff --git a/misc/database/tables/11_station.sql b/misc/database/tables/11_station.sql
deleted file mode 100644
index 6b0a5e57c99f86a4723ab34e71b35a817156f40b..0000000000000000000000000000000000000000
--- a/misc/database/tables/11_station.sql
+++ /dev/null
@@ -1,51 +0,0 @@
-create table station (
-    "id" bigserial not null,
-    "name" text null,
-    "latest_sender_id" bigint null,
-    "station_type_id" smallint not null,
-    "source_id" smallint not null,
-
-    "latest_location_packet_id" bigint null,
-    "latest_location_packet_timestamp" bigint null,
-    "latest_location_marker_id" bigint null,
-    "latest_location_symbol" text null,
-    "latest_location_symbol_table" text null,
-    "latest_location_latitude" double precision null,
-    "latest_location_longitude" double precision null,
-
-    "latest_confirmed_packet_id" bigint null,
-    "latest_confirmed_packet_timestamp" bigint null,
-    "latest_confirmed_marker_id" bigint null,
-    "latest_confirmed_symbol" text null,
-    "latest_confirmed_symbol_table" text null,
-    "latest_confirmed_latitude" double precision null,
-    "latest_confirmed_longitude" double precision null,
-
-    "latest_packet_id" bigint null,
-    "latest_packet_timestamp" bigint null,
-
-    "latest_weather_packet_id" bigint null,
-    "latest_weather_packet_timestamp" bigint null,
-    "latest_weather_packet_comment" text null,
-
-    "latest_telemetry_packet_id" bigint null,
-    "latest_telemetry_packet_timestamp" bigint null,
-
-    "latest_ogn_packet_id" bigint null,
-    "latest_ogn_packet_timestamp" bigint null,
-    "latest_ogn_sender_address" text null,
-    "latest_ogn_aircraft_type_id" smallint null,
-    "latest_ogn_address_type_id" smallint null,
-
-    primary key (id),
-    foreign key(latest_sender_id) references sender(id),
-    foreign key(station_type_id) references station_type(id),
-    foreign key(source_id) references source(id),
-    foreign key(latest_ogn_aircraft_type_id) references ogn_aircraft_type(id),
-    foreign key(latest_ogn_address_type_id) references ogn_address_type(id)
-);
-
-create index station_name_idx on station(name);
-create index station_latest_sender_id_idx on station(latest_sender_id);
-create index station_pos_timestamp_idx on station(latest_confirmed_latitude, latest_confirmed_longitude, latest_confirmed_packet_timestamp);
-create index station_ogn_sender_address_idx on station(latest_ogn_sender_address);
diff --git a/misc/database/tables/12_station_telemetry_bits.sql b/misc/database/tables/12_station_telemetry_bits.sql
deleted file mode 100644
index e6d181f30016ffabf5ac327ae97d5603af5fc2e6..0000000000000000000000000000000000000000
--- a/misc/database/tables/12_station_telemetry_bits.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-create table station_telemetry_bits (
-    "id" bigserial not null,
-    "station_id" bigint null,
-    "created_ts" bigint default extract(epoch from now()),
-    "latest_ts" bigint default extract(epoch from now()),
-    "valid_to_ts" bigint null,
-    "bits" text null,
-    "title" text null,
-    primary key (id),
-    foreign key(station_id) references station(id)
-);
-
-create index station_telemetry_bits_station_id_idx on station_telemetry_bits(station_id, valid_to_ts, latest_ts);
diff --git a/misc/database/tables/13_station_telemetry_eqns.sql b/misc/database/tables/13_station_telemetry_eqns.sql
deleted file mode 100644
index 40d2c89fc71c826ed668aff9ab2d17aba56375bf..0000000000000000000000000000000000000000
--- a/misc/database/tables/13_station_telemetry_eqns.sql
+++ /dev/null
@@ -1,32 +0,0 @@
-create table station_telemetry_eqns (
-    "id" bigserial not null,
-    "station_id" bigint null,
-    "created_ts" bigint default extract(epoch from now()),
-    "latest_ts" bigint default extract(epoch from now()),
-    "valid_to_ts" bigint null,
-
-    "a1" real null,
-    "b1" real null,
-    "c1" real null,
-
-    "a2" real null,
-    "b2" real null,
-    "c2" real null,
-
-    "a3" real null,
-    "b3" real null,
-    "c3" real null,
-
-    "a4" real null,
-    "b4" real null,
-    "c4" real null,
-
-    "a5" real null,
-    "b5" real null,
-    "c5" real null,
-
-    primary key (id),
-    foreign key(station_id) references station(id)
-);
-
-create index station_telemetry_eqns_station_id_idx on station_telemetry_eqns(station_id, valid_to_ts, latest_ts);
diff --git a/misc/database/tables/14_station_telemetry_param.sql b/misc/database/tables/14_station_telemetry_param.sql
deleted file mode 100644
index 97bd4336e4bd3f7eafa7a606ac1d7065da4161c2..0000000000000000000000000000000000000000
--- a/misc/database/tables/14_station_telemetry_param.sql
+++ /dev/null
@@ -1,24 +0,0 @@
-create table station_telemetry_param (
-    "id" bigserial not null,
-    "station_id" bigint null,
-    "created_ts" bigint default extract(epoch from now()),
-    "latest_ts" bigint default extract(epoch from now()),
-    "valid_to_ts" bigint null,
-    "p1" text null,
-    "p2" text null,
-    "p3" text null,
-    "p4" text null,
-    "p5" text null,
-    "b1" text null,
-    "b2" text null,
-    "b3" text null,
-    "b4" text null,
-    "b5" text null,
-    "b6" text null,
-    "b7" text null,
-    "b8" text null,
-    primary key (id),
-    foreign key(station_id) references station(id)
-);
-
-create index station_telemetry_param_station_id_idx on station_telemetry_param(station_id, valid_to_ts, latest_ts);
diff --git a/misc/database/tables/15_station_telemetry_unit.sql b/misc/database/tables/15_station_telemetry_unit.sql
deleted file mode 100644
index 167a174bbe23cb727ed4037f1d90f2bea8d5cb96..0000000000000000000000000000000000000000
--- a/misc/database/tables/15_station_telemetry_unit.sql
+++ /dev/null
@@ -1,24 +0,0 @@
-create table station_telemetry_unit (
-    "id" bigserial not null,
-    "station_id" bigint null,
-    "created_ts" bigint default extract(epoch from now()),
-    "latest_ts" bigint default extract(epoch from now()),
-    "valid_to_ts" bigint null,
-    "u1" text null,
-    "u2" text null,
-    "u3" text null,
-    "u4" text null,
-    "u5" text null,
-    "l1" text null,
-    "l2" text null,
-    "l3" text null,
-    "l4" text null,
-    "l5" text null,
-    "l6" text null,
-    "l7" text null,
-    "l8" text null,
-    primary key (id),
-    foreign key(station_id) references station(id)
-);
-
-create index station_telemetry_unit_station_id_idx on station_telemetry_unit(station_id, valid_to_ts, latest_ts);
diff --git a/misc/database/tables/16_packet.sql b/misc/database/tables/16_packet.sql
deleted file mode 100644
index c14e79daf76f6a7cd5693461fab4601d8b08bc8d..0000000000000000000000000000000000000000
--- a/misc/database/tables/16_packet.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-create table packet (
-     "id" bigserial not null,
-     "station_id" bigint not null,
-     "sender_id" bigint not null,
-     "marker_id" bigint null,
-     "marker_counter" int null,
-     "packet_type_id" smallint not null,
-     "timestamp" bigint not null,
-     "reported_timestamp" bigint null,
-     "position_timestamp" bigint null,
-     "latitude" double precision null,
-     "longitude" double precision null,
-     "posambiguity" smallint null,
-     "symbol" text null,
-     "symbol_table" text null,
-     "map_sector" int null,
-     "related_map_sectors" int array null,
-     "map_id" smallint default 1,
-     "source_id" smallint default 1,
-     "speed" real null,
-     "course" real null,
-     "altitude" real null,
-     "rng" real null,
-     "latest_rng_timestamp" bigint null,
-     "phg" int null,
-     "latest_phg_timestamp" bigint null,
-     "packet_tail_timestamp" bigint null,
-     "is_moving" smallint null,
-     "comment" text null,
-     "raw_path" text null,
-     "raw" text null,
-     primary key (id),
-     foreign key(packet_type_id) references packet_type(id),
-     foreign key(station_id) references station(id),
-     foreign key(sender_id) references sender(id),
-     foreign key(map_id) references map(id),
-     foreign key(source_id) references source(id)
-);
-
-
-
-
diff --git a/misc/database/tables/17_packet_weather.sql b/misc/database/tables/17_packet_weather.sql
deleted file mode 100644
index 8d2857012a088d9bd2d0f3f986ed0dbe28e52910..0000000000000000000000000000000000000000
--- a/misc/database/tables/17_packet_weather.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-create table packet_weather (
-     "id" bigserial not null,
-     "packet_id" bigint not null,
-     "station_id" bigint not null,
-     "timestamp" bigint not null,
-     "humidity" int null,
-     "pressure" real null,
-     "rain_1h" real null,
-     "rain_24h" real null,
-     "rain_since_midnight" real null,
-     "temperature" real null,
-     "wind_direction" int null,
-     "wind_gust" real null,
-     "wind_speed" real null,
-     "luminosity" real null,
-     "snow" real null,
-     "wx_raw_timestamp" bigint null,
-     primary key (id),
-     foreign key(station_id) references station(id)
-);
diff --git a/misc/database/tables/18_packet_telemetry.sql b/misc/database/tables/18_packet_telemetry.sql
deleted file mode 100644
index 20547386bb93acbfc90ec78ac623d22183a579c7..0000000000000000000000000000000000000000
--- a/misc/database/tables/18_packet_telemetry.sql
+++ /dev/null
@@ -1,23 +0,0 @@
-create table packet_telemetry (
-     "id" bigserial not null,
-     "packet_id" bigint not null,
-     "station_id" bigint not null,
-     "timestamp" bigint not null,
-     "val1" real null,
-     "val2" real null,
-     "val3" real null,
-     "val4" real null,
-     "val5" real null,
-     "bits" text null,
-     "seq" int null,
-     "station_telemetry_param_id" bigint null,
-     "station_telemetry_unit_id" bigint null,
-     "station_telemetry_eqns_id" bigint null,
-     "station_telemetry_bits_id" bigint null,
-     primary key (id),
-     foreign key(station_id) references station(id),
-     foreign key(station_telemetry_param_id) references station_telemetry_param(id),
-     foreign key(station_telemetry_unit_id) references station_telemetry_unit(id),
-     foreign key(station_telemetry_eqns_id) references station_telemetry_eqns(id),
-     foreign key(station_telemetry_bits_id) references station_telemetry_bits(id)
-);
diff --git a/misc/database/tables/19_packet_path.sql b/misc/database/tables/19_packet_path.sql
deleted file mode 100644
index 824d728a91ef342ecb8ba1c13275e66745c5fb6d..0000000000000000000000000000000000000000
--- a/misc/database/tables/19_packet_path.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-create table packet_path (
-     "id" bigserial not null,
-     "packet_id" bigint not null,
-     "station_id" bigint not null,
-     "latitude" double precision null,
-     "longitude" double precision null,
-     "timestamp" bigint null,
-     "distance" int null,
-     "number" smallint,
-     "sending_station_id" bigint not null,
-     "sending_latitude" double precision null,
-     "sending_longitude" double precision null,
-     primary key (id),
-     foreign key(station_id) references station(id),
-     foreign key(sending_station_id) references station(id)
-);
diff --git a/misc/database/tables/20_packet_ogn.sql b/misc/database/tables/20_packet_ogn.sql
deleted file mode 100644
index 83208eb5d28ae041b1f97be61c94dcd9fb876bf6..0000000000000000000000000000000000000000
--- a/misc/database/tables/20_packet_ogn.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-create table packet_ogn (
-     "id" bigserial not null,
-     "packet_id" bigint not null,
-     "station_id" bigint not null,
-     "timestamp" bigint not null,
-     "ogn_sender_address" text null,
-     "ogn_address_type_id" smallint null,
-     "ogn_aircraft_type_id" smallint null,
-     "ogn_climb_rate" int null,
-     "ogn_turn_rate" float null,
-     "ogn_signal_to_noise_ratio" float null,
-     "ogn_bit_errors_corrected" int null,
-     "ogn_frequency_offset" float null,
-     primary key (id),
-     foreign key(station_id) references station(id)
-);
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 2a592dacdb7807b368d831d8e8995116459fb4a6..0000000000000000000000000000000000000000
--- a/requirements.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-psycopg2-binary
-wheel
-setuptools
-autobahn[twisted]
-twisted
-pympler
-image_slicer
-jsmin
-psutil
-git+https://github.com/rossengeorgiev/aprs-python
\ No newline at end of file
diff --git a/server/bin/collector.py b/server/bin/collector.py
deleted file mode 100644
index 7025864c22d54e015219745602e6cb0e5cb73f1a..0000000000000000000000000000000000000000
--- a/server/bin/collector.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import sys
-import os.path
-import logging
-import logging.handlers
-import trackdirect
-
-if __name__ == '__main__':
-
-    if (len(sys.argv) < 2):
-        print("\n" + sys.argv[0] + ' [config.ini] [collector number]')
-        sys.exit()
-    elif (sys.argv[1].startswith("/")):
-        if (not os.path.isfile(sys.argv[1])):
-            print(f"\n File {sys.argv[1]} does not exists")
-            print("\n" + sys.argv[0] + ' [config.ini] [collector number]')
-            sys.exit()
-    elif (not os.path.isfile(os.path.expanduser('~/trackdirect/config/' + sys.argv[1]))):
-        print(f"\n File ~/trackdirect/config/{sys.argv[1]} does not exists")
-        print("\n" + sys.argv[0] + ' [config.ini] [collector number]')
-        sys.exit()
-
-    config = trackdirect.TrackDirectConfig()
-    config.populate(sys.argv[1])
-
-    if (len(sys.argv) < 3):
-        collectorNumber = 0
-    else:
-        collectorNumber = int(sys.argv[2])
-    collectorOptions = config.collector[collectorNumber]
-
-    saveOgnStationsWithMissingIdentity = False
-    if (config.saveOgnStationsWithMissingIdentity):
-        saveOgnStationsWithMissingIdentity = True
-
-    fh = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
-        collectorOptions['error_log']), mode='a', maxBytes=1000000, backupCount=10)
-
-    formatter = logging.Formatter(
-        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-    fh.setFormatter(formatter)
-
-    consoleHandler = logging.StreamHandler()
-    consoleHandler.setFormatter(formatter)
-
-    trackDirectLogger = logging.getLogger('trackdirect')
-    trackDirectLogger.addHandler(fh)
-    trackDirectLogger.addHandler(consoleHandler)
-    trackDirectLogger.setLevel(logging.INFO)
-
-    aprslibLogger = logging.getLogger('aprslib.IS')
-    aprslibLogger.addHandler(fh)
-    aprslibLogger.addHandler(consoleHandler)
-    aprslibLogger.setLevel(logging.INFO)
-
-    trackDirectLogger.warning("Starting (Collecting from " + collectorOptions['host'] + ":" + str(
-        collectorOptions['port_full']) + " using " + collectorOptions['callsign'] + " and " + str(collectorOptions['passcode']) + ")")
-
-    try:
-        trackDirectDataCollector = trackdirect.TrackDirectDataCollector(
-            collectorOptions,
-            saveOgnStationsWithMissingIdentity)
-        trackDirectDataCollector.run()
-    except Exception as e:
-        trackDirectLogger.error(e, exc_info=1)
diff --git a/server/bin/remover.py b/server/bin/remover.py
deleted file mode 100644
index 0d80f5b8791a6a554822333f75e427308f45b5c0..0000000000000000000000000000000000000000
--- a/server/bin/remover.py
+++ /dev/null
@@ -1,248 +0,0 @@
-import sys
-import os.path
-import logging
-import logging.handlers
-import datetime
-import time
-import trackdirect
-
-from trackdirect.database.DatabaseConnection import DatabaseConnection
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.repositories.PacketRepository import PacketRepository
-
-if __name__ == '__main__':
-
-    if (len(sys.argv) < 2):
-        print("\n" + sys.argv[0] + ' [config.ini]')
-        sys.exit()
-    elif (sys.argv[1].startswith("/")):
-        if (not os.path.isfile(sys.argv[1])):
-            print(f"\n File {sys.argv[1]} does not exists")
-            print("\n" + sys.argv[0] + ' [config.ini]')
-            sys.exit()
-    elif (not os.path.isfile(os.path.expanduser('~/trackdirect/config/' + sys.argv[1]))):
-        print(f"\n File ~/trackdirect/config/{sys.argv[1]} does not exists")
-        print("\n" + sys.argv[0] + ' [config.ini]')
-        sys.exit()
-
-    config = trackdirect.TrackDirectConfig()
-    config.populate(sys.argv[1])
-
-    maxDaysToSavePositionData = int(config.daysToSavePositionData)
-    maxDaysToSaveStationData = int(config.daysToSaveStationData)
-    maxDaysToSaveWeatherData = int(config.daysToSaveWeatherData)
-    maxDaysToSaveTelemetryData = int(config.daysToSaveTelemetryData)
-
-    try:
-        fh = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
-            '~/trackdirect/server/log/remover_' + config.dbName + '.log'), mode='a', maxBytes=1000000, backupCount=10)
-
-        formatter = logging.Formatter(
-            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-        fh.setFormatter(formatter)
-
-        consoleHandler = logging.StreamHandler()
-        consoleHandler.setFormatter(formatter)
-
-        trackDirectLogger = logging.getLogger('trackdirect')
-        trackDirectLogger.addHandler(fh)
-        trackDirectLogger.addHandler(consoleHandler)
-        trackDirectLogger.setLevel(logging.INFO)
-
-        trackDirectLogger.info("Starting")
-        trackDirectLogger.info(
-            "Saving position data for %s days" % (maxDaysToSavePositionData))
-        trackDirectLogger.info(
-            "Saving station data for %s days" % (maxDaysToSaveStationData))
-        trackDirectLogger.info(
-            "Saving weather data for %s days" % (maxDaysToSaveWeatherData))
-        trackDirectLogger.info(
-            "Saving telemetry data for %s days" % (maxDaysToSaveTelemetryData))
-
-        trackDirectDb = DatabaseConnection()
-        dbNoAutoCommit = trackDirectDb.getConnection(False)
-        db = trackDirectDb.getConnection(True)
-        db.set_isolation_level(0)
-        cursor = db.cursor()
-        cursor.execute("SET statement_timeout = '240s'")
-
-        trackDirectDbObjectFinder = DatabaseObjectFinder(db)
-
-        packetRepository = PacketRepository(db)
-
-        #
-        # Loop over the latest days and delete packets that is not needed any more
-        #
-        for x in range(2, 16):
-            prevDay = datetime.date.today() - datetime.timedelta(x)  # today minus x days
-            prevDayTimestamp = prevDay.strftime("%s")
-            prevDayFormat = datetime.datetime.utcfromtimestamp(
-                int(prevDayTimestamp)).strftime('%Y%m%d')
-            packetTable = "packet" + prevDayFormat
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable)):
-                deletedRows = None
-                doFullVacuum = False
-                while (deletedRows is None or deletedRows >= 5000):
-                    sql = """delete from """ + packetTable + \
-                        """ where id in (select id from """ + packetTable + \
-                        """ where map_id not in (1,12) limit 5000)"""
-                    cursor.execute(sql)
-                    deletedRows = cursor.rowcount
-                    trackDirectLogger.info(
-                        "Deleted %s %s" % (deletedRows, packetTable))
-                    if (deletedRows > 0):
-                        doFullVacuum = True
-                    time.sleep(0.5)
-                if (doFullVacuum):
-                    cursor.execute("""VACUUM FULL """ +
-                                   packetTable + """_path""")
-                    cursor.execute("""REINDEX TABLE """ +
-                                   packetTable + """_path""")
-                    cursor.execute("""VACUUM FULL """ + packetTable)
-                    cursor.execute("""REINDEX TABLE """ + packetTable)
-
-        #
-        # Drop packet_weather
-        #
-        for x in range(maxDaysToSaveWeatherData, maxDaysToSaveWeatherData+100):
-            prevDay = datetime.date.today() - datetime.timedelta(x)  # today minus x days
-            prevDayTimestamp = prevDay.strftime("%s")
-            prevDayFormat = datetime.datetime.utcfromtimestamp(
-                int(prevDayTimestamp)).strftime('%Y%m%d')
-            packetTable = "packet" + prevDayFormat
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable + "_weather")):
-                cursor.execute("""drop table """ +
-                               packetTable + """_weather""")
-                trackDirectLogger.info(
-                    "Dropped table %s_weather" % (packetTable))
-
-        #
-        # Drop packet_telemetry
-        #
-        for x in range(maxDaysToSaveTelemetryData, maxDaysToSaveTelemetryData+100):
-            prevDay = datetime.date.today() - datetime.timedelta(x)  # today minus x days
-            prevDayTimestamp = prevDay.strftime("%s")
-            prevDayFormat = datetime.datetime.utcfromtimestamp(
-                int(prevDayTimestamp)).strftime('%Y%m%d')
-            packetTable = "packet" + prevDayFormat
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable + "_telemetry")):
-                cursor.execute("""drop table """ +
-                               packetTable + """_telemetry""")
-                trackDirectLogger.info(
-                    "Dropped table %s_telemetry" % (packetTable))
-
-        #
-        # Drop packets
-        #
-        for x in range(maxDaysToSavePositionData, maxDaysToSavePositionData+100):
-            prevDay = datetime.date.today() - datetime.timedelta(x)  # today minus x days
-            prevDayTimestamp = prevDay.strftime("%s")
-            prevDayFormat = datetime.datetime.utcfromtimestamp(
-                int(prevDayTimestamp)).strftime('%Y%m%d')
-            packetTable = "packet" + prevDayFormat
-
-            # Drop packet_ogn table
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable + "_ogn")):
-                cursor.execute("""drop table """ + packetTable + """_ogn""")
-                trackDirectLogger.info("Dropped table %s_ogn" % (packetTable))
-
-            #
-            # Drop packet_path table
-            #
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable + "_path")):
-                cursor.execute("""drop table """ + packetTable + """_path""")
-                trackDirectLogger.info("Dropped table %s_path" % (packetTable))
-
-            #
-            # Drop packet table
-            #
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable)):
-                cursor.execute("""drop table """ + packetTable)
-                trackDirectLogger.info("Dropped table %s" % (packetTable))
-
-        #
-        # Delete old stations
-        #
-        timestampLimit = int(time.time()) - (60*60*24*maxDaysToSaveStationData)
-        deletedRows = 0
-        sql = """select station.id, station.latest_sender_id, station.name
-            from station
-            where latest_packet_timestamp < %s
-                and (
-                    exists (
-                        select 1
-                        from sender
-                        where sender.id = station.latest_sender_id
-                            and sender.name != station.name
-                    )
-                    or
-                    not exists (
-                        select 1
-                        from station station2, sender
-                        where sender.id = station.latest_sender_id
-                            and station2.latest_sender_id = sender.id
-                            and station2.name != sender.name
-                    )
-                )
-            order by latest_packet_timestamp"""
-
-        selectStationCursor = db.cursor()
-        selectStationCursor.execute(sql, (timestampLimit,))
-        for record in selectStationCursor:
-            trackDirectLogger.info("Trying to delete station %s (%s)" % (
-                record["name"], record["id"]))
-            try:
-                deleteCursor = dbNoAutoCommit.cursor()
-
-                sql = """delete from station_telemetry_bits where station_id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from station_telemetry_eqns where station_id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from station_telemetry_param where station_id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from station_telemetry_unit where station_id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from station_city where station_id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from station where id = %s"""
-                deleteCursor.execute(sql, (record["id"],))
-
-                sql = """delete from sender where id = %s and not exists (select 1 from station where latest_sender_id = sender.id)"""
-                deleteCursor.execute(sql, (record["latest_sender_id"],))
-
-                dbNoAutoCommit.commit()
-                deleteCursor.close()
-                deletedRows += 1
-                time.sleep(0.5)
-            except Exception as e:
-                # Something went wrong
-                #trackDirectLogger.error(e, exc_info=1)
-                dbNoAutoCommit.rollback()
-                deleteCursor.close()
-
-        selectStationCursor.close()
-        if (deletedRows > 0):
-            trackDirectLogger.info("Deleted %s stations" % (deletedRows))
-
-        cursor.execute("""VACUUM ANALYZE station""")
-        cursor.execute("""REINDEX TABLE station""")
-        cursor.execute("""VACUUM ANALYZE sender""")
-        cursor.execute("""REINDEX TABLE sender""")
-
-        #
-        # Close DB connection
-        #
-        cursor.close()
-        db.close()
-        trackDirectLogger.info("Done!")
-
-    except Exception as e:
-        trackDirectLogger.error(e, exc_info=1)
diff --git a/server/bin/stationremover.py b/server/bin/stationremover.py
deleted file mode 100644
index 6e13a2eb0a1336393edf6be4dfd74ce2dc7f190b..0000000000000000000000000000000000000000
--- a/server/bin/stationremover.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import sys
-import os.path
-import logging
-import logging.handlers
-import datetime
-import time
-import trackdirect
-
-from trackdirect.database.DatabaseConnection import DatabaseConnection
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-
-if __name__ == '__main__':
-
-    if (len(sys.argv) < 3):
-        print("\n" + sys.argv[0] + ' [config.ini] [staion id]')
-        sys.exit()
-    elif (sys.argv[1].startswith("/")):
-        if (not os.path.isfile(sys.argv[1])):
-            print(f"\n File {sys.argv[1]} does not exists")
-            print("\n" + sys.argv[0] + ' [config.ini] [staion id]')
-            sys.exit()
-    elif (not os.path.isfile(os.path.expanduser('~/trackdirect/config/' + sys.argv[1]))):
-        print(f"\n File ~/trackdirect/config/{sys.argv[1]} does not exists")
-        print("\n" + sys.argv[0] + ' [config.ini] [staion id]')
-        sys.exit()
-
-    stationId = sys.argv[2]
-
-    config = trackdirect.TrackDirectConfig()
-    config.populate(sys.argv[1])
-
-    try:
-        fh = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
-            '~/trackdirect/server/log/stationremover.log'), mode='a', maxBytes=1000000, backupCount=10)
-
-        formatter = logging.Formatter(
-            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-        fh.setFormatter(formatter)
-
-        consoleHandler = logging.StreamHandler()
-        consoleHandler.setFormatter(formatter)
-
-        trackDirectLogger = logging.getLogger('trackdirect')
-        trackDirectLogger.addHandler(fh)
-        trackDirectLogger.addHandler(consoleHandler)
-        trackDirectLogger.setLevel(logging.INFO)
-
-        trackDirectLogger.info("Starting")
-
-        trackDirectDb = DatabaseConnection()
-        db = trackDirectDb.getConnection(True)
-        db.set_isolation_level(0)
-        cursor = db.cursor()
-        cursor.execute("SET statement_timeout = '120s'")
-
-        trackDirectDbObjectFinder = DatabaseObjectFinder(db)
-
-        # If saving longer than 365 days, modify range
-        for x in range(0, 365):
-            prevDay = datetime.date.today() - datetime.timedelta(x)  # today minus x days
-            prevDayTimestamp = prevDay.strftime("%s")
-            prevDayFormat = datetime.datetime.utcfromtimestamp(
-                int(prevDayTimestamp)).strftime('%Y%m%d')
-
-            packetTable = "packet" + prevDayFormat
-            packetPathTable = "packet" + prevDayFormat + "_path"
-            packetWeatherTable = "packet" + prevDayFormat + "_weather"
-            packetTelemetryTable = "packet" + prevDayFormat + "_telemetry"
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetPathTable)):
-
-                # Delete paths for this station
-                sql = """delete from """ + packetPathTable + \
-                    """ where packet_id in (select id from """ + \
-                    packetTable + """ where station_id = %s)"""
-                cursor.execute(sql, (stationId,))
-                trackDirectLogger.info("Deleted %s rows in %s" % (
-                    cursor.rowcount or 0, packetPathTable))
-                time.sleep(0.5)
-
-                # Delete paths related to this station
-                sql = """delete from """ + packetPathTable + """ where station_id = %s"""
-                cursor.execute(sql, (stationId,))
-                trackDirectLogger.info("Deleted %s related rows in %s" % (
-                    cursor.rowcount or 0, packetPathTable))
-                time.sleep(0.5)
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetTelemetryTable)):
-                # Delete telemetry for this station
-                sql = """delete from """ + packetTelemetryTable + """ where station_id = %s"""
-                cursor.execute(sql, (stationId,))
-                trackDirectLogger.info("Deleted %s rows in %s" % (
-                    cursor.rowcount or 0, packetTelemetryTable))
-                time.sleep(0.5)
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetWeatherTable)):
-                # Delete weather for this station
-                sql = """delete from """ + packetWeatherTable + """ where station_id = %s"""
-                cursor.execute(sql, (stationId,))
-                trackDirectLogger.info("Deleted %s rows in %s" % (
-                    cursor.rowcount or 0, packetWeatherTable))
-                time.sleep(0.5)
-
-            if (trackDirectDbObjectFinder.checkTableExists(packetTable)):
-                # Delete packets for this station
-                sql = """delete from """ + packetTable + """ where station_id = %s"""
-                cursor.execute(sql, (stationId,))
-                trackDirectLogger.info("Deleted %s rows in %s" % (
-                    cursor.rowcount or 0, packetTable))
-                time.sleep(0.5)
-
-        # Delete station
-        sql = "delete from station where id = %s"
-        cursor.execute(sql, (stationId,))
-        trackDirectLogger.info(
-            "Deleted %s rows from station" % (cursor.rowcount or 0))
-        time.sleep(0.5)
-
-        cursor.close()
-        db.close()
-        trackDirectLogger.info("Done!")
-
-    except Exception as e:
-        trackDirectLogger.error(e, exc_info=1)
diff --git a/server/bin/wsserver.py b/server/bin/wsserver.py
deleted file mode 100644
index 890ce097ee02f6ff0859db4b64bf5cc09c220e6a..0000000000000000000000000000000000000000
--- a/server/bin/wsserver.py
+++ /dev/null
@@ -1,151 +0,0 @@
-from autobahn.twisted.websocket import WebSocketServerFactory
-from autobahn.twisted.resource import WebSocketResource
-from autobahn.websocket.compress import PerMessageDeflateOffer, PerMessageDeflateOfferAccept
-import trackdirect
-import argparse
-import psutil
-import sys
-import os.path
-import logging
-import logging.handlers
-from twisted.internet import reactor
-from twisted.web.server import Site
-from twisted.web.static import File
-from socket import AF_INET
-
-
-def master(options, trackDirectLogger):
-    """
-    Start of the master process.
-    """
-    config = trackdirect.TrackDirectConfig()
-    config.populate(options.config)
-
-    workerPid = os.getpid()
-    p = psutil.Process(workerPid)
-    p.cpu_affinity([0])
-    trackDirectLogger.warning("Starting master with PID " + str(workerPid) + " (on CPU id(s): " + ','.join(map(str, p.cpu_affinity())) + ")")
-
-    try:
-        factory = WebSocketServerFactory()
-        factory.protocol = trackdirect.TrackDirectWebsocketServer
-
-        resource = WebSocketResource(factory)
-        root = File(".")
-        root.putChild(b"ws", resource)
-        site = Site(root)
-
-        port = reactor.listenTCP(config.websocketPort, site)
-
-        for i in range(1, options.workers):
-            args = [sys.executable, "-u", __file__]
-            args.extend(sys.argv[1:])
-            args.extend(["--fd", str(port.fileno()), "--cpuid", str(i)])
-
-            reactor.spawnProcess(
-                None, sys.executable, args,
-                childFDs={0: 0, 1: 1, 2: 2, port.fileno(): port.fileno()},
-                env=os.environ)
-
-        options.fd = port.fileno()
-        listen(options, trackDirectLogger)
-
-    except Exception as e:
-        trackDirectLogger.error(e, exc_info=1)
-
-
-def worker(options, trackDirectLogger):
-    """
-    Start background worker process.
-    """
-    config = trackdirect.TrackDirectConfig()
-    config.populate(options.config)
-
-    try:
-        workerPid = os.getpid()
-        p = psutil.Process(workerPid)
-        p.cpu_affinity([options.cpuid])
-
-        trackDirectLogger.warning("Starting worker with PID " + str(workerPid) + " (on CPU id(s): " + ','.join(map(str, p.cpu_affinity())) + ")")
-
-        listen(options, trackDirectLogger)
-
-    except Exception as e:
-        trackDirectLogger.error(e, exc_info=1)
-
-
-def listen(options, trackDirectLogger) :
-    """
-    Start to listen on websocket requests.
-    """
-    config = trackdirect.TrackDirectConfig()
-    config.populate(options.config)
-
-    factory = WebSocketServerFactory(
-        "ws://" + config.websocketHostname + ":" + str(config.websocketPort),
-        externalPort = config.websocketExternalPort)
-    factory.protocol = trackdirect.TrackDirectWebsocketServer
-
-    # Enable WebSocket extension "permessage-deflate".
-    # Function to accept offers from the client ..
-    def accept(offers):
-        for offer in offers:
-            if isinstance(offer, PerMessageDeflateOffer):
-                return PerMessageDeflateOfferAccept(offer)
-    factory.setProtocolOptions(perMessageCompressionAccept=accept)
-
-    reactor.suggestThreadPoolSize(25)
-
-    # Socket already created, just start listening and accepting
-    reactor.adoptStreamPort(options.fd, AF_INET, factory)
-
-    reactor.run()
-
-
-if __name__ == '__main__':
-    DEFAULT_WORKERS = psutil.cpu_count()
-
-    parser = argparse.ArgumentParser(
-        description='Track Direct WebSocket Server')
-    parser.add_argument('--config', dest='config', type=str, default=None,
-                        help='The Track Direct config file, e.g. trackdirect.ini')
-    parser.add_argument('--workers', dest='workers', type=int, default=DEFAULT_WORKERS,
-                        help='Number of workers to spawn - should fit the number of (physical) CPU cores.')
-    parser.add_argument('--fd', dest='fd', type=int, default=None,
-                        help='If given, this is a worker which will use provided FD and all other options are ignored.')
-    parser.add_argument('--cpuid', dest='cpuid', type=int, default=None,
-                        help='If given, this is a worker which will use provided CPU core to set its affinity.')
-
-    options = parser.parse_args()
-    config = trackdirect.TrackDirectConfig()
-    config.populate(options.config)
-
-    formatter = logging.Formatter(
-        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-
-    fh = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
-        config.errorLog), mode='a', maxBytes=1000000, backupCount=10)
-    fh.setFormatter(formatter)
-
-    consoleHandler = logging.StreamHandler()
-    consoleHandler.setFormatter(formatter)
-
-    trackDirectLogger = logging.getLogger('trackdirect')
-    trackDirectLogger.addHandler(fh)
-    trackDirectLogger.addHandler(consoleHandler)
-    trackDirectLogger.setLevel(logging.INFO)
-
-    fh2 = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
-        config.errorLog), mode='a', maxBytes=1000000, backupCount=10)
-    # aprslib is logging non important "socket error on ..." using ERROR-level
-    fh2.setFormatter(formatter)
-
-    aprslibLogger = logging.getLogger('aprslib.IS')
-    aprslibLogger.addHandler(fh2)
-    aprslibLogger.addHandler(consoleHandler)
-    aprslibLogger.setLevel(logging.INFO)
-
-    if options.fd is not None:
-        worker(options, trackDirectLogger)
-    else:
-        master(options, trackDirectLogger)
diff --git a/server/log/.gitignore b/server/log/.gitignore
deleted file mode 100644
index 5e7d2734cfc60289debf74293817c0a8f572ff32..0000000000000000000000000000000000000000
--- a/server/log/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore
diff --git a/server/scripts/collector.sh b/server/scripts/collector.sh
deleted file mode 100755
index 50bd14ddfd9d66e06cfe2a1a74e8bbf0450318cd..0000000000000000000000000000000000000000
--- a/server/scripts/collector.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [config file] [collector number]"
-    exit
-fi
-
-CONFIGFILE=$1
-COLLECTORNUMBER=$2
-
-if ps -ef | grep -v grep | grep "bin/collector.py $CONFIGFILE $COLLECTORNUMBER" ; then
-    exit 0
-else
-    CURRENTDIR=$(dirname $0)
-
-    export PYTHONPATH=$PYTHONPATH:$CURRENTDIR/../trackdirect
-    cd $CURRENTDIR/..
-    python $CURRENTDIR/../bin/collector.py $CONFIGFILE $COLLECTORNUMBER
-    exit 0
-fi
diff --git a/server/scripts/db_setup.sh b/server/scripts/db_setup.sh
deleted file mode 100755
index acea6638e202648a49c5a878f7b0b4179014eaa7..0000000000000000000000000000000000000000
--- a/server/scripts/db_setup.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [dbname] [dbport] [sqlpath]"
-    exit
-fi
-
-DATABASE=$1
-PORT=$2
-SQLPATH=$3
-
-# Assumes .pgpass is correctly set
-psql -p $PORT $DATABASE << EOF
-
-begin transaction;
-
-\i $SQLPATH/01_map.sql
-\i $SQLPATH/02_marker.sql
-\i $SQLPATH/03_ogn_address_type.sql
-\i $SQLPATH/04_ogn_aircraft_type.sql
-\i $SQLPATH/05_ogn_device.sql
-\i $SQLPATH/06_ogn_hidden_station.sql
-\i $SQLPATH/07_packet_type.sql
-\i $SQLPATH/08_sender.sql
-\i $SQLPATH/09_source.sql
-\i $SQLPATH/10_station_type.sql
-\i $SQLPATH/11_station.sql
-\i $SQLPATH/12_station_telemetry_bits.sql
-\i $SQLPATH/13_station_telemetry_eqns.sql
-\i $SQLPATH/14_station_telemetry_param.sql
-\i $SQLPATH/15_station_telemetry_unit.sql
-\i $SQLPATH/16_packet.sql
-\i $SQLPATH/17_packet_weather.sql
-\i $SQLPATH/18_packet_telemetry.sql
-\i $SQLPATH/19_packet_path.sql
-\i $SQLPATH/20_packet_ogn.sql
-
-commit;
-
-EOF
-
-
-exit 0
diff --git a/server/scripts/ogn_devices_install.sh b/server/scripts/ogn_devices_install.sh
deleted file mode 100755
index 5859bc1a39ff4ccf1dbf7c14886483aba128d415..0000000000000000000000000000000000000000
--- a/server/scripts/ogn_devices_install.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [dbname] [dbport]"
-    exit
-fi
-
-DATABASE=$1
-PORT=$2
-
-pushd `dirname $0` > /dev/null
-SCRIPTPATH=`pwd -P`
-popd > /dev/null
-
-# Create dir and remove old stuff (keep zip-file since it may be equal to latest)
-mkdir -p $SCRIPTPATH/ogndevices
-mkdir -p $SCRIPTPATH/ogndevices/${DATABASE}
-rm $SCRIPTPATH/ogndevices/${DATABASE}/*.csv
-rm $SCRIPTPATH/ogndevices/${DATABASE}/*.txt
-cd $SCRIPTPATH/ogndevices/${DATABASE}
-
-# Download latest csv file (but only if newer)
-wget -N http://ddb.glidernet.org/download/?t=1 -O ogndevices.csv
-
-if test `find "ogndevices.csv" -cmin +30`
-then
-    echo "File is not updated, skip reload of database."
-else
-
-
-# Remove comments in file
-sed '/^#/ d' < ogndevices.csv > ogndevices2.csv
-
-# Load file into database (assumes .pgpass is correctly set)
-psql -p $PORT $DATABASE << EOF
-
-create table if not exists ogn_device (
-    "device_type" text not null,
-    "device_id" text not null,
-    "aircraft_model" text not null,
-    "registration" text not null,
-    "cn" text not null,
-    "tracked" text not null,
-    "identified" text not null,
-    "ddb_aircraft_type" text not null
-);
-
-begin transaction;
-
-drop index if exists ogn_device_device_id_idx;
-truncate ogn_device;
-\copy ogn_device from '$SCRIPTPATH/ogndevices/$DATABASE/ogndevices2.csv' DELIMITERS ',' CSV QUOTE '''';
-create index ogn_device_device_id_idx on ogn_device(device_id);
-
-insert into ogn_device(device_type, device_id, aircraft_model, registration, cn, tracked, identified, ddb_aircraft_type) values ('F', '3FEF6F', '', '', '', 'N', 'N', 1);
-commit;
-
-EOF
-
-fi
-
-exit 0
diff --git a/server/scripts/remover.sh b/server/scripts/remover.sh
deleted file mode 100755
index ccb0cae108ffce298477e29787a43cc9b82ba732..0000000000000000000000000000000000000000
--- a/server/scripts/remover.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [config file path]"
-    exit
-fi
-
-CONFIGFILE=$1
-
-if ps -ef | grep -v grep | grep "bin/remover.py $CONFIGFILE" ; then
-    exit 0
-else
-    CURRENTDIR=$(dirname $0)
-
-    export PYTHONPATH=$PYTHONPATH:$CURRENTDIR/../trackdirect
-    cd $CURRENTDIR/..
-    python $CURRENTDIR/../bin/remover.py $CONFIGFILE
-    exit 0
-fi
diff --git a/server/scripts/stationremover.sh b/server/scripts/stationremover.sh
deleted file mode 100755
index 72be13e363e1517dbb68fc5663bdb9b7b14f1b17..0000000000000000000000000000000000000000
--- a/server/scripts/stationremover.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [config file path] [station id]"
-    exit
-fi
-
-CONFIGFILE=$1
-STATIONID=$2
-
-if ps -ef | grep -v grep | grep "bin/stationremover.py $CONFIGFILE $STATIONID" ; then
-    exit 0
-else
-    CURRENTDIR=$(dirname $0)
-
-    export PYTHONPATH=$PYTHONPATH:$CURRENTDIR/../trackdirect
-    cd $CURRENTDIR/..
-    python $CURRENTDIR/../bin/stationremover.py $CONFIGFILE $STATIONID
-    exit 0
-fi
diff --git a/server/scripts/wsserver.sh b/server/scripts/wsserver.sh
deleted file mode 100755
index 999d3e7936b254ea8e55f9544715d55f63d20bd7..0000000000000000000000000000000000000000
--- a/server/scripts/wsserver.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied"
-    echo "$0 [config file]"
-    exit
-fi
-
-CONFIGFILE=$1
-
-if ps -eo pid,pgid,cmd | grep -v grep | grep "bin/wsserver.py --config $CONFIGFILE" ; then
-    exit 0
-else
-    CURRENTDIR=$(dirname $0)
-
-    export PYTHONPATH=$PYTHONPATH:$CURRENTDIR/../trackdirect
-    cd $CURRENTDIR/..
-    python $CURRENTDIR/../bin/wsserver.py --config $CONFIGFILE
-    exit 0
-fi
diff --git a/server/trackdirect/TrackDirectConfig.py b/server/trackdirect/TrackDirectConfig.py
deleted file mode 100644
index 422d26afcbf2400e5bf48b2b0e50b6c6bf38b574..0000000000000000000000000000000000000000
--- a/server/trackdirect/TrackDirectConfig.py
+++ /dev/null
@@ -1,190 +0,0 @@
-import os
-import os.path
-import configparser
-
-from trackdirect.common.Singleton import Singleton
-
-
-class TrackDirectConfig(Singleton):
-    """Track Direct Config class
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-        self.collector = {}
-
-    def populate(self, configFile):
-        """The __init__ method.
-
-        Args:
-            configFile (string):  Config file name
-        """
-        configParser = configparser.SafeConfigParser()
-        if (configFile.startswith('/')):
-            configParser.read(os.path.expanduser(configFile))
-        else:
-            configParser.read(os.path.expanduser(
-                '~/trackdirect/config/' + configFile))
-
-        # Database
-        self.dbHostname = configParser.get('database', 'host').strip('"')
-        self.dbName = configParser.get('database', 'database').strip('"')
-        try:
-            self.dbUsername = configParser.get(
-                'database', 'username').strip('"')
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            self.dbUsername = os.getlogin()
-        self.dbPassword = configParser.get('database', 'password').strip('"')
-        self.dbPort = int(configParser.get('database', 'port').strip('"'))
-        self.daysToSavePositionData = int(configParser.get(
-            'database', 'days_to_save_position_data').strip('"'))
-        self.daysToSaveStationData = int(configParser.get(
-            'database', 'days_to_save_station_data').strip('"'))
-        self.daysToSaveWeatherData = int(configParser.get(
-            'database', 'days_to_save_weather_data').strip('"'))
-        self.daysToSaveTelemetryData = int(configParser.get(
-            'database', 'days_to_save_telemetry_data').strip('"'))
-
-        self.saveOgnStationsWithMissingIdentity = False
-        try:
-            saveOgnStationsWithMissingIdentity = configParser.get(
-                'database', 'save_ogn_stations_with_missing_identity').strip('"')
-            if (saveOgnStationsWithMissingIdentity == "1"):
-                self.saveOgnStationsWithMissingIdentity = True
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            pass
-
-        # Websocket server
-        self.websocketHostname = configParser.get(
-            'websocket_server', 'host').strip('"')
-        self.websocketPort = int(configParser.get(
-            'websocket_server', 'port').strip('"'))
-
-        self.websocketExternalPort = self.websocketPort
-        try :
-            self.websocketExternalPort = int(configParser.get(
-                'websocket_server', 'external_port').strip('"'))
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            pass
-
-        self.errorLog = configParser.get(
-            'websocket_server', 'error_log').strip('"')
-        self.websocketFrequencyLimit = configParser.get(
-            'websocket_server', 'frequency_limit').strip('"')
-
-        self.maxDefaultTime = int(configParser.get(
-            'websocket_server', 'max_default_time').strip('"'))
-        self.maxFilterTime = int(configParser.get(
-            'websocket_server', 'max_filter_time').strip('"'))
-        self.maxClientIdleTime = int(configParser.get(
-            'websocket_server', 'max_client_idle_time').strip('"'))
-        self.maxQueuedRealtimePackets = int(configParser.get(
-            'websocket_server', 'max_queued_realtime_packets').strip('"'))
-
-        allowTimeTravel = configParser.get(
-            'websocket_server', 'allow_time_travel').strip('"')
-        self.allowTimeTravel = False
-        if (allowTimeTravel == "1"):
-            self.allowTimeTravel = True
-
-        # Websocket server APRS connection (we support 2 different sources, more can be added...)
-        try:
-            self.websocketAprsHost1 = configParser.get(
-                'websocket_server', 'aprs_host1').strip('"')
-            self.websocketAprsPort1 = configParser.get(
-                'websocket_server', 'aprs_port1').strip('"')
-            self.websocketAprsSourceId1 = int(configParser.get(
-                'websocket_server', 'aprs_source_id1').strip('"'))
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            self.websocketAprsSourceId1 = None
-            self.websocketAprsHost1 = None
-            self.websocketAprsPort1 = None
-
-        try:
-            self.websocketAprsHost2 = configParser.get(
-                'websocket_server', 'aprs_host2').strip('"')
-            self.websocketAprsPort2 = configParser.get(
-                'websocket_server', 'aprs_port2').strip('"')
-            self.websocketAprsSourceId2 = int(configParser.get(
-                'websocket_server', 'aprs_source_id2').strip('"'))
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            self.websocketAprsSourceId2 = None
-            self.websocketAprsHost2 = None
-            self.websocketAprsPort2 = None
-
-        if (self.websocketAprsSourceId1 == 5 or self.websocketAprsSourceId2 == 5) :
-            # At least one source is of type OGN, disable display of older data
-            self.allowTimeTravel = False
-            if (self.maxDefaultTime > 1440) :
-                self.maxDefaultTime = 1440
-            if (self.maxFilterTime > 1440) :
-                self.maxDefaultTime = 1440
-
-        # Collectors
-        for collectorNumber in range(0, 5):
-            self.collector[collectorNumber] = {}
-            try:
-                self.collector[collectorNumber]['source_id'] = int(configParser.get(
-                    'collector' + str(collectorNumber), 'source_id').strip('"'))
-                self.collector[collectorNumber]['host'] = configParser.get(
-                    'collector' + str(collectorNumber), 'host').strip('"')
-                self.collector[collectorNumber]['port_full'] = int(configParser.get(
-                    'collector' + str(collectorNumber), 'port_full').strip('"'))
-                self.collector[collectorNumber]['port_filtered'] = int(configParser.get(
-                    'collector' + str(collectorNumber), 'port_filtered').strip('"'))
-
-                self.collector[collectorNumber]['callsign'] = configParser.get(
-                    'collector' + str(collectorNumber), 'callsign').strip('"')
-                self.collector[collectorNumber]['passcode'] = configParser.get(
-                    'collector' + str(collectorNumber), 'passcode').strip('"')
-
-                self.collector[collectorNumber]['numbers_in_batch'] = configParser.get(
-                    'collector' + str(collectorNumber), 'numbers_in_batch').strip('"')
-                try:
-                    self.collector[collectorNumber]['frequency_limit'] = int(configParser.get(
-                        'collector' + str(collectorNumber), 'frequency_limit').strip('"'))
-                except (configparser.NoSectionError, configparser.NoOptionError):
-                    self.collector[collectorNumber]['frequency_limit'] = 0
-
-                try:
-                    saveFastPackets = configParser.get(
-                        'collector' + str(collectorNumber), 'save_fast_packets').strip('"')
-                    self.collector[collectorNumber]['save_fast_packets'] = bool(
-                        int(saveFastPackets))
-                except (configparser.NoSectionError, configparser.NoOptionError):
-                    self.collector[collectorNumber]['save_fast_packets'] = False
-
-                try:
-                    detectDuplicates = configParser.get(
-                        'collector' + str(collectorNumber), 'detect_duplicates').strip('"')
-                    self.collector[collectorNumber]['detect_duplicates'] = bool(
-                        int(detectDuplicates))
-                except (configparser.NoSectionError, configparser.NoOptionError):
-                    self.collector[collectorNumber]['detect_duplicates'] = False
-
-                self.collector[collectorNumber]['error_log'] = configParser.get(
-                    'collector' + str(collectorNumber), 'error_log').strip('"')
-
-                if (self.websocketAprsSourceId1 == 5 or self.websocketAprsSourceId2 == 5) :
-                    # source is of type OGN, make sure we do not save to many packets (will cause to high load on db)
-                    if (self.collector[collectorNumber]['frequency_limit'] < 10) :
-                        self.collector[collectorNumber]['frequency_limit'] = 10
-                    self.collector[collectorNumber]['save_fast_packets'] = False
-
-
-            except (configparser.NoSectionError, configparser.NoOptionError):
-                self.collector[collectorNumber]['source_id'] = None
-                self.collector[collectorNumber]['host'] = None
-                self.collector[collectorNumber]['port_full'] = None
-                self.collector[collectorNumber]['port_filtered'] = None
-
-                self.collector[collectorNumber]['callsign'] = None
-                self.collector[collectorNumber]['passcode'] = None
-
-                self.collector[collectorNumber]['numbers_in_batch'] = "20"
-                self.collector[collectorNumber]['frequency_limit'] = "0"
-                self.collector[collectorNumber]['save_fast_packets'] = True
-                self.collector[collectorNumber]['detect_duplicates'] = False
-
-                self.collector[collectorNumber]['error_log'] = None
diff --git a/server/trackdirect/TrackDirectDataCollector.py b/server/trackdirect/TrackDirectDataCollector.py
deleted file mode 100644
index 63959b197bf4dfc6724add2bfb144516423d34be..0000000000000000000000000000000000000000
--- a/server/trackdirect/TrackDirectDataCollector.py
+++ /dev/null
@@ -1,524 +0,0 @@
-import logging
-import psycopg2
-import psycopg2.extras
-import re
-import aprslib
-import datetime
-import time
-from twisted.internet import reactor, threads
-
-from trackdirect.parser.AprsPacketParser import AprsPacketParser
-from trackdirect.parser.AprsISConnection import AprsISConnection
-from trackdirect.parser.policies.PacketDuplicatePolicy import PacketDuplicatePolicy
-from trackdirect.collector.PacketBatchInserter import PacketBatchInserter
-from trackdirect.exceptions.TrackDirectParseError import TrackDirectParseError
-from trackdirect.database.DatabaseConnection import DatabaseConnection
-from trackdirect.repositories.StationRepository import StationRepository
-
-#from pympler.tracker import SummaryTracker
-
-class TrackDirectDataCollector():
-    """An TrackDirectDataCollector instance connects to the data source and saves all received packets to the database
-
-    Note:
-        The collector class is built to handle ONE connection to a data source server (may be a APRS-IS server), if two is wanted run two processes.
-        This is useful if you want one connection to the regular APRS-IS network and one connection to the CWOP network.
-    """
-
-    def __init__(self, collectorOptions, saveOgnStationsWithMissingIdentity):
-        """The __init__ method.
-
-        Args:
-            collectorOptions (dict):                       Contains data like host, port, callsign, passcode, source id
-            saveOgnStationsWithMissingIdentity (boolean):  True if we should not ignore stationss with a missing identity
-        """
-        self.saveOgnStationsWithMissingIdentity = saveOgnStationsWithMissingIdentity
-        self.sourceHostname = collectorOptions['host']
-        self.sourcePort = collectorOptions['port_full']
-        self.numbersInBatch = collectorOptions['numbers_in_batch']
-        self.saveFastPackets = collectorOptions['save_fast_packets']
-        self.frequencyLimit = collectorOptions['frequency_limit']
-        self.detectDuplicates = collectorOptions['detect_duplicates']
-        self.hardFrequencyLimit = None
-        if (not self.saveFastPackets and self.frequencyLimit is not None and int(self.frequencyLimit) > 0):
-            # Only respect hard frequency limit if we are not saving "fast packets"
-            self.hardFrequencyLimit = self.frequencyLimit
-        self.sourceId = collectorOptions['source_id']
-        self.callsign = collectorOptions['callsign']
-        self.passcode = collectorOptions['passcode']
-
-        dbConnection = DatabaseConnection()
-        self.db = dbConnection.getConnection(True)
-        self.dbNoAutoCommit = dbConnection.getConnection(False)
-
-        self.stationRepository = StationRepository(self.db)
-        self.logger = logging.getLogger(__name__)
-
-        self.latestPacketTimestamp = None
-        self.firstPacketTimestamp = None
-        self.latestBatchInsertTimestamp = int(time.time())
-
-        self.packets = []
-        self.stationIdsWithVisiblePacket = []
-        self.movingStationIdsWithVisiblePacket = []
-        self.movingMarkerIdsWithVisiblePacket = []
-        self.delay = 0
-
-    def run(self):
-        """Start the collector
-        """
-        threads.deferToThread(self.consume)
-        # reactor.suggestThreadPoolSize(20)
-        reactor.run()
-
-    def consume(self):
-        """Start consuming packets
-        """
-
-        #tracker = SummaryTracker()
-
-        connection = AprsISConnection(
-            self.callsign, self.passcode, self.sourceHostname, self.sourcePort)
-        connection.setFrequencyLimit(self.hardFrequencyLimit)
-        connection.setSourceId(self.sourceId)
-
-        def onPacketRead(line):
-            if (not reactor.running):
-                raise StopIteration('Stopped')
-
-            timestamp = int(time.time())
-            deferred = threads.deferToThread(self._parse, line, timestamp)
-            deferred.addCallback(onParseComplete)
-            deferred.addErrback(onParseError)
-
-        def onParseComplete(packet):
-            reactor.callFromThread(self._addPacket, packet)
-
-        def onParseError(error):
-            # Parse will more or less only cast exception if db connection is lost
-
-            # Force restart of collector (we assume that server will be autostarted if stopped)
-            if reactor.running:
-                reactor.stop()
-            raise error
-
-        try:
-            connection.connect()
-            connection.filteredConsumer(onPacketRead, True, True)
-
-            #tracker.print_diff()
-
-        except (aprslib.ConnectionDrop) as exp:
-            # Just reconnect...
-            self.logger.warning('Lost connection')
-            self.logger.warning(exp)
-            self.consume()
-
-        except Exception as e:
-            self.logger.error(e)
-
-            # Force restart of collector
-            if reactor.running:
-                reactor.stop()
-
-    def _parse(self, line, timestamp):
-        """Parse raw packet
-
-        Args:
-            line (string):     APRS raw packet string
-            timestamp (int):   Receive time of packet
-
-        Returns:
-            Returns a Packet
-        """
-        try:
-            self.delay = int(time.time())-timestamp
-            if (self.delay > 60):
-                self.logger.error(
-                    'Collector has a delay on %s seconds, ignoring packets until solved', self.delay)
-                return None
-            elif (self.delay > 15):
-                self.logger.warning(
-                    'Collector has a delay on %s seconds', self.delay)
-
-            packetDict = aprslib.parse(line)
-            parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
-            parser.setSourceId(self.sourceId)
-            packet = parser.getPacket(packetDict, timestamp)
-
-            if (packet.mapId == 15 or packet.mapId == 16):
-                return None
-
-            if (self.detectDuplicates):
-                self._checkIfDuplicate(packet)
-
-            return self._cleanPacket(packet)
-
-        except (aprslib.ParseError, aprslib.UnknownFormat, TrackDirectParseError) as exp:
-            return self._parseUnsupportedPacket(line, timestamp)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just exit
-            raise e
-        except (UnicodeDecodeError) as exp:
-            # just forget about this packet
-            pass
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-        return None
-
-    def _parseUnsupportedPacket(self, line, timestamp):
-        """Try to parse raw packet that aprs-lib could not handle
-
-        Args:
-            line (string):     APRS raw packet string
-            timestamp (int):   Receive time of packet
-
-        Returns:
-            Returns a Packet
-        """
-        try:
-            line = line.decode('utf-8', 'ignore')
-            packetDict = self.basicParse(line)
-            parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
-            parser.setSourceId(self.sourceId)
-            packet = parser.getPacket(packetDict, timestamp, True)
-            packet.markerId = 1
-
-            if (packet.packetTypeId == 6): # Telemetry packet
-                packet.packetTypeId = 10 # Has no position
-            else:
-                packet.mapId = 11 # Unsupported packet
-
-            return packet
-        except Exception as e:
-            self.logger.debug(e)
-            self.logger.debug(line)
-        return None
-
-    def _addPacket(self, packet):
-        """Adds packet to database
-
-        Args:
-            packet (Packet):   The packet
-        """
-        if (packet is None):
-            return
-
-        # Soft frequency limit check
-        if (self._isStationSendingToFast(packet)):
-            if (not self.saveFastPackets):
-                return
-
-            packet.markerId = 1
-            packet.mapId = 8
-
-            # Reset all mapId related values
-            packet.replacePacketId = None
-            packet.abnormalPacketId = None
-            packet.confirmPacketId = None
-            packet.replacePacketTimestamp = None
-            packet.abnormalPacketTimestamp = None
-            packet.confirmPacketTimestamp = None
-
-        if (packet.mapId == 6):
-            # Packet received in wrong order
-            if (not self.saveFastPackets):
-                return
-
-        if (not self._isPacketValidInCurrentBatch(packet)):
-            self._insertBatch()
-
-        if (self._shouldPacketBeAdded(packet)):
-            self._addPacketToBatch(packet)
-
-        if (self._isBatchFull()):
-            self._insertBatch()
-
-        if (self._isBatchOld()):
-            self._insertBatch()
-
-    def _isStationSendingToFast(self, packet):
-        """Returns true if this packet has been sent to close to previous packet from the same station (we need to save previous packet first)
-
-        Args:
-            packet (Packet) :  The packet that may have been sent to fast
-
-        Returns:
-            Boolean
-        """
-        if (packet.mapId in [1, 5, 7, 9] and packet.isMoving == 1 and self.frequencyLimit is not None):
-            frequencyLimitToApply = int(self.frequencyLimit)
-
-            if (frequencyLimitToApply == 0):
-                return False
-
-            if (packet.ogn is not None and packet.ogn.ognTurnRate is not None):
-                turnRate = abs(float(packet.ogn.ognTurnRate))
-                if (turnRate > 0) :
-                    frequencyLimitToApply = int(frequencyLimitToApply / (1+turnRate))
-
-            if packet.markerPrevPacketTimestamp:
-                if ((packet.timestamp - frequencyLimitToApply) < packet.markerPrevPacketTimestamp):
-                    # This station is sending faster than config limit
-                    return True
-
-            if (packet.stationId in self.movingStationIdsWithVisiblePacket):
-                # This station is sending way to fast (we havn't even added the previous packet to database yet)
-                return True
-
-            if (packet.markerId in self.movingMarkerIdsWithVisiblePacket):
-                # The senders of this object is sending way to fast (we havn't even added the previous packet to database yet)
-                return True
-        return False
-
-    def _isPacketValidInCurrentBatch(self, packet):
-        """Returns true if this packet can be added to current batch
-
-        Args:
-            packet (Packet) :  The packet that e want to add to current batch
-
-        Returns:
-            Boolean
-        """
-        if (self.latestPacketTimestamp is not None):
-            # If previous packet belongs to another date we can not add packet to current batch
-            currentPacketDate = datetime.datetime.utcfromtimestamp(
-                int(packet.timestamp)).strftime('%Y%m%d')
-            latestPacketDate = datetime.datetime.utcfromtimestamp(
-                self.latestPacketTimestamp).strftime('%Y%m%d')
-
-            if (currentPacketDate != latestPacketDate and len(self.packets) > 0):
-                return False
-
-        if (packet.stationId in self.stationIdsWithVisiblePacket):
-            # We only want to handle one packet per station per batch
-            return False
-
-        return True
-
-    def _shouldPacketBeAdded(self, packet):
-        """Returns true if this packet should be added to database
-
-        Args:
-            packet (Packet) :  The packet that we want to add to batch
-
-        Returns:
-            Boolean
-        """
-        if (packet.sourceId != 3 or packet.stationIdPath):
-            # We only add pure duplicates to batch if they have a path, otherwise we are not interested
-            return True
-        return False
-
-    def _isBatchFull(self):
-        """Returns true if batch is considered full
-
-        Returns:
-            Boolean
-        """
-        # If we do insert when we have specified amount of packets (or if more than 5s has passed)
-        if (int(len(self.packets)) > int(self.numbersInBatch)):
-            return True
-        elif (len(self.packets) > 0 and self.latestBatchInsertTimestamp < int(time.time()) - 5):
-            return True
-        return False
-
-    def _isBatchOld(self):
-        """Returns true if batch is considered old
-
-        Returns:
-            Boolean
-        """
-        if (self.latestPacketTimestamp is not None
-                and self.firstPacketTimestamp is not None
-                and self.latestPacketTimestamp - self.firstPacketTimestamp > 1):
-            return True
-        return False
-
-    def _addPacketToBatch(self, packet):
-        """Add instance of ParsedPacket to batch
-
-        Args:
-            packet (Packet):  Packet that we want to add to batch
-        """
-        self.latestPacketTimestamp = int(packet.timestamp)
-        if (self.firstPacketTimestamp is None):
-            self.firstPacketTimestamp = int(packet.timestamp)
-        self.packets.append(packet)
-        if (packet.mapId in [1, 5, 7, 9]):
-            self.stationIdsWithVisiblePacket.append(packet.stationId)
-            if (packet.isMoving == 1):
-                self.movingStationIdsWithVisiblePacket.append(packet.stationId)
-                self.movingMarkerIdsWithVisiblePacket.append(packet.markerId)
-
-    def _insertBatch(self):
-        """Perform insert on the current batch
-        """
-        if (len(self.packets) > 0):
-            self.latestBatchInsertTimestamp = int(time.time())
-
-            # Make sure packets is inserted in the order that they where received
-            self.packets.reverse()
-
-            # Do batch insert
-            packetBatchInserter = PacketBatchInserter(
-                self.db, self.dbNoAutoCommit)
-            packetBatchInserter.insert(self.packets[:], self.sourceId)
-
-            self._reset()
-
-    def _reset(self):
-        """Reset all collector variables
-        """
-        self.packets = []
-        self.stationIdsWithVisiblePacket = []
-        self.movingStationIdsWithVisiblePacket = []
-        self.movingMarkerIdsWithVisiblePacket = []
-        self.latestPacketTimestamp = None
-        self.firstPacketTimestamp = None
-
-    def _cleanPacket(self, packet):
-        """Method used to clean a Packet from unused columns
-
-        Args:
-            packet (Packet): Object of class Packet
-
-        Returns:
-            Returns a packet (cleaned)
-        """
-        if (packet.mapId not in [1, 5, 7, 9]):
-            # This packet will never be shown on map, remove information that won't be used (just to save some space in database)
-            packet.markerId = None
-            packet.markerCounter = None
-            packet.packetTailTimestamp = None
-            packet.positionTimestamp = None
-            packet.posambiguity = None
-            packet.symbol = None
-            packet.symbolTable = None
-            packet.mapSector = None
-            packet.relatedMapSectors = None
-            packet.speed = None
-            packet.course = None
-            packet.altitude = None
-            packet.isMoving = 1
-        return packet
-
-    def _checkIfDuplicate(self, packet):
-        """Method used to check if this packet is a duplicate
-
-        Note:
-            If packet is a duplicate the object attribute mapId will be updated, and some related attributes.
-
-        Args:
-            packet (Packet): Object of class Packet
-        """
-        packetDuplicatePolicy = PacketDuplicatePolicy(self.stationRepository)
-        if (packetDuplicatePolicy.isDuplicate(packet)):
-            # It is a duplicate (or at least we treat it as one just to be safe)
-            packet.mapId = 3
-            packet.markerId = 1
-            packet.replacePacketId = None  # No older packet should be replaced!!!
-            packet.replacePacketTimestamp = None
-            packet.abnormalPacketId = None  # Do not mark previous as abnormal yet
-            packet.abnormalPacketTimestamp = None
-            packet.confirmPacketId = None  # Do not confirm previous position
-            packet.confirmPacketTimestamp = None
-
-    def basicParse(self, line):
-        """Performes a basic packet parse and returnes result as a dict
-
-        Args:
-            line (string):  Packet raw string
-
-        Returns:
-            Returns packet dict
-        """
-        # Divide into body and head
-        try:
-            (head, body) = line.split(':', 1)
-        except:
-            raise TrackDirectParseError("no body", {})
-
-        if len(body) == 0:
-            raise TrackDirectParseError("body is empty", {})
-
-        packetType = body[0]
-        body = body[1:]
-
-        # Find sender, destination and path in header
-        try:
-            (fromcall, path) = head.split('>', 1)
-        except:
-            raise TrackDirectParseError("no header", {})
-
-        if (not 1 <= len(fromcall) <= 9):
-            raise TrackDirectParseError("fromcallsign has invalid length", {})
-
-        path = path.split(',')
-        tocall = path[0]
-
-        if len(tocall) == 0:
-            tocall = None
-
-        path = path[1:]
-
-        for station in path:
-            if not re.findall(r"^[A-Z0-9\-]{1,9}\*?$", station, re.I):
-                path = None
-                break
-
-        objectName = ''
-        if packetType == ';':
-            match = re.findall(r"^([ -~]{9})(\*|_)", body)
-            if match:
-                name, flag = match[0]
-                objectName = name
-                body = body[10:]
-
-        if packetType == ')':
-            match = re.findall(r"^([ -~!]{3,9})(\!|_)", body)
-            if match:
-                name, flag = match[0]
-                objectName = name
-                body = body[len(name)+1:]
-
-        comment = None
-        telemetry = None
-        if packetType == 'T':
-            telemetry = {}
-            lst = body.split(',')
-            if len(lst) >= 7 :
-                seq = body.split(',')[0]
-                vals = body.split(',')[1:6]
-                bits = body.split(',')[6][:8]
-                comment = body.split(',')[6][8:]
-
-                if seq.startswith('T'):
-                    seq = seq[1:]
-                if seq.startswith('#'):
-                    seq = seq[1:]
-
-                for i in range(5):
-                    try:
-                        vals[i] = float(vals[i]) if vals[i] != '' else None
-                    except ValueError:
-                        vals[i] = None
-
-                telemetry = {
-                    'seq': seq,
-                    'vals': vals,
-                    'bits': bits
-                }
-
-        # Create result
-        packet = {
-            'from': fromcall,
-            'to': tocall,
-            'path': path,
-            'raw': line,
-            'object_name': objectName,
-            'packet_type': packetType,
-            'telemetry': telemetry,
-            'comment': comment
-        }
-        return packet
diff --git a/server/trackdirect/TrackDirectWebsocketServer.py b/server/trackdirect/TrackDirectWebsocketServer.py
deleted file mode 100644
index fe9a0706c957f011ea84cdbd05a2e63dfc0aa1b0..0000000000000000000000000000000000000000
--- a/server/trackdirect/TrackDirectWebsocketServer.py
+++ /dev/null
@@ -1,434 +0,0 @@
-import logging
-
-from twisted.internet import threads, reactor, task
-from twisted.internet.error import AlreadyCancelled, AlreadyCalled
-
-from autobahn.twisted.websocket import WebSocketServerProtocol
-
-import json
-import time
-import psycopg2
-import psycopg2.extras
-import os
-import trackdirect
-from trackdirect.database.DatabaseConnection import DatabaseConnection
-
-from trackdirect.websocket.WebsocketResponseCreator import WebsocketResponseCreator
-from trackdirect.websocket.WebsocketConnectionState import WebsocketConnectionState
-
-from trackdirect.websocket.aprsis.AprsISReader import AprsISReader
-from trackdirect.websocket.aprsis.AprsISPayloadCreator import AprsISPayloadCreator
-
-
-class TrackDirectWebsocketServer(WebSocketServerProtocol):
-    """The TrackDirectWebsocketServer class handles the incoming requests
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-        WebSocketServerProtocol.__init__(self)
-        self.logger = logging.getLogger('trackdirect')
-
-        self.config = trackdirect.TrackDirectConfig()
-        self.maxClientIdleTime = int(self.config.maxClientIdleTime) * 60
-        self.maxQueuedRealtimePackets = int(
-            self.config.maxQueuedRealtimePackets)
-
-        dbConnection = DatabaseConnection()
-        db = dbConnection.getConnection(True)
-
-        self.connectionState = WebsocketConnectionState()
-        self.responseCreator = WebsocketResponseCreator(
-            self.connectionState, db)
-        self.aprsISReader = AprsISReader(self.connectionState, db)
-        self.aprsISPayloadCreator = AprsISPayloadCreator(
-            self.connectionState, db)
-
-        self.numberOfRealTimePacketThreads = 0
-        self.timestampSenderCall = None
-        self.realTimeListenerCall = None
-        self.onInactiveCall = None
-        self.isUnknownClient = False
-
-    def onConnect(self, request):
-        """Method that is executed on connect
-
-        Args:
-            request (object):  The connection request
-        """
-        try:
-            if ('x-forwarded-for' in request.headers):
-                self.logger.warning("Client connecting from origin: {0}, x-forwarded-for: {1} (server pid {2})".format(
-                    request.origin, request.headers['x-forwarded-for'], str(os.getpid())))
-            else:
-                self.logger.warning(
-                    "Client connecting from origin: {0} (server pid {1})".format(request.origin, str(os.getpid())))
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-            raise e
-
-    def onOpen(self):
-        """Method that is executed on open
-        """
-        try:
-            self.logger.info("WebSocket connection open.")
-
-            self._sendResponseByType(42)  # Inform client that we are active
-            self._startTimestampSender()
-            self._reScheduleInactiveEvent()
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-    def onMessage(self, payload, isBinary):
-        """Method that is executed on incoming message
-
-        Args:
-            request (object):   The connection request
-            isBinary (boolean): True if binary otherwise false
-        """
-        try:
-            request = json.loads(payload)
-            if (self.isUnknownClient):
-                self.logger.warning(
-                    "Incoming message from unknown client: {0}".format(str(request)))
-
-            if ("payload_request_type" not in request):
-                self.logger.warning(
-                    "Incoming request has no type (%s)" % (exp))
-                self.logger.warning(payload)
-                return
-            self._onRequest(request)
-        except (ValueError) as exp:
-            self.logger.warning(
-                "Incoming request could not be parsed (%s)" % (exp))
-            self.logger.warning(payload)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def onClose(self, wasClean, code, reason):
-        """Method that is executed on close
-
-        Args:
-            wasClean (boolean):  True if clean close otherwise false
-            code (int):          Close code
-            reason (object):     Reason for close
-        """
-        try:
-            self.logger.info("WebSocket connection closed: {0}".format(reason))
-            self.connectionState.disconnected = True
-            self._stopTimestampSender()
-            self._stopRealTimeListener(True)
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _onRequest(self, request, requestId=None):
-        """Method that is executed on incoming request
-
-        Args:
-            request (object):   The connection request
-            requestId (int):    Id of the request
-        """
-        if (request["payload_request_type"] != 11):
-            self._reScheduleInactiveEvent()
-
-        if (request["payload_request_type"] in [5, 7, 9]):
-            # Request that not affects the current map status (to much)
-            deferred = threads.deferToThread(
-                self._processRequest, request, None)
-            deferred.addErrback(self._onError)
-
-        else:
-            # Request that affects map and current state
-            if (requestId is None):
-                requestId = self.connectionState.latestRequestId + 1
-                self.connectionState.latestRequestType = request["payload_request_type"]
-                self.connectionState.latestRequestId = requestId
-                self.connectionState.latestRequestTimestamp = int(time.time())
-                self._stopRealTimeListener(False)
-
-            if (self.connectionState.latestHandledRequestId < requestId - 1):
-                reactor.callLater(0.1, self._onRequest, request, requestId)
-            else:
-                self._updateState(request)
-
-                deferred = threads.deferToThread(
-                    self._processRequest, request, requestId)
-                deferred.addErrback(self._onError)
-                deferred.addCallback(self._onRequestDone)
-
-    def _processRequest(self, request, requestId):
-        """Method that sends a response to websocket client based on request
-
-        Args:
-            request (Dict):   Request from websocket client
-            requestId (int):   Request id of processed request
-        """
-        try:
-            for response in self.responseCreator.getResponses(request, requestId):
-                if self.connectionState.disconnected:
-                    break
-                reactor.callFromThread(self._sendDictResponse, response)
-            return requestId
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _onRequestDone(self, requestId):
-        """Method that is executed when request is processed
-
-        Args:
-            requestId (int):   Request id of processed request
-        """
-        try:
-            if (self.connectionState.latestHandledRequestId < requestId):
-                self.connectionState.latestHandledRequestId = requestId
-            if (self.connectionState.latestRequestId == requestId):
-                # We have no newer requests
-                # Tell client response is complete
-                self._sendResponseByType(35)
-
-                if (self.connectionState.latestTimeTravelRequest is None
-                        and self.connectionState.noRealTime is False
-                        and self.connectionState.isValidLatestPosition()):
-                    self._startRealTimeListener(requestId)
-
-                elif ((int(time.time()) - self.connectionState.latestRequestTimestamp) <= self.maxClientIdleTime):
-                    self._sendResponseByType(33)  # Tell client we are idle
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _onError(self, error):
-        """Method that is executed when a deferToThread failed
-
-        Args:
-            error (Exception):   The Exception
-        """
-        # Exception should only end up here if db connection is lost
-        # Force restart of wsserver
-        if reactor.running:
-            reactor.stop()
-        raise error
-
-    def _startRealTimeListener(self, relatedRequestId):
-        """Start real time APRS-IS listener, onRealTimePacketFound will be executed when a packet is received
-
-        Args:
-            relatedRequestId (int):   Request id of related request
-        """
-        def readRealTimePacket():
-            if (self.connectionState.latestRequestId == relatedRequestId and not self.connectionState.disconnected):
-                self.aprsISReader.read(onRealTimePacketFound)
-
-        def onRealTimePacketComplete():
-            self.numberOfRealTimePacketThreads -= 1
-            if (self.numberOfRealTimePacketThreads <= 0):
-                # If we have no packets on the way we should see if we have another waiting
-                readRealTimePacket()
-
-        def onRealTimePacketFound(raw, sourceId):
-            if (raw is None and sourceId is None):
-                # Something went wrong, stop everything
-                self._onInactive()
-            else:
-                if (self.numberOfRealTimePacketThreads > self.maxQueuedRealtimePackets):
-                    # To many packets, several previous LoopingCall's is not done yet.
-                    # We need to discard some packets, otherwise server will be overloaded and we will only send old packets.
-                    # Client is required to request total update now and then, so the discarded packets should be send to client later.
-
-                    counter = self.aprsISReader.clear(5)
-                    #self.logger.warning('Discarding ' + str(counter) + ' packets')
-                else:
-                    self.numberOfRealTimePacketThreads += 1
-                    deferred = threads.deferToThread(
-                        self._processRealTimePacket, raw, sourceId)
-                    deferred.addCallback(lambda _: onRealTimePacketComplete())
-                    deferred.addErrback(self._onError)
-
-        # Tell client we are connecting to real time feed
-        self._sendResponseByType(34)
-        self.aprsISReader.start()  # Will start if needed and change filter if needed
-        # Tell client we are listening on real time feed
-        self._sendResponseByType(31)
-
-        self.realTimeListenerCall = task.LoopingCall(readRealTimePacket)
-        self.realTimeListenerCall.start(0.2)
-
-    def _stopRealTimeListener(self, disconnect=False):
-        """Stop real time APRS-IS listener, onRealTimePacketFound will be executed when a packet is received
-
-        Args:
-            disconnect (Boolean):   Set to true to also disconnect from APRS-IS servers
-        """
-        if (self.realTimeListenerCall is not None):
-            try:
-                self.realTimeListenerCall.stop()
-            except (AlreadyCalled, AssertionError) as e:
-                pass
-
-            if (disconnect):
-                self.aprsISReader.stop()
-            else:
-                self.aprsISReader.pause()
-
-    def _processRealTimePacket(self, raw, sourceId):
-        """Method that is executed when we have a new real time packet to send
-
-        Args:
-            raw (string):    Raw packet from APRS-IS
-            sourceId (int):  The id of the source (1 for APRS and 2 for CWOP ...)
-        """
-        try:
-            for response in self.aprsISPayloadCreator.getPayloads(raw, sourceId):
-                reactor.callFromThread(self._sendDictResponse, response)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _startTimestampSender(self):
-        """Method schedules call to _sendTimestampResponse to keep connection up
-        """
-        self.timestampSenderCall = task.LoopingCall(
-            self._sendTimestampResponse)
-        self.timestampSenderCall.start(1.0)
-
-    def _stopTimestampSender(self):
-        """Stop looping call to _sendTimestampResponse
-        """
-        if (self.timestampSenderCall is not None):
-            try:
-                self.timestampSenderCall.stop()
-            except AssertionError as e:
-                pass
-
-    def _reScheduleInactiveEvent(self):
-        """Method schedules call to _onInactive when client has been idle too long
-
-        Note:
-            When _reScheduleInactiveEvent is called any previous schedules will be cancelled and countdown will be reset
-        """
-        if (self.onInactiveCall is not None):
-            try:
-                self.onInactiveCall.cancel()
-            except (AlreadyCalled, AlreadyCancelled) as e:
-                pass
-        self.onInactiveCall = reactor.callLater(
-            self.maxClientIdleTime, self._onInactive)
-
-    def _onInactive(self):
-        """Method that is executed when client has been inactive too long
-        """
-        try:
-            # Client is inactive, pause (to save bandwidth, cpu and memory)
-            self._sendResponseByType(36)
-            self._stopTimestampSender()
-            self._stopRealTimeListener(True)
-            self.connectionState.totalReset()
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _sendTimestampResponse(self):
-        """Send server timestamp to syncronize server and client
-
-        Notes:
-            This is also used to tell the client that we are still here
-            Most browser will disconnect if they do not hear anything in 300sec
-        """
-        try:
-            if (self.connectionState.latestHandledRequestId < self.connectionState.latestRequestId):
-                # server is busy with request, no point in doing this now
-                return
-            data = {}
-            data["timestamp"] = int(time.time())
-            self._sendResponseByType(41, data)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.error(e, exc_info=1)
-
-    def _sendResponseByType(self, payloadResponseType, data=None):
-        """Send specified response to client
-
-        Args:
-            payloadResponseType (int):  A number that specifies what type of response we are sending
-            data (dict):                The response data as a dict
-        """
-        if (data is not None):
-            payload = {
-                'payload_response_type': payloadResponseType, 'data': data}
-        else:
-            payload = {'payload_response_type': payloadResponseType}
-        self._sendDictResponse(payload)
-
-    def _sendDictResponse(self, payload):
-        """Send message dict payload to client
-
-        Args:
-            payload (Dict):  Response payload
-        """
-        try:
-            jsonPayload = json.dumps(payload, ensure_ascii=True).encode('utf8')
-            if (jsonPayload is not None):
-                self.sendMessage(jsonPayload)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just terminate connection to make user reconnect with new db connection
-            self.logger.error(e, exc_info=1)
-            raise e
-        except Exception as e:
-            # Log error to make us aware of unknow problem
-            self.logger.warning(e, exc_info=1)
-
-    def _updateState(self, request):
-        """Update the connection state based on request
-
-        Args:
-            request (Dict):    Request form client
-        """
-        if ("neLat" in request
-                and "neLng" in request
-                and "swLat" in request
-                and "swLng" in request
-                and "minutes" in request):
-            self.connectionState.setLatestMapBounds(
-                request["neLat"], request["neLng"], request["swLat"], request["swLng"])
-
-        if ("onlyLatestPacket" in request):
-            self.connectionState.setOnlyLatestPacketRequested(
-                (request["onlyLatestPacket"] == 1))
-
-        if ("minutes" in request):
-            if ("time" in request):
-                self.connectionState.setLatestMinutes(
-                    request["minutes"], request["time"])
-            else:
-                self.connectionState.setLatestMinutes(request["minutes"], None)
-
-        if ("noRealTime" in request):
-            self.connectionState.disableRealTime()
diff --git a/server/trackdirect/__init__.py b/server/trackdirect/__init__.py
deleted file mode 100644
index 27c9b557ec18ba62184bcaf63c90ac1d8b8606d3..0000000000000000000000000000000000000000
--- a/server/trackdirect/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
-
-from TrackDirectDataCollector import *
-from TrackDirectWebsocketServer import *
-from TrackDirectConfig import *
diff --git a/server/trackdirect/collector/PacketBatchInserter.py b/server/trackdirect/collector/PacketBatchInserter.py
deleted file mode 100644
index a0899d440a0d3e113ce343b5e5abb7b7d28b14c9..0000000000000000000000000000000000000000
--- a/server/trackdirect/collector/PacketBatchInserter.py
+++ /dev/null
@@ -1,425 +0,0 @@
-import logging
-import psycopg2
-import psycopg2.extras
-
-from trackdirect.collector.StationLatestPacketModifier import StationLatestPacketModifier
-from trackdirect.collector.PacketMapIdModifier import PacketMapIdModifier
-
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-from trackdirect.database.PacketPathTableCreator import PacketPathTableCreator
-from trackdirect.database.PacketWeatherTableCreator import PacketWeatherTableCreator
-from trackdirect.database.PacketTelemetryTableCreator import PacketTelemetryTableCreator
-from trackdirect.database.PacketOgnTableCreator import PacketOgnTableCreator
-
-
-class PacketBatchInserter():
-    """PacketBatchInserter is used to add a list of packets to the database
-    """
-
-    def __init__(self, db, dbNoAutoCommit):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):              Database connection (with autocommit)
-            dbNoAutoCommit (psycopg2.Connection):  Database connection (without autocommit)
-        """
-        self.db = db
-        self.dbNoAutoCommit = dbNoAutoCommit
-        self.logger = logging.getLogger(__name__)
-
-        self.packetIdList = []
-        self.weatherPacketIdList = []
-        self.ognPacketIdList = []
-        self.telemetryPacketIdList = []
-        self.pathPacketIdList = []
-        self.positionPacketIdList = []
-        self.confirmedPositionPacketIdList = []
-
-    def insert(self, packets, sourceId):
-        """Insert this packets into database
-
-        Args:
-            packets (array):  Packets to insert
-            sourceId (int):   Id that corresponds to id in source-table
-        """
-        cur = self.dbNoAutoCommit.cursor()
-        try:
-            # Make sure needed tables exists before starting the main database transaction
-            self._makeSureTablesExists(packets)
-
-            # insert telemetry data
-            self._insertTelemetryDefinitions(packets)
-
-            # Update mapId on previous packets
-            packetTableCreator = PacketTableCreator(self.db)
-            packetMapIdModifier = PacketMapIdModifier(cur, packetTableCreator)
-            packetMapIdModifier.execute(packets)
-
-            # insert into packet (and packet_path ...)
-            self._insertIntoPacketTables(packets, cur)
-
-            self.dbNoAutoCommit.commit()
-            cur.close()
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just exit
-            self.dbNoAutoCommit.rollback()
-            cur.close()
-            raise e
-        except Exception as e:
-            # Something went wrong
-            self.logger.error(e, exc_info=1)
-            self.dbNoAutoCommit.rollback()
-            cur.close()
-            return
-        self._performPostInsertActions(packets)
-
-    def _makeSureTablesExists(self, packets):
-        """Make sures all tables needed to insert specified packets exists
-
-        Args:
-            packets (array):  Packets to insert
-        """
-        timestamp = packets[0].timestamp  # All packets is known to be on the same date
-
-        packetTableCreator = PacketTableCreator(self.db)
-        packetTable = packetTableCreator.getPacketTable(timestamp)
-
-        packetPathTableCreator = PacketPathTableCreator(self.db)
-        packetPathTable = packetPathTableCreator.getPacketPathTable(timestamp)
-
-        packetWeatherTableCreator = PacketWeatherTableCreator(self.db)
-        packetWeatherTable = packetWeatherTableCreator.getPacketWeatherTable(
-            timestamp)
-
-        packetTelemetryTableCreator = PacketTelemetryTableCreator(self.db)
-        packetTelemetryTable = packetTelemetryTableCreator.getPacketTelemetryTable(
-            timestamp)
-
-        packetOgnTableCreator = PacketOgnTableCreator(self.db)
-        packetOgnTable = packetOgnTableCreator.getPacketOgnTable(timestamp)
-
-    def _performPostInsertActions(self, packets):
-        """Perform post insert updates like updating station latest packet and related
-
-        Args:
-            packets (array):  Packets to insert
-        """
-        timestamp = packets[0].timestamp
-        latestPacketModifier = StationLatestPacketModifier(self.db)
-        latestPacketModifier.updateStationLatestPacket(
-            self.packetIdList, timestamp)
-        latestPacketModifier.updateStationLatestTelemetryPacket(
-            self.telemetryPacketIdList, timestamp)
-        latestPacketModifier.updateStationLatestWeatherPacket(
-            self.weatherPacketIdList, timestamp)
-        latestPacketModifier.updateStationLatestOgnPacket(
-            self.ognPacketIdList, timestamp)
-        latestPacketModifier.updateStationLatestLocationPacket(
-            self.positionPacketIdList, timestamp)
-        latestPacketModifier.updateStationLatestConfirmedPacket(
-            self.confirmedPositionPacketIdList, timestamp)
-
-    def _insertIntoPacketTables(self, packets, cur):
-        """Insert packets into the correct packet tables
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        self._insertIntoPacketTable(packets, cur)
-        self._insertIntoPacketPathTable(packets, cur)
-        self._insertIntoPacketWeatherTable(packets, cur)
-        self._insertIntoPacketOgnTable(packets, cur)
-        self._insertIntoPacketTelemetryTable(packets, cur)
-
-    def _insertIntoPacketTable(self, packets, cur):
-        """Insert packets into the correct packet table
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        timestamp = packets[0].timestamp
-        packetTableCreator = PacketTableCreator(self.db)
-        packetTable = packetTableCreator.getPacketTable(timestamp)
-
-        datePacketTuples = []
-        for packet in packets:
-
-            datePacketTuples.append((packet.stationId,
-                                     packet.senderId,
-                                     packet.mapId,
-                                     packet.sourceId,
-                                     packet.packetTypeId,
-                                     packet.latitude,
-                                     packet.longitude,
-                                     packet.posambiguity,
-                                     packet.symbol,
-                                     packet.symbolTable,
-                                     packet.mapSector,
-                                     packet.relatedMapSectors,
-                                     packet.markerId,
-                                     packet.markerCounter,
-                                     packet.speed,
-                                     packet.course,
-                                     packet.altitude,
-                                     packet.rng,
-                                     packet.phg,
-                                     packet.latestPhgTimestamp,
-                                     packet.latestRngTimestamp,
-                                     packet.timestamp,
-                                     packet.packetTailTimestamp,
-                                     packet.isMoving,
-                                     packet.reportedTimestamp,
-                                     packet.positionTimestamp,
-                                     packet.comment,
-                                     packet.rawPath,
-                                     packet.raw))
-
-        try:
-            # insert into packetYYYYMMDD
-            argString = b','.join(cur.mogrify(
-                "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", x) for x in datePacketTuples)
-            sql = "insert into " + packetTable + "(station_id, sender_id, map_id, source_id, packet_type_id, latitude, longitude, posambiguity, symbol, symbol_table, map_sector, related_map_sectors, marker_id, marker_counter, speed, course, altitude, rng, phg, latest_phg_timestamp, latest_rng_timestamp, timestamp, packet_tail_timestamp, is_moving, reported_timestamp, position_timestamp, comment, raw_path, raw) values " + argString.decode() + " RETURNING id"
-            cur.execute(sql)
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just exit
-            raise e
-        except Exception as e:
-            # Something went wrong, log error so we can fix problem
-            self.logger.error(e, exc_info=1)
-            self.logger.error(sql)
-            return
-
-        i = 0
-        for record in cur:
-            if packets[i]:
-                packets[i].id = record["id"]
-
-                if packets[i].mapId in [1]:
-                    self.confirmedPositionPacketIdList.append(record["id"])
-                elif packets[i].mapId in [1, 5, 7, 9]:
-                    self.positionPacketIdList.append(record["id"])
-                else:
-                    # We only need to add the packet to the packetIdList if not in the positionPacketIdList or confirmedPositionPacketIdList array's
-                    self.packetIdList.append(record["id"])
-            i += 1
-
-    def _insertIntoPacketPathTable(self, packets, cur):
-        """Insert packets into the correct packet path table
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        timestamp = packets[0].timestamp
-        packetPathTableCreator = PacketPathTableCreator(self.db)
-        packetPathTable = packetPathTableCreator.getPacketPathTable(timestamp)
-
-        i = 0
-        pathTuples = []
-        for packet in packets:
-            if (packet.stationIdPath):
-                self.pathPacketIdList.append(packet.id)
-                number = 0
-                for stationId in packet.stationIdPath:
-                    if (packet.stationLocationPath
-                            and packet.stationLocationPath[number]):
-                        latitude = packet.stationLocationPath[number][0]
-                        longitude = packet.stationLocationPath[number][1]
-                        distance = packet.getTransmitDistance()
-
-                        pathTuples.append(
-                            (packet.id, stationId, latitude, longitude, packet.timestamp, distance, number, packet.stationId, packet.latitude, packet.longitude))
-                        number += 1
-            i += 1
-
-        # insert into packetYYYYMMDD_path
-        if pathTuples:
-            try:
-                argString = b','.join(cur.mogrify(
-                    "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", x) for x in pathTuples)
-                cur.execute("insert into " + packetPathTable +
-                            "(packet_id, station_id, latitude, longitude, timestamp, distance, number, sending_station_id, sending_latitude, sending_longitude) values " + argString.decode())
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                # Something went wrong, log error so we can fix problem
-                self.logger.error(e, exc_info=1)
-                self.logger.error(argString)
-
-    def _insertIntoPacketWeatherTable(self, packets, cur):
-        """Insert packets into the correct packet weather table
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        timestamp = packets[0].timestamp
-        packetWeatherTableCreator = PacketWeatherTableCreator(self.db)
-        packetWeatherTable = packetWeatherTableCreator.getPacketWeatherTable(
-            timestamp)
-
-        i = 0
-        weatherTuples = []
-        for packet in packets:
-            if (packet.weather):
-                self.weatherPacketIdList.append(packet.id)
-                weatherTuples.append((packet.id,
-                                      packet.stationId,
-                                      packet.timestamp,
-                                      packet.weather.humidity,
-                                      packet.weather.pressure,
-                                      packet.weather.rain1h,
-                                      packet.weather.rain24h,
-                                      packet.weather.rainSinceMidnight,
-                                      packet.weather.temperature,
-                                      packet.weather.windDirection,
-                                      packet.weather.windGust,
-                                      packet.weather.windSpeed,
-                                      packet.weather.luminosity,
-                                      packet.weather.snow,
-                                      packet.weather.wxRawTimestamp))
-            i += 1
-
-        # insert into packetYYYYMMDD_weather
-        if weatherTuples:
-            try:
-                argString = b','.join(cur.mogrify(
-                    "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", x) for x in weatherTuples)
-                cur.execute("insert into " + packetWeatherTable +
-                            "(packet_id, station_id, timestamp, humidity, pressure, rain_1h, rain_24h, rain_since_midnight, temperature, wind_direction, wind_gust, wind_speed, luminosity, snow, wx_raw_timestamp) values " + argString.decode())
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                # Something went wrong, log error so we can fix problem
-                self.logger.error(e, exc_info=1)
-                self.logger.error(argString)
-
-    def _insertIntoPacketOgnTable(self, packets, cur):
-        """Insert packets into the correct packet OGN table
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        timestamp = packets[0].timestamp
-        packetOgnTableCreator = PacketOgnTableCreator(self.db)
-        packetOgnTable = packetOgnTableCreator.getPacketOgnTable(timestamp)
-
-        i = 0
-        ognTuples = []
-        for packet in packets:
-            if (packet.ogn):
-                self.ognPacketIdList.append(packet.id)
-                ognTuples.append((packet.id,
-                                  packet.stationId,
-                                  packet.timestamp,
-                                  packet.ogn.ognSenderAddress,
-                                  packet.ogn.ognAddressTypeId,
-                                  packet.ogn.ognAircraftTypeId,
-                                  packet.ogn.ognClimbRate,
-                                  packet.ogn.ognTurnRate,
-                                  packet.ogn.ognSignalToNoiseRatio,
-                                  packet.ogn.ognBitErrorsCorrected,
-                                  packet.ogn.ognFrequencyOffset))
-
-            i += 1
-        # insert into packetYYYYMMDD_ogn
-        if ognTuples:
-            try:
-                argString = b','.join(cur.mogrify(
-                    "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", x) for x in ognTuples)
-                cur.execute("insert into " + packetOgnTable + "(packet_id, station_id, timestamp, ogn_sender_address, ogn_address_type_id, ogn_aircraft_type_id, ogn_climb_rate, ogn_turn_rate, ogn_signal_to_noise_ratio, ogn_bit_errors_corrected, ogn_frequency_offset) values " + argString.decode())
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                # Something went wrong, log error so we can fix problem
-                self.logger.error(e, exc_info=1)
-                self.logger.error(argString)
-
-    def _insertIntoPacketTelemetryTable(self, packets, cur):
-        """Insert packets into the correct packet telemetry table
-
-        Args:
-            packets (array):   Packets to insert
-            cur (cursor):      Database curser to use
-        """
-        timestamp = packets[0].timestamp
-        packetTelemetryTableCreator = PacketTelemetryTableCreator(self.db)
-        packetTelemetryTable = packetTelemetryTableCreator.getPacketTelemetryTable(
-            timestamp)
-
-        i = 0
-        telemetryTuples = []
-        for packet in packets:
-            if (packet.telemetry):
-                self.telemetryPacketIdList.append(packet.id)
-                if (not packet.telemetry.isDuplicate()):
-                    telemetryTuples.append((packet.id,
-                                            packet.stationId,
-                                            packet.timestamp,
-                                            packet.telemetry.val1,
-                                            packet.telemetry.val2,
-                                            packet.telemetry.val3,
-                                            packet.telemetry.val4,
-                                            packet.telemetry.val5,
-                                            packet.telemetry.bits,
-                                            packet.telemetry.seq))
-            i += 1
-
-        # insert into packetYYYYMMDD_telemetry
-        if telemetryTuples:
-            try:
-                argString = b','.join(cur.mogrify(
-                    "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", x) for x in telemetryTuples)
-                cur.execute("insert into " + packetTelemetryTable +
-                            "(packet_id, station_id, timestamp, val1, val2, val3, val4, val5, bits, seq) values " + argString.decode() + " returning id")
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                # Something went wrong, log error so we can fix problem
-                self.logger.error(e, exc_info=1)
-
-            packetTelemetryIds = []
-            record = cur.fetchone()
-            while record:
-                packetTelemetryIds.append(record['id'])
-                record = cur.fetchone()
-
-            try:
-                cur.execute("""update """ + packetTelemetryTable + """ packet_telemetry set
-                        station_telemetry_param_id = (select id from station_telemetry_param where station_id = packet_telemetry.station_id and valid_to_ts is null),
-                        station_telemetry_unit_id = (select id from station_telemetry_unit where station_id = packet_telemetry.station_id and valid_to_ts is null),
-                        station_telemetry_eqns_id = (select id from station_telemetry_eqns where station_id = packet_telemetry.station_id and valid_to_ts is null),
-                        station_telemetry_bits_id = (select id from station_telemetry_bits where station_id = packet_telemetry.station_id and valid_to_ts is null)
-                    where id in %s""", (tuple(packetTelemetryIds), ))
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                # Something went wrong, log error so we can fix problem
-                self.logger.error(e, exc_info=1)
-
-    def _insertTelemetryDefinitions(self, packets):
-        """Insert telemetry definitions (PARAM, UNIT, EQNS, BITS) if any exists in current packets
-
-        Args:
-            packets (array):  Packets to insert
-        """
-        for packet in packets:
-            if (packet.stationTelemetryBits):
-                packet.stationTelemetryBits.save()
-
-            if (packet.stationTelemetryEqns):
-                packet.stationTelemetryEqns.save()
-
-            if (packet.stationTelemetryParam):
-                packet.stationTelemetryParam.save()
-
-            if (packet.stationTelemetryUnit):
-                packet.stationTelemetryUnit.save()
diff --git a/server/trackdirect/collector/PacketMapIdModifier.py b/server/trackdirect/collector/PacketMapIdModifier.py
deleted file mode 100644
index 2893c45f605dda00b101287368c3ab80859a2df4..0000000000000000000000000000000000000000
--- a/server/trackdirect/collector/PacketMapIdModifier.py
+++ /dev/null
@@ -1,164 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketMapIdModifier():
-    """PacketMapIdModifier is used to modify mapId on existing packets in database based on new packets
-    """
-
-    def __init__(self, cur, packetTableCreator):
-        """The __init__ method.
-
-        Args:
-            cur (psycopg2.Cursor):                      Database cursor
-            packetTableCreator (PacketTableCreator):    PacketTableCreator instance
-        """
-        self.cur = cur
-        self.packetTableCreator = packetTableCreator
-
-    def execute(self, packets):
-        """Perform mapId mofifications based on information in specified packets
-
-        Args:
-            packets (array):  Packets that may affect exisintg packets mapId
-            cur (cursor):     Database curser to use
-        """
-        self._markPreviousPacketsAsReplaced(packets)
-        self._markPreviousPacketsAsAbnormal(packets)
-        self._markPreviousPacketsAsConfirmed(packets)
-
-    def _markPreviousPacketsAsReplaced(self, packets):
-        """Find packets that has been replaced by packets in this batch and mark them as replaced (mapId 2, 12 or 13)
-
-        Args:
-            packets (array):  Packets that may affect exisintg packets mapId
-        """
-        packetsToUpdateToMapId2 = {}
-        packetsToUpdateToMapId12 = {}
-        packetsToUpdateToMapId13 = {}
-        for packet in packets:
-            if (packet.replacePacketId is not None):
-                try:
-                    self.packetTableCreator.enableCreateIfMissing()
-                    newPacketTable = self.packetTableCreator.getPacketTable(
-                        packet.timestamp)
-                    self.packetTableCreator.disableCreateIfMissing()
-                    oldPacketTable = self.packetTableCreator.getPacketTable(
-                        packet.replacePacketTimestamp)
-
-                    if (packet.mapId == 5):
-                        if (oldPacketTable not in packetsToUpdateToMapId13):
-                            packetsToUpdateToMapId13[oldPacketTable] = []
-
-                        packetsToUpdateToMapId13[oldPacketTable].append(
-                            packet.replacePacketId)
-
-                    elif (newPacketTable == oldPacketTable):
-                        if (oldPacketTable not in packetsToUpdateToMapId2):
-                            packetsToUpdateToMapId2[oldPacketTable] = []
-
-                        packetsToUpdateToMapId2[oldPacketTable].append(
-                            packet.replacePacketId)
-
-                    else:
-                        if (oldPacketTable not in packetsToUpdateToMapId12):
-                            packetsToUpdateToMapId12[oldPacketTable] = []
-
-                        packetsToUpdateToMapId12[oldPacketTable].append(
-                            packet.replacePacketId)
-                except TrackDirectMissingTableError as e:
-                    pass
-
-        if (packetsToUpdateToMapId2):
-            for packetTable in packetsToUpdateToMapId2:
-                # Set map_id = 2
-                self._updatePacketMapId(
-                    packetTable, packetsToUpdateToMapId2[packetTable], 2)
-
-        if (packetsToUpdateToMapId12):
-            for packetTable in packetsToUpdateToMapId12:
-                # Set map_id = 12
-                self._updatePacketMapId(
-                    packetTable, packetsToUpdateToMapId12[packetTable], 12)
-
-        if (packetsToUpdateToMapId13):
-            for packetTable in packetsToUpdateToMapId13:
-                # Set map_id = 13
-                self._updatePacketMapId(
-                    packetTable, packetsToUpdateToMapId13[packetTable], 13)
-
-    def _markPreviousPacketsAsAbnormal(self, packets):
-        """Find packets that has been confirmed to by abnormal becuse of packets in this batch and mark them as abnormal (mapId 9)
-
-        Args:
-            packets (array):  Packets that may affect exisintg packets mapId
-        """
-        packetsToUpdate = {}
-        for packet in packets:
-            if (packet.abnormalPacketId is not None):
-                try:
-                    self.packetTableCreator.disableCreateIfMissing()
-                    packetTable = self.packetTableCreator.getPacketTable(
-                        packet.abnormalPacketTimestamp)
-
-                    if (packetTable not in packetsToUpdate):
-                        packetsToUpdate[packetTable] = []
-
-                    packetsToUpdate[packetTable].append(
-                        packet.abnormalPacketId)
-                except TrackDirectMissingTableError as e:
-                    pass
-
-        if (packetsToUpdate):
-            for packetTable in packetsToUpdate:
-                # Set map_id = 9
-                self._updatePacketMapId(
-                    packetTable, packetsToUpdate[packetTable], 9)
-
-    def _markPreviousPacketsAsConfirmed(self, packets):
-        """Find packets that has been found to be correct becuase of packets in this batch and mark them as confirmed (mapId 1)
-
-        Args:
-            packets (array):  Packets that may affect exisintg packets mapId
-            cur (cursor):     Database curser to use
-        """
-        packetsToUpdate = {}
-        for packet in packets:
-            if (packet.confirmPacketId is not None):
-                try:
-                    self.packetTableCreator.disableCreateIfMissing()
-                    packetTable = self.packetTableCreator.getPacketTable(
-                        packet.confirmPacketTimestamp)
-
-                    if (packetTable not in packetsToUpdate):
-                        packetsToUpdate[packetTable] = []
-
-                    packetsToUpdate[packetTable].append(packet.confirmPacketId)
-                except TrackDirectMissingTableError as e:
-                    pass
-
-        if (packetsToUpdate):
-            for packetTable in packetsToUpdate:
-                # Set map_id = 1
-                self._updatePacketMapId(
-                    packetTable, packetsToUpdate[packetTable], 1)
-
-    def _updatePacketMapId(self, packetTable, packetIdList, mapId):
-        """Update map id on all specified packets
-
-        Args:
-            cur (cursor):          Database cursor to use
-            packetTable (str):     Packet database table to perform update on
-            packetIdList (array):  Array of all packet id's to update
-            mapId (int):           The requested new map id
-        """
-        if (packetIdList):
-            sql = self.cur.mogrify("""update """ + packetTable + """
-                set map_id = %s
-                where id in %s""", (mapId, tuple(packetIdList),))
-            self.cur.execute(sql)
diff --git a/server/trackdirect/collector/StationLatestPacketModifier.py b/server/trackdirect/collector/StationLatestPacketModifier.py
deleted file mode 100644
index ecc06231ec38bd306884c60c93d4e3b6e7298ec5..0000000000000000000000000000000000000000
--- a/server/trackdirect/collector/StationLatestPacketModifier.py
+++ /dev/null
@@ -1,187 +0,0 @@
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-
-
-class StationLatestPacketModifier():
-    """The StationLatestPacketModifier class contains functionality to modify the station latest packet
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.packetTableCreator = PacketTableCreator(db)
-
-    def updateStationLatestConfirmedPacket(self, packetIdList, timestamp):
-        """Updates several stations latest confirmed packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest confirmed packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_sender_id = packet.sender_id,
-                    latest_confirmed_packet_id = packet.id,
-                    latest_confirmed_marker_id = packet.marker_id,
-                    latest_confirmed_packet_timestamp = packet.timestamp,
-                    latest_confirmed_symbol = packet.symbol,
-                    latest_confirmed_symbol_table = packet.symbol_table,
-                    latest_confirmed_latitude = packet.latitude,
-                    latest_confirmed_longitude = packet.longitude,
-                    latest_location_packet_id = packet.id,
-                    latest_location_packet_timestamp = packet.timestamp,
-                    latest_packet_id = packet.id,
-                    latest_packet_timestamp = packet.timestamp
-                from """ + packetTable + """ packet
-                where packet.station_id = station.id
-                    and packet.id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-
-            cur.close()
-            return rowCount
-        return 0
-
-    def updateStationLatestLocationPacket(self, packetIdList, timestamp):
-        """Updates several stations latest location packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest location packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_location_packet_id = packet.id,
-                    latest_location_packet_timestamp = packet.timestamp,
-                    latest_packet_id = packet.id,
-                    latest_packet_timestamp = packet.timestamp
-                from """ + packetTable + """ packet
-                where packet.station_id = station.id
-                    and packet.id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-
-            cur.close()
-            return rowCount
-        return 0
-
-    def updateStationLatestPacket(self, packetIdList, timestamp):
-        """Updates several stations latest packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_packet_id = packet.id,
-                    latest_packet_timestamp = packet.timestamp
-                from """ + packetTable + """ packet
-                where packet.station_id = station.id
-                    and packet.id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-
-            cur.close()
-            return rowCount
-        return 0
-
-
-    def updateStationLatestTelemetryPacket(self, packetIdList, timestamp):
-        """Updates several stations latest telemetry packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_telemetry_packet_id = packet.id,
-                    latest_telemetry_packet_timestamp = packet.timestamp
-                from """ + packetTable + """ packet
-                where packet.station_id = station.id
-                    and packet.id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-
-            cur.close()
-            return rowCount
-        return 0
-
-    def updateStationLatestOgnPacket(self, packetIdList, timestamp):
-        """Updates several stations latest OGN packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_ogn_packet_id = packet_ogn.packet_id,
-                    latest_ogn_packet_timestamp = packet_ogn.timestamp,
-                    latest_ogn_sender_address = packet_ogn.ogn_sender_address,
-                    latest_ogn_aircraft_type_id = packet_ogn.ogn_aircraft_type_id,
-                    latest_ogn_address_type_id = packet_ogn.ogn_address_type_id
-                from """ + packetTable + """_ogn packet_ogn
-                where packet_ogn.station_id = station.id
-                    and packet_ogn.packet_id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-            cur.close()
-            return rowCount
-        return 0
-
-    def updateStationLatestWeatherPacket(self, packetIdList, timestamp):
-        """Updates several stations latest weather packet based on the specified list of packet id's
-
-        Args:
-            packetIdList (array):  Array of packet id's that should be used to set the latest packets on related stations
-            timestamp (int):       Unix timestamp which is in the same date as the receive date of all packets (UTC)
-
-        Returns:
-            number of updated stations
-        """
-        if (packetIdList):
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            cur = self.db.cursor()
-            sql = cur.mogrify("""
-                update station set latest_weather_packet_id = packet.id,
-                    latest_weather_packet_timestamp = packet.timestamp,
-                    latest_weather_packet_comment = packet.comment
-                from """ + packetTable + """ packet
-                where packet.station_id = station.id
-                    and packet.id in %s""", (tuple(packetIdList),))
-            cur.execute(sql)
-            rowCount = cur.rowcount
-
-            cur.close()
-            return rowCount
-        return 0
\ No newline at end of file
diff --git a/server/trackdirect/collector/__init__.py b/server/trackdirect/collector/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/collector/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/common/Model.py b/server/trackdirect/common/Model.py
deleted file mode 100644
index 5661308d479137c40ee20ded7a55c0dd9605c936..0000000000000000000000000000000000000000
--- a/server/trackdirect/common/Model.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import abc
-
-
-class Model():
-    """The Model class is the parent of all my models
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            id (int):  Database row id
-        """
-        self.id = None
-        self.db = db
-
-    def isExistingObject(self):
-        """Returns true if the object exists in database
-
-        Returns:
-            true if the object exists in database otherwise false
-        """
-        if ((type(self.id) == int) and self.id is not None and self.id > 0):
-            return True
-        else:
-            return False
-
-    @abc.abstractmethod
-    def insert(self):
-        """Insert this object into database
-
-        Returns:
-            true on success otherwise false
-        """
-        return False
-
-    @abc.abstractmethod
-    def update(self):
-        """Update columns in database based on this object
-
-        Returns:
-            true on success otherwise false
-        """
-        return False
-
-    @abc.abstractmethod
-    def validate(self):
-        """Return true if object attribute values are valid
-
-        Returns:
-            true if object attribute values are valid otherwise false
-        """
-        return
-
-    def save(self):
-        """Save object data to database if attribute data is valid
-
-        Returns:
-            true on success otherwise false
-        """
-        if (self.validate()):
-            if (self.isExistingObject()):
-                return self.update()
-            else:
-                return self.insert()
-        return False
diff --git a/server/trackdirect/common/Repository.py b/server/trackdirect/common/Repository.py
deleted file mode 100644
index 7888c399483d89dbb66504631dada22bdef12c2e..0000000000000000000000000000000000000000
--- a/server/trackdirect/common/Repository.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-import abc
-
-
-class Repository():
-    """The Repository class is the parent of all my repository classes
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (object):  Database connection (with autocommit)
-        """
-        self.db = db
-
-    @abc.abstractmethod
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            object
-        """
-        return
diff --git a/server/trackdirect/common/Singleton.py b/server/trackdirect/common/Singleton.py
deleted file mode 100644
index b767e94323824d87992769e9399afb315861e3e4..0000000000000000000000000000000000000000
--- a/server/trackdirect/common/Singleton.py
+++ /dev/null
@@ -1,7 +0,0 @@
-class Singleton(object):
-    _instance = None
-
-    def __new__(class_, *args, **kwargs):
-        if not isinstance(class_._instance, class_):
-            class_._instance = object.__new__(class_, *args, **kwargs)
-        return class_._instance
diff --git a/server/trackdirect/common/__init__.py b/server/trackdirect/common/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/common/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/database/DatabaseConnection.py b/server/trackdirect/database/DatabaseConnection.py
deleted file mode 100644
index 42c2ec95b760b626454fc520d58951f53790328b..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/DatabaseConnection.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import psycopg2
-import psycopg2.extras
-
-import trackdirect
-
-
-class DatabaseConnection():
-    """The DatabaseConnection class handles the most basic communication with the database
-    """
-
-    db = None
-    dbNoAutoCommit = None
-
-    def __init__(self):
-        """The __init__ method.
-        """
-        config = trackdirect.TrackDirectConfig()
-        self.host = config.dbHostname
-        self.database = config.dbName
-        self.username = config.dbUsername
-        self.password = config.dbPassword
-        self.port = config.dbPort
-
-    def getConnection(self, autocommit=True, createNewConnection=False):
-        """Returns a connection to the database
-
-        Args:
-            autocommit (boolean):            set to true if you want the connection to autocommit otherwise false
-            createNewConnection (boolean):   set to true to force a new connection
-        Returns:
-            psycopg2.Connection
-        """
-        if (createNewConnection):
-            db = self._createNewConnection()
-            if (autocommit):
-                # Active autocommit to avoid open transactions laying around
-                DatabaseConnection.db.autocommit = True
-            return db
-
-        elif (autocommit):
-            if (DatabaseConnection.db is None):
-                DatabaseConnection.db = self._createNewConnection()
-                # Active autocommit to avoid open transactions laying around
-                DatabaseConnection.db.autocommit = True
-            return DatabaseConnection.db
-
-        else:
-            if (DatabaseConnection.dbNoAutoCommit is None):
-                DatabaseConnection.dbNoAutoCommit = self._createNewConnection()
-            return DatabaseConnection.dbNoAutoCommit
-
-    def _createNewConnection(self):
-        """Returns a connection to the database
-
-        Returns:
-            psycopg2.Connection
-        """
-        return psycopg2.connect(host=self.host,
-                                database=self.database,
-                                user=self.username,
-                                password=self.password,
-                                port=self.port,
-                                sslmode='disable',
-                                cursor_factory=psycopg2.extras.DictCursor)
diff --git a/server/trackdirect/database/DatabaseObjectFinder.py b/server/trackdirect/database/DatabaseObjectFinder.py
deleted file mode 100644
index 680f99254d15d452bb4d6238336033d1fdb468b6..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/DatabaseObjectFinder.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import logging
-from twisted.python import log
-import datetime
-import time
-
-
-class DatabaseObjectFinder():
-    """The DatabaseObjectFinder class can be used to check if a database table exists or not
-    """
-
-    existingTables = {}
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):  Database connection
-        """
-        self.db = db
-
-    def setTableExists(self, tablename):
-        """Mark a table as existing
-
-        Args:
-            tablename (str):  table to be marked as existing
-        """
-        DatabaseObjectFinder.existingTables[tablename] = True
-
-    def checkTableExists(self, tablename):
-        """Returns true if specified table exists in database
-
-        Args:
-            tablename (str):       Table that we want's to know if it exists or not
-
-        Returns:
-            Returns true if specified table exists in database otherwise false
-        """
-        todayDateStr = datetime.datetime.utcfromtimestamp(
-            int(time.time())).strftime('%Y%m%d')
-        yesterdayDateStr = datetime.datetime.utcfromtimestamp(
-            int(time.time()) - 86400).strftime('%Y%m%d')
-
-        if (todayDateStr in tablename or yesterdayDateStr in tablename):
-            # We only trust cache for the latest two days
-            if (tablename in DatabaseObjectFinder.existingTables):
-                # we know table exists
-                return True
-
-        cur = self.db.cursor()
-        cur.execute("""
-            SELECT COUNT(*)
-            FROM information_schema.tables
-            WHERE table_name = '{0}'
-            """.format(tablename.replace('\'', '\'\'')))
-        if cur.fetchone()[0] == 1:
-            DatabaseObjectFinder.existingTables[tablename] = True
-            cur.close()
-            return True
-        else:
-            cur.close()
-            return False
-
-    def checkIndexExists(self, index):
-        """Returns true if specified index exists in database
-
-        Args:
-            index (str): index that we want's to know if it exists or not
-
-        Returns:
-            Returns true if specified index exists in database otherwise false
-        """
-        cur = self.db.cursor()
-        cur.execute("""select to_regclass('{0}') \"name\"""".format(
-            index.replace('\'', '\'\'')))
-        record = cur.fetchone()
-        if record and record['name'] == index.replace('\'', '\'\''):
-            cur.close()
-            return True
-        else:
-            cur.close()
-            return False
diff --git a/server/trackdirect/database/PacketOgnTableCreator.py b/server/trackdirect/database/PacketOgnTableCreator.py
deleted file mode 100644
index 46364051025bb18f255ab423b41ad8205d735a15..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/PacketOgnTableCreator.py
+++ /dev/null
@@ -1,108 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-import datetime
-import time
-import calendar
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketOgnTableCreator():
-    """The PacketOgnTableCreator class handles packet OGN table name logic
-
-    Note:
-        Packets are stored in different tables depending on what day they are received,
-        new packet tables are created by this class.
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.logger = logging.getLogger('trackdirect')
-        self.createIfMissing = True
-
-    def disableCreateIfMissing(self):
-        """Disable feature that creates new tables if missing
-        """
-        self.createIfMissing = False
-
-    def getPacketOgnTable(self, packetTimestamp):
-        """Returns the name of the OGN packet table
-
-        Args:
-            packetTimestamp (int): Unix timestamp that we need the table for
-
-        Returns:
-            the name of the OGN packet table as a string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            packetTimestamp).strftime('%Y%m%d')
-        packetOgnTable = 'packet' + date + '_ogn'
-        if (not self.dbObjectFinder.checkTableExists(packetOgnTable)):
-            if(self.createIfMissing):
-                minTimestamp = packetTimestamp // (24*60*60) * (24*60*60)
-                maxTimestamp = minTimestamp + (24*60*60)
-                self._createPacketOgnTable(
-                    packetOgnTable, minTimestamp, maxTimestamp)
-                self.dbObjectFinder.setTableExists(packetOgnTable)
-            else:
-                raise TrackDirectMissingTableError(
-                    'Database table does not exists')
-        return packetOgnTable
-
-    def _createPacketOgnTable(self, tablename, minTimestamp, maxTimestamp):
-        """Create a packet OGN table with the specified name
-
-        Args:
-            tablename (str):        Name of the packet OGN table to create
-            packetTablename (str):  Name of the related packet table
-            minTimestamp (int):     Min Unix timestamp for this table
-            maxTimestamp (int):     Max Unix timestamp for this table
-        """
-        try:
-            # Note that we have no reference constraint to the packet table (we will keep rows in this table longer than rows in packet table)
-            cur = self.db.cursor()
-            sql = """
-                create table %s () inherits (packet_ogn)""" % (tablename)
-            cur.execute(sql)
-
-            sql = """alter table %s add constraint timestamp_range_check check(timestamp >= %d and timestamp < %d)""" % (tablename, minTimestamp, maxTimestamp)
-            cur.execute(sql)
-
-            sql = """create index %s_pkey on %s using btree (id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_packet_id_idx on %s(packet_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_station_id_idx on %s(station_id, timestamp)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            cur.close()
-
-        except (psycopg2.IntegrityError, psycopg2.ProgrammingError) as e:
-            # Probably the other collector created the table at the same time (might happen when you run multiple collectors), just go on...
-            if ('already exists' not in str(e)):
-                self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
diff --git a/server/trackdirect/database/PacketPathTableCreator.py b/server/trackdirect/database/PacketPathTableCreator.py
deleted file mode 100644
index 8eda761db01a205fc9df18dc1a4aeee3683eb19a..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/PacketPathTableCreator.py
+++ /dev/null
@@ -1,111 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-import datetime
-import time
-import calendar
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketPathTableCreator():
-    """The PacketPathTableCreator class handles packet table name logic
-
-    Note:
-        Packets are stored in different tables depending on what day they are received,
-        new packet tables are created by this class.
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.logger = logging.getLogger('trackdirect')
-        self.createIfMissing = True
-
-    def disableCreateIfMissing(self):
-        """Disable feature that creates new tables if missing
-        """
-        self.createIfMissing = False
-
-    def getPacketPathTable(self, packetTimestamp):
-        """Returns the name of the path packet table
-
-        Args:
-            packetTimestamp (int): Unix timestamp that we need the table for
-
-        Returns:
-            Returns the name of the path packet table as a string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            packetTimestamp).strftime('%Y%m%d')
-        packetTable = 'packet' + date
-        packetPathTable = 'packet' + date + '_path'
-        if (not self.dbObjectFinder.checkTableExists(packetPathTable)):
-            if(self.createIfMissing):
-                minTimestamp = packetTimestamp // (24*60*60) * (24*60*60)
-                maxTimestamp = minTimestamp + (24*60*60)
-                self._createPacketPathTable(
-                    packetPathTable, minTimestamp, maxTimestamp)
-                self.dbObjectFinder.setTableExists(packetPathTable)
-            else:
-                raise TrackDirectMissingTableError(
-                    'Database table does not exists')
-        return packetPathTable
-
-    def _createPacketPathTable(self, tablename, minTimestamp, maxTimestamp):
-        """Create a packet path table with the specified name
-
-        Args:
-            tablename (str):        Name of the packet path table to create
-            minTimestamp (int):     Min Unix timestamp for this table
-            maxTimestamp (int):     Max Unix timestamp for this table
-        """
-        try:
-            cur = self.db.cursor()
-            sql = """
-                create table %s () inherits (packet_path)""" % (tablename)
-            cur.execute(sql)
-
-            sql = """alter table %s add constraint timestamp_range_check check(timestamp >= %d and timestamp < %d)""" % (tablename, minTimestamp, maxTimestamp)
-            cur.execute(sql)
-
-            sql = """create index %s_pkey on %s using btree (id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_packet_id_idx on %s(packet_id, number)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_station_id_idx on %s(station_id, timestamp)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_sending_station_id_idx on %s(sending_station_id, timestamp)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            cur.close()
-
-        except (psycopg2.IntegrityError, psycopg2.ProgrammingError) as e:
-            # Probably the other collector created the table at the same time (might happen when you run multiple collectors), just go on...
-            if ('already exists' not in str(e)):
-                self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
diff --git a/server/trackdirect/database/PacketTableCreator.py b/server/trackdirect/database/PacketTableCreator.py
deleted file mode 100644
index 26077c370e092afd981f8b86bf14643b2e114e77..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/PacketTableCreator.py
+++ /dev/null
@@ -1,157 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-import datetime
-import time
-import calendar
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketTableCreator():
-    """The PacketTableCreator class handles packet table name logic
-
-    Note:
-        Packets are stored in different tables depending on what day they are received,
-        new packet tables are created by this class.
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.logger = logging.getLogger('trackdirect')
-        self.createIfMissing = True
-
-    def disableCreateIfMissing(self):
-        """Disable feature that creates new tables if missing
-        """
-        self.createIfMissing = False
-
-    def enableCreateIfMissing(self):
-        """Enable feature that creates new tables if missing
-        """
-        self.createIfMissing = True
-
-    def getPacketTable(self, packetTimestamp):
-        """Returns the name of the packet table
-
-        Args:
-            packetTimestamp (int): Unix timestamp that we need the table for
-
-        Returns:
-            Returns the name of the packet table as a string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            packetTimestamp).strftime('%Y%m%d')
-        packetTable = 'packet' + date
-        if (not self.dbObjectFinder.checkTableExists(packetTable)):
-            if(self.createIfMissing):
-                minTimestamp = packetTimestamp // (24*60*60) * (24*60*60)
-                maxTimestamp = minTimestamp + (24*60*60)
-                self._createPacketTable(
-                    packetTable, minTimestamp, maxTimestamp)
-                self.dbObjectFinder.setTableExists(packetTable)
-            else:
-                raise TrackDirectMissingTableError(
-                    'Database table ' + packetTable + ' does not exists')
-        return packetTable
-
-    def getPacketTables(self, startTimestamp, endTimestamp=None):
-        """Returns an array of packet table names based on the specified timestamp range
-
-        Note:
-            If table does not exist we will not include the packet table name in array
-
-        Args:
-            startTimestamp (int):  Start unix timestamp for requested packet tables
-            endTimestamp (int):    End unix timestamp for requested packet tables
-
-        Returns:
-            Array of packet table names
-        """
-        if (endTimestamp is None):
-            endTimestamp = int(time.time())
-
-        # We allways want to include
-        endDateTime = datetime.datetime.utcfromtimestamp(int(endTimestamp))
-        endDateTime = endDateTime.replace(
-            hour=0, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
-        endTimestamp = calendar.timegm(endDateTime.timetuple())
-
-        result = []
-        if (startTimestamp == 0):
-            # Go back 1 year
-            ts = int(time.time()) - (60*60*24*366)
-        else:
-            ts = startTimestamp
-        while (ts < endTimestamp):
-            date = datetime.datetime.utcfromtimestamp(
-                int(ts)).strftime('%Y%m%d')
-            datePacketTable = 'packet' + date
-            if (self.dbObjectFinder.checkTableExists(datePacketTable)):
-                result.append(datePacketTable)
-
-            ts = ts + 86400  # 1 day in seconds
-        return result
-
-    def _createPacketTable(self, tablename, minTimestamp, maxTimestamp):
-        """Create a packet table with the specified name
-
-        Args:
-            tablename (str): Name of the packet table to create
-            minTimestamp (int):     Min Unix timestamp for this table
-            maxTimestamp (int):     Max Unix timestamp for this table
-        """
-        try:
-            cur = self.db.cursor()
-            sql = """
-                create table %s () inherits (packet)""" % (tablename)
-            cur.execute(sql)
-
-            sql = """alter table %s add constraint timestamp_range_check check(timestamp >= %d and timestamp < %d)""" % (tablename, minTimestamp, maxTimestamp)
-            cur.execute(sql)
-
-            # The regular primary key index
-            sql = """create index %s_pkey on %s using btree (id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            # This index is magic for multiple methods in PacketRepository
-            sql = """create index %s_station_id_idx on %s(station_id, map_id, marker_id, timestamp)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            # This should be good when using the time-travel functionality
-            sql = """create index %s_map_sector_idx on %s(map_sector, timestamp, map_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            # Used by remover
-            sql = """create index %s_sender_id_idx on %s(sender_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            cur.close()
-
-        except (psycopg2.IntegrityError, psycopg2.ProgrammingError) as e:
-            # Probably the other collector created the table at the same time (might happen when you run multiple collectors), just go on...
-            if ('already exists' not in str(e)):
-                self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
diff --git a/server/trackdirect/database/PacketTelemetryTableCreator.py b/server/trackdirect/database/PacketTelemetryTableCreator.py
deleted file mode 100644
index 54967a016e4859b5f93116eb3e7b8d1233ff9be8..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/PacketTelemetryTableCreator.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-import datetime
-import time
-import calendar
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketTelemetryTableCreator():
-    """The PacketTelemetryTableCreator class handles packet telemetry table name logic
-
-    Note:
-        Packets are stored in different tables depending on what day they are received,
-        new packet tables are created by this class.
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.logger = logging.getLogger('trackdirect')
-        self.createIfMissing = True
-
-    def disableCreateIfMissing(self):
-        """Disable feature that creates new tables if missing
-        """
-        self.createIfMissing = False
-
-    def getPacketTelemetryTable(self, packetTimestamp):
-        """Returns the name of the telemetry packet table
-
-        Args:
-            packetTimestamp (int): Unix timestamp that we need the table for
-
-        Returns:
-            Returns the name of the telemetry packet table as a string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            packetTimestamp).strftime('%Y%m%d')
-        packetTelemetryTable = 'packet' + date + '_telemetry'
-        if (not self.dbObjectFinder.checkTableExists(packetTelemetryTable)):
-            if(self.createIfMissing):
-                minTimestamp = packetTimestamp // (24*60*60) * (24*60*60)
-                maxTimestamp = minTimestamp + (24*60*60)
-                self._createPacketTelemetryTable(
-                    packetTelemetryTable, minTimestamp, maxTimestamp)
-                self.dbObjectFinder.setTableExists(packetTelemetryTable)
-            else:
-                raise TrackDirectMissingTableError(
-                    'Database table does not exists')
-        return packetTelemetryTable
-
-    def _createPacketTelemetryTable(self, tablename, minTimestamp, maxTimestamp):
-        """Create a packet telemetry table with the specified name
-
-        Args:
-            tablename (str):        Name of the packet telemetry table to create
-            packetTablename (str):  Name of the related packet table
-            minTimestamp (int):     Min Unix timestamp for this table
-            maxTimestamp (int):     Max Unix timestamp for this table
-        """
-        try:
-            # Note that we have no reference constraint to the packet table (we might keep rows in this table longer than rows in packet table)
-            cur = self.db.cursor()
-            sql = """
-                create table %s () inherits (packet_telemetry)""" % (tablename)
-            cur.execute(sql)
-
-            sql = """alter table %s add constraint timestamp_range_check check(timestamp >= %d and timestamp < %d)""" % (tablename, minTimestamp, maxTimestamp)
-            cur.execute(sql)
-
-            sql = """create index %s_pkey on %s using btree (id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_packet_id_idx on %s(packet_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_station_id_idx on %s(station_id, timestamp, seq)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_telemetry_param_id on %s(station_telemetry_param_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_telemetry_unit_id on %s(station_telemetry_unit_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_telemetry_eqns_id on %s(station_telemetry_eqns_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_telemetry_bits_id on %s(station_telemetry_bits_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            cur.close()
-
-        except (psycopg2.IntegrityError, psycopg2.ProgrammingError) as e:
-            # Probably the other collector created the table at the same time (might happen when you run multiple collectors), just go on...
-            if ('already exists' not in str(e)):
-                self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
diff --git a/server/trackdirect/database/PacketWeatherTableCreator.py b/server/trackdirect/database/PacketWeatherTableCreator.py
deleted file mode 100644
index f2ced64e7c5ac3d5993831d73718c205cbff0f76..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/PacketWeatherTableCreator.py
+++ /dev/null
@@ -1,107 +0,0 @@
-import logging
-from twisted.python import log
-import psycopg2
-import psycopg2.extras
-import datetime
-import time
-import calendar
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketWeatherTableCreator():
-    """The PacketWeatherTableCreator class handles packet weather table name logic
-
-    Note:
-        Packets are stored in different tables depending on what day they are received,
-        new packet tables are created by this class.
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.logger = logging.getLogger('trackdirect')
-        self.createIfMissing = True
-
-    def disableCreateIfMissing(self):
-        """Disable feature that creates new tables if missing
-        """
-        self.createIfMissing = False
-
-    def getPacketWeatherTable(self, packetTimestamp):
-        """Returns the name of the weather packet table
-
-        Args:
-            packetTimestamp (int): Unix timestamp that we need the table for
-
-        Returns:
-            the name of the weather packet table as a string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            packetTimestamp).strftime('%Y%m%d')
-        packetWeatherTable = 'packet' + date + '_weather'
-        if (not self.dbObjectFinder.checkTableExists(packetWeatherTable)):
-            if(self.createIfMissing):
-                minTimestamp = packetTimestamp // (24*60*60) * (24*60*60)
-                maxTimestamp = minTimestamp + (24*60*60)
-                self._createPacketWeatherTable(
-                    packetWeatherTable, minTimestamp, maxTimestamp)
-                self.dbObjectFinder.setTableExists(packetWeatherTable)
-            else:
-                raise TrackDirectMissingTableError(
-                    'Database table does not exists')
-        return packetWeatherTable
-
-    def _createPacketWeatherTable(self, tablename, minTimestamp, maxTimestamp):
-        """Create a packet weather table with the specified name
-
-        Args:
-            tablename (str):        Name of the packet weather table to create
-            minTimestamp (int):     Min Unix timestamp for this table
-            maxTimestamp (int):     Max Unix timestamp for this table
-        """
-        try:
-            # Note that we have no reference constraint to the packet table (we might keep rows in this table longer than rows in packet table)
-            cur = self.db.cursor()
-            sql = """
-                create table %s () inherits (packet_weather)""" % (tablename)
-            cur.execute(sql)
-
-            sql = """alter table %s add constraint timestamp_range_check check(timestamp >= %d and timestamp < %d)""" % (tablename, minTimestamp, maxTimestamp)
-            cur.execute(sql)
-
-            sql = """create index %s_pkey on %s using btree (id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_packet_id_idx on %s(packet_id)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            sql = """create index %s_station_id_idx on %s(station_id, timestamp)""" % (
-                tablename, tablename)
-            cur.execute(sql)
-
-            cur.close()
-
-        except (psycopg2.IntegrityError, psycopg2.ProgrammingError) as e:
-            # Probably the other collector created the table at the same time (might happen when you run multiple collectors), just go on...
-            if ('already exists' not in str(e)):
-                self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
-
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-            # Do some sleep and let the other process create all related tables (if other table failes we will do it after sleep)
-            time.sleep(10)
-            return
diff --git a/server/trackdirect/database/__init__.py b/server/trackdirect/database/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/database/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/exceptions/TrackDirectGenericError.py b/server/trackdirect/exceptions/TrackDirectGenericError.py
deleted file mode 100644
index 1ea03e41d393a484fb4657504548703632bb2b62..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/TrackDirectGenericError.py
+++ /dev/null
@@ -1,12 +0,0 @@
-class TrackDirectGenericError(Exception):
-    """ Base exception class for the library. Logs information via logging module
-    """
-
-    def __init__(self, message):
-        """The __init__ method.
-
-        Args:
-            message (str): Exception message
-        """
-        super(TrackDirectGenericError, self).__init__(message)
-        self.message = message
diff --git a/server/trackdirect/exceptions/TrackDirectMissingSenderError.py b/server/trackdirect/exceptions/TrackDirectMissingSenderError.py
deleted file mode 100644
index 1f70550ebe8ec7dfdb303e8701e6360e8143ae6e..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/TrackDirectMissingSenderError.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from trackdirect.exceptions.TrackDirectGenericError import TrackDirectGenericError
-
-
-class TrackDirectMissingSenderError(TrackDirectGenericError):
-    """Raised when unexpected format of a supported packet format is encountered
-    """
-
-    def __init__(self, message, data={}):
-        """The __init__ method.
-
-        Args:
-            message (str): Exception message
-            data (dict):   Packet data that caused parse error
-        """
-        super(TrackDirectMissingSenderError, self).__init__(message)
-        self.packet = data
diff --git a/server/trackdirect/exceptions/TrackDirectMissingStationError.py b/server/trackdirect/exceptions/TrackDirectMissingStationError.py
deleted file mode 100644
index 425593176149f095f3352da128930027684f3e08..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/TrackDirectMissingStationError.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from trackdirect.exceptions.TrackDirectGenericError import TrackDirectGenericError
-
-
-class TrackDirectMissingStationError(TrackDirectGenericError):
-    """Raised when unexpected format of a supported packet format is encountered
-    """
-
-    def __init__(self, message, data={}):
-        """The __init__ method.
-
-        Args:
-            message (str): Exception message
-            data (dict):   Packet data that caused parse error
-        """
-        super(TrackDirectMissingStationError, self).__init__(message)
-        self.packet = data
diff --git a/server/trackdirect/exceptions/TrackDirectMissingTableError.py b/server/trackdirect/exceptions/TrackDirectMissingTableError.py
deleted file mode 100644
index 454d90ad36a87a05423ab3e2de036f2cb27ea155..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/TrackDirectMissingTableError.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from trackdirect.exceptions.TrackDirectGenericError import TrackDirectGenericError
-
-
-class TrackDirectMissingTableError(TrackDirectGenericError):
-    """Raised when unexpected format of a supported packet format is encountered
-    """
-
-    def __init__(self, message, data={}):
-        """The __init__ method.
-
-        Args:
-            message (str): Exception message
-            data (dict):   Packet data that caused parse error
-        """
-        super(TrackDirectMissingTableError, self).__init__(message)
-        self.packet = data
diff --git a/server/trackdirect/exceptions/TrackDirectParseError.py b/server/trackdirect/exceptions/TrackDirectParseError.py
deleted file mode 100644
index 74587d7228952fc4c1f6b4b83801ebded7911580..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/TrackDirectParseError.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from trackdirect.exceptions.TrackDirectGenericError import TrackDirectGenericError
-
-
-class TrackDirectParseError(TrackDirectGenericError):
-    """Raised when unexpected format of a supported packet format is encountered
-    """
-
-    def __init__(self, message, data={}):
-        """The __init__ method.
-
-        Args:
-            message (str): Exception message
-            data (dict):   Packet data that caused parse error
-        """
-        super(TrackDirectParseError, self).__init__(message)
-        self.packet = data
diff --git a/server/trackdirect/exceptions/__init__.py b/server/trackdirect/exceptions/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/exceptions/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/objects/Marker.py b/server/trackdirect/objects/Marker.py
deleted file mode 100644
index 2db8363e610ef9df0d111c7bbf14652218212913..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/Marker.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class Marker(Model):
-    """Marker represents the marker that each visible packet has, two packet with the same marker id will be connected on map
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            cursor = self.db.cursor()
-            cursor.execute("""select nextval('marker_seq')""")
-            self.id = cursor.fetchone()[0]
-            cursor.close()
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/OgnDevice.py b/server/trackdirect/objects/OgnDevice.py
deleted file mode 100644
index 9b813e20c5589fa8f5170d0e2ce1b43fcc73d9ab..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/OgnDevice.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class OgnDevice(Model):
-    """OgnDevice represents a pre registered device in the ogn ddb
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-
-        self.deviceType = None
-        self.deviceId = None
-        self.aircraftModel = None
-        self.registration = None
-        self.cn = None
-        self.tracked = None
-        self.identified = None
-        self.ddbAircraftType = None  # Do not confuse with the aircraft type in aprs message
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def getDict(self):
-        """Returns a dict representation of the object
-
-        Returns:
-            Dict representation of the object
-        """
-        data = {}
-
-        data['device_type'] = self.deviceType
-        data['device_id'] = self.deviceId
-        data['aircraft_model'] = self.aircraftModel
-        data['registration'] = self.registration
-        data['cn'] = self.cn
-        data['tracked'] = self.tracked
-        data['identified'] = self.identified
-        data['ddb_aircraft_type'] = self.ddbAircraftType
-
-        return data
diff --git a/server/trackdirect/objects/OgnHiddenStation.py b/server/trackdirect/objects/OgnHiddenStation.py
deleted file mode 100644
index aedaf18960d6a4aaff7944d4472a5df2211a0eed..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/OgnHiddenStation.py
+++ /dev/null
@@ -1,65 +0,0 @@
-
-from trackdirect.common.Model import Model
-
-
-class OgnHiddenStation(Model):
-    """OgnDevice represents a pre registered device in the ogn ddb
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-
-        self.id = None
-        self.hashedName = None
-
-    def getStationName(self):
-        """Returns the unidentifiable station name used for the current hashed name
-
-        Returns:
-            string
-        """
-        if (self.isExistingObject()):
-            return 'UNKNOWN' + str(self.id)
-        else:
-            return None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute(
-                """insert into ogn_hidden_station(hashed_name) values(%s) RETURNING id""", (str(
-                    self.hashedName).strip(),)
-            )
-            self.id = insertCursor.fetchone()[0]
-            insertCursor.close()
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/Packet.py b/server/trackdirect/objects/Packet.py
deleted file mode 100644
index ccacf5b5a97b2c5b2d4b41be52032f006091a05a..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/Packet.py
+++ /dev/null
@@ -1,359 +0,0 @@
-import logging
-import re
-from twisted.python import log
-import json
-import datetime
-import time
-from math import sin, cos, sqrt, atan2, radians, floor, ceil
-
-from trackdirect.common.Model import Model
-from trackdirect.repositories.StationRepository import StationRepository
-from trackdirect.repositories.SenderRepository import SenderRepository
-from trackdirect.objects.Station import Station
-
-from trackdirect.exceptions.TrackDirectMissingSenderError import TrackDirectMissingSenderError
-from trackdirect.exceptions.TrackDirectMissingStationError import TrackDirectMissingStationError
-
-
-class Packet(Model):
-    """Packet represents a APRS packet, AIS packet or any other supported packet
-
-    Note:
-        Packet corresponds to a row in the packetYYYYMMDD table
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.logger = logging.getLogger('trackdirect')
-
-        self.id = None
-        self.stationId = None
-        self.senderId = None
-        self.packetTypeId = None
-        self.timestamp = None
-        self.reportedTimestamp = None
-        self.positionTimestamp = None # Inherited from prev packet if position was equal
-        self.latitude = None
-        self.longitude = None
-        self.symbol = None
-        self.symbolTable = None
-        self.markerId = None
-        self.markerCounter = None
-        self.markerPrevPacketTimestamp = None
-        self.mapId = None
-        self.sourceId = None
-        self.mapSector = None
-        self.relatedMapSectors = []
-        self.speed = None
-        self.course = None
-        self.altitude = None
-        self.rng = None
-        self.phg = None
-        self.latestRngTimestamp = None
-        self.latestPhgTimestamp = None
-        self.comment = None
-        self.rawPath = None
-        self.raw = None
-
-        # packet tail timestamp indicates how long time ago we had a tail
-        self.packetTailTimestamp = None
-
-        # If packet reports a new position for a moving symbol is_moving will be 1 otherwise 0
-        # Some times is_moving will be 0 for a moving symbol, but as fast we realize it is moving related packets will have is_moving set to 1
-        self.isMoving = 1
-
-        self.posambiguity = None
-
-        # Following attributes will not allways be loaded from database (comes from related tables)
-        self.stationIdPath = []
-        self.stationNamePath = []
-        self.stationLocationPath = []
-
-        # Will only be used when packet is not inserted to database yet
-        self.replacePacketId = None
-        self.replacePacketTimestamp = None
-        self.abnormalPacketId = None
-        self.abnormalPacketTimestamp = None
-        self.confirmPacketId = None
-        self.confirmPacketTimestamp = None
-
-        # Will only be used when packet is not inserted to database yet
-        self.ogn = None
-        self.weather = None
-        self.telemetry = None
-        self.stationTelemetryBits = None
-        self.stationTelemetryEqns = None
-        self.stationTelemetryParam = None
-        self.stationTelemetryUnit = None
-        self.senderName = None
-        self.stationName = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def getDistance(self, p2Lat, p2Lng):
-        """Get distance in meters between current position and specified position
-
-        Args:
-            p2Lat (float): Position 2 latitude
-            p2Lng (float): Position 2 longitude
-
-        Returns:
-            Distance in meters between the two specified positions (as float)
-        """
-        if (self.latitude is not None
-                and self.longitude is not None):
-            p1Lat = self.latitude
-            p1Lng = self.longitude
-            R = 6378137  # Earths mean radius in meter
-            dLat = radians(p2Lat - p1Lat)
-            dLong = radians(p2Lng - p1Lng)
-            a = sin(dLat / 2) * sin(dLat / 2) + cos(radians(p1Lat)) * \
-                cos(radians(p2Lat)) * sin(dLong / 2) * sin(dLong / 2)
-            c = 2 * atan2(sqrt(a), sqrt(1 - a))
-            d = R * c
-            return d  # returns the distance in meter
-        else:
-            return None
-
-    def getCalculatedSpeed(self, prevPacket):
-        """Get speed compared to previous packet position and timestamp
-
-        Args:
-            prevPacket (Packet):  Previous related packet for the same station
-
-        Returns:
-            Speed in kmh compared to previous packet position and timestamp (as float)
-        """
-        if (self.latitude is not None
-                and self.longitude is not None):
-            distance = self.getDistance(
-                prevPacket.latitude, prevPacket.longitude)
-            time = abs(prevPacket.timestamp - self.timestamp)
-            if (self.reportedTimestamp is not None
-                    and prevPacket.reportedTimestamp is not None
-                    and self.reportedTimestamp != 0
-                    and prevPacket.reportedTimestamp != 0
-                    and (self.reportedTimestamp % 60 != 0 or prevPacket.reportedTimestamp % 60 != 0)
-                    and prevPacket.reportedTimestamp != self.reportedTimestamp):
-                time = abs(prevPacket.reportedTimestamp -
-                           self.reportedTimestamp)
-
-            if (time == 0):
-                return 0
-            return distance / time  # meters per second
-        else:
-            return None
-
-    def isSymbolEqual(self, comparePacket):
-        """Returns true if current symbol is equal to symbol in specified packet
-
-        Args:
-            comparePacket (Packet): Packet to compare current symbol with
-
-        Returns:
-            True if current symbol is equal to symbol in specified packet
-        """
-        if (self.symbol is not None
-            and self.symbolTable is not None
-            and comparePacket.symbol is not None
-            and comparePacket.symbolTable is not None
-            and self.symbol == comparePacket.symbol
-                and self.symbolTable == comparePacket.symbolTable):
-            return True
-        else:
-            return False
-
-    def isPostitionEqual(self, comparePacket):
-        """Returns true if current position is equal to position in specified packet
-
-        Args:
-            comparePacket (Packet): Packet to compare current position with
-
-        Returns:
-            True if current position is equal to position in specified packet
-        """
-        if (comparePacket.latitude is not None
-              and comparePacket.longitude is not None
-              and self.longitude is not None
-              and self.latitude is not None
-              and round(self.latitude, 5) == round(comparePacket.latitude, 5)
-              and round(self.longitude, 5) == round(comparePacket.longitude, 5)):
-            return True
-        else:
-            return False
-
-    def getTransmitDistance(self):
-        """Calculate the transmit distance
-
-        Notes:
-            require that stationLocationPath is set
-
-        Args:
-            None
-
-        Returns:
-            Distance in meters for this transmission
-        """
-        if (self.stationLocationPath is None
-                or len(self.stationLocationPath) < 1):
-            return None
-
-        location = self.stationLocationPath[0]
-        if (location[0] is None
-                or location[1] is None):
-            return None
-
-        if (self.latitude is not None
-                and self.longitude is not None):
-
-            # Current packet contains position, use that
-            return self.getDistance(location[0], location[1])
-        else:
-
-            # Current packet is missing position, use latest station position
-            stationRepository = StationRepository(self.db)
-            station = stationRepository.getObjectById(self.stationId)
-            if (not station.isExistingObject()):
-                return None
-
-            if (station.latestConfirmedLatitude is not None and station.latestConfirmedLongitude is not None):
-                curStationLatestLocationPacket = Packet(self.db)
-                curStationLatestLocationPacket.latitude = station.latestConfirmedLatitude
-                curStationLatestLocationPacket.longitude = station.latestConfirmedLongitude
-                return curStationLatestLocationPacket.getDistance(location[0], location[1])
-            else:
-                return None
-
-    def getDict(self, includeStationName=False):
-        """Returns a dict representation of the object
-
-        Args:
-            includeStationName (Boolean):  Include station name and sender name in dict
-
-        Returns:
-            Dict representation of the object
-        """
-        data = {}
-        data['id'] = self.id
-
-        if (self.stationId is not None):
-            data['station_id'] = int(self.stationId)
-        else:
-            data['station_id'] = None
-
-        if (self.senderId is not None):
-            data['sender_id'] = int(self.senderId)
-        else:
-            data['sender_id'] = None
-
-        data['packet_type_id'] = self.packetTypeId
-        data['timestamp'] = self.timestamp
-        data['reported_timestamp'] = self.reportedTimestamp
-        data['position_timestamp'] = self.positionTimestamp
-
-        if (self.latitude is not None and self.longitude is not None):
-            data['latitude'] = float(self.latitude)
-            data['longitude'] = float(self.longitude)
-        else:
-            data['latitude'] = None
-            data['longitude'] = None
-
-        data['symbol'] = self.symbol
-        data['symbol_table'] = self.symbolTable
-        data['marker_id'] = self.markerId
-        data['marker_counter'] = self.markerCounter
-        data['map_id'] = self.mapId
-        data['source_id'] = self.sourceId
-        data['map_sector'] = self.mapSector
-        data['related_map_sectors'] = self.relatedMapSectors
-        data['speed'] = self.speed
-        data['course'] = self.course
-        data['altitude'] = self.altitude
-        data['rng'] = self.rng
-        data['phg'] = self.phg
-        data['latest_phg_timestamp'] = self.latestPhgTimestamp
-        data['latest_rng_timestamp'] = self.latestRngTimestamp
-        data['comment'] = self.comment
-        data['raw_path'] = self.rawPath
-        data['raw'] = self.raw
-        data['packet_tail_timestamp'] = self.packetTailTimestamp
-        data['is_moving'] = self.isMoving
-        data['posambiguity'] = self.posambiguity
-        data['db'] = 1
-
-        if (includeStationName):
-            try:
-                stationRepository = StationRepository(self.db)
-                station = stationRepository.getCachedObjectById(
-                    data['station_id'])
-                data['station_name'] = station.name
-            except TrackDirectMissingStationError as e:
-                data['station_name'] = ''
-
-            try:
-                senderRepository = SenderRepository(self.db)
-                sender = senderRepository.getCachedObjectById(
-                    data['sender_id'])
-                data['sender_name'] = sender.name
-            except TrackDirectMissingSenderError as e:
-                data['sender_name'] = ''
-
-        data['station_id_path'] = self.stationIdPath
-        data['station_name_path'] = self.stationNamePath
-        data['station_location_path'] = self.stationLocationPath
-        data['telemetry'] = None
-        if (self.telemetry is not None):
-            data['telemetry'] = self.telemetry.getDict()
-        data['weather'] = None
-        if (self.weather is not None):
-            data['weather'] = self.weather.getDict()
-        data['ogn'] = None
-        if (self.ogn is not None):
-            data['ogn'] = self.ogn.getDict()
-        return data
-
-    def getJson(self):
-        """Returns a json representation of the object
-
-        Returns:
-            Json representation of the object (returnes None on failure)
-        """
-        data = self.getDict()
-
-        try:
-            return json.dumps(data, ensure_ascii=False).encode('utf8')
-        except (ValueError) as exp:
-            self.logger.error(e, exc_info=1)
-
-        return None
diff --git a/server/trackdirect/objects/PacketOgn.py b/server/trackdirect/objects/PacketOgn.py
deleted file mode 100644
index 74adb4aa932fbe243de8b0276f4ee72182ac6902..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/PacketOgn.py
+++ /dev/null
@@ -1,84 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class PacketOgn(Model):
-    """PacketOgn represents the OGN data in a APRS packet
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.packetId = None
-        self.stationId = None
-        self.timestamp = None
-        self.ognSenderAddress = None
-        self.ognAddressTypeId = None
-        self.ognAircraftTypeId = None
-        self.ognClimbRate = None
-        self.ognTurnRate = None
-        self.ognSignalToNoiseRatio = None
-        self.ognBitErrorsCorrected = None
-        self.ognFrequencyOffset = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.stationId <= 0):
-            return False
-
-        if (self.packetId <= 0):
-            return False
-
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def getDict(self):
-        """Returns the packet OGN as a dict
-
-        Args:
-            None
-
-        Returns:
-            A packet OGN dict
-        """
-        data = {}
-        data['id'] = self.id
-        data['packet_id'] = self.packetId
-        data['station_id'] = self.stationId
-        data['timestamp'] = self.timestamp
-        data['ogn_sender_address'] = self.ognSenderAddress
-        data['ogn_address_type_id'] = self.ognAddressTypeId
-        data['ogn_aircraft_type_id'] = self.ognAircraftTypeId
-        data['ogn_climb_rate'] = self.ognClimbRate
-        data['ogn_turn_rate'] = self.ognTurnRate
-        data['ogn_signal_to_noise_ratio'] = self.ognSignalToNoiseRatio
-        data['ogn_bit_errors_corrected'] = self.ognBitErrorsCorrected
-        data['ogn_frequency_offset'] = self.ognFrequencyOffset
-        return data
diff --git a/server/trackdirect/objects/PacketTelemetry.py b/server/trackdirect/objects/PacketTelemetry.py
deleted file mode 100644
index ad2d20439e39546d7af3d76e19a00022142607cb..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/PacketTelemetry.py
+++ /dev/null
@@ -1,105 +0,0 @@
-from trackdirect.common.Model import Model
-from trackdirect.database.PacketTelemetryTableCreator import PacketTelemetryTableCreator
-
-
-class PacketTelemetry(Model):
-    """PacketTelemetry represents the telemetry data in a APRS packet
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.packetId = None
-        self.stationId = None
-        self.timestamp = None
-        self.val1 = None
-        self.val2 = None
-        self.val3 = None
-        self.val4 = None
-        self.val5 = None
-        self.bits = None
-        self.seq = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.stationId <= 0):
-            return False
-
-        if (self.packetId <= 0):
-            return False
-
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def isDuplicate(self):
-        """Method returnes true if a duplicate exists in database
-
-        Returns:
-            True if a duplicate exists in database otherwise False
-        """
-        packetTelemetryTableCreator = PacketTelemetryTableCreator(self.db)
-        packetTelemetryTableCreator.disableCreateIfMissing()
-        packetTelemetryTable = packetTelemetryTableCreator.getPacketTelemetryTable(
-            self.timestamp)
-        if (packetTelemetryTable is not None):
-
-            selectCursor = self.db.cursor()
-            selectCursor.execute("""select * from """ + packetTelemetryTable +
-                                 """ where station_id = %s order by timestamp desc limit 1""", (self.stationId,))
-
-            record = selectCursor.fetchone()
-            selectCursor.close()
-            if record is not None and record['seq'] == self.seq:
-                return True
-        return False
-
-    def getDict(self):
-        """Returns a packet telemetry dict
-
-        Args:
-            None
-
-        Returns:
-            A packet telemetry dict
-        """
-        data = {}
-        data['id'] = self.id
-        data['packet_id'] = self.packetId
-        data['station_id'] = self.stationId
-        data['timestamp'] = self.timestamp
-        data['val1'] = self.val1
-        data['val2'] = self.val2
-        data['val3'] = self.val3
-        data['val4'] = self.val4
-        data['val5'] = self.val5
-        data['bits'] = self.bits
-        data['seq'] = self.seq
-        return data
diff --git a/server/trackdirect/objects/PacketWeather.py b/server/trackdirect/objects/PacketWeather.py
deleted file mode 100644
index aaef5eb5f0a1ec9287de96719f796ae297db3ad5..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/PacketWeather.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class PacketWeather(Model):
-    """PacketWeather represents the weather data in a APRS packet
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.packetId = None
-        self.stationId = None
-        self.timestamp = None
-        self.humidity = None
-        self.pressure = None
-        self.rain1h = None
-        self.rain24h = None
-        self.rainSinceMidnight = None
-        self.temperature = None
-        self.windDirection = None
-        self.windGust = None
-        self.windSpeed = None
-        self.luminosity = None
-        self.snow = None
-        self.wxRawTimestamp = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.stationId <= 0):
-            return False
-
-        if (self.packetId <= 0):
-            return False
-
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
-
-    def getDict(self):
-        """Returns the packet weather as a dict
-
-        Args:
-            None
-
-        Returns:
-            A packet weather dict
-        """
-        data = {}
-        data['id'] = self.id
-        data['packet_id'] = self.packetId
-        data['station_id'] = self.stationId
-        data['timestamp'] = self.timestamp
-        data['humidity'] = self.humidity
-        data['pressure'] = self.pressure
-        data['rain_1h'] = self.rain1h
-        data['rain_24h'] = self.rain24h
-        data['rain_since_midnight'] = self.rainSinceMidnight
-        data['temperature'] = self.temperature
-        data['wind_direction'] = self.windDirection
-        data['wind_gust'] = self.windGust
-        data['wind_speed'] = self.windSpeed
-        data['luminosity'] = self.luminosity
-        data['snow'] = self.snow
-        data['wx_raw_timestamp'] = self.wxRawTimestamp
-        return data
diff --git a/server/trackdirect/objects/Sender.py b/server/trackdirect/objects/Sender.py
deleted file mode 100644
index 6c926be3a9ced33efa19455778b511bf03eb7add..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/Sender.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class Sender(Model):
-    """Sender represents the sender of a packet (often same name as station name)
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-
-        self.id = None
-        self.name = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.name == ''):
-            return False
-
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute(
-                """insert into sender(name) values(%s) RETURNING id""", (self.name.strip(
-                ),)
-            )
-            self.id = insertCursor.fetchone()[0]
-            insertCursor.close()
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Since packet will be updated in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/Station.py b/server/trackdirect/objects/Station.py
deleted file mode 100644
index da4e9d8426e544e4d5461163958a9c97727d1b97..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/Station.py
+++ /dev/null
@@ -1,149 +0,0 @@
-import logging
-from trackdirect.common.Model import Model
-
-
-class Station(Model):
-    """Station represents the object/station that the packet is about
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.logger = logging.getLogger('trackdirect')
-
-        self.id = None
-        self.name = None
-        self.latestSenderId = None
-        self.stationTypeId = 1  # default to 1
-        self.sourceId = None
-
-        self.latestPacketId = None
-        self.latestPacketTimestamp = None
-
-        self.latestLocationPacketId = None
-        self.latestLocationPacketTimestamp = None
-
-        self.latestWeatherPacketId = None
-        self.latestWeatherPacketTimestamp = None
-
-        self.latestTelemetryPacketId = None
-        self.latestTelemetryPacketTimestamp = None
-
-        # Latest packet with a location that is confirmed to be correct
-        self.latestConfirmedPacketId = None
-        self.latestConfirmedPacketTimestamp = None
-        self.latestConfirmedSymbol = None
-        self.latestConfirmedSymbolTable = None
-        self.latestConfirmedLatitude = None
-        self.latestConfirmedLongitude = None
-        self.latestConfirmedMarkerId = None
-
-        self.latestOgnPacketId = None
-        self.latestOgnPacketTimestamp = None
-        self.latestOgnSenderAddress = None
-        self.latestOgnAircraftTypeId = None
-        self.latestOgnAddressTypeId = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.name == ''):
-            return False
-
-        return True
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Since packet will be inserted in batch we never use this method.
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute(
-                """insert into station(name, station_type_id, source_id) values(%s, %s, %s) RETURNING id""", (
-                    self.name.strip(), self.stationTypeId, self.sourceId)
-            )
-            self.id = insertCursor.fetchone()[0]
-            insertCursor.close()
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        if (self.isExistingObject()):
-            cursor = self.db.cursor()
-            cursor.execute(
-                """update station set source_id = %s, name = %s, station_type_id = %s where id = %s and source_id is null""", (
-                    self.sourceId, self.name, self.stationTypeId, self.id)
-            )
-            cursor.close()
-            return True
-        else:
-            return False
-
-    def getShortDict(self):
-        """Returns a dict representation of the object
-
-        Returns:
-            Dict representation of the object
-        """
-        data = {}
-        data['id'] = self.id
-
-        data['name'] = self.name
-        data['latest_sender_id'] = self.latestSenderId
-        data['station_type_id'] = self.stationTypeId
-        data['source_id'] = self.sourceId
-
-        if (self.latestConfirmedPacketId is not None):
-            data['latest_confirmed_packet_id'] = int(
-                self.latestConfirmedPacketId)
-        else:
-            data['latest_confirmed_packet_id'] = None
-
-        data['latest_confirmed_packet_timestamp'] = self.latestConfirmedPacketTimestamp
-        data['latest_confirmed_symbol'] = self.latestConfirmedSymbol
-        data['latest_confirmed_symbol_table'] = self.latestConfirmedSymbolTable
-
-        if (self.latestConfirmedLatitude is not None):
-            data['latest_confirmed_latitude'] = float(
-                self.latestConfirmedLatitude)
-        else:
-            data['latest_confirmed_latitude'] = None
-
-        if (self.latestConfirmedLongitude is not None):
-            data['latest_confirmed_longitude'] = float(
-                self.latestConfirmedLongitude)
-        else:
-            data['latest_confirmed_longitude'] = None
-
-        if (self.latestLocationPacketId is not None):
-            data['latest_location_packet_id'] = self.latestLocationPacketId
-        else:
-            data['latest_location_packet_id'] = None
-
-        data['latest_location_packet_timestamp'] = self.latestLocationPacketTimestamp
-
-        if (self.latestPacketId is not None):
-            data['latest_packet_id'] = int(self.latestPacketId)
-        else:
-            data['latest_packet_id'] = None
-
-        data['latest_packet_timestamp'] = self.latestPacketTimestamp
-
-        return data
diff --git a/server/trackdirect/objects/StationTelemetryBits.py b/server/trackdirect/objects/StationTelemetryBits.py
deleted file mode 100644
index e8e90b0332e3fe5f28c86db261e2644a571d9c1a..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/StationTelemetryBits.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class StationTelemetryBits(Model):
-    """StationTelemetryBits represents the telemetry bits sent by the related station
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.stationId = None
-        self.createdTs = None
-        self.latestTs = None
-        self.validToTs = None
-        self.bits = None
-        self.title = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (type(self.stationId) != int or self.stationId <= 0):
-            return False
-
-        return True
-
-    def save(self):
-        """Save object data to database if attribute data is valid
-
-        Returns:
-            Returns true on success otherwise false
-        """
-        if (self.validate()):
-            if (self.isExistingObject()):
-                return self.update()
-            else:
-                cursor = self.db.cursor()
-                cursor.execute("""update station_telemetry_bits
-                    set latest_ts = %s
-                    where station_id = %s
-                        and valid_to_ts is null
-                        and bits = %s
-                        and title = %s""",
-                               (self.createdTs,
-                                self.stationId,
-                                self.bits,
-                                self.title))
-
-                if (cursor.rowcount == 0):
-                    return self.insert()
-                else:
-                    # We do not insert it since it was equal to the existsing row
-                    return True
-        return False
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute("""update station_telemetry_bits
-                set valid_to_ts = %s
-                where station_id = %s
-                    and valid_to_ts is null""",
-                                 (self.createdTs,
-                                  self.stationId))
-
-            insertCursor.execute("""insert into station_telemetry_bits(
-                    station_id,
-                    created_ts,
-                    latest_ts,
-                    bits,
-                    title)
-                values (%s, %s, %s, %s, %s)""",
-                                 (self.stationId,
-                                  self.createdTs,
-                                  self.createdTs,
-                                  self.bits,
-                                  self.title))
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/StationTelemetryEqns.py b/server/trackdirect/objects/StationTelemetryEqns.py
deleted file mode 100644
index 85b07b8b10c1449cea7e89d830375c69c9decfa9..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/StationTelemetryEqns.py
+++ /dev/null
@@ -1,161 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class StationTelemetryEqns(Model):
-    """StationTelemetryEqns represents the telemetry equations sent by the related station
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.stationId = None
-        self.createdTs = None
-        self.latestTs = None
-        self.validToTs = None
-        self.a1 = None
-        self.b1 = None
-        self.c1 = None
-        self.a2 = None
-        self.b2 = None
-        self.c2 = None
-        self.a3 = None
-        self.b3 = None
-        self.c3 = None
-        self.a4 = None
-        self.b4 = None
-        self.c4 = None
-        self.a5 = None
-        self.b5 = None
-        self.c5 = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (type(self.stationId) != int or self.stationId <= 0):
-            return False
-
-        return True
-
-    def save(self):
-        """Save object data to database if attribute data is valid
-
-        Returns:
-            Returns true on success otherwise false
-        """
-        if (self.validate()):
-            if (self.isExistingObject()):
-                return self.update()
-            else:
-                cursor = self.db.cursor()
-                cursor.execute("""update station_telemetry_eqns
-                    set latest_ts = %s
-                    where station_id = %s
-                        and valid_to_ts is null
-                        and a1::numeric = %s
-                        and b1::numeric = %s
-                        and c1::numeric = %s
-
-                        and a2::numeric = %s
-                        and b2::numeric = %s
-                        and c2::numeric = %s
-
-                        and a3::numeric = %s
-                        and b3::numeric = %s
-                        and c3::numeric = %s
-
-                        and a4::numeric = %s
-                        and b4::numeric = %s
-                        and c4::numeric = %s
-
-                        and a5::numeric = %s
-                        and b5::numeric = %s
-                        and c5::numeric = %s""",
-
-                               (self.createdTs,
-                                self.stationId,
-                                self.a1,
-                                self.b1,
-                                self.c1,
-
-                                self.a2,
-                                self.b2,
-                                self.c2,
-
-                                self.a3,
-                                self.b3,
-                                self.c3,
-
-                                self.a4,
-                                self.b4,
-                                self.c4,
-
-                                self.a5,
-                                self.b5,
-                                self.c5))
-
-                if (cursor.rowcount == 0):
-                    return self.insert()
-                else:
-                    # We do not insert it since it was equal to the existsing row
-                    return True
-        return False
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute("""update station_telemetry_eqns
-                set valid_to_ts = %s
-                where station_id = %s
-                    and valid_to_ts is null""", (
-                self.createdTs,
-                self.stationId))
-
-            insertCursor.execute("""insert into station_telemetry_eqns(station_id, created_ts, latest_ts, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5)
-                values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
-                                 (self.stationId,
-                                  self.createdTs,
-                                  self.timestamp,
-
-                                  self.a1,
-                                  self.b1,
-                                  self.c1,
-
-                                  self.a2,
-                                  self.b2,
-                                  self.c2,
-
-                                  self.a3,
-                                  self.b3,
-                                  self.c3,
-
-                                  self.a4,
-                                  self.b4,
-                                  self.c4,
-
-                                  self.a5,
-                                  self.b5,
-                                  self.c5))
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/StationTelemetryParam.py b/server/trackdirect/objects/StationTelemetryParam.py
deleted file mode 100644
index 11657f0cc346986de9764949b32b2527b950cc80..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/StationTelemetryParam.py
+++ /dev/null
@@ -1,139 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class StationTelemetryParam(Model):
-    """StationTelemetryParam represents the telemetry parameters sent by the related station
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.stationId = None
-        self.createdTs = None
-        self.latestTs = None
-        self.validToTs = None
-        self.p1 = None
-        self.p2 = None
-        self.p3 = None
-        self.p4 = None
-        self.p5 = None
-        self.b1 = None
-        self.b2 = None
-        self.b3 = None
-        self.b4 = None
-        self.b5 = None
-        self.b6 = None
-        self.b7 = None
-        self.b8 = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (type(self.stationId) != int or self.stationId <= 0):
-            return False
-
-        return True
-
-    def save(self):
-        """Save object data to database if attribute data is valid
-
-        Returns:
-            Returns true on success otherwise false
-        """
-        if (self.validate()):
-            if (self.isExistingObject()):
-                return self.update()
-            else:
-                cursor = self.db.cursor()
-                cursor.execute("""update station_telemetry_param
-                    set latest_ts = %s
-                    where station_id = %s
-                        and valid_to_ts is null
-                        and p1 = %s
-                        and p2 = %s
-                        and p3 = %s
-                        and p4 = %s
-                        and p5 = %s
-                        and b1 = %s
-                        and b2 = %s
-                        and b3 = %s
-                        and b4 = %s
-                        and b5 = %s
-                        and b6 = %s
-                        and b7 = %s
-                        and b8 = %s""",
-                               (self.createdTs,
-                                self.stationId,
-                                self.p1,
-                                self.p2,
-                                self.p3,
-                                self.p4,
-                                self.p5,
-                                self.b1,
-                                self.b2,
-                                self.b3,
-                                self.b4,
-                                self.b5,
-                                self.b6,
-                                self.b7,
-                                self.b8))
-
-                if (cursor.rowcount == 0):
-                    return self.insert()
-                else:
-                    # We do not insert it since it was equal to the existsing row
-                    return True
-        return False
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute("""update station_telemetry_param
-                set valid_to_ts = %s
-                where station_id = %s
-                    and valid_to_ts is null""",
-                                 (self.createdTs,
-                                  self.stationId))
-
-            insertCursor.execute("""insert into station_telemetry_param(station_id, created_ts, latest_ts, p1, p2, p3, p4, p5, b1, b2, b3, b4, b5, b6, b7, b8)
-                values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
-                                 (self.stationId,
-                                  self.createdTs,
-                                  self.createdTs,
-                                  self.p1,
-                                  self.p2,
-                                  self.p3,
-                                  self.p4,
-                                  self.p5,
-                                  self.b1,
-                                  self.b2,
-                                  self.b3,
-                                  self.b4,
-                                  self.b5,
-                                  self.b6,
-                                  self.b7,
-                                  self.b8))
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/StationTelemetryUnit.py b/server/trackdirect/objects/StationTelemetryUnit.py
deleted file mode 100644
index 1e9b244b0fcb0301663eddfe53c0050c6f09fd90..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/StationTelemetryUnit.py
+++ /dev/null
@@ -1,140 +0,0 @@
-from trackdirect.common.Model import Model
-
-
-class StationTelemetryUnit(Model):
-    """StationTelemetryUnit represents the telemetry UNIT sent by the related station
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        Model.__init__(self, db)
-        self.id = None
-        self.stationId = None
-        self.createdTs = None
-        self.latestTs = None
-        self.validToTs = None
-        self.u1 = None
-        self.u2 = None
-        self.u3 = None
-        self.u4 = None
-        self.u5 = None
-        self.l1 = None
-        self.l2 = None
-        self.l3 = None
-        self.l4 = None
-        self.l5 = None
-        self.l6 = None
-        self.l7 = None
-        self.l8 = None
-
-    def validate(self):
-        """Returns true on success (when object content is valid), otherwise false
-
-        Returns:
-            True on success otherwise False
-        """
-        if (type(self.stationId) != int or self.stationId <= 0):
-            return False
-
-        return True
-
-    def save(self):
-        """Save object data to database if attribute data is valid
-
-        Returns:
-            Returns true on success otherwise false
-        """
-        if (self.validate()):
-            if (self.isExistingObject()):
-                return self.update()
-            else:
-                cursor = self.db.cursor()
-                cursor.execute("""update station_telemetry_unit
-                    set latest_ts = %s
-                    where station_id = %s
-                        and valid_to_ts is null
-                        and u1 = %s
-                        and u2 = %s
-                        and u3 = %s
-                        and u4 = %s
-                        and u5 = %s
-                        and l1 = %s
-                        and l2 = %s
-                        and l3 = %s
-                        and l4 = %s
-                        and l5 = %s
-                        and l6 = %s
-                        and l7 = %s
-                        and l8 = %s""",
-                               (self.createdTs,
-                                self.stationId,
-                                self.u1,
-                                self.u2,
-                                self.u3,
-                                self.u4,
-                                self.u5,
-                                self.l1,
-                                self.l2,
-                                self.l3,
-                                self.l4,
-                                self.l5,
-                                self.l6,
-                                self.l7,
-                                self.l8))
-
-                if (cursor.rowcount == 0):
-                    return self.insert()
-                else:
-                    # We do not insert it since it was equal to the existsing row
-                    return True
-        return False
-
-    def insert(self):
-        """Method to call when we want to save a new object to database
-
-        Returns:
-            True on success otherwise False
-        """
-        if (not self.isExistingObject()):
-            insertCursor = self.db.cursor()
-            insertCursor.execute("""update station_telemetry_unit
-                set valid_to_ts = %s
-                where station_id = %s
-                and valid_to_ts is null""",
-                                 (self.createdTs,
-                                  self.stationId))
-
-            insertCursor.execute("""insert into station_telemetry_unit(station_id, created_ts, latest_ts, u1, u2, u3, u4, u5, l1, l2, l3, l4, l5, l6, l7, l8)
-                values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
-                                 (self.stationId,
-                                  self.createdTs,
-                                  self.createdTs,
-                                  self.u1,
-                                  self.u2,
-                                  self.u3,
-                                  self.u4,
-                                  self.u5,
-                                  self.l1,
-                                  self.l2,
-                                  self.l3,
-                                  self.l4,
-                                  self.l5,
-                                  self.l6,
-                                  self.l7,
-                                  self.l8))
-
-            return True
-        else:
-            return False
-
-    def update(self):
-        """Method to call when we want to save changes to database
-
-        Returns:
-            True on success otherwise False
-        """
-        return False
diff --git a/server/trackdirect/objects/__init__.py b/server/trackdirect/objects/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/objects/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/parser/AprsISConnection.py b/server/trackdirect/parser/AprsISConnection.py
deleted file mode 100644
index 3cfad1cd076a1e3380b68c839801422390c02e77..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/AprsISConnection.py
+++ /dev/null
@@ -1,140 +0,0 @@
-import logging
-import aprslib
-import collections
-import time
-import re
-
-
-class AprsISConnection(aprslib.IS):
-    """Handles communication with the APRS-IS server
-    """
-
-    def __init__(self, callsign, passwd="-1", host="rotate.aprs.net", port=10152):
-        """The __init__ method.
-
-        Args:
-            callsign (string):               APRS-IS callsign
-            passwd (string):                 APRS-IS password
-            host (string):                   APRS-IS Server hostname
-            port (int):                      APRS-IS Server port
-        """
-        aprslib.IS.__init__(self, callsign, passwd, host, port)
-
-        self.logger = logging.getLogger("aprslib.IS")
-        self.frequencyLimit = None
-        self.stationHashTimestamps = collections.OrderedDict()
-        self.sourceId = 1
-
-    def setFrequencyLimit(self, frequencyLimit):
-        """Set frequency limit
-
-        Args:
-            frequencyLimit (int):  Hard frequency limit (in seconds)
-        """
-        self.frequencyLimit = frequencyLimit
-
-    def getFrequencyLimit(self):
-        """Get frequency limit
-
-        Return:
-            int
-        """
-        return self.frequencyLimit
-
-    def setSourceId(self, sourceId):
-        """Set what source packet is from (APRS, CWOP ...)
-
-        Args:
-            sourceId (int):  Id that corresponds to id in source-table
-        """
-        self.sourceId = sourceId
-
-    def filteredConsumer(self, callback, blocking=True, raw=False):
-        """The filtered consume method
-
-        Args:
-            callback (boolean):    Method to call with result
-            blocking (boolean):    Set to true if consume should be blocking
-            raw (boolean):         Set to true if result should be raw
-        """
-        def filterCallback(line):
-            try:
-                # decode first then replace
-                line = line.decode()
-                line = line.replace('\x00', '')
-            except UnicodeError as e:
-                # string is not UTF-8
-                return
-
-            if line.startswith('dup'):
-                line = line[4:].strip()
-
-            if (self._isSendingToFast(line)):
-                return
-
-            if raw:
-                callback(line)
-            else:
-                callback(self._parse(line))
-
-        self.consumer(filterCallback, blocking, False, True)
-
-    def _isSendingToFast(self, line):
-        """Simple check that returns True if sending frequency limit is to fast
-
-        Args:
-            line (string):         Packet string
-
-        Returns:
-            True if sending frequency limit is to fast
-        """
-        if (self.frequencyLimit is not None):
-            try:
-                (name, other) = line.split('>', 1)
-            except:
-                return False
-
-            # Divide into body and head
-            try:
-                (head, body) = other.split(':', 1)
-            except:
-                return False
-
-            if len(body) == 0:
-                return False
-
-            packetType = body[0]
-            body = body[1:]
-
-            # Try to find turn rate and reduce frequency limit if high turn rate
-            frequencyLimitToApply = int(self.frequencyLimit)
-            if (self.sourceId == 5) :
-                match = re.search("(\+|\-)(\d\.\d)rot ", line)
-                try:
-                    turnRate = abs(float(match.group(2)))
-                    if (turnRate > 0) :
-                        frequencyLimitToApply = int(frequencyLimitToApply / (1+turnRate))
-                except:
-                    pass
-
-            latestTimestampOnMap = 0
-            if (name + packetType in self.stationHashTimestamps):
-                latestTimestampOnMap = self.stationHashTimestamps[name + packetType]
-
-                if (((int(time.time()) - 1) - frequencyLimitToApply) < latestTimestampOnMap):
-                    # This sender is sending faster than config limit
-                    return True
-            self.stationHashTimestamps[name + packetType] = int(time.time()) - 1
-            self._cacheMaintenance()
-        return False
-
-    def _cacheMaintenance(self):
-        """Make sure cache does not contain to many packets
-        """
-        frequencyLimitToApply = int(self.frequencyLimit)
-        maxNumberOfPackets =  frequencyLimitToApply * 1000 # We assume that we never have more than 1000 packets per second
-        if (len(self.stationHashTimestamps) > maxNumberOfPackets):
-            try:
-                self.stationHashTimestamps.popitem(last=False)
-            except (KeyError, StopIteration) as e:
-                pass
diff --git a/server/trackdirect/parser/AprsPacketParser.py b/server/trackdirect/parser/AprsPacketParser.py
deleted file mode 100644
index d8eabb82082cbfbca6f30f84f1d15417d476d5ed..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/AprsPacketParser.py
+++ /dev/null
@@ -1,629 +0,0 @@
-import logging
-from twisted.python import log
-import json
-import datetime
-import time
-import calendar
-import hashlib
-
-from trackdirect.exceptions.TrackDirectParseError import TrackDirectParseError
-from trackdirect.exceptions.TrackDirectMissingSenderError import TrackDirectMissingSenderError
-from trackdirect.exceptions.TrackDirectMissingStationError import TrackDirectMissingStationError
-
-from trackdirect.repositories.OgnHiddenStationRepository import OgnHiddenStationRepository
-from trackdirect.repositories.OgnDeviceRepository import OgnDeviceRepository
-from trackdirect.repositories.StationRepository import StationRepository
-from trackdirect.repositories.SenderRepository import SenderRepository
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.repositories.PacketTelemetryRepository import PacketTelemetryRepository
-from trackdirect.repositories.PacketWeatherRepository import PacketWeatherRepository
-from trackdirect.repositories.PacketOgnRepository import PacketOgnRepository
-from trackdirect.repositories.MarkerRepository import MarkerRepository
-from trackdirect.repositories.StationTelemetryBitsRepository import StationTelemetryBitsRepository
-from trackdirect.repositories.StationTelemetryEqnsRepository import StationTelemetryEqnsRepository
-from trackdirect.repositories.StationTelemetryParamRepository import StationTelemetryParamRepository
-from trackdirect.repositories.StationTelemetryUnitRepository import StationTelemetryUnitRepository
-
-from trackdirect.objects.Packet import Packet
-from trackdirect.objects.Station import Station
-from trackdirect.objects.PacketWeather import PacketWeather
-from trackdirect.objects.PacketTelemetry import PacketTelemetry
-from trackdirect.objects.Marker import Marker
-from trackdirect.objects.OgnHiddenStation import OgnHiddenStation
-from trackdirect.objects.OgnDevice import OgnDevice
-
-from trackdirect.parser.policies.AprsPacketTypePolicy import AprsPacketTypePolicy
-from trackdirect.parser.policies.PacketAssumedMoveTypePolicy import PacketAssumedMoveTypePolicy
-from trackdirect.parser.policies.PacketSpeedComputablePolicy import PacketSpeedComputablePolicy
-from trackdirect.parser.policies.PreviousPacketPolicy import PreviousPacketPolicy
-from trackdirect.parser.policies.PacketTailPolicy import PacketTailPolicy
-from trackdirect.parser.policies.PacketRelatedMapSectorsPolicy import PacketRelatedMapSectorsPolicy
-from trackdirect.parser.policies.PacketMapIdPolicy import PacketMapIdPolicy
-from trackdirect.parser.policies.PacketPathPolicy import PacketPathPolicy
-from trackdirect.parser.policies.MapSectorPolicy import MapSectorPolicy
-from trackdirect.parser.policies.PacketCommentPolicy import PacketCommentPolicy
-from trackdirect.parser.policies.PacketKillCharPolicy import PacketKillCharPolicy
-from trackdirect.parser.policies.StationNameFormatPolicy import StationNameFormatPolicy
-from trackdirect.parser.policies.PacketOgnDataPolicy import PacketOgnDataPolicy
-
-
-class AprsPacketParser():
-    """AprsPacketParser tackes a aprslib output and converts it to a Trackdirect Packet
-    """
-
-    def __init__(self, db, saveOgnStationsWithMissingIdentity):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):                       Database connection
-            saveOgnStationsWithMissingIdentity (boolean):   True if we should not ignore stationss with a missing identity
-        """
-        self.db = db
-        self.saveOgnStationsWithMissingIdentity = saveOgnStationsWithMissingIdentity
-        self.logger = logging.getLogger('trackdirect')
-
-        self.databaseWriteAccess = True
-        self.sourceId = 1
-
-        self.ognDeviceRepository = OgnDeviceRepository(db)
-        self.ognHiddenStationRepository = OgnHiddenStationRepository(db)
-        self.stationRepository = StationRepository(db)
-        self.senderRepository = SenderRepository(db)
-        self.packetRepository = PacketRepository(db)
-        self.packetTelemetryRepository = PacketTelemetryRepository(db)
-        self.packetWeatherRepository = PacketWeatherRepository(db)
-        self.packetOgnRepository = PacketOgnRepository(db)
-        self.markerRepository = MarkerRepository(db)
-        self.stationTelemetryBitsRepository = StationTelemetryBitsRepository(db)
-        self.stationTelemetryEqnsRepository = StationTelemetryEqnsRepository(db)
-        self.stationTelemetryParamRepository = StationTelemetryParamRepository(db)
-        self.stationTelemetryUnitRepository = StationTelemetryUnitRepository(db)
-
-    def setDatabaseWriteAccess(self, databaseWriteAccess):
-        """Enable or disable database updates
-
-        Args:
-            databaseWriteAccess (boolean):   True if we have database access otherwise false
-        """
-        self.databaseWriteAccess = databaseWriteAccess
-
-    def setSourceId(self, sourceId):
-        """Set what source packet is from (APRS, CWOP ...)
-
-        Args:
-            sourceId (int):  Id that corresponds to id in source-table
-        """
-        self.sourceId = sourceId
-
-    def getPacket(self, data, timestamp=None, minimal=False):
-        """Returns the resulting packet
-
-        Args:
-            data (dict):            Raw packet data
-            timestamp (int):        Packet timestamp
-            minimal (boolean):      Set to true to only perform minimal parsing
-
-        Returns:
-            Packet
-        """
-        self.isHiddenStation = False
-        self.data = data
-        self.packet = Packet(self.db)
-        self.packet.sourceId = self.sourceId
-        self._parsePacketInitialValues(timestamp)
-        self._parsePacketReportedTimestamp()
-
-        # Parse OGN stuff before station-id, may result in no station to create
-        self._parsePacketOgn()
-        if (self.packet.mapId != 15):
-            self._parsePacketType()
-            self._parsePacketSender()
-            self._parsePacketStationName()
-            self._parsePacketStationId()
-
-            self._parsePacketRng()
-            self._parsePacketPhg()
-
-            if (self.packet.stationId is None):
-                self.packet.mapId = 4
-            else:
-                self._parsePacketComment()
-                self._parsePacketWeather()
-                self._parsePacketTelemetryDefinition()
-                self._parsePacketTelemetry()
-                self._parsePacketPosition()
-                self._parsePacketPath()
-
-                if (not minimal):
-                    previousPacketPolicy = PreviousPacketPolicy(
-                        self.packet, self.db)
-                    previousPacket = previousPacketPolicy.getPreviousPacket()
-                    self._parseAssumedMoveTypeId(previousPacket)
-                    self._parsePacketTail(previousPacket)
-                    self._parsePacketMapId(previousPacket)
-                    self._parsePacketPreviousTimestamps(previousPacket)
-                    self._parsePacketPhgRngTimestamps(previousPacket)
-                    self._parsePacketRelatedMapSectors(previousPacket)
-
-        if (self.isHiddenStation):
-            if (self.packet.ogn is not None):
-                self.packet.ogn.ognAddressTypeId = None
-                self.packet.ogn.ognSenderAddress = None
-            self.packet.comment = None
-            self.packet.raw = None
-        return self.packet
-
-    def _parsePacketInitialValues(self, timestamp):
-        """Set packet initial values
-
-        Args:
-            timestamp (int):    Packet timestamp
-        """
-        self.packet.raw = self.data['raw'].replace('\x00', '')
-        self.packet.symbol = self.data['symbol'] if (
-            'symbol' in self.data) else None
-        self.packet.symbolTable = self.data['symbol_table'] if (
-            'symbol_table' in self.data) else None
-        self.packet.reportedTimestamp = self.data['timestamp'] if (
-            'timestamp' in self.data) else None
-        self.packet.rawPath = self.data['to'] + ',' + ','.join(self.data['path']) if (
-            'path' in self.data and 'to' in self.data) else None
-        if (timestamp is not None):
-            self.packet.timestamp = timestamp
-        else:
-            self.packet.timestamp = int(time.time())
-        self.packet.positionTimestamp = self.packet.timestamp
-        self.packet.packetTailTimestamp = 0
-        self.packet.posambiguity = self.data['posambiguity'] if (
-            'posambiguity' in self.data) else None
-        self.packet.speed = self.data['speed'] if (
-            'speed' in self.data) else None
-        self.packet.course = self.data['course'] if (
-            'course' in self.data) else None
-        self.packet.altitude = self.data['altitude'] if (
-            'altitude' in self.data) else None
-        self.packet.mapId = 10  # Default map for a packet without a position
-        self.packet.markerId = 1
-        self.packet.markerCounter = 1  # We allways start at 1
-
-    def _parsePacketReportedTimestamp(self):
-        """Set packet reported timestamp
-        """
-        if ('timestamp' in self.data):
-            reportedTimestampDay = int(datetime.datetime.utcfromtimestamp(
-                int(self.data['timestamp'])).strftime('%d'))
-            currentTimestampDay = int(datetime.datetime.utcfromtimestamp(
-                self.packet.timestamp).strftime('%d'))
-            if (reportedTimestampDay > currentTimestampDay and self.data['timestamp'] > self.packet.timestamp):
-                # Day is in the future, the reported timestamp was probably in previous month
-
-                prevMonth = int(datetime.datetime.utcfromtimestamp(
-                    int(self.data['timestamp']) - (reportedTimestampDay+1)*24*60*60).strftime('%m'))
-                prevMonthYear = int(datetime.datetime.utcfromtimestamp(
-                    int(self.data['timestamp']) - (reportedTimestampDay+1)*24*60*60).strftime('%Y'))
-                numberOfDaysInMonth = int(
-                    calendar.monthrange(prevMonthYear, prevMonth)[1])
-
-                self.packet.reportedTimestamp = int(
-                    self.data['timestamp']) - (numberOfDaysInMonth*24*60*60)
-        else:
-            self.packet.reportedTimestamp = None
-
-    def _parsePacketRng(self):
-        """Set packet RNG data
-        """
-        if ('rng' in self.data):
-            try:
-                self.packet.rng = float(self.data['rng'])
-                self.packet.latestRngTimestamp = self.packet.timestamp
-                if (self.packet.rng <= 0):
-                    self.packet.rng = None
-            except ValueError:
-                # Not a float
-                self.packet.rng = None
-
-    def _parsePacketPhg(self):
-        """Set packet PHG data
-        """
-        if ('phg' in self.data):
-            phg = str(self.data['phg'])[0:4]
-            if (len(phg) == 4 and phg.isdigit()):
-                self.packet.phg = phg
-                self.packet.latestPhgTimestamp = self.packet.timestamp
-
-    def _parsePacketSender(self):
-        """Set sender id and name
-        """
-        stationNameFormatPolicy = StationNameFormatPolicy()
-        self.packet.senderName = stationNameFormatPolicy.getCorrectFormat(
-            self.data["from"])
-        try:
-            sender = self.senderRepository.getCachedObjectByName(
-                self.packet.senderName)
-            self.packet.senderId = sender.id
-        except (TrackDirectMissingSenderError) as exp:
-            if (self.databaseWriteAccess):
-                sender = self.senderRepository.getObjectByName(
-                    self.packet.senderName, True, self.packet.sourceId)
-                self.packet.senderId = sender.id
-
-    def _parsePacketStationName(self):
-        """Set station name
-        """
-        if ("object_name" in self.data
-                and self.data["object_name"] is not None
-                and self.data["object_name"] != ''):
-            self.packet.stationTypeId = 2
-            stationNameFormatPolicy = StationNameFormatPolicy()
-            self.packet.stationName = stationNameFormatPolicy.getCorrectFormat(
-                self.data["object_name"])
-            if (self.packet.stationName is None or self.packet.stationName == ''):
-                self.packet.stationName = self.packet.senderName
-            if (self.packet.stationName == self.packet.senderName):
-                self.packet.stationTypeId = 1
-        else:
-            self.packet.stationTypeId = 1
-            self.packet.stationName = self.packet.senderName
-
-    def _parsePacketStationId(self):
-        """Set station id
-        """
-        if (self.packet.stationName is None):
-            return
-        try:
-            station = self.stationRepository.getCachedObjectByName(
-                self.packet.stationName,
-                self.packet.sourceId
-            )
-            self.packet.stationId = station.id
-
-            if (self.packet.stationName != station.name):
-                # Station lower/upper case is modified
-                station.name = self.packet.stationName
-                station.save()
-
-            if (station.stationTypeId != self.packet.stationTypeId and int(self.packet.stationTypeId) == 1):
-                # Switch to station type 1
-                station.stationTypeId = self.packet.stationTypeId
-                station.save()
-
-        except (TrackDirectMissingStationError) as exp:
-            if (self.databaseWriteAccess):
-                station = self.stationRepository.getObjectByName(
-                    self.packet.stationName,
-                    self.packet.sourceId,
-                    self.packet.stationTypeId,
-                    True
-                )
-                self.packet.stationId = station.id
-
-    def _parsePacketComment(self):
-        """Set packet comment
-        """
-        commentPolicy = PacketCommentPolicy()
-        self.packet.comment = commentPolicy.getComment(
-            self.data, self.packet.packetTypeId)
-
-    def _parsePacketOgn(self):
-        """Set th OGN sender address
-        """
-        ognDataPolicy = PacketOgnDataPolicy(
-            self.data, self.ognDeviceRepository, self.packet.sourceId)
-        if (ognDataPolicy.isOgnPositionPacket):
-            originalRaw = self.packet.raw
-
-            if (not ognDataPolicy.isAllowedToTrack):
-                self.packet.mapId = 15
-                return
-
-            elif (not ognDataPolicy.isAllowedToIdentify):
-                if (not self.saveOgnStationsWithMissingIdentity) :
-                    self.packet.mapId = 15
-                    return
-                self.isHiddenStation = True
-                self.data["from"] = self._getHiddenStationName()
-                self.data["object_name"] = None
-
-            self.data['ogn'] = ognDataPolicy.getOgnData()
-            if (self.data['ogn'] is not None):
-                self.packet.ogn = self.packetOgnRepository.getObjectFromPacketData(
-                    self.data)
-                self.packet.ogn.stationId = self.packet.stationId
-                self.packet.ogn.timestamp = self.packet.timestamp
-                self.data["comment"] = None
-            self._modifyOgnSymbol(originalRaw)
-
-    def _modifyOgnSymbol(self, originalRaw):
-        """Sets a better symbol for an OGN station
-
-        Args:
-            originalRaw (string):    Non modified raw
-        """
-        if ((self.packet.symbol == '\'' and self.packet.symbolTable == '/') or (self.packet.symbol == '^' and self.packet.symbolTable in ['/', '\\']) or (self.packet.symbol == 'g' and self.packet.symbolTable in ['/'])):
-            ognDevice = None
-            if (self.packet.ogn is not None and self.packet.ogn.ognSenderAddress is not None):
-                ognDevice = self.ognDeviceRepository.getObjectByDeviceId(
-                    self.packet.ogn.ognSenderAddress)
-
-            if (ognDevice is not None and ognDevice.isExistingObject() and ognDevice.ddbAircraftType > 0 and ognDevice.ddbAircraftType < 6):
-                # If another aircraft type exist in device db, use that instead
-                if (ognDevice.ddbAircraftType == 1):  # Gliders/motoGliders
-                    # Glider -> Glider
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'G'
-
-                elif (ognDevice.ddbAircraftType == 2):  # Planes
-                    # Powered aircraft -> Propeller aircraft
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'P'
-
-                elif (ognDevice.ddbAircraftType == 3):  # Ultralights
-                    # Small plane
-                    self.packet.symbol = '\''
-                    self.packet.symbolTable = '/'
-
-                elif (ognDevice.ddbAircraftType == 4):  # Helicopters
-                    # Helicopter
-                    self.packet.symbol = 'X'
-                    self.packet.symbolTable = '/'
-
-                elif (ognDevice.ddbAircraftType == 5):  # Drones/UAV
-                    # UAV -> Drone
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'D'
-
-            elif (self.packet.ogn is not None and self.packet.ogn.ognAircraftTypeId is not None):
-                if (self.packet.ogn.ognAircraftTypeId == 1):
-                    # Glider -> Glider
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'G'
-                elif (self.packet.ogn.ognAircraftTypeId == 9):
-                    # Jet aircraft -> Jet
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'J'
-                elif (self.packet.ogn.ognAircraftTypeId == 8):
-                    # Powered aircraft -> Propeller aircraft
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'P'
-                elif (self.packet.ogn.ognAircraftTypeId == 13):
-                    # UAV -> Drone
-                    self.packet.symbol = '^'
-                    self.packet.symbolTable = 'D'
-                elif (self.packet.ogn.ognAircraftTypeId == 7): #paraglider
-                    # map to own symbol 94-76.svg (do not show hangglider symbol 103-1.svg, 'g' = 103)
-                    self.packet.symbol = '^' #94
-                    self.packet.symbolTable = 'L' #76
-
-        if ((self.packet.symbol == '\'' and self.packet.symbolTable == '/') or (self.packet.symbol == '^' and self.packet.symbolTable in ['/', '\\'])):
-            # Current symbol is still "small aircraft" or "large aircraft"
-            if (originalRaw.startswith('FMT')):
-                # FMT, Remotely Piloted
-                self.packet.symbol = '^'
-                self.packet.symbolTable = 'R'
-
-    def _getHiddenStationName(self):
-        """Returnes a unidentifiable station name
-
-        Returns:
-            string
-        """
-        date = datetime.datetime.utcfromtimestamp(
-            self.packet.timestamp).strftime('%Y%m%d')
-        dailyStationNameHash = hashlib.sha256(
-            self.data["from"] + date).hexdigest()
-
-        ognHiddenStation = self.ognHiddenStationRepository.getObjectByHashedName(
-            dailyStationNameHash, True)
-        return ognHiddenStation.getStationName()
-
-    def _parsePacketWeather(self):
-        """Parse weather data
-        """
-        if ("weather" in self.data):
-            self.packet.weather = self.packetWeatherRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.weather.stationId = self.packet.stationId
-            self.packet.weather.timestamp = self.packet.timestamp
-
-    def _parsePacketTelemetry(self):
-        """Parse telemetry data
-        """
-        if ("telemetry" in self.data):
-            self.packet.telemetry = self.packetTelemetryRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.telemetry.stationId = self.packet.stationId
-            self.packet.telemetry.timestamp = self.packet.timestamp
-
-    def _parsePacketTelemetryDefinition(self):
-        """Parse telemetry definition
-        """
-        if ("tBITS" in self.data):
-            self.packet.stationTelemetryBits = self.stationTelemetryBitsRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.stationTelemetryBits.stationId = self.packet.stationId
-            self.packet.stationTelemetryBits.timestamp = self.packet.timestamp
-
-        if ("tEQNS" in self.data):
-            self.packet.stationTelemetryEqns = self.stationTelemetryEqnsRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.stationTelemetryEqns.stationId = self.packet.stationId
-            self.packet.stationTelemetryEqns.timestamp = self.packet.timestamp
-
-        if ("tPARM" in self.data):
-            self.packet.stationTelemetryParam = self.stationTelemetryParamRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.stationTelemetryParam.stationId = self.packet.stationId
-            self.packet.stationTelemetryParam.timestamp = self.packet.timestamp
-
-        if ("tUNIT" in self.data):
-            self.packet.stationTelemetryUnit = self.stationTelemetryUnitRepository.getObjectFromPacketData(
-                self.data)
-            self.packet.stationTelemetryUnit.stationId = self.packet.stationId
-            self.packet.stationTelemetryUnit.timestamp = self.packet.timestamp
-
-    def _parsePacketType(self):
-        """Set packet type
-        """
-        aprsPacketTypePolicy = AprsPacketTypePolicy()
-        self.packet.packetTypeId = aprsPacketTypePolicy.getPacketType(
-            self.packet)
-
-    def _parsePacketPosition(self):
-        """Parse the packet position and related attributes
-        """
-        if ("latitude" in self.data
-            and "longitude" in self.data
-            and self.data["latitude"] is not None
-                and self.data["longitude"] is not None):
-
-            self.packet.latitude = self.data['latitude']
-            self.packet.longitude = self.data['longitude']
-
-            mapSectorPolicy = MapSectorPolicy()
-            self.packet.mapSector = mapSectorPolicy.getMapSector(
-                self.data["latitude"], self.data["longitude"])
-            self.packet.mapId = 1  # Default map for a packet with a position
-            self.packet.isMoving = 1  # Moving/Stationary, default value is moving
-
-    def _parsePacketPath(self):
-        """Parse packet path
-        """
-        if ("path" in self.data and isinstance(self.data["path"], list)):
-            packetPathPolicy = PacketPathPolicy(
-                self.data['path'], self.packet.sourceId, self.stationRepository, self.senderRepository)
-            self.packet.stationIdPath = packetPathPolicy.getStationIdPath()
-            self.packet.stationNamePath = packetPathPolicy.getStationNamePath()
-            self.packet.stationLocationPath = packetPathPolicy.getStationLocationPath()
-
-    def _getPacketRawBody(self):
-        """Returns packet raw body as string
-
-        Returns:
-            Packet raw body as string
-        """
-        try:
-            (rawHeader, rawBody) = self.data["raw"].split(':', 1)
-        except:
-            raise TrackDirectParseError(
-                'Could not split packet into header and body', self.data)
-
-        if len(rawBody) == 0:
-            raise TrackDirectParseError('Packet body is empty', self.data)
-        return rawBody
-
-    def _parsePacketPhgRngTimestamps(self, previousPacket):
-        """Set current packet timestamp when latest rng / phg was received
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        if (previousPacket.isExistingObject()
-                and self.packet.isPostitionEqual(previousPacket)):
-            if (self.packet.phg is None
-                    and previousPacket.latestPhgTimestamp is not None
-                    and previousPacket.latestPhgTimestamp > (self.packet.timestamp - (60*60*24))):
-                self.latestPhgTimestamp = previousPacket.latestPhgTimestamp
-
-            if (self.packet.rng is None
-                    and previousPacket.latestRngTimestamp is not None
-                    and previousPacket.latestRngTimestamp > (self.packet.timestamp - (60*60*24))):
-                self.latestRngTimestamp = previousPacket.latestRngTimestamp
-
-    def _parsePacketMapId(self, previousPacket):
-        """Set current packet map id and related
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        mapIdPolicy = PacketMapIdPolicy(self.packet, previousPacket)
-        killCharPolicy = PacketKillCharPolicy()
-        if (killCharPolicy.hasKillCharacter(self.data)):
-            mapIdPolicy.enableHavingKillCharacter()
-
-        if (mapIdPolicy.isReplacingPreviousPacket()):
-            self.packet.replacePacketId = previousPacket.id
-            self.packet.replacePacketTimestamp = previousPacket.timestamp
-
-        if (mapIdPolicy.isConfirmingPreviousPacket()):
-            self.packet.confirmPacketId = previousPacket.id
-            self.packet.confirmPacketTimestamp = previousPacket.timestamp
-
-        if (mapIdPolicy.isKillingPreviousPacket()):
-            self.packet.abnormalPacketId = previousPacket.id
-            self.packet.abnormalPacketTimestamp = previousPacket.timestamp
-
-        self.packet.mapId = mapIdPolicy.getMapId()
-        self.packet.markerId = mapIdPolicy.getMarkerId()
-        if (self.packet.markerId is None):
-            # Policy could not find a marker id to use, create a new
-            self.packet.markerId = self._getNewMarkerId()
-            if (self.packet.markerId == 1):
-                self.packet.mapId = 4
-
-    def _parsePacketPreviousTimestamps(self, previousPacket):
-        """Set packet previous timestamps and related
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        if (previousPacket.isExistingObject()
-                and self.packet.markerId == previousPacket.markerId):
-            isPostitionEqual = self.packet.isPostitionEqual(previousPacket)
-            if (not self.databaseWriteAccess
-                    and isPostitionEqual
-                    and self.packet.isMoving == 1
-                    and previousPacket.positionTimestamp == previousPacket.timestamp):
-                # This is probably the exact same packet
-                self.packet.markerPrevPacketTimestamp = previousPacket.markerPrevPacketTimestamp
-                self.packet.markerCounter = previousPacket.markerCounter
-                self.packet.positionTimestamp = self.packet.timestamp
-            else:
-                self.packet.markerPrevPacketTimestamp = previousPacket.timestamp
-                self.packet.markerCounter = previousPacket.markerCounter + 1
-                if (isPostitionEqual):
-                    self.packet.positionTimestamp = previousPacket.positionTimestamp
-                else:
-                    self.packet.positionTimestamp = self.packet.timestamp
-
-    def _parseAssumedMoveTypeId(self, previousPacket):
-        """Set current packet move type id
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        packetAssumedMoveTypePolicy = PacketAssumedMoveTypePolicy(self.db)
-        self.packet.isMoving = packetAssumedMoveTypePolicy.getAssumedMoveType(self.packet, previousPacket)
-
-    def _parsePacketTail(self, previousPacket):
-        """Set current packet tail timestamp
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        packetTailPolicy = PacketTailPolicy(self.packet, previousPacket)
-        self.packet.packetTailTimestamp = packetTailPolicy.getPacketTailTimestamp()
-
-    def _parsePacketRelatedMapSectors(self, previousPacket):
-        """Set current packet related map sectors
-
-        Args:
-            previousPacket (Packet): Packet object that represents the packet before the current packet
-        """
-        packetRelatedMapSectorsPolicy = PacketRelatedMapSectorsPolicy(
-            self.packetRepository)
-        self.packet.relatedMapSectors = packetRelatedMapSectorsPolicy.getAllRelatedMapSectors(
-            self.packet, previousPacket)
-
-    def _getNewMarkerId(self):
-        """Creates a new marker id
-
-        Returns:
-            int
-        """
-        if (not self.databaseWriteAccess):
-            return 1
-        else:
-            # No suitable marker id found, let's create a new!
-            marker = self.markerRepository.create()
-            marker.save()
-            return marker.id
diff --git a/server/trackdirect/parser/__init__.py b/server/trackdirect/parser/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/parser/policies/AprsPacketSymbolPolicy.py b/server/trackdirect/parser/policies/AprsPacketSymbolPolicy.py
deleted file mode 100644
index 20e39008c884c0980276040c4787e152fe8968ce..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/AprsPacketSymbolPolicy.py
+++ /dev/null
@@ -1,410 +0,0 @@
-class AprsPacketSymbolPolicy():
-    """The AprsPacketSymbolPolicy class can answer APRS symbol related questions for a specified packet symbol characters.
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-        self.primarySymbolMoving = []
-        self.primarySymbolStationary = []
-        self.primarySymbolMaybeMoving = []
-
-        self.alternativeSymbolMoving = []
-        self.alternativeSymbolStationary = []
-        self.alternativeSymbolMaybeMoving = []
-
-        self.primarySymbolWeather = []
-        self.alternativeSymbolWeather = []
-
-        self._initSymbolArrays()
-
-    def isMovingSymbol(self, symbol, symbolTable):
-        """Returns true is symbol indicates that station is of moving type
-
-        Args:
-            symbol (string):        The symbol character
-            symbolTable (string):   The symbol table character
-
-        Returns:
-            Boolean
-        """
-        if (symbolTable == "/"):
-            # Primary symbol
-            if (symbol in self.primarySymbolMoving):
-                return True
-        else:
-            # Alternative Symbol
-            if (symbol in self.alternativeSymbolMoving):
-                return True
-        return False
-
-    def isMaybeMovingSymbol(self, symbol, symbolTable):
-        """Returns true is symbol indicates that station maybe is moving
-
-        Note:
-            "maybe moving" means that station should be treated as it's stationary, but you should allways be ready to change your mind and treat it as moving.
-
-        Args:
-            symbol (string):        The symbol character
-            symbolTable (string):   The symbol table character
-
-        Returns:
-            Boolean
-        """
-        if (symbolTable == "/"):
-            # Primary symbol
-            if (symbol in self.primarySymbolMaybeMoving):
-                return True
-        else:
-            # Alternative Symbol
-            if (symbol in self.alternativeSymbolMaybeMoving):
-                return True
-        return False
-
-    def isStationarySymbol(self, symbol, symbolTable):
-        """Returns true is symbol indicates that station seems to be stationary
-
-        Args:
-            symbol (string):        The symbol character
-            symbolTable (string):   The symbol table character
-
-        Returns:
-            Boolean
-        """
-        if (symbolTable == "/"):
-            # Primary symbol
-            if (symbol in self.primarySymbolStationary):
-                return True
-        else:
-            # Alternative Symbol
-            if (symbol in self.alternativeSymbolStationary):
-                return True
-        return False
-
-    def isWeatherSymbol(self, symbol, symbolTable):
-        """Returns true is symbol seems to be a weather station symbol
-
-        Args:
-            symbol (string):        The symbol character
-            symbolTable (string):   The symbol table character
-
-        Returns:
-            Boolean
-        """
-        if (symbolTable == "/"):
-            # Primary symbol
-            if (symbol in self.primarySymbolWeather):
-                return True
-        else:
-            # Alternative Symbol
-            if (symbol in self.alternativeSymbolWeather):
-                return True
-        return False
-
-    def _initSymbolArrays(self):
-        """Init the symbol arrays
-        """
-        # If we are not sure if it is moving or not we should set it to maybe moving
-        # A station marked as stationary will not get a tail on map (it will get a new marker Id for each new position), until a certain limit
-        self.primarySymbolStationary.append('!')  # BB  Police, Sheriff
-        self.primarySymbolStationary.append('"')  # BC  reserved  (was rain)
-        self.primarySymbolStationary.append('#')  # BD  DIGI (white center)
-        self.primarySymbolMaybeMoving.append('$')  # BE  PHONE
-        self.primarySymbolStationary.append('%')  # BF  DX CLUSTER
-        self.primarySymbolStationary.append('&')  # BG  HF GATEway
-        self.primarySymbolMaybeMoving.append(
-            '\'')  # BH  Small AIRCRAFT (SSID-11)
-        self.primarySymbolMoving.append('(')  # BI  Mobile Satellite Station
-        self.primarySymbolMaybeMoving.append(
-            ')')  # BJ  Wheelchair (handicapped)
-        self.primarySymbolMoving.append('*')  # BK  SnowMobile
-        self.primarySymbolStationary.append('+')  # BL  Red Cross
-        self.primarySymbolStationary.append(',')  # BM  Boy Scouts
-        self.primarySymbolStationary.append('-')  # BN  House QTH (VHF)
-        self.primarySymbolStationary.append('.')  # BO  X
-        self.primarySymbolMaybeMoving.append('/')  # BP  Red Dot
-        self.primarySymbolMaybeMoving.append('0')  # P0  # circle (obsolete)
-        self.primarySymbolMaybeMoving.append(
-            '1')  # P1  TBD (these were numbered)
-        self.primarySymbolMaybeMoving.append(
-            '2')  # P2  TBD (circles like pool)
-        self.primarySymbolMaybeMoving.append('3')  # P3  TBD (balls.  But with)
-        self.primarySymbolMaybeMoving.append('4')  # P4  TBD (overlays, we can)
-        self.primarySymbolMaybeMoving.append(
-            '5')  # P5  TBD (put all #'s on one)
-        self.primarySymbolMaybeMoving.append(
-            '6')  # P6  TBD (So 1-9 are available)
-        self.primarySymbolMaybeMoving.append('7')  # P7  TBD (for new uses?)
-        self.primarySymbolMaybeMoving.append(
-            '8')  # P8  TBD (They are often used)
-        self.primarySymbolMaybeMoving.append(
-            '9')  # P9  TBD (as mobiles at events)
-        self.primarySymbolStationary.append(':')  # MR  FIRE
-        self.primarySymbolMaybeMoving.append(
-            ';')  # MS  Campground (Portable ops)
-        self.primarySymbolMoving.append('<')  # MT  Motorcycle     (SSID-10)
-        self.primarySymbolMaybeMoving.append('=')  # MU  RAILROAD ENGINE
-        self.primarySymbolMoving.append('>')  # MV  CAR            (SSID-9)
-        self.primarySymbolStationary.append('?')  # MW  SERVER for Files
-        self.primarySymbolStationary.append('@')  # MX  HC FUTURE predict (dot)
-        self.primarySymbolStationary.append('A')  # PA  Aid Station
-        self.primarySymbolStationary.append('B')  # PB  BBS or PBBS
-        self.primarySymbolMoving.append('C')  # PC  Canoe
-        self.primarySymbolStationary.append('D')  # PD
-        self.primarySymbolStationary.append('E')  # PE  EYEBALL (Events, etc!)
-        self.primarySymbolMoving.append('F')  # PF  Farm Vehicle (tractor)
-        self.primarySymbolStationary.append('G')  # PG  Grid Square (6 digit)
-        self.primarySymbolStationary.append('H')  # PH  HOTEL (blue bed symbol)
-        self.primarySymbolStationary.append(
-            'I')  # PI  TcpIp on air network stn
-        self.primarySymbolStationary.append('J')  # PJ
-        self.primarySymbolStationary.append('K')  # PK  School
-        self.primarySymbolMaybeMoving.append('L')  # PL  PC user (Jan 03)
-        self.primarySymbolMaybeMoving.append('M')  # PM  MacAPRS
-        self.primarySymbolStationary.append('N')  # PN  NTS Station
-        self.primarySymbolMoving.append('O')  # PO  BALLOON        (SSID-11)
-        self.primarySymbolMaybeMoving.append('P')  # PP  Police
-        self.primarySymbolStationary.append('Q')  # PQ  TBD
-        self.primarySymbolMaybeMoving.append(
-            'R')  # PR  REC. VEHICLE   (SSID-13)
-        self.primarySymbolMaybeMoving.append('S')  # PS  SHUTTLE
-        self.primarySymbolStationary.append('T')  # PT  SSTV
-        self.primarySymbolMoving.append('U')  # PU  BUS            (SSID-2)
-        self.primarySymbolStationary.append('V')  # PV  ATV
-        self.primarySymbolStationary.append(
-            'W')  # PW  National WX Service Site
-        self.primarySymbolMaybeMoving.append(
-            'X')  # PX  HELO           (SSID-6)
-        self.primarySymbolMoving.append('Y')  # PY  YACHT (sail)   (SSID-5)
-        self.primarySymbolMaybeMoving.append('Z')  # PZ  WinAPRS
-        self.primarySymbolMoving.append('[')  # HS  Human/Person   (SSID-7)
-        self.primarySymbolStationary.append('\\')  # HT  TRIANGLE(DF station)
-        self.primarySymbolStationary.append(
-            ']')  # HU  MAIL/PostOffice(was PBBS)
-        self.primarySymbolMaybeMoving.append('^')  # HV  LARGE AIRCRAFT
-        self.primarySymbolStationary.append('_')  # HW  WEATHER Station (blue)
-        self.primarySymbolStationary.append('`')  # HX  Dish Antenna
-        self.primarySymbolMaybeMoving.append('a')  # LA  AMBULANCE     (SSID-1)
-        self.primarySymbolMoving.append('b')  # LB  BIKE          (SSID-4)
-        self.primarySymbolStationary.append('c')  # LC  Incident Command Post
-        self.primarySymbolStationary.append('d')  # LD  Fire dept
-        self.primarySymbolMoving.append('e')  # LE  HORSE (equestrian)
-        self.primarySymbolMaybeMoving.append('f')  # LF  FIRE TRUCK    (SSID-3)
-        self.primarySymbolMoving.append('g')  # LG  Glider
-        self.primarySymbolStationary.append('h')  # LH  HOSPITAL
-        self.primarySymbolStationary.append(
-            'i')  # LI  IOTA (islands on the air)
-        self.primarySymbolMoving.append('j')  # LJ  JEEP          (SSID-12)
-        self.primarySymbolMoving.append('k')  # LK  TRUCK         (SSID-14)
-        self.primarySymbolMaybeMoving.append(
-            'l')  # LL  Laptop (Jan 03)  (Feb 07)
-        self.primarySymbolStationary.append('m')  # LM  Mic-E Repeater
-        self.primarySymbolStationary.append('n')  # LN  Node (black bulls-eye)
-        self.primarySymbolStationary.append('o')  # LO  EOC
-        self.primarySymbolMoving.append('p')  # LP  ROVER (puppy, or dog)
-        self.primarySymbolStationary.append(
-            'q')  # LQ  GRID SQ shown above 128 m
-        self.primarySymbolStationary.append(
-            'r')  # LR  Repeater         (Feb 07)
-        self.primarySymbolMoving.append('s')  # LS  SHIP (pwr boat)  (SSID-8)
-        self.primarySymbolStationary.append('t')  # LT  TRUCK STOP
-        self.primarySymbolMoving.append('u')  # LU  TRUCK (18 wheeler)
-        self.primarySymbolMoving.append('v')  # LV  VAN           (SSID-15)
-        self.primarySymbolStationary.append('w')  # LW  WATER station
-        self.primarySymbolStationary.append('x')  # LX  xAPRS (Unix)
-        self.primarySymbolStationary.append('y')  # LY  YAGI @ QTH
-        self.primarySymbolStationary.append('z')  # LZ  TBD
-        self.primarySymbolStationary.append('{')  # J1
-        self.primarySymbolStationary.append('|')  # J2  TNC Stream Switch
-        self.primarySymbolStationary.append('}')  # J3
-        self.primarySymbolStationary.append('~')  # J4  TNC Stream Switch
-
-        self.alternativeSymbolStationary.append(
-            '!')  # OBO EMERGENCY (and overlays)
-        self.alternativeSymbolStationary.append('"')  # OC  reserved
-        self.alternativeSymbolStationary.append(
-            '#')  # OD# OVERLAY DIGI (green star)
-        self.alternativeSymbolStationary.append(
-            '$')  # OEO Bank or ATM  (green box)
-        self.alternativeSymbolStationary.append(
-            '%')  # OFO Power Plant with overlay
-        self.alternativeSymbolStationary.append(
-            '&')  # OG# I=Igte R=RX T=1hopTX 2=2hopTX
-        self.alternativeSymbolStationary.append(
-            '\'')  # OHO Crash (& now Incident sites)
-        self.alternativeSymbolStationary.append(
-            '(')  # OIO CLOUDY (other clouds w ovrly)
-        # OJO Firenet MEO, MODIS Earth Obs.
-        self.alternativeSymbolStationary.append(')')
-        self.alternativeSymbolStationary.append(
-            '*')  # OK  AVAIL (SNOW moved to ` ovly S)
-        self.alternativeSymbolStationary.append('+')  # OL  Church
-        self.alternativeSymbolStationary.append(',')  # OM  Girl Scouts
-        self.alternativeSymbolStationary.append(
-            '-')  # ONO House (H=HF) (O = Op Present)
-        self.alternativeSymbolStationary.append(
-            '.')  # OO  Ambiguous (Big Question mark)
-        self.alternativeSymbolStationary.append(
-            '/')  # OP  Waypoint Destination
-        self.alternativeSymbolStationary.append(
-            '0')  # A0# CIRCLE (IRLP/Echolink/WIRES)
-        self.alternativeSymbolStationary.append('1')  # A1  AVAIL
-        self.alternativeSymbolStationary.append('2')  # A2  AVAIL
-        self.alternativeSymbolStationary.append('3')  # A3  AVAIL
-        self.alternativeSymbolStationary.append('4')  # A4  AVAIL
-        self.alternativeSymbolStationary.append('5')  # A5  AVAIL
-        self.alternativeSymbolStationary.append('6')  # A6  AVAIL
-        self.alternativeSymbolStationary.append('7')  # A7  AVAIL
-        self.alternativeSymbolMaybeMoving.append(
-            '8')  # A8O 802.11 or other network node
-        self.alternativeSymbolStationary.append(
-            '9')  # A9  Gas Station (blue pump)
-        self.alternativeSymbolStationary.append(
-            ':')  # NR  AVAIL (Hail ==> ` ovly H)
-        self.alternativeSymbolStationary.append(
-            ';')  # NSO Park/Picnic + overlay events
-        self.alternativeSymbolStationary.append(
-            '<')  # NTO ADVISORY (one WX flag)
-        self.alternativeSymbolMaybeMoving.append(
-            '=')  # NUO APRStt Touchtone (DTMF users)
-        self.alternativeSymbolMoving.append(
-            '>')  # NV# OVERLAYED CARs & Vehicles
-        self.alternativeSymbolStationary.append(
-            '?')  # NW  INFO Kiosk  (Blue box with ?)
-        self.alternativeSymbolStationary.append('@')  # NX  HURICANE/Trop-Storm
-        self.alternativeSymbolStationary.append(
-            'A')  # AA# overlayBOX DTMF & RFID & XO
-        self.alternativeSymbolStationary.append(
-            'B')  # AB  AVAIL (BlwngSnow ==> E ovly B
-        self.alternativeSymbolStationary.append('C')  # AC  Coast Guard
-        self.alternativeSymbolStationary.append(
-            'D')  # ADO  DEPOTS (Drizzle ==> ' ovly D)
-        self.alternativeSymbolStationary.append(
-            'E')  # AE  Smoke (& other vis codes)
-        self.alternativeSymbolStationary.append(
-            'F')  # AF  AVAIL (FrzngRain ==> `F)
-        self.alternativeSymbolStationary.append(
-            'G')  # AG  AVAIL (Snow Shwr ==> I ovly S)
-        self.alternativeSymbolStationary.append(
-            'H')  # AHO \Haze (& Overlay Hazards)
-        self.alternativeSymbolStationary.append('I')  # AI  Rain Shower
-        # AJ  AVAIL (Lightening ==> I ovly L)
-        self.alternativeSymbolStationary.append('J')
-        self.alternativeSymbolMaybeMoving.append('K')  # AK  Kenwood HT (W)
-        self.alternativeSymbolStationary.append('L')  # AL  Lighthouse
-        self.alternativeSymbolStationary.append(
-            'M')  # AMO MARS (A=Army,N=Navy,F=AF)
-        self.alternativeSymbolStationary.append('N')  # AN  Navigation Buoy
-        self.alternativeSymbolMaybeMoving.append(
-            'O')  # AO  Overlay Balloon (Rocket = \O)
-        # AP  Parking  [Some cars use this when they stop]
-        self.alternativeSymbolMaybeMoving.append('P')
-        self.alternativeSymbolStationary.append('Q')  # AQ  QUAKE
-        self.alternativeSymbolStationary.append('R')  # ARO Restaurant
-        self.alternativeSymbolMoving.append('S')  # AS  Satellite/Pacsat
-        self.alternativeSymbolStationary.append('T')  # AT  Thunderstorm
-        self.alternativeSymbolStationary.append('U')  # AU  SUNNY
-        self.alternativeSymbolStationary.append('V')  # AV  VORTAC Nav Aid
-        self.alternativeSymbolStationary.append(
-            'W')  # AW# # NWS site (NWS options)
-        self.alternativeSymbolStationary.append(
-            'X')  # AX  Pharmacy Rx (Apothicary)
-        self.alternativeSymbolMaybeMoving.append('Y')  # AYO Radios and devices
-        self.alternativeSymbolStationary.append('Z')  # AZ  AVAIL
-        self.alternativeSymbolMaybeMoving.append(
-            '[')  # DSO W.Cloud (& humans w Ovrly)
-        self.alternativeSymbolMaybeMoving.append(
-            '\\')  # DTO New overlayable GPS symbol
-        self.alternativeSymbolStationary.append(']')  # DU  AVAIL
-        self.alternativeSymbolMaybeMoving.append(
-            '^')  # DV# other Aircraft ovrlys (2014)
-        self.alternativeSymbolStationary.append(
-            '_')  # DW# # WX site (green digi)
-        self.alternativeSymbolStationary.append(
-            '`')  # DX  Rain (all types w ovrly)
-        self.alternativeSymbolStationary.append(
-            'a')  # SA#O ARRL,ARES,WinLINK,Dstar, etc
-        self.alternativeSymbolStationary.append(
-            'b')  # SB  AVAIL(Blwng Dst/Snd => E ovly)
-        self.alternativeSymbolStationary.append(
-            'c')  # SC#O CD triangle RACES/SATERN/etc
-        self.alternativeSymbolStationary.append('d')  # SD  DX spot by callsign
-        self.alternativeSymbolStationary.append(
-            'e')  # SE  Sleet (& future ovrly codes)
-        self.alternativeSymbolStationary.append('f')  # SF  Funnel Cloud
-        self.alternativeSymbolStationary.append('g')  # SG  Gale Flags
-        self.alternativeSymbolStationary.append(
-            'h')  # SHO Store. or HAMFST Hh=HAM store
-        self.alternativeSymbolStationary.append(
-            'i')  # SI# BOX or points of Interest
-        self.alternativeSymbolMaybeMoving.append(
-            'j')  # SJ  WorkZone (Steam Shovel)
-        # SKO Special Vehicle SUV,ATV,4x4
-        self.alternativeSymbolMoving.append('k')
-        self.alternativeSymbolStationary.append(
-            'l')  # SL  Areas(box,circles,etc)
-        self.alternativeSymbolStationary.append(
-            'm')  # SM  Value Sign (3 digit display)
-        self.alternativeSymbolStationary.append('n')  # SN# OVERLAY TRIANGLE
-        self.alternativeSymbolStationary.append('o')  # SO  small circle
-        self.alternativeSymbolStationary.append(
-            'p')  # SP  AVAIL (PrtlyCldy => ( ovly P
-        self.alternativeSymbolStationary.append('q')  # SQ  AVAIL
-        self.alternativeSymbolStationary.append('r')  # SR  Restrooms
-        self.alternativeSymbolMoving.append('s')  # SS# OVERLAY SHIP/boats
-        self.alternativeSymbolStationary.append('t')  # ST  Tornado
-        self.alternativeSymbolMoving.append('u')  # SU# OVERLAYED TRUCK
-        self.alternativeSymbolMoving.append('v')  # SV# OVERLAYED Van
-        self.alternativeSymbolStationary.append(
-            'w')  # SWO Flooding (Avalanches/Slides)
-        self.alternativeSymbolStationary.append(
-            'x')  # SX  Wreck or Obstruction ->X<-
-        self.alternativeSymbolStationary.append('y')  # SY  Skywarn
-        self.alternativeSymbolStationary.append('z')  # SZ# OVERLAYED Shelter
-        self.alternativeSymbolStationary.append(
-            '{')  # Q1  AVAIL? (Fog ==> E ovly F)
-        self.alternativeSymbolStationary.append('|')  # Q2  TNC Stream Switch
-        self.alternativeSymbolStationary.append('}')  # Q3  AVAIL? (maybe)
-        self.alternativeSymbolStationary.append('~')  # Q4  TNC Stream Switch
-
-        self.primarySymbolWeather.append('W')  # PW  National WX Service Site
-        self.primarySymbolWeather.append('_')  # HW  WEATHER Station (blue)
-
-        self.alternativeSymbolWeather.append(
-            '(')  # OIO CLOUDY (other clouds w ovrly)
-        # OK  AVAIL (SNOW moved to ` ovly S)
-        self.alternativeSymbolWeather.append('*')
-        self.alternativeSymbolWeather.append(
-            ':')  # NR  AVAIL (Hail ==> ` ovly H)
-        self.alternativeSymbolWeather.append('@')  # NX  HURICANE/Trop-Storm
-        self.alternativeSymbolWeather.append(
-            'B')  # AB  AVAIL (BlwngSnow ==> E ovly B
-        # ADO  DEPOTS (Drizzle ==> ' ovly D)
-        self.alternativeSymbolWeather.append('D')
-        self.alternativeSymbolWeather.append(
-            'F')  # AF  AVAIL (FrzngRain ==> `F)
-        # AG  AVAIL (Snow Shwr ==> I ovly S)
-        self.alternativeSymbolWeather.append('G')
-        self.alternativeSymbolWeather.append(
-            'H')  # AHO \Haze (& Overlay Hazards)
-        self.alternativeSymbolWeather.append('I')  # AI  Rain Shower
-        # AJ  AVAIL (Lightening ==> I ovly L)
-        self.alternativeSymbolWeather.append('J')
-        self.alternativeSymbolWeather.append('T')  # AT  Thunderstorm
-        self.alternativeSymbolWeather.append('U')  # AU  SUNNY
-        self.alternativeSymbolWeather.append(
-            '[')  # DSO W.Cloud (& humans w Ovrly)
-        self.alternativeSymbolWeather.append('_')  # DW# # WX site (green digi)
-        self.alternativeSymbolWeather.append(
-            '`')  # DX  Rain (all types w ovrly)
-        # SB  AVAIL(Blwng Dst/Snd => E ovly)
-        self.alternativeSymbolWeather.append('b')
-        # SE  Sleet (& future ovrly codes)
-        self.alternativeSymbolWeather.append('e')
-        self.alternativeSymbolWeather.append('f')  # SF  Funnel Cloud
-        # SP  AVAIL (PrtlyCldy => ( ovly P
-        self.alternativeSymbolWeather.append('p')
-        self.alternativeSymbolWeather.append('t')  # ST  Tornado
-        self.alternativeSymbolWeather.append('y')  # SY  Skywarn
-        self.alternativeSymbolWeather.append(
-            '{')  # Q1  AVAIL? (Fog ==> E ovly F)
diff --git a/server/trackdirect/parser/policies/AprsPacketTypePolicy.py b/server/trackdirect/parser/policies/AprsPacketTypePolicy.py
deleted file mode 100644
index 651cae2e5a4397a823df33d76f7da07b278a8695..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/AprsPacketTypePolicy.py
+++ /dev/null
@@ -1,275 +0,0 @@
-from trackdirect.exceptions.TrackDirectParseError import TrackDirectParseError
-
-
-class AprsPacketTypePolicy():
-    """The AprsPacketTypePolicy class can answer questions related to what packet type
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-        self.onlyPositionCharList = []
-        self.generalPositionCharList = []
-        self.objectCharList = []
-        self.itemCharList = []
-        self.weatherCharList = []
-        self.telemetryCharList = []
-        self.messageCharList = []
-        self.queryCharList = []
-        self.statusCharList = []
-        self.otherCharList = []
-        self._initPacketTypeArrays()
-
-    def getPacketType(self, packet):
-        """Returns the packet type id
-
-        Args:
-            packet (Packet):  Packet that we want analyze
-
-        Returns:
-            Packet type id as integer
-        """
-        if (packet is None):
-            return 11
-        elif (packet.sourceId == 4):
-            return 12
-        else:
-            packetTypeChar = self._getPacketTypeChar(packet)
-
-            if (self._isPositionPacketType(packetTypeChar)):
-                return 1
-            elif (self._isGeneralPositionPacketType(packetTypeChar)):
-                if (packet.symbol == "\\" and packet.symbolTable == "/"):
-                    return 2
-                elif (packet.symbol == "_"):
-                    return 3
-                else:
-                    return 1
-            elif (self._isObjectPacketType(packetTypeChar)):
-                return 4
-            elif (self._isItemPacketType(packetTypeChar)):
-                return 5
-            elif (self._isWeatherPacketType(packetTypeChar)):
-                return 3
-            elif (self._isTelemetryPacketType(packetTypeChar)):
-                return 6
-            elif (self._isMessagePacketType(packetTypeChar)):
-                return 7
-            elif (self._isQueryPacketType(packetTypeChar)):
-                return 8
-            elif (self._isStatusPacketType(packetTypeChar)):
-                return 10
-            elif (self._isOtherPacketType(packetTypeChar)):
-                return 11
-            else:
-                return 11
-
-    def _isPositionPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type position
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type position
-        """
-        if (packetTypeChar in self.onlyPositionCharList):
-            return True
-        else:
-            return False
-
-    def _isGeneralPositionPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type general position
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type general position
-        """
-        if (packetTypeChar in self.generalPositionCharList):
-            return True
-        else:
-            return False
-
-    def _isObjectPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type object
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type object
-        """
-        if (packetTypeChar in self.objectCharList):
-            return True
-        else:
-            return False
-
-    def _isItemPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type item
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type item
-        """
-        if (packetTypeChar in self.itemCharList):
-            return True
-        else:
-            return False
-
-    def _isWeatherPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type weather
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type weather
-        """
-        if (packetTypeChar in self.weatherCharList):
-            return True
-        else:
-            return False
-
-    def _isTelemetryPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type telemetry
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type telemetry
-        """
-        if (packetTypeChar in self.telemetryCharList):
-            return True
-        else:
-            return False
-
-    def _isMessagePacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type message
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type message
-        """
-        if (packetTypeChar in self.messageCharList):
-            return True
-        else:
-            return False
-
-    def _isQueryPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type query
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type query
-        """
-        if (packetTypeChar in self.queryCharList):
-            return True
-        else:
-            return False
-
-    def _isStatusPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type status
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type status
-        """
-        if (packetTypeChar in self.statusCharList):
-            return True
-        else:
-            return False
-
-    def _isOtherPacketType(self, packetTypeChar):
-        """Returns true if the specified packet type character is of type other
-
-        Args:
-            None
-
-        Returns:
-            True if the specified packet type character is of type other
-        """
-        if (packetTypeChar in self.otherCharList):
-            return True
-        else:
-            return False
-
-    def _initPacketTypeArrays(self):
-        """Init the packet type arrays
-
-        Args:
-            None
-        """
-        self.onlyPositionCharList.append("`")  # New Mic-E data
-        self.onlyPositionCharList.append("'")  # Old Mic-E data
-        self.onlyPositionCharList.append("[")  # maidenhead locator beacon
-        self.onlyPositionCharList.append("$")  # raw gps
-
-        # Position without timestamp (no APRS messaging), or Ultimeter 2000 WX Station
-        self.generalPositionCharList.append("!")
-        # Position without timestamp (with APRS messaging)
-        self.generalPositionCharList.append("=")
-        # Position with timestamp (no APRS messaging)
-        self.generalPositionCharList.append("/")
-        # Position with timestamp (with APRS messaging)
-        self.generalPositionCharList.append("@")
-
-        self.objectCharList.append(";")  # Object
-
-        self.itemCharList.append(")")  # item report
-
-        self.weatherCharList.append("#")  # raw weather report
-        self.weatherCharList.append("*")  # complete weather report
-        self.weatherCharList.append("_")  # positionless weather report
-
-        self.telemetryCharList.append("T")  # telemetry report"
-
-        self.messageCharList.append(":")  # Message
-
-        self.queryCharList.append("?")  # general query format
-
-        self.statusCharList.append(">")  # Status
-
-        self.otherCharList.append("%")  # agrelo
-        self.otherCharList.append("&")  # reserved
-        self.otherCharList.append("(")  # unused
-        self.otherCharList.append("+")  # reserved
-        self.otherCharList.append(",")  # invalid/test format
-        self.otherCharList.append("-")  # unused
-        self.otherCharList.append(".")  # reserved
-        self.otherCharList.append("<")  # station capabilities
-        self.otherCharList.append("\\")  # unused
-        self.otherCharList.append("]")  # unused
-        self.otherCharList.append("^")  # unused
-        self.otherCharList.append("{")  # user defined
-        self.otherCharList.append("}")  # 3rd party traffic
-
-    def _getPacketTypeChar(self, packet):
-        """Returns the packet type char
-
-        Args:
-            packet (Packet): Packet object to find type char for
-
-        Returns:
-            Packet type char
-        """
-        try:
-            (rawHeader, rawBody) = packet.raw.split(':', 1)
-        except:
-            raise TrackDirectParseError(
-                'Could not split packet into header and body', packet)
-
-        if len(rawBody) == 0:
-            raise TrackDirectParseError('Packet body is empty', packet)
-
-        return rawBody[0]
diff --git a/server/trackdirect/parser/policies/MapSectorPolicy.py b/server/trackdirect/parser/policies/MapSectorPolicy.py
deleted file mode 100644
index 07ef365a7ebcdee9cb4861fdc87dac40489f46b6..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/MapSectorPolicy.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from math import floor, ceil
-
-
-class MapSectorPolicy():
-    """The MapSectorPolicy class hanles logic related to map sectors
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def getMapSector(self, latitude, longitude):
-        """Returns a map sector integer specified by latitude and longitude
-
-        Args:
-            latitude (float):  Numeric latitude
-            longitude (float): Numeric longitude
-
-        Returns:
-            A map sector integer
-        """
-        if (type(latitude) is float and type(longitude) is float):
-            lat = self.getMapSectorLatRepresentation(latitude)
-            lng = self.getMapSectorLngRepresentation(longitude)
-
-            # lat interval: 0 - 18000000
-            # lng interval: 0 - 00003600
-            return lat+lng
-        else:
-            return None
-
-    def getMapSectorLatRepresentation(self, latitude):
-        """Returns the latitude part of a map sector integer
-
-        Args:
-            latitude (float):  Numeric latitude
-
-        Returns:
-            The latitude part of a map sector integer
-        """
-        lat = int(floor(latitude)) + 90  # Positive representation of lat
-        latDecimalPart = latitude - floor(latitude)
-
-        if (latDecimalPart < 0.2):
-            lat = lat * 10 + 0
-        elif (latDecimalPart < 0.4):
-            lat = lat * 10 + 2
-        elif (latDecimalPart < 0.6):
-            lat = lat * 10 + 4
-        elif (latDecimalPart < 0.8):
-            lat = lat * 10 + 6
-        else:
-            lat = lat * 10 + 8
-
-        lat = lat * 10000
-
-        # lat interval: 0 - 18000000
-        return lat
-
-    def getMapSectorLngRepresentation(self, longitude):
-        """Returns the longitude part of a map sector integer
-
-        Args:
-            longitude (float):  Numeric latitude
-
-        Returns:
-            The longitude part of a map sector integer
-        """
-        lng = int(floor(longitude)) + 180  # Positive representation of lng
-        lngDecimalPart = longitude - floor(longitude)
-
-        if (lngDecimalPart < 0.5):
-            lng = lng * 10 + 0
-        else:
-            lng = lng * 10 + 5
-
-        # lng interval: 0 - 00003600
-        return lng
diff --git a/server/trackdirect/parser/policies/PacketAssumedMoveTypePolicy.py b/server/trackdirect/parser/policies/PacketAssumedMoveTypePolicy.py
deleted file mode 100644
index 4ea33a5877772def5f300d6070b9db3556390a53..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketAssumedMoveTypePolicy.py
+++ /dev/null
@@ -1,174 +0,0 @@
-from trackdirect.parser.policies.AprsPacketSymbolPolicy import AprsPacketSymbolPolicy
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-
-
-class PacketAssumedMoveTypePolicy():
-    """PacketAssumedMoveTypeIdPolicy calculates a packets default move type
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getAssumedMoveType(self, packet, prevPacket):
-        """Returns the current packet move type based on if it seems to be moving or not
-
-        Args:
-            packet (Packet):       Packet that we want to know move typ for
-            prevPacket (Packet):   Previous related packet for the same station
-
-        Returns:
-            Returns the current packet move type id as integer
-        """
-        isMoving = self._getDefaultAssumedMoveType(packet)
-        if (prevPacket.isExistingObject()
-                and isMoving == 0
-                and not self._isBalloonPredictedTouchdown(packet)):
-            aprsPacketSymbolPolicy = AprsPacketSymbolPolicy()
-
-            # If assumed stationary we validate this by comparing to previous packet
-            if (packet.isSymbolEqual(prevPacket)
-                    and (prevPacket.timestamp - prevPacket.positionTimestamp) < 36000
-                    and prevPacket.isMoving == 1):
-                # Previous packet has same symbol and is moving
-                # (If previous was moving so should this)
-                isMoving = 1
-
-            elif (aprsPacketSymbolPolicy.isMaybeMovingSymbol(packet.symbol, packet.symbolTable)
-                    and prevPacket.isMoving == 1):
-                # symbol that maybe is moving is considered moving if prev packet is moving
-                isMoving = 1
-
-            elif (packet.isSymbolEqual(prevPacket)
-                    and not packet.isPostitionEqual(prevPacket)):
-                # Previous packet has same symbol and another position
-                isMoving = 1
-
-            elif (not packet.isPostitionEqual(prevPacket)):
-                # Previous packet has another symbol and another position
-                # In this case we do a deper investigation... (this is to heavy to do for all packets)
-                numberOfPackets = self._getNumberOfPacketWithSameSymbolAndOtherPos(
-                    packet, packet.timestamp - 86400
-                )
-
-                if (numberOfPackets > 0):
-                    # We have more then 1 positions for this symbol from this station, assume it is moving
-                    isMoving = 1
-        return isMoving
-
-    def _isBalloonPredictedTouchdown(self, packet):
-        """Returns true if packet probably is a balloon touchdown
-
-        Args:
-            packet (Packet):  Packet that we want to know move typ for
-
-        Returns:
-            true if packet probably is a balloon touchdown otherwise false
-        """
-        if (packet.symbolTable != "/" and packet.symbol == "o"):
-            # Symbol is a small circle often used as predicted touchdown
-            if (packet.comment is not None and "touchdown" in packet.comment):
-                return True
-        return False
-
-    def _getDefaultAssumedMoveType(self, packet):
-        """Returns the default packet move type id
-
-        Args:
-            packet (Packet):  Packet that we want to know move typ for
-
-        Returns:
-            Returns the default packet move type id as integer
-        """
-        # Default is moving and if we are not sure we should choose moving
-        isMoving = 1
-        if (packet is not None
-                and packet.symbol is not None
-                and packet.symbolTable is not None):
-            # First we set a initial value based on symbol
-            aprsPacketSymbolPolicy = AprsPacketSymbolPolicy()
-            if (aprsPacketSymbolPolicy.isStationarySymbol(packet.symbol, packet.symbolTable)
-                    or aprsPacketSymbolPolicy.isMaybeMovingSymbol(packet.symbol, packet.symbolTable)):
-                isMoving = 0
-            if (isMoving == 0 and self._isSsidIndicateMoving(packet.stationName)
-                    and aprsPacketSymbolPolicy.isMaybeMovingSymbol(packet.symbol, packet.symbolTable)):
-                isMoving = 1
-            if (isMoving == 0
-                    and (packet.course is not None or packet.speed is not None)
-                    and packet.packetTypeId != 3):
-                # Packet has a speed and a course and is not a weather packet!
-                # If it looks like a weather station we validate that speed is higher than 0
-                if (aprsPacketSymbolPolicy.isMaybeMovingSymbol(packet.symbol, packet.symbolTable)):
-                    isMoving = 1
-                elif (self._isSsidIndicateMoving(packet.stationName)):
-                    isMoving = 1
-                elif (packet.speed is not None and packet.speed > 0):
-                    # A moving stationary station?!
-                    isMoving = 1
-                elif (packet.course is not None and packet.course > 0):
-                    # A moving stationary station?!
-                    isMoving = 1
-        return isMoving
-
-    def _isSsidIndicateMoving(self, stationName):
-        """Returns true if station SSID indicates moving
-
-        Args:
-            stationName (string):   Packet station name
-
-        Returns:
-            Returns true if station SSID indicates moving otherwise false
-        """
-        if (stationName.endswith('-7')):
-            # walkie talkies, HT's or other human portable
-            return True
-        elif (stationName.endswith('-8')):
-            # boats, sailboats, RV's or second main mobile
-            return True
-        elif (stationName.endswith('-9')):
-            # Primary Mobile (usually message capable)
-            return True
-        elif (stationName.endswith('-11')):
-            # balloons, aircraft, spacecraft, etc
-            return True
-        elif (stationName.endswith('-14')):
-            # Truckers or generally full time drivers
-            return True
-        else:
-            return False
-
-    def _getNumberOfPacketWithSameSymbolAndOtherPos(self, packet, minTimestamp):
-        """Returns the number of packets that has the same symbol but another position (for the same station)
-
-        Args:
-            stationId (int):     Id of the station
-            packet (Packet):     Packet instance that we base the search on
-
-        Returns:
-            The number of packets that has the same symbol but another position
-        """
-        selectCursor = self.db.cursor()
-        packetTableCreator = PacketTableCreator(self.db)
-        packetTables = packetTableCreator.getPacketTables(minTimestamp)
-        result = 0
-        for packetTable in packetTables:
-            sql = selectCursor.mogrify("""select count(*) number_of_packets from """ + packetTable + """ where station_id = %s and map_id = 1 and symbol = %s and symbol_table = %s and latitude != %s and longitude != %s""", (
-                packet.stationId,
-                packet.symbol,
-                packet.symbolTable,
-                packet.latitude,
-                packet.longitude,))
-
-            selectCursor = self.db.cursor()
-            selectCursor.execute(sql)
-            record = selectCursor.fetchone()
-
-            if (record is not None):
-                result = result + record["number_of_packets"]
-
-        selectCursor.close()
-        return result
diff --git a/server/trackdirect/parser/policies/PacketCommentPolicy.py b/server/trackdirect/parser/policies/PacketCommentPolicy.py
deleted file mode 100644
index e2fde323f9ecdcfd9a69a0de5f004582ff6bf543..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketCommentPolicy.py
+++ /dev/null
@@ -1,135 +0,0 @@
-import re
-
-
-class PacketCommentPolicy():
-    """The PacketCommentPolicy class handles logic to format comments
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def getComment(self, data, packetTypeId):
-        """Returns the packet comment
-
-        Args:
-            data (dict):         Raw packet data
-            packetTypeId (int):  Packet type id
-
-        Returns:
-            String
-        """
-        comment = None
-        if (packetTypeId == 7 and "message_text" in data):
-            # We save messages as a comment (a message packet does not have a comment so this column is free)
-            comment = data["message_text"]
-        elif (packetTypeId == 10 and "status" in data):
-            # We save status as comment (a status message does not have a comment so this column is free)
-            comment = data["status"]
-        elif ("comment" in data):
-            comment = data["comment"]
-
-        if isinstance(comment, bytes):
-            comment = comment.encode('ascii', 'ignore')
-            comment = comment.replace('\x00', '')
-
-        return self._formatComment(comment)
-
-    def _formatComment(self, comment):
-        """Remove junk from comment
-
-        Args:
-            comment (string):   Comment from packet
-
-        Returns:
-            String
-        """
-        comment = self._lchop(comment, "!=")
-        comment = self._rchop(comment, "!=")
-        comment = self._lchop(comment, "]=")
-        comment = self._rchop(comment, "]=")
-        comment = self._lchop(comment, ">=")
-        comment = self._rchop(comment, ">=")
-        comment = self._lchop(comment, "_%")
-        comment = self._rchop(comment, "_%")
-        comment = self._lchop(comment, "_#")
-        comment = self._rchop(comment, "_#")
-        comment = self._lchop(comment, "_\"")
-        comment = self._rchop(comment, "_\"")
-        comment = self._lchop(comment, "_$")
-        comment = self._rchop(comment, "_$")
-        comment = self._lchop(comment, "_)")
-        comment = self._rchop(comment, "_)")
-        comment = self._lchop(comment, "_(")
-        comment = self._rchop(comment, "_(")
-        comment = self._lchop(comment, "()")
-        comment = self._rchop(comment, "()")
-        comment = self._lchop(comment, "^")
-        comment = self._rchop(comment, "^")
-        comment = self._lchop(comment, "\\x")
-        comment = self._rchop(comment, "\\x")
-        comment = self._lchop(comment, "/")
-        comment = self._rchop(comment, "/")
-        comment = self._lchop(comment, "\\!")
-        comment = self._rchop(comment, "\\!")
-        comment = self._lchop(comment, "1}")
-        comment = self._rchop(comment, "1}")
-        comment = self._lchop(comment, "_1")
-        comment = self._rchop(comment, "_1")
-        comment = self._lchop(comment, "\"(}")
-        comment = self._rchop(comment, "\"(}")
-        comment = self._rchop(comment, "=")
-        comment = self._lchop(comment, "]")
-        comment = self._lchopRegex(comment, "\.\.\.\/\d\d\d")
-        comment = self._lchopRegex(comment, "\d\d\d\/\d\d\d")
-        comment = self._lchop(comment, ".../...")
-
-        if (comment is not None and len(comment) <= 1):
-            # Comments with one letter is probably wrong
-            comment = None
-        return comment
-
-    def _rchop(self, string, substr):
-        """Chops substr from right of string
-
-        Args:
-            string (str): String to do modification on
-            substr (str): Substr to look for in string
-
-        Returns:
-            Updated version of string
-        """
-        if (string is not None and string.endswith(substr)):
-            return string[:-len(substr)]
-        return string
-
-    def _lchop(self, string, substr):
-        """Chops substr from left of string
-
-        Args:
-            string (str): String to do modification on
-            substr (str): Substr to look for in string
-
-        Returns:
-            Updated version of string
-        """
-        if (string is not None and string.startswith(substr)):
-            return string[len(substr):]
-        return string
-
-    def _lchopRegex(self, string, substrRegex):
-        """Chops substr from left of string
-
-        Args:
-            string (str): String to do modification on
-            substrRegex (str): Substr to look for in string
-
-        Returns:
-            Updated version of string
-        """
-        regex = re.compile(substrRegex)
-        if (string is not None):
-            m = re.match(regex, string)
-            if (m):
-                return string[len(m.group(0)):]
-        return string
diff --git a/server/trackdirect/parser/policies/PacketDuplicatePolicy.py b/server/trackdirect/parser/policies/PacketDuplicatePolicy.py
deleted file mode 100644
index 4e3c084e845840423a68130d8712a46f96f3ccdd..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketDuplicatePolicy.py
+++ /dev/null
@@ -1,139 +0,0 @@
-import logging
-from twisted.python import log
-
-import collections
-from trackdirect.exceptions.TrackDirectParseError import TrackDirectParseError
-
-
-class PacketDuplicatePolicy():
-    """Handles duplicate checks
-    """
-
-    # static class variables
-    latestPacketsHashOrderedDict = collections.OrderedDict()
-
-    def __init__(self, stationRepository):
-        """The __init__ method.
-        """
-        self.minutesBackToLookForDuplicates = 30
-        self.stationRepository = stationRepository
-
-        self.logger = logging.getLogger('trackdirect')
-
-    def isDuplicate(self, packet):
-        """Method used to check if this packet is a duplicate
-
-        Args:
-            packet (Packet): Packet that may be a duplicate
-
-        Returns:
-            Boolean
-        """
-        if (packet.mapId in [1, 5, 7, 8, 9]
-                and (packet.isMoving == 1 or packet.mapId == 8)
-                and packet.latitude is not None
-                and packet.longitude is not None):
-            if (self._isPacketBodyInCache(packet)):
-                # It looks like a duplicate, treat it as one if needed
-                # (if position is equal to the latest confirmed position it doesn't matter if we treat it as a duplicate or not)
-                if (self._isToBeTreateAsDuplicate(packet)):
-                    return True
-            self._addToCache(packet)
-
-        elif (packet.sourceId == 3):
-            # It is a duplicate (everything from this source is)
-            return True
-
-        return False
-
-    def _isPacketBodyInCache(self, packet):
-        """Returns true if packet body is in cache
-
-        Args:
-            packet (Packet):   Packet look for in cashe
-
-        Returns:
-            Boolean
-        """
-        packetHash = self._getPacketHash(packet)
-        if (packetHash is None):
-            return False
-
-        if (packetHash in PacketDuplicatePolicy.latestPacketsHashOrderedDict):
-            prevPacketValues = PacketDuplicatePolicy.latestPacketsHashOrderedDict[packetHash]
-            if (packet.rawPath != prevPacketValues['path']
-                    and prevPacketValues['timestamp'] > packet.timestamp - (60*self.minutesBackToLookForDuplicates)):
-                return True
-        return False
-
-    def _isToBeTreateAsDuplicate(self, packet):
-        """Returns true if packet should be treated as duplicate
-
-        Args:
-            packet (Packet):   Packet to check
-
-        Returns:
-            Boolean
-        """
-        station = self.stationRepository.getObjectById(packet.stationId)
-        if (station.latestConfirmedLatitude is not None and station.latestConfirmedLongitude is not None):
-            stationLatCmp = int(round(station.latestConfirmedLatitude*100000))
-            stationLngCmp = int(round(station.latestConfirmedLongitude*100000))
-        else:
-            stationLatCmp = 0
-            stationLngCmp = 0
-
-        packetlatCmp = int(round(packet.latitude*100000))
-        packetlngCmp = int(round(packet.longitude*100000))
-
-        if (station.isExistingObject()
-            and stationLatCmp != 0
-            and stationLngCmp != 0
-                and (packet.mapId == 8 or stationLatCmp != packetlatCmp or stationLngCmp != packetlngCmp)):
-
-            # We treat this packet as a duplicate
-            return True
-        else:
-            return False
-
-    def _getPacketHash(self, packet):
-        """Returns a hash value of the Packet object
-
-        Args:
-            packet (Packet): Packet to get hash for
-
-        Returns:
-            A string that contains the hash value
-        """
-        if (packet.raw is None or packet.raw == ''):
-            return None
-
-        packetString = packet.raw.split(':', 1)[1]
-        if (packetString == ''):
-            return None
-        else:
-            return hash(packetString.strip())
-
-    def _addToCache(self, packet):
-        """Add packet to cache
-
-        Args:
-            packet (Packet):  Packet to add to cache
-        """
-        packetHash = self._getPacketHash(packet)
-        PacketDuplicatePolicy.latestPacketsHashOrderedDict[packetHash] = {
-            'path': packet.rawPath,
-            'timestamp': packet.timestamp
-        }
-        self._cacheMaintenance()
-
-    def _cacheMaintenance(self):
-        """Make sure cache does not contain to many packets
-        """
-        maxNumberOfPackets = self.minutesBackToLookForDuplicates * 60 * 100 # We assume that we have an average of 100 packets per second
-        if (len(PacketDuplicatePolicy.latestPacketsHashOrderedDict) > maxNumberOfPackets):
-            try:
-                PacketDuplicatePolicy.latestPacketsHashOrderedDict.popitem(
-                    last=False)
-            except (KeyError, StopIteration) as e:
-                pass
diff --git a/server/trackdirect/parser/policies/PacketKillCharPolicy.py b/server/trackdirect/parser/policies/PacketKillCharPolicy.py
deleted file mode 100644
index 3b03ccfaf601165d69b880c686ea6711c787d911..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketKillCharPolicy.py
+++ /dev/null
@@ -1,23 +0,0 @@
-class PacketKillCharPolicy():
-    """The PacketKillCharPolicy class handles logic related to packet kill character
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def hasKillCharacter(self, data):
-        """A packet may contain a kill char, if exists the object/item should be hidden on map
-
-        Args:
-            data (dict):   Raw packet data
-
-        Returns:
-            Boolean
-        """
-        if ("object_name" in data
-                and data["object_name"] is not None
-                and data["object_name"] != ''
-                and data["object_name"].endswith('_')):
-            return True
-        return False
diff --git a/server/trackdirect/parser/policies/PacketMapIdPolicy.py b/server/trackdirect/parser/policies/PacketMapIdPolicy.py
deleted file mode 100644
index 3f87d38aae5b2a03c5604d73243312d70504e421..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketMapIdPolicy.py
+++ /dev/null
@@ -1,278 +0,0 @@
-from trackdirect.parser.policies.PacketOrderPolicy import PacketOrderPolicy
-from trackdirect.parser.policies.PacketMaxSpeedPolicy import PacketMaxSpeedPolicy
-
-
-class PacketMapIdPolicy():
-    """PacketMapIdPolicy tries to find the best mapId for the current packet
-    """
-
-    def __init__(self, packet, prevPacket):
-        """The __init__ method.
-
-        Args:
-            packet (Packet):  Packet that we want analyze
-        """
-        self.packet = packet
-        self.prevPacket = prevPacket
-        self.hasKillCharacter = False
-        # Marker will be confirmed when we receive the third packet
-        self.markerCounterConfirmLimit = 3
-
-        # Results
-        self.mapId = None
-        self.markerId = None
-        self.isReplacingPrevPacket = False
-        self.isConfirmingPrevPacket = False
-        self.isKillingPrevPacket = False
-
-    def enableHavingKillCharacter(self):
-        """Treat this packet as having a kill character
-        """
-        self.hasKillCharacter = True
-
-    def getMapId(self):
-        """Returns the map id that corresponds to the found marker id
-
-        Returns:
-            int
-        """
-        self._findMapId()
-        return self.mapId
-
-    def getMarkerId(self):
-        """Returns the found marker id
-
-        Returns:
-            int
-        """
-        self._findMapId()
-        return self.markerId
-
-    def isReplacingPreviousPacket(self):
-        """Returns true if packet replaces previous packet
-
-        Returns:
-            boolean
-        """
-        self._findMapId()
-        return self.isReplacingPrevPacket
-
-    def isConfirmingPreviousPacket(self):
-        """Returns true if packet confirmes previous packet
-
-        Returns:
-            boolean
-        """
-        self._findMapId()
-        return self.isConfirmingPrevPacket
-
-    def isKillingPreviousPacket(self):
-        """Returns true if packet kills previous packet
-
-        Returns:
-            boolean
-        """
-        self._findMapId()
-        return self.isKillingPrevPacket
-
-    def _findMapId(self):
-        """Find a suitable marker id for the current packet and set correponding attribute (and related attributes)
-        """
-        if (self.mapId is None):
-            packetOrderPolicy = PacketOrderPolicy()
-            if (self.packet.sourceId == 2 and len(self.packet.stationIdPath) > 0):
-                # A CWOP-station is allways sending directly
-                self.mapId = 16
-                self.markerId = 1
-            elif (not self._isPacketOnMap()):
-                self.mapId = 10
-                self.markerId = 1
-            elif (packetOrderPolicy.isPacketInWrongOrder(self.packet, self.prevPacket)):
-                self.mapId = 6
-                self.markerId = 1
-            elif (self._isFaultyGpsPosition()):
-                self._findMapIdForFaultyGpsPosition()
-            elif (self.packet.isMoving == 1):
-                self._findMapIdForMovingStation()
-            else:
-                self._findMapIdForStationaryStation()
-
-    def _isPacketOnMap(self):
-        """Returns true if current packet will be on map
-
-        Returns:
-            boolean
-        """
-        if (self.packet.latitude is not None
-                and self.packet.longitude is not None
-                and type(self.packet.latitude) == float
-                and type(self.packet.longitude) == float
-                and self.packet.sourceId != 3
-                and self.packet.mapId in [1, 5, 7, 9]):
-            return True
-        else:
-            return False
-
-    def _findMapIdForStationaryStation(self):
-        """Find a suitable marker id for the current packet (assumes it is a stationary station) and set correponding attribute (and related attributes)
-        """
-        if (self.prevPacket.isExistingObject()
-                and self.packet.isPostitionEqual(self.prevPacket)
-                and self.packet.isSymbolEqual(self.prevPacket)
-                and self.packet.isMoving == self.prevPacket.isMoving
-                and self.prevPacket.mapId in [1, 7]):
-            # Same position and same symbol
-            self.mapId = 1
-            self.markerId = self.prevPacket.markerId
-            if (self.hasKillCharacter):
-                # This station we can actually kill (it's stationary), let the markerId be
-                self.mapId = 14
-
-            # Also mark this to replace previous packet
-            self.isReplacingPrevPacket = True
-        elif (self.hasKillCharacter):
-            # We found nothing to kill
-            self.markerId = 1
-            self.mapId = 4
-        else:
-            # Seems to be a new stationary station (or at least a new symbol for an existing station)
-            self.mapId = 1
-            self.markerId = None
-
-    def _findMapIdForMovingStation(self):
-        """Find a suitable marker id for the current packet (assumes it is a moving station) and set correponding attribute (and related attributes)
-        """
-        if (self.hasKillCharacter):
-            # Makes no sense in handling kill characters for moving
-            self.mapId = 4
-            self.markerId = 1
-
-        elif (self.prevPacket.isExistingObject()
-                and self.prevPacket.isMoving == 1
-                and self.prevPacket.mapId in [1, 7]):
-            calculatedDistance = self.packet.getDistance(
-                self.prevPacket.latitude, self.prevPacket.longitude)
-            calculatedSpeed = self.packet.getCalculatedSpeed(self.prevPacket)
-            packetMaxSpeedPolicy = PacketMaxSpeedPolicy()
-            maxSpeed = packetMaxSpeedPolicy.getMaxLikelySpeed(
-                self.packet, self.prevPacket)
-            # distance is likely if distance is shorter than 50km (map performance is bad with to long polylines)
-            absoluteMaxDistance = 50000
-            # speed may be likely but if it is faster than absoluteMaxSpeed we create a new marker any way
-            absoluteMaxSpeed = 2000
-
-            if (self.packet.isPostitionEqual(self.prevPacket)):
-                # Same position
-                self._findMapIdForMovingStationWithSamePosition()
-
-            elif (calculatedDistance < 5000 and calculatedSpeed <= absoluteMaxSpeed):
-                # Distance is very short (shorter than 5km)
-                self._findMapIdForMovingStationWithLikelySpeed()
-
-            elif (calculatedSpeed <= maxSpeed and calculatedSpeed <= absoluteMaxSpeed and calculatedDistance <= absoluteMaxDistance):
-                # Speed and distance is likely
-                self._findMapIdForMovingStationWithLikelySpeed()
-
-            elif (calculatedSpeed <= maxSpeed and calculatedDistance > absoluteMaxDistance):
-                # Speed is likly but distance is to long or speed is very fast
-                self._findMapIdForMovingStationWithToLongDistance()
-
-            else:
-                # No suitable marker id
-                self.mapId = 7
-                self.markerId = None
-        else:
-            if (self.prevPacket.isExistingObject()
-                and self.prevPacket.isMoving == 0
-                    and self.packet.isSymbolEqual(self.prevPacket)):
-                # We previously made a mistake, previous packet should have been marked as moving, just mark previous as abnormal (ghost marker)
-                self.isKillingPrevPacket = True
-
-            # Seems to be a new station
-            self.mapId = 1
-            self.markerId = None
-
-    def _findMapIdForMovingStationWithToLongDistance(self):
-        """Sets a suitable marker id for the current packet based on prevPacket and assumes that distance is to long between them
-        """
-        if (self.prevPacket.markerCounter == 1):
-            # Previous packet is not related to any previous and it is not related to this, mark it as abnormal
-            self.isKillingPrevPacket = True
-
-        # This is kind of a special case, we have no requirements on the previous packet
-        # Station is either sending few packets or is moving very fast, we accept everything as long as speed is likely
-        # Create new marker
-        self.mapId = 1
-        self.markerId = None
-
-    def _findMapIdForMovingStationWithLikelySpeed(self):
-        """Sets a suitable marker id for the current packet based on prevPacket and assumes that speed is likly
-        """
-        self.markerId = self.prevPacket.markerId
-        if (self.prevPacket.mapId == 1
-                or (self.prevPacket.markerCounter + 1) >= self.markerCounterConfirmLimit):
-            self.mapId = 1
-        else:
-            self.mapId = self.prevPacket.mapId
-
-        if (self.mapId == 1
-                and self.prevPacket.mapId == 7):
-            # To mark a previous packet as confirmed is not important since client should handle it anyway when a connected packet that is confirmed is recived
-            # But we do it when possible to make things easier for the client (currently we are not doiong it if several previous packets is unconfirmed)
-            self.isConfirmingPrevPacket = True
-
-    def _findMapIdForMovingStationWithSamePosition(self):
-        """Sets a suitable marker id for the current packet based on prevPacket and assumes that position is equal
-        """
-        # Also mark this to replace previous packet
-        # If this packet is converted to a 12 it will be treated as confirmed in history
-        # (we kind of assumes that markerCounterConfirmLimit == 2, maybe a TODO?)
-        self.markerId = self.prevPacket.markerId
-        self.isReplacingPrevPacket = True
-        if (self.prevPacket.mapId == 1
-                or (self.prevPacket.markerCounter + 1) >= self.markerCounterConfirmLimit):
-            self.mapId = 1
-        else:
-            self.mapId = self.prevPacket.mapId
-
-    def _findMapIdForFaultyGpsPosition(self):
-        """Sets a suitable marker id for the current packet based on prevPacket and assumes that gps position is faulty (mapId 5)
-        """
-        if (self.hasKillCharacter):
-            # No point in killing a ghost-marker
-            self.mapId = 4
-            self.markerId = 1
-        elif (self.prevPacket.mapId == self.mapId
-                and self.packet.isPostitionEqual(self.prevPacket)
-                and self.packet.isSymbolEqual(self.prevPacket)):
-            # Same mapId and position and same symbol
-            # Also mark this to replace previous packet
-            self.isReplacingPrevPacket = True
-            self.mapId = 5  # it is still 5
-            self.markerId = self.prevPacket.markerId
-        else:
-            # Seems to be a new stationary station (or at least a new symbol for an existing station)
-            self.mapId = 5
-            self.markerId = None
-
-    def _isFaultyGpsPosition(self):
-        """Parse the packet and modify the mapId attribute if position is faulty
-        """
-        packetlatCmp = int(round(self.packet.latitude*100000))
-        packetlngCmp = int(round(self.packet.longitude*100000))
-
-        if (packetlatCmp == int(0) and packetlngCmp == int(0)):
-            return True
-
-        if (packetlatCmp == int(1*100000) and packetlngCmp == int(1*100000)):
-            return True
-
-        if (packetlatCmp == int(36*100000) and packetlngCmp == int(136*100000)):
-            # Some gps units seems to use this position as default until they find the real position
-            # Maybe it is the position of a gps manufacturer?
-            return True
-
-        if (packetlatCmp == int(-48*100000) and packetlngCmp == int(0)):
-            # Some gps units seems to use this position as default until they find the real position
-            return True
-        return False
diff --git a/server/trackdirect/parser/policies/PacketMaxSpeedPolicy.py b/server/trackdirect/parser/policies/PacketMaxSpeedPolicy.py
deleted file mode 100644
index 991c2f61d52592c013e27bc1592901623638c554..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketMaxSpeedPolicy.py
+++ /dev/null
@@ -1,79 +0,0 @@
-from trackdirect.parser.policies.PacketSpeedComputablePolicy import PacketSpeedComputablePolicy
-
-
-class PacketMaxSpeedPolicy():
-    """PacketMaxSpeedPolicy handles logic related to max possible speed (used to filter out faulty packets)
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def getMaxLikelySpeed(self, packet, prevPacket):
-        """Returns the max likely speed
-
-        Args:
-            packet (Packet):  Packet that we want analyze
-            prevPacket (Packet):   Previous related packet for the same station
-
-        Returns:
-            Max likly speed as float
-        """
-        maxSpeed = self._getDefaultStationMaxSpeed(packet)
-
-        if (packet.speed is not None and packet.speed > maxSpeed):
-            # We allow 100% faster speed than the reported speed
-            maxSpeed = packet.speed * 2
-
-        if (prevPacket.isExistingObject()
-                and prevPacket.speed is not None
-                and prevPacket.speed > maxSpeed):
-            # We allow 100% faster speed than the previous reported speed
-            maxSpeed = prevPacket.speed * 2
-
-        calculatedSpeed = 0
-        if (prevPacket.isExistingObject()):
-            calculatedSpeed = packet.getCalculatedSpeed(prevPacket)
-        packetSpeedComputablePolicy = PacketSpeedComputablePolicy()
-        if (packetSpeedComputablePolicy.isSpeedComputable(packet, prevPacket)
-            and prevPacket.mapId == 7
-                and calculatedSpeed > maxSpeed):
-            # If last position is unconfirmed but still is closer to the last confirmed and calculated speed is trusted we accept that speed
-            # This part is IMPORTANT to avoid that all packets get map_id == 7
-            maxSpeed = calculatedSpeed
-
-        maxSpeed = (maxSpeed * (1 + len(packet.stationIdPath)))
-        return maxSpeed
-
-    def _getDefaultStationMaxSpeed(self, packet):
-        """Returns the station default max speed (not affected by or adaptive speed limit)
-
-        Args:
-            packet (Packet):  Packet that we want analyze
-
-        Returns:
-            Returns the station default max speed as int
-        """
-        # Bugatti Veyron Super Sport Record Edition 2010, the fastest production car can do 431 kmh (but a regular car usually drives a bit slower...)
-        maxSpeed = 200
-        if (packet.altitude is not None):
-            highestLandAltitude = 5767  # Uturuncu, Bolivia, highest road altitude
-            airPlaneMaxAltitude = 15240  # Very rare that airplanes go higher than 50.000 feet
-            # Objects below approximately 160 kilometers (99 mi) will experience very rapid orbital decay and altitude loss.
-            satelliteMinAltitude = 160000
-
-            if (packet.altitude > satelliteMinAltitude):
-                # Seems like this is an satellite
-                # Until we know more we dont change anything
-                maxSpeed = maxSpeed
-
-            elif (packet.altitude > airPlaneMaxAltitude):
-                # Higher than a normal airplane but not a satellite, could be a high altitude ballon
-                maxSpeed = 50
-
-            elif (packet.altitude > highestLandAltitude):
-                # Seems like this is a airplane or a ballon
-                # 394 kmh is the ground speed record for a hot air ballon
-                # 950 kmh is a common upper crouse speed for regular airplanes
-                maxSpeed = 950
-        return maxSpeed
diff --git a/server/trackdirect/parser/policies/PacketOgnDataPolicy.py b/server/trackdirect/parser/policies/PacketOgnDataPolicy.py
deleted file mode 100644
index 7029bbec98d76b03fa37c617a3f5714bc6b73ca4..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketOgnDataPolicy.py
+++ /dev/null
@@ -1,242 +0,0 @@
-import logging
-from twisted.python import log
-
-from trackdirect.parser.policies.AprsPacketSymbolPolicy import AprsPacketSymbolPolicy
-from trackdirect.parser.policies.PacketPathTcpPolicy import PacketPathTcpPolicy
-
-
-class PacketOgnDataPolicy():
-    """PacketOgnDataPolicy can answer questions about OGN data in the packet
-    """
-
-    def __init__(self, data, ognDeviceRepository, sourceId):
-        """The __init__ method.
-
-        Args:
-            data (dict):                          Raw packet data
-            ognDeviceRepository (OgnDeviceRepository):  OgnDeviceRepository instance
-            sourceId (int):                       Source Id
-        """
-        self.data = data
-        self.ognDeviceRepository = ognDeviceRepository
-
-        self.logger = logging.getLogger('trackdirect')
-
-        self.isOgnPositionPacket = self.isOgnPositionPacket(sourceId)
-        self.isAllowedToTrack = True
-        self.isAllowedToIdentify = True
-
-        self.result = {}
-        self._parse()
-
-    def getOgnData(self):
-        """Returnes raw OGN data
-
-        Returns:
-            Dict of OGN data
-        """
-        return self.result
-
-    def isOgnPositionPacket(self, sourceId):
-        """Returnes true if packet is a OGN Position packet
-
-        Args:
-            sourceId (int): Source Id
-
-        Returns:
-            Boolean
-        """
-        if (sourceId == 5):
-            if ("comment" in self.data
-                    and self.data["comment"] is not None
-                    and len(self.data["comment"].strip()) > 10
-                    and self.data["comment"].strip().startswith("id")):
-                return True
-
-            symbol = self.data['symbol'] if ('symbol' in self.data) else None
-            symbolTable = self.data['symbol_table'] if (
-                'symbol_table' in self.data) else None
-            aprsPacketSymbolPolicy = AprsPacketSymbolPolicy()
-            if (aprsPacketSymbolPolicy.isMaybeMovingSymbol(symbol, symbolTable)):
-                return True
-        else:
-            if ("comment" in self.data
-                    and self.data["comment"] is not None
-                    and len(self.data["comment"].strip()) > 10
-                    and self.data["comment"].strip().startswith("id")
-                    and "fpm " in self.data["comment"] + " "
-                    and "rot " in self.data["comment"] + " "
-                    and "dB " in self.data["comment"] + " "):
-                return True
-        return False
-
-    def _parse(self):
-        """Parse the OGN data in packet
-        """
-        if (not self.isOgnPositionPacket):
-            self.result = None
-        else:
-            packetPathTcpPolicy = PacketPathTcpPolicy(self.data['path'])
-            if (not packetPathTcpPolicy.isSentByTCP()):
-                self.isAllowedToIdentify = False
-
-            if ("comment" in self.data and self.data["comment"] is not None):
-                ognParts = self.data["comment"].split()
-                for part in ognParts:
-                    if (part.startswith('id')):
-                        part = part.replace("-", "")
-                        self._parseSenderAddress(part)
-                        self._parseSenderDetails(part)
-
-                    elif (part.endswith('fpm')):
-                        self._parseClimbRate(part)
-
-                    elif (part.endswith('rot')):
-                        self._parseTurnRate(part)
-
-                    elif (part.endswith('dB')):
-                        if (self.isAllowedToIdentify and self.isAllowedToTrack):
-                            self._parseSignalToNoiseRatio(part)
-
-                    elif (part.endswith('e')):
-                        if (self.isAllowedToIdentify and self.isAllowedToTrack):
-                            self._parseBitErrorsCorrected(part)
-
-                    elif (part.endswith('kHz')):
-                        if (self.isAllowedToIdentify and self.isAllowedToTrack):
-                            self._parseFrequencyOffset(part)
-                    if (not self.isAllowedToTrack):
-                        return
-
-        if (not self.isAllowedToIdentify):
-            if ('ogn_sender_address' in self.result):
-                self.result['ogn_sender_address'] = None
-
-    def _parseSenderAddress(self, content):
-        """Parse th OGN sender address
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_sender_address' not in self.result):
-            self.isAllowedToIdentify = True
-            self.result['ogn_sender_address'] = content[4:10].strip()
-
-            ognDevice = self.ognDeviceRepository.getObjectByDeviceId(
-                self.result['ogn_sender_address'])
-            if (ognDevice.isExistingObject() and not ognDevice.tracked):
-                # Pilot do not want to be tracked, so we skip saving the packet
-                self.isAllowedToIdentify = False
-                self.isAllowedToTrack = False
-
-            elif (self.result['ogn_sender_address'] == 'ICAFFFFFF'):
-                # The Device ID ICAFFFFFF is used by several aircrafts, we can not know what to do with them...
-                self.isAllowedToIdentify = False
-                self.isAllowedToTrack = False
-
-            elif (not ognDevice.isExistingObject() or not ognDevice.identified):
-                # Pilot has not approved to show identifiable data, so we make up a random station name and clear all identifiable data
-                self.isAllowedToIdentify = False
-        else:
-            self.isAllowedToIdentify = False
-
-    def _parseSenderDetails(self, content):
-        """Parse OGN aircraft type and OGN address type
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_aircraft_type_id' not in self.result):
-            try:
-                ognSenderDetailsHex = content[2:4]
-                ognSenderDetailsBinary = bin(
-                    int(ognSenderDetailsHex, 16))[2:].zfill(8)
-
-                stealth = ognSenderDetailsBinary[0:1]
-                noTracking = ognSenderDetailsBinary[1:2]
-                ognAircraftTypeIdBinary = ognSenderDetailsBinary[2:6]
-                ognAddressTypeIdBinary = ognSenderDetailsBinary[6:8]
-
-                self.result['ogn_aircraft_type_id'] = int(
-                    ognAircraftTypeIdBinary, 2)
-                if (self.result['ogn_aircraft_type_id'] == 0 or self.result['ogn_aircraft_type_id'] > 15):
-                    self.result['ogn_aircraft_type_id'] = None
-
-                self.result['ogn_address_type_id'] = int(
-                    ognAddressTypeIdBinary, 2)
-                if (self.result['ogn_address_type_id'] == 0 or self.result['ogn_address_type_id'] > 4):
-                    self.result['ogn_address_type_id'] = None
-
-            except ValueError:
-                # Assume that we should track this aircraft (we should not receive packets that has the noTracking or stealth flag set)
-                noTracking = '0'
-                stealth = '0'
-
-            if (stealth == '1' or noTracking == '1'):
-                self.isAllowedToIdentify = False
-                self.isAllowedToTrack = False
-
-    def _parseClimbRate(self, content):
-        """Parse OGN climb rate
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_climb_rate' not in self.result and content.endswith('fpm')):
-            content = content.replace("fpm", "")
-            try:
-                self.result['ogn_climb_rate'] = int(content)
-            except ValueError:
-                pass
-
-    def _parseTurnRate(self, content):
-        """Parse OGN turn rate
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_turn_rate' not in self.result and content.endswith('rot')):
-            content = content.replace("rot", "")
-            try:
-                self.result['ogn_turn_rate'] = float(content)
-            except ValueError:
-                pass
-
-    def _parseSignalToNoiseRatio(self, content):
-        """Parse OGN SNR
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_signal_to_noise_ratio' not in self.result and content.endswith('dB')):
-            content = content.replace("dB", "")
-            try:
-                self.result['ogn_signal_to_noise_ratio'] = float(content)
-            except ValueError:
-                pass
-
-    def _parseBitErrorsCorrected(self, content):
-        """Parse OGN number of bit errors corrected in the packet upon reception
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_bit_errors_corrected' not in self.result and content.endswith('e')):
-            content = content.replace("e", "")
-            try:
-                self.result['ogn_bit_errors_corrected'] = int(content)
-            except ValueError:
-                pass
-
-    def _parseFrequencyOffset(self, content):
-        """Parse OGN frequency offset measured upon reception
-
-        Arguments:
-            content (string) :  String that contains information to parse
-        """
-        if ('ogn_frequency_offset' not in self.result and content.endswith('kHz')):
-            content = content.replace("kHz", "")
-            try:
-                self.result['ogn_frequency_offset'] = float(content)
-            except ValueError:
-                pass
diff --git a/server/trackdirect/parser/policies/PacketOrderPolicy.py b/server/trackdirect/parser/policies/PacketOrderPolicy.py
deleted file mode 100644
index 0ab847dbc69e900c3be68287feb5d9478ee1c6f7..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketOrderPolicy.py
+++ /dev/null
@@ -1,34 +0,0 @@
-class PacketOrderPolicy():
-    """PacketOrderPolicy handles logic related to packet receive order
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def isPacketInWrongOrder(self, packet, previousPacket):
-        """Checks if current packet is received in the wrong order compared to the previous specified packet
-
-        Note:
-            We only care for packets in wrong order if station is moving
-
-        Args:
-            packet (Packet):          Packet that we want analyze
-            previousPacket (Packet):  Packet objekt that represents the previous packet for this station
-
-        Returns:
-            True if this packet is received in the wrong order otherwise false
-        """
-        if (previousPacket is not None
-                and previousPacket.isExistingObject()):
-            if (previousPacket.reportedTimestamp is not None
-                    and packet.reportedTimestamp is not None
-                    and previousPacket.reportedTimestamp != 0
-                    and previousPacket.senderId == packet.senderId
-                    and packet.reportedTimestamp != 0
-                    and previousPacket.isMoving == 1
-                    and previousPacket.reportedTimestamp < (packet.timestamp + 60*60*24)
-                    and packet.reportedTimestamp < (packet.timestamp + 60*60*24)
-                    and previousPacket.reportedTimestamp > packet.reportedTimestamp):
-                return True
-        return False
diff --git a/server/trackdirect/parser/policies/PacketPathPolicy.py b/server/trackdirect/parser/policies/PacketPathPolicy.py
deleted file mode 100644
index f1195cf3bda6fa73d32c987c779ad0a9262a7b62..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketPathPolicy.py
+++ /dev/null
@@ -1,263 +0,0 @@
-import collections
-import re
-
-from trackdirect.exceptions.TrackDirectMissingStationError import TrackDirectMissingStationError
-from trackdirect.parser.policies.PacketPathTcpPolicy import PacketPathTcpPolicy
-
-
-class PacketPathPolicy():
-    """PacketPathPolicy handles logic to generate the path for a specified packet
-    """
-
-    def __init__(self, path, sourceId, stationRepository, senderRepository):
-        """The __init__ method.
-
-        Args:
-            path (list):      Raw packet path list
-            sourceId (int):   Packet source id
-            stationRepository (StationRepository):   StationRepository instance
-            senderRepository (SenderRepository):    SenderRepository instance
-        """
-        self.path = path
-        self.sourceId = sourceId
-        self.stationRepository = stationRepository
-        self.senderRepository = senderRepository
-
-        self.stationIdPath = []
-        self.stationNamePath = []
-        self.stationLocationPath = []
-        self._parsePath()
-
-    def getStationIdPath(self):
-        """Returns station id path
-
-        Returns:
-            list
-        """
-        return self.stationIdPath
-
-    def getStationNamePath(self):
-        """Returns station name path
-
-        Returns:
-            list
-        """
-        return self.stationNamePath
-
-    def getStationLocationPath(self):
-        """Returns station location path, a list of longitude and latitude values
-
-        Returns:
-            list
-        """
-        return self.stationLocationPath
-
-    def _parsePath(self):
-        """Parse Station path
-
-        Note:
-            Include station in path if
-            - Station name is after q-code (this is the I-gate)
-            - Station name is before unused path command and a used command exists after (this is a digipeater that has inserted itself into the path)
-            - As a precaution we also include stations where name has a * after it (no matter the position in path)
-        """
-        isQCodeFound = False
-        isNonUsedPathCommandFound = False
-        packetPathTcpPolicy = PacketPathTcpPolicy(self.path)
-        if (packetPathTcpPolicy.isSentByTCP()):
-            return
-
-        i = 0
-        while i < len(self.path):
-            index = i
-            i += 1
-            name = self.path[index]
-
-            if (isinstance(name, int)):
-                name = str(name)
-
-            if (self._isQCode(name)):
-                isQCodeFound = True
-                continue
-
-            if (self._isPathCommand(name)):
-                if (not self._isUsedPathCommand(name)):
-                    isNonUsedPathCommandFound = True
-                continue
-
-            pathStationName = name.replace('*', '')
-            if (not self._isStationNameValid(pathStationName)):
-                continue
-
-            if (isQCodeFound
-                    or name.find('*') >= 0
-                    or not isNonUsedPathCommandFound):
-                self._addStationToPath(pathStationName)
-
-    def _addStationToPath(self, name):
-        """Returns true if specified string is a Q code
-
-        Args:
-            name (string):  station
-        """
-        try:
-            station = self.stationRepository.getCachedObjectByName(
-                name, self.sourceId)
-            stationId = station.id
-
-            if (stationId not in self.stationIdPath):
-                location = self._getStationLatestLocation(stationId)
-                if (location is not None):
-                    self.stationNamePath.append(name)
-                    self.stationIdPath.append(stationId)
-                    self.stationLocationPath.append(location)
-        except (TrackDirectMissingStationError) as exp:
-            pass
-
-    def _isQCode(self, value):
-        """Returns true if specified string is a Q code
-
-        Args:
-            value (string): value
-
-        Returns:
-            Returns true if specified string is a Q code otherwise false
-        """
-        if (value.upper().find('QA') == 0 and len(value) == 3):
-            return True
-        else:
-            return False
-
-    def _isStationNameValid(self, name):
-        """Returns true if specified station name is valid. This method is used to filter out common station names that is not valid.
-
-        Args:
-            name (string):  Station name
-
-        Returns:
-            Returns true if specified station name is valid otherwise false
-        """
-        if (name.find('NONE') == 0):
-            return False
-        elif (name.find('0') == 0 and len(name) == 1):
-            return False
-        elif (name.find('1') == 0 and len(name) == 1):
-            return False
-        elif (name.find('2') == 0 and len(name) == 1):
-            return False
-        elif (name.find('3') == 0 and len(name) == 1):
-            return False
-        elif (name.find('4') == 0 and len(name) == 1):
-            return False
-        elif (name.find('5') == 0 and len(name) == 1):
-            return False
-        elif (name.find('6') == 0 and len(name) == 1):
-            return False
-        elif (name.find('7') == 0 and len(name) == 1):
-            return False
-        elif (name.find('8') == 0 and len(name) == 1):
-            return False
-        elif (name.find('9') == 0 and len(name) == 1):
-            return False
-        elif (name.find('APRS') == 0 and len(name) == 4):
-            return False
-        elif (name.find('1-1') == 0 and len(name) == 3):
-            return False
-        elif (name.find('2-1') == 0 and len(name) == 3):
-            return False
-        elif (name.find('2-2') == 0 and len(name) == 3):
-            return False
-        elif (name.find('3-1') == 0 and len(name) == 3):
-            return False
-        elif (name.find('3-2') == 0 and len(name) == 3):
-            return False
-        elif (name.find('3-3') == 0 and len(name) == 3):
-            return False
-        elif (name.find('4-1') == 0 and len(name) == 3):
-            return False
-        elif (name.find('4-2') == 0 and len(name) == 3):
-            return False
-        elif (name.find('4-3') == 0 and len(name) == 3):
-            return False
-        elif (name.find('4-4') == 0 and len(name) == 3):
-            return False
-        elif (name.find('DSTAR') == 0):
-            return False
-        elif (name.find('TCP') == 0):
-            return False
-        elif (name.find('NULL') == 0):
-            return False
-        elif (name.find('LOCAL') == 0):
-            return False
-        elif (name.find('GATE') == 0):
-            return False
-        elif (name.find('DIRECT') == 0 and len(name) == 6):
-            return False
-        elif (name.find('CWOP') == 0 and len(name) == 6):
-            return False
-        elif (name.find('DMR') == 0 and len(name) == 3):
-            return False
-        elif (name.find('ECHO') == 0 and len(name) == 4):
-            return False
-        elif (name.find('OR1-') == 0):
-            return False
-        elif (name.find('OR2-') == 0):
-            return False
-
-        else:
-            return True
-
-    def _isPathCommand(self, value):
-        """Returns true if specified value is a path command
-
-        Args:
-            value (string):  value
-
-        Returns:
-            Returns true if specified value is a path command otherwise false
-        """
-        if (value.find('WIDE') == 0):
-            return True
-        elif (value.find('RELAY') == 0):
-            return True
-        elif (value.find('TRACE') == 0):
-            return True
-        elif (value.find('RPN') == 0):
-            return True
-        else:
-            return False
-
-    def _isUsedPathCommand(self, value):
-        """Returns true if specified value is a path command and it is completly used
-
-        Args:
-            value (string):  value
-
-        Returns:
-            Returns true if specified value is a path command (and it is completly used) otherwise false
-        """
-        if (value.find('*') >= 0):
-            # If a star is added it means that the path command is completly used
-            return True
-
-        if (value.find('WIDE') == 0 or value.find('TRACE') == 0 or value.find('RPN') == 0):
-            if (value.find('-') < 0):
-                # if the wide/trace command still has a hyphen it means that it is not used up
-                # Example: WIDE2-1 (can be used one more time), WIDE2 (can not be used any more)
-                return True
-        return False
-
-    def _getStationLatestLocation(self, stationId):
-        """Get latest location for at specified station
-
-        Args:
-            None
-
-        Returns:
-            Returns the location of the specified station as an array, first value is latitude, second is longitude
-        """
-        station = self.stationRepository.getObjectById(stationId)
-        if (station.isExistingObject()):
-            if (station.latestConfirmedLatitude is not None and station.latestConfirmedLongitude is not None):
-                return [station.latestConfirmedLatitude, station.latestConfirmedLongitude]
-        return None
diff --git a/server/trackdirect/parser/policies/PacketPathTcpPolicy.py b/server/trackdirect/parser/policies/PacketPathTcpPolicy.py
deleted file mode 100644
index 03b4f987da1d3caf0bc5c137e71c7f7ad23ab501..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketPathTcpPolicy.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import re
-
-
-class PacketPathTcpPolicy():
-    """PacketPathTcpPolicy is used to figure out if packet is sent using radio or TCP
-    """
-
-    def __init__(self, path):
-        """The __init__ method.
-
-        Args:
-            path (list):      Raw packet path list
-        """
-        self.path = path
-
-    def isSentByTCP(self):
-        """Returns True if packet is sent through TCPIP
-
-        Returns:
-            True if packet is sent through TCPIP otherwise False
-        """
-        if (isinstance(self.path, list)):
-            if len(self.path) >= 2 and (re.match(r"^TCPIP\*.*$", self.path[0]) or re.match(r"^TCPXX\*.*$", self.path[0])):
-                # first station is TCP (this usually means it is sent over TCP...)
-                return True
-            if ('qAC' in self.path):
-                # Packet was received from the client directly via a verified connection
-                return True
-            if ('qAX' in self.path):
-                # Packet was received from the client directly via a unverified connection
-                return True
-            if ('qAU' in self.path):
-                # Packet was received from the client directly via a UDP connection.
-                return True
-        return False
diff --git a/server/trackdirect/parser/policies/PacketRelatedMapSectorsPolicy.py b/server/trackdirect/parser/policies/PacketRelatedMapSectorsPolicy.py
deleted file mode 100644
index a0595ef225fc96df404aa4c14e2b93bfa3051007..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketRelatedMapSectorsPolicy.py
+++ /dev/null
@@ -1,133 +0,0 @@
-import time
-
-from trackdirect.parser.policies.MapSectorPolicy import MapSectorPolicy
-
-
-class PacketRelatedMapSectorsPolicy():
-    """PacketRelatedMapSectorsPolicy handles logic related to map sectors for a packet
-    """
-
-    def __init__(self, packetRepository):
-        """The __init__ method.
-
-        Args:
-            packetRepository (PacketRepository):   PacketRepository instance
-        """
-        self.packetRepository = packetRepository
-
-    def getAllRelatedMapSectors(self, packet, previousPacket):
-        """Returns all related map sectors to current packet
-
-        Note:
-            A related map sector is a map-sector that is not the map sector of the current packet nor the previous packet,
-            it is all the map-sectors in between the current packet and the previous packet.
-
-        Args:
-            packet (Packet):         Packet that we want analyze
-            previousPacket (Packet): Packet object that represents the previous packet for this station
-
-        Returns:
-            Returns any related map sectors (as an array)
-        """
-        if (not self._mayPacketHaveRelatedMapSectors(packet, previousPacket)):
-            return []
-
-        relatedMapSectors = []
-        if (previousPacket.mapId == 7):
-            # When previous packet is unconfirmed we need to add path between prev-prev-packet and prev-packet also
-            minTimestamp = int(time.time()) - 86400  # 24 hours
-            prevpreviousPacket = self.packetRepository.getLatestConfirmedMovingObjectByStationId(
-                previousPacket.stationId, minTimestamp)
-            if (prevpreviousPacket.isExistingObject() and prevpreviousPacket.markerCounter > 1):
-                # We found a confirmed prev prev packet
-                relatedMapSectors.extend(self._getRelatedMapSectors(
-                    previousPacket, prevpreviousPacket))
-
-        relatedMapSectors.extend(
-            self._getRelatedMapSectors(packet, previousPacket))
-        return relatedMapSectors
-
-    def _mayPacketHaveRelatedMapSectors(self, packet,  previousPacket):
-        """Returns true if packet may be related to other map sectors then the map sector it's in
-
-        Args:
-            packet (Packet):           Packet that we want analyze
-            previousPacket (Packet):   Packet objekt that represents the previous packet for this station
-
-        Returns:
-            Returns true if packet may be related to other map sectors otherwise false
-        """
-        if (packet.isMoving == 1
-                and previousPacket.isMoving == 1
-                and packet.markerId != 1):
-            # We only add related map-sectors to moving stations (that has a marker)
-            if (packet.mapId == 1):
-                # If new packet is not confirmed (mapId 7) we connect it with related map-sectors later
-                if (previousPacket.markerCounter is not None and previousPacket.markerCounter > 1
-                        or packet.markerId == previousPacket.markerId):
-                    # We only add related map-sectors if previous packet has a marker with several connected packet
-                    # A packet with a marker that is not shared with anyone will be converted to a ghost-marker in client
-                    if (previousPacket.mapId == 1
-                            or packet.markerId == previousPacket.markerId):
-                        # If a previous packet has mapId = 7 (unconfirmed position),
-                        # and new packet has another marker,
-                        # then the previous marker is doomed to be a ghost-marker forever
-                        return True
-        return False
-
-    def _getRelatedMapSectors(self, packet1, packet2):
-        """Get any related map sectors between specified packets
-
-        Note:
-            A related map sector is a map-sector that is not the map sector of the current packet nor the previous packet,
-            it is all the map-sectors in between the current packet and the previous packet.
-
-        Args:
-            packet1 (Packet):           Primary packet object
-            packet2 (Packet):   Prvious packet object
-
-        Returns:
-            Returns any related map sectors (as an array)
-        """
-        relatedMapSectors = []
-        distance = calculatedDistance = packet1.getDistance(
-            packet2.latitude, packet2.longitude)
-        if (distance > 500000):
-            # if distance is longer than 500km, we consider this station to be world wide...
-            # but currently we do not use this information since it would affect performance to much
-            # but it is extremly few stations that actually is affected by this (about 0-2 stations)
-            relatedMapSectors.append(99999999)
-        else:
-            minLat = packet2.latitude
-            maxLat = packet1.latitude
-            minLng = packet2.longitude
-            maxLng = packet1.longitude
-
-            if (maxLat < minLat):
-                minLat = packet1.latitude
-                maxLat = packet2.latitude
-            if (maxLng < minLng):
-                minLng = packet1.longitude
-                maxLng = packet2.longitude
-
-            mapSectorPolicy = MapSectorPolicy()
-            minLng = mapSectorPolicy.getMapSectorLngRepresentation(minLng)
-            minLat = mapSectorPolicy.getMapSectorLatRepresentation(minLat)
-            maxLng = mapSectorPolicy.getMapSectorLngRepresentation(
-                maxLng + 0.5)
-            maxLat = mapSectorPolicy.getMapSectorLatRepresentation(
-                maxLat + 0.2)
-            prevPacketAreaCode = mapSectorPolicy.getMapSector(
-                packet2.latitude, packet2.longitude)
-            newPacketAreaCode = mapSectorPolicy.getMapSector(
-                packet1.latitude, packet1.longitude)
-
-            # lat interval: 0 - 18000000
-            # lng interval: 0 - 00003600
-            # Maybe we can do this smarter? Currently we are adding many map-sectors that is not relevant
-            for lat in range(minLat, maxLat, 20000):
-                for lng in range(minLng, maxLng, 5):
-                    mapSectorAreaCode = lat+lng
-                    if (mapSectorAreaCode != prevPacketAreaCode and mapSectorAreaCode != newPacketAreaCode):
-                        relatedMapSectors.append(mapSectorAreaCode)
-        return relatedMapSectors
diff --git a/server/trackdirect/parser/policies/PacketSpeedComputablePolicy.py b/server/trackdirect/parser/policies/PacketSpeedComputablePolicy.py
deleted file mode 100644
index e1409b480b27900fc12925972fd74b68adf3fc76..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketSpeedComputablePolicy.py
+++ /dev/null
@@ -1,47 +0,0 @@
-class PacketSpeedComputablePolicy():
-    """PacketSpeedComputablePolicy handles logic related to parameters that may cause errors in speed calculations
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def isSpeedComputable(self, packet, prevPacket):
-        """Returns true if speed is possible to calculate in a way that we can trust it
-
-        Args:
-            packet (Packet):        Packet that we want to know move typ for
-            prevPacket (Packet):    Previous related packet for the same station
-
-        Returns:
-            Returns true if speed is possible to calculate
-        """
-        if (packet is None
-                or prevPacket is None
-                or prevPacket.isMoving != 1
-                or prevPacket.mapId not in [1, 7]
-                or packet.markerId == 1
-                or packet.isMoving != 1):
-            return False
-
-        if (packet.reportedTimestamp is not None
-                and prevPacket.reportedTimestamp is not None
-                and packet.reportedTimestamp != 0
-                and prevPacket.reportedTimestamp != 0
-                and (packet.reportedTimestamp % 60 != 0 or prevPacket.reportedTimestamp % 60 != 0)
-                and prevPacket.reportedTimestamp != packet.reportedTimestamp):
-            return True
-        else:
-            calculatedDistance = packet.getDistance(
-                prevPacket.latitude, prevPacket.longitude)
-            if (len(packet.stationIdPath) < 1):
-                # Packet was sent through internet, delay should be small
-                return True
-            elif (len(packet.stationIdPath) <= 1 and calculatedDistance > 5000):
-                # Packet has not been digipeated (delay should not be extreme)
-                # and distance is longer than 5km
-                return True
-            else:
-                # Packet was digipeated (delay can be very long)
-                # or distance was short, calculated speed can not be trusted
-                return False
diff --git a/server/trackdirect/parser/policies/PacketTailPolicy.py b/server/trackdirect/parser/policies/PacketTailPolicy.py
deleted file mode 100644
index b422f2274bf73c29d19bed3b16e30bc99ba542c2..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PacketTailPolicy.py
+++ /dev/null
@@ -1,46 +0,0 @@
-class PacketTailPolicy():
-    """PacketTailPolicy handles logic related to packet tail id
-    """
-
-    def __init__(self, packet, prevPacket):
-        """The __init__ method.
-
-        Args:
-            packet (Packet):       Packet that we want analyze
-            prevPacket (Packet):   Previous related packet for the same station
-        """
-        self.packet = packet
-        self.prevPacket = prevPacket
-        self.packetTailTimestamp = None
-
-    def getPacketTailTimestamp(self):
-        """Returns the current packet tail timestamp
-        """
-        if (self.packetTailTimestamp is None):
-            self._findPacketTail()
-        return self.packetTailTimestamp
-
-    def _findPacketTail(self):
-        """Finds the current packet tail
-        """
-        self.packetTailTimestamp = self.packet.timestamp
-
-        if (self.prevPacket.isExistingObject()):
-            # The packet_tail_id is used to get a faster map, no need to fetch older packets if a station has no tail.
-            # It's not a big problem if packet_tail_id is "Has tail" but no tail exists (the opposite is worse)
-            if (not self.packet.isPostitionEqual(self.prevPacket)):
-                # Both moving and stationary has tail if packet with other position exists
-                self.packetTailTimestamp = self.packet.timestamp
-
-            if (self.packet.isMoving == 0 and not self.packet.isSymbolEqual(self.prevPacket)):
-                # Stationary packet also has a tail if another symbol exists on same position
-                self.packetTailTimestamp = self.packet.timestamp
-
-            if (self.packetTailTimestamp == self.packet.timestamp):
-                # We have not found any tail yet
-                if (self.prevPacket.packetTailTimestamp < self.prevPacket.timestamp):
-                    # prevous packet has a tail
-                    dbMaxAge = 86400  # 1 day
-                    if (self.prevPacket.packetTailTimestamp > (self.packet.timestamp - dbMaxAge)):
-                        # Previous packet indicates that we have a tail and tail is not to old
-                        self.packetTailTimestamp = self.prevPacket.timestamp
diff --git a/server/trackdirect/parser/policies/PreviousPacketPolicy.py b/server/trackdirect/parser/policies/PreviousPacketPolicy.py
deleted file mode 100644
index feea95b14e100b56079f94ccd513904596035f1e..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/PreviousPacketPolicy.py
+++ /dev/null
@@ -1,180 +0,0 @@
-import logging
-from twisted.python import log
-import datetime
-import time
-
-from trackdirect.parser.policies.PacketAssumedMoveTypePolicy import PacketAssumedMoveTypePolicy
-from trackdirect.parser.policies.PacketOrderPolicy import PacketOrderPolicy
-
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.repositories.StationRepository import StationRepository
-
-
-class PreviousPacketPolicy():
-    """The PreviousPacketPolicy class tries to find the most related previous packet for the same station
-    """
-
-    def __init__(self, packet, db):
-        """The __init__ method.
-
-        Args:
-            packet (Packet):             Packet for that we want to find previous most related packet
-            db (psycopg2.Connection):    Database connection
-        """
-        self.db = db
-        self.packet = packet
-        self.packetRepository = PacketRepository(db)
-        self.stationRepository = StationRepository(db)
-
-    def getPreviousPacket(self):
-        """Tries to find the previous packet for the specified packet
-
-        Returns:
-            Packet
-        """
-        if (not self._mayPacketHavePreviousPacket()):
-            return self.packetRepository.create()
-
-        minTimestamp = int(time.time()) - 86400  # 24 hours
-        latestPreviousPacket = self.packetRepository.getLatestObjectByStationId(self.packet.stationId, minTimestamp)
-
-        if (not latestPreviousPacket.isExistingObject()):
-            return latestPreviousPacket
-
-        if (self.packet.mapId == 5):
-            return self._getBestPreviousPacketForFaultyGpsPacket(latestPreviousPacket)
-        else:
-            packetAssumedMoveTypePolicy = PacketAssumedMoveTypePolicy(self.db)
-            isMoving = packetAssumedMoveTypePolicy.getAssumedMoveType(self.packet, latestPreviousPacket)
-            if (isMoving == 1):
-                return self._getBestPreviousPacketForMovingStation(latestPreviousPacket, minTimestamp)
-            else:
-                return self._getBestPreviousPacketForStationaryStation(latestPreviousPacket)
-
-    def _mayPacketHavePreviousPacket(self):
-        """Returns true if current packet is ready for previous packet calculation
-
-        Returns:
-            boolean
-        """
-        if (self.packet.latitude is not None
-                and self.packet.longitude is not None
-                and type(self.packet.latitude) == float
-                and type(self.packet.longitude) == float
-                and self.packet.sourceId != 3
-                and self.packet.mapId in [1, 5, 7, 9]):
-            return True
-        else:
-            return False
-
-    def _getBestPreviousPacketForFaultyGpsPacket(self, latestPreviousPacket):
-        """Find the previous packet that is best related to the current packet
-
-        Args:
-            latestPreviousPacket (Packet):  Packet object that represents the latest previous packet for this station
-
-        Returns:
-            Packet
-        """
-        if (latestPreviousPacket.mapId != self.packet.mapId
-                or not self.packet.isPostitionEqual(latestPreviousPacket)
-                or not self.packet.isSymbolEqual(latestPreviousPacket)):
-            # Try to find prev packet
-            prevPacketSamePos = self.packetRepository.getLatestObjectByStationIdAndPosition(
-                self.packet.stationId,
-                self.packet.latitude,
-                self.packet.longitude,
-                [self.packet.mapId],
-                self.packet.symbol,
-                self.packet.symbolTable,
-                self.packet.timestamp - 86400
-            )
-            if (prevPacketSamePos.isExistingObject()):
-                return prevPacketSamePos
-        return latestPreviousPacket
-
-    def _getBestPreviousPacketForStationaryStation(self, latestPreviousPacket):
-        """Find the previous packet that is best related to the current packet
-
-        Args:
-            latestPreviousPacket (Packet):  Packet object that represents the latest previous packet for this station
-
-        Returns:
-            Packet
-        """
-        if (not self.packet.isPostitionEqual(latestPreviousPacket)
-                or not self.packet.isSymbolEqual(latestPreviousPacket)
-                or self.packet.isMoving != latestPreviousPacket.isMoving
-                or latestPreviousPacket.mapId not in [1, 7]):
-            # Try to find stationary marker for packet position
-            previousPacketSamePos = self.packetRepository.getLatestObjectByStationIdAndPosition(
-                self.packet.stationId,
-                self.packet.latitude,
-                self.packet.longitude,
-                [1, 7],
-                self.packet.symbol,
-                self.packet.symbolTable,
-                self.packet.timestamp - 86400
-            )
-            if (previousPacketSamePos.isExistingObject()):
-                return previousPacketSamePos
-        return latestPreviousPacket
-
-    def _getBestPreviousPacketForMovingStation(self, latestPreviousPacket, minTimestamp):
-        """Find the previous packet that is best related to the current packet
-
-        Args:
-            latestPreviousPacket (Packet):  Packet object that represents the latest previous packet for this station
-            minTimestamp (int):             Oldest accepted timestamp (Unix timestamp)
-
-        Returns:
-            Packet
-        """
-        previousPacket = latestPreviousPacket
-        if (previousPacket.isExistingObject()
-                and (previousPacket.isMoving != 1
-                     or previousPacket.mapId not in [1, 7])):
-            # Current packet is assumed moving but previous is stationary, try to find last moving instead
-            prevMovingPacket = self.packetRepository.getLatestMovingObjectByStationId(
-                self.packet.stationId, minTimestamp)
-            if (prevMovingPacket.isExistingObject()):
-                previousPacket = prevMovingPacket
-
-        packetOrderPolicy = PacketOrderPolicy()
-        if (previousPacket.isExistingObject()
-                and previousPacket.isMoving == 1
-                and previousPacket.mapId == 7
-                and not packetOrderPolicy.isPacketInWrongOrder(self.packet, previousPacket)):
-            # previousPacket is not confirmed (see if we have a better alternative)
-            prevConfirmedPacket = self.packetRepository.getLatestConfirmedMovingObjectByStationId(
-                self.packet.stationId, minTimestamp)
-            previousPacket = self._getClosestPacketObject(
-                previousPacket, prevConfirmedPacket)
-
-        return previousPacket
-
-    def _getClosestPacketObject(self, previousPacket1, previousPacket2):
-        """Returns the packet closest to the current position
-
-        Args:
-            previousPacket1 (Packet):  Packet object that represents one previous packet for current station
-            previousPacket2 (Packet):  Packet object that represents one previous packet for current station
-
-        Returns:
-            Packet
-        """
-        if (not previousPacket1.isExistingObject()):
-            return previousPacket2
-
-        if (not previousPacket2.isExistingObject()):
-            return previousPacket1
-
-        prevPacket1CalculatedDistance = self.packet.getDistance(
-            previousPacket1.latitude, previousPacket1.longitude)
-        prevPacket2CalculatedDistance = self.packet.getDistance(
-            previousPacket2.latitude, previousPacket2.longitude)
-
-        if (prevPacket2CalculatedDistance < prevPacket1CalculatedDistance):
-            return previousPacket2
-        else:
-            return previousPacket1
diff --git a/server/trackdirect/parser/policies/StationNameFormatPolicy.py b/server/trackdirect/parser/policies/StationNameFormatPolicy.py
deleted file mode 100644
index ca07c6163d74fd26ffee62f8b03d24354f3685f8..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/StationNameFormatPolicy.py
+++ /dev/null
@@ -1,26 +0,0 @@
-class StationNameFormatPolicy():
-    """The StationNameFormatPolicy class handles logic related to station name format
-    """
-
-    def __init__(self):
-        """The __init__ method.
-        """
-
-    def getCorrectFormat(self, name):
-        """ Returns the specified name in correct format
-        (without any status characters)
-
-        Notes:
-            _ == kill character
-            ! == live character for item
-            * == live character for object
-            single quote and double quote is just to annoying
-            (of course we can handle it in database but why use it in a name...)
-
-        Args:
-            name (string):  name of station
-
-        Returns:
-            string
-        """
-        return name.replace('*', '').replace('!', '').replace('_', '').replace('\'', '').replace('"', '').replace('`', '').strip()
diff --git a/server/trackdirect/parser/policies/__init__.py b/server/trackdirect/parser/policies/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/parser/policies/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/repositories/MarkerRepository.py b/server/trackdirect/repositories/MarkerRepository.py
deleted file mode 100644
index 10b98f1eb254ca90f1e957a08b144c8a49c885f0..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/MarkerRepository.py
+++ /dev/null
@@ -1,45 +0,0 @@
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.Marker import Marker
-
-
-class MarkerRepository(Repository):
-    """A Repository class for the Marker class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            Marker
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select %s from marker_seq where last_value > %s""", (id, id, ))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-
-        selectCursor.close()
-        return dbObject
-
-    def create(self):
-        """Creates an empty Marker object
-
-        Returns:
-            Marker
-        """
-        return Marker(self.db)
diff --git a/server/trackdirect/repositories/OgnDeviceRepository.py b/server/trackdirect/repositories/OgnDeviceRepository.py
deleted file mode 100644
index b5d678531a52f4764239228bd4779bd0be5cb8b9..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/OgnDeviceRepository.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from random import randint
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.OgnDevice import OgnDevice
-
-
-class OgnDeviceRepository(Repository):
-    """A Repository class for the OgnDevice class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            OgnDevice
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from ogn_device where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-        else:
-            # ogn_device do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectByDeviceId(self, deviceId):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            deviceId (string):  Device Id (corresponds to ogn_sender_address)
-
-        Returns:
-            OgnDevice instance
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from ogn_device where device_id like %s""", (deviceId,))
-        record = selectCursor.fetchone()
-
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-        else:
-            # ogn_device do not exists, return empty object
-            dbObject = OgnDevice(self.db)
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromRecord(self, record):
-        """Returns a OgnDevice object based on the specified database record dict
-
-        Args:
-            record (dict):  A database record dict from the ogn_device database table
-
-        Returns:
-            A OgnDevice object
-        """
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = randint(1, 9999999)
-            dbObject.deviceType = record["device_type"]
-            dbObject.deviceId = record["device_id"]
-            dbObject.aircraftModel = record["aircraft_model"]
-            dbObject.registration = record["registration"]
-            dbObject.cn = record["cn"]
-
-            if (record["tracked"] == 'N'):
-                dbObject.tracked = False
-            else:
-                dbObject.tracked = True
-
-            if (record["identified"] == 'N'):
-                dbObject.identified = False
-            else:
-                dbObject.identified = True
-
-            try:
-                dbObject.ddbAircraftType = int(record["ddb_aircraft_type"])
-            except ValueError:
-                pass
-
-        return dbObject
-
-    def create(self):
-        """Creates an empty OgnDevice object
-
-        Returns:
-            OgnDevice instance
-        """
-        return OgnDevice(self.db)
diff --git a/server/trackdirect/repositories/OgnHiddenStationRepository.py b/server/trackdirect/repositories/OgnHiddenStationRepository.py
deleted file mode 100644
index 2e805e1f4bec85c0a2146a704063bef69b4c93b4..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/OgnHiddenStationRepository.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.OgnHiddenStation import OgnHiddenStation
-
-
-class OgnHiddenStationRepository(Repository):
-    """A Repository class for the OgnHiddenStation class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            OgnHiddenStation
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from ogn_hidden_station where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-        else:
-            # station do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectByHashedName(self, hashedName, createNewIfMissing):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            hashedName (string):           Uniqe hash for station
-            createNewIfMissing (boolean):  Set to true if a new should be created if no one is found
-
-        Returns:
-            OgnHiddenStation instance
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from ogn_hidden_station where hashed_name = %s""", (str(hashedName),))
-        record = selectCursor.fetchone()
-
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-        elif (createNewIfMissing):
-            # not exist, create it
-            dbObject = self.create()
-            dbObject.hashedName = hashedName
-            dbObject.save()
-        else:
-            # ogn_device do not exists, return empty object
-            dbObject = self.create()
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromRecord(self, record):
-        """Returns a OgnHiddenStation object based on the specified database record dict
-
-        Args:
-            record (dict):  A database record dict from the ogn_device database table
-
-        Returns:
-            A OgnHiddenStation object
-        """
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = int(record["id"])
-            dbObject.name = record["hashed_name"]
-
-        return dbObject
-
-    def create(self):
-        """Creates an empty OgnHiddenStation object
-
-        Returns:
-            OgnHiddenStation instance
-        """
-        return OgnHiddenStation(self.db)
diff --git a/server/trackdirect/repositories/PacketOgnRepository.py b/server/trackdirect/repositories/PacketOgnRepository.py
deleted file mode 100644
index 46fff16170bd0ff2a102beb88f43b4c0aa9ccfaa..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/PacketOgnRepository.py
+++ /dev/null
@@ -1,126 +0,0 @@
-import datetime
-import time
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.PacketOgn import PacketOgn
-
-
-class PacketOgnRepository(Repository):
-    """A Repository class for the PacketOgn class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):   Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            PacketOgn
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from packet_ogn where id = %s""", (id,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectByPacketIdAndTimestamp(self, id, timestamp):
-        """Returns an object based on the specified packet id in database
-
-        Args:
-            id (int):         Database row id
-            timestamp (int):  Unix timestamp for requested packet (must be samt date as packet was received)
-
-        Returns:
-            PacketOgn
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from packet_ogn where packet_id = %s and timestamp = %s""", (id, timestamp,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectFromRecord(self, record):
-        """Returns a packet OGN object from a record
-
-        Args:
-            record (dict):  Database record dict to convert to a packet OGN object
-
-        Returns:
-            A packet OGN object
-        """
-        dbObject = PacketOgn(self.db)
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.packetId = int(record["packet_id"])
-            dbObject.stationId = int(record["station_id"])
-            dbObject.timestamp = int(record["timestamp"])
-
-            dbObject.ognSenderAddress = record['ogn_sender_address']
-            dbObject.ognAddressTypeId = record['ogn_address_type_id']
-            dbObject.ognAircraftTypeId = record['ogn_aircraft_type_id']
-            dbObject.ognClimbRate = record['ogn_climb_rate']
-            dbObject.ognTurnRate = record['ogn_turn_rate']
-            dbObject.ognSignalToNoiseRatio = record['ogn_signal_to_noise_ratio']
-            dbObject.ognBitErrorsCorrected = record['ogn_bit_errors_corrected']
-            dbObject.ognFrequencyOffset = record['ogn_frequency_offset']
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            PacketOgn
-        """
-        newObject = self.create()
-        if ("ogn" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.timestamp = int(time.time()) - 1
-
-            if ("ogn_sender_address" in data["ogn"]):
-                newObject.ognSenderAddress = data["ogn"]["ogn_sender_address"]
-
-            if ("ogn_address_type_id" in data["ogn"]):
-                newObject.ognAddressTypeId = data["ogn"]["ogn_address_type_id"]
-
-            if ("ogn_aircraft_type_id" in data["ogn"]):
-                newObject.ognAircraftTypeId = data["ogn"]["ogn_aircraft_type_id"]
-
-            if ("ogn_climb_rate" in data["ogn"]):
-                newObject.ognClimbRate = data["ogn"]["ogn_climb_rate"]
-
-            if ("ogn_turn_rate" in data["ogn"]):
-                newObject.ognTurnRate = data["ogn"]["ogn_turn_rate"]
-
-            if ("ogn_signal_to_noise_ratio" in data["ogn"]):
-                newObject.ognSignalToNoiseRatio = data["ogn"]["ogn_signal_to_noise_ratio"]
-
-            if ("ogn_bit_errors_corrected" in data["ogn"]):
-                newObject.ognBitErrorsCorrected = data["ogn"]["ogn_bit_errors_corrected"]
-
-            if ("ogn_frequency_offset" in data["ogn"]):
-                newObject.ognFrequencyOffset = data["ogn"]["ogn_frequency_offset"]
-
-        return newObject
-
-    def create(self):
-        """Creates an empty PacketOgn object
-
-        Returns:
-            PacketOgn
-        """
-        return PacketOgn(self.db)
diff --git a/server/trackdirect/repositories/PacketRepository.py b/server/trackdirect/repositories/PacketRepository.py
deleted file mode 100644
index 39380f34f3894e155b3ff6ac63b7fd47ac4d0051..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/PacketRepository.py
+++ /dev/null
@@ -1,764 +0,0 @@
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.Packet import Packet
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-
-
-class PacketRepository(Repository):
-    """The PacketRepository class contains different method that creates Packet instances
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):  Database connection (with autocommit)
-        """
-        self.db = db
-
-        # After testing I have realized that several queries are faster if you query one packet child at the time
-        # That is why we are using packetTableCreator to fetch childtables instead of using the parent packet table
-        self.packetTableCreator = PacketTableCreator(self.db)
-        self.packetTableCreator.disableCreateIfMissing()
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from packet where id = %s""", (id,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectByIdAndTimestamp(self, id, timestamp):
-        """Returns an object based on the specified id in database
-
-        Args:
-            id (int):         Database row id
-            timestamp (int):  Unix timestamp for requested packet
-
-        Returns:
-            Packet
-        """
-        try:
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-        except TrackDirectMissingTableError as e:
-            return Packet(self.db)
-
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from """ +
-                             packetTable + """ where id = %s""", (id,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectByStationIdAndTimestamp(self, stationId, timestamp):
-        """Returns an object based on the specified stationId in database
-
-        Args:
-            stationId (int):  Station id
-            timestamp (int):  Unix timestamp for requested packet
-
-        Returns:
-            Packet
-        """
-        try:
-            packetTable = self.packetTableCreator.getPacketTable(timestamp)
-            selectCursor = self.db.cursor()
-            selectCursor.execute("""select * from """ + packetTable +
-                                 """ where station_id = %s and timestamp = %s order by id limit 1""", (stationId, timestamp, ))
-            record = selectCursor.fetchone()
-
-            selectCursor.close()
-            return self.getObjectFromRecord(record)
-        except TrackDirectMissingTableError as e:
-            return self.create()
-
-    def getLatestObjectListByStationIdListAndTimeInterval(self, stationIdList, minPacketTimestamp, maxPacketTimestamp, onlyConfirmed=True):
-        """Returns an array of Packet's specified by station id's
-        Args:
-            stationIdList (array):     Station id's to look for
-            minPacketTimestamp (int):  Min requested unix timestamp
-            maxPacketTimestamp (int):  Max requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-
-        selectCursor = self.db.cursor()
-        result = []
-        foundStationIdList = []
-        packetTables = self.packetTableCreator.getPacketTables(
-            minPacketTimestamp, maxPacketTimestamp)
-        mapIdList = [1, 2, 12]
-        if (not onlyConfirmed):
-            mapIdList = [1, 2, 5, 7, 9, 12]
-
-        for packetTable in reversed(packetTables):
-            stationIdListToFind = tuple(
-                list(set(stationIdList) - set(foundStationIdList)))
-
-            if (len(stationIdListToFind) > 0):
-                sql1 = selectCursor.mogrify("""select *
-                    from """ + packetTable + """ packet
-                    where id in (
-                        select max(id)
-                        from """ + packetTable + """ packet
-                        where map_id in %s
-                            and station_id in %s
-                            and timestamp > %s
-                            and timestamp <= %s
-                        group by station_id
-                    )
-                    order by packet.marker_id desc, packet.id desc""", (tuple(mapIdList), tuple(stationIdListToFind), int(minPacketTimestamp), int(maxPacketTimestamp)))
-                # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-                selectCursor.execute(sql1)
-                for record in selectCursor:
-                    if (record is not None):
-                        if (record['station_id'] not in foundStationIdList):
-                            dbObject = self.getObjectFromRecord(record)
-                            result.append(dbObject)
-                            foundStationIdList.append(record['station_id'])
-            if (len(foundStationIdList) >= len(stationIdList)):
-                break
-
-        if (len(foundStationIdList) < len(stationIdList)):
-            for packetTable in reversed(packetTables):
-                stationIdListToFind = tuple(
-                    list(set(stationIdList) - set(foundStationIdList)))
-
-                if (len(stationIdListToFind) > 0):
-                    sql2 = selectCursor.mogrify("""select *
-                        from """ + packetTable + """ packet
-                        where map_id = 12
-                            and station_id in %s
-                            and position_timestamp <= %s
-                            and timestamp > %s
-                        order by packet.marker_id desc, packet.id desc""", (tuple(stationIdListToFind), int(maxPacketTimestamp), int(minPacketTimestamp)))
-                    # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-                    selectCursor.execute(sql2)
-                    for record in selectCursor:
-                        if (record is not None):
-                            if (record['station_id'] not in foundStationIdList):
-                                dbObject = self.getObjectFromRecord(record)
-                                result.append(dbObject)
-                                foundStationIdList.append(record['station_id'])
-
-                if (len(foundStationIdList) >= len(stationIdList)):
-                    break
-
-        selectCursor.close()
-        return result
-
-    def getObjectListByStationIdListAndTimeInterval(self, stationIdList, minPacketTimestamp, maxPacketTimestamp):
-        """Returns an array of Packet's specified by station id's
-        Args:
-            stationIdList (array):     Station id's to look for
-            minPacketTimestamp (int):  Min requested unix timestamp
-            maxPacketTimestamp (int):  Max requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-
-        selectCursor = self.db.cursor()
-
-        result = []
-        packetTables = self.packetTableCreator.getPacketTables(
-            minPacketTimestamp, maxPacketTimestamp)
-
-        for packetTable in packetTables:
-            sql1 = selectCursor.mogrify("""select *
-                from """ + packetTable + """ packet
-                where map_id in (1,2,5,7,9,12)
-                    and station_id in %s
-                    and timestamp > %s
-                    and timestamp <= %s
-                order by packet.marker_id, packet.id""", (tuple(stationIdList), int(minPacketTimestamp), int(maxPacketTimestamp)))
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-            selectCursor.execute(sql1)
-            for record in selectCursor:
-                if (record is not None):
-                    dbObject = self.getObjectFromRecord(record)
-                    result.append(dbObject)
-
-            # Also add packets that has been replace but where position_timestamp was in or before period
-            sql2 = selectCursor.mogrify("""select *
-                from """ + packetTable + """ packet
-                where map_id = 12
-                    and station_id in %s
-                    and position_timestamp <= %s
-                    and timestamp > %s
-                order by packet.marker_id, packet.id""", (tuple(stationIdList), int(maxPacketTimestamp), int(maxPacketTimestamp)))
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-            selectCursor.execute(sql2)
-            for record in selectCursor:
-                if (record is not None):
-                    dbObject = self.getObjectFromRecord(record)
-                    result.append(dbObject)
-
-        selectCursor.close()
-        return result
-
-    def getObjectListByStationIdList(self, stationIdList, minPacketTimestamp):
-        """Returns an array of Packet's specified by station id's
-        Args:
-            stationIdList (array):     Station id's to look for
-            minPacketTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-        selectCursor = self.db.cursor()
-        result = []
-
-        packetTables = self.packetTableCreator.getPacketTables(
-            minPacketTimestamp)
-        for packetTable in packetTables:
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """ packet
-                where map_id in (1,5,7,9)
-                    and station_id in %s""", (tuple(stationIdList),))
-
-            if (minPacketTimestamp != 0):
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ and timestamp > %s""", (int(minPacketTimestamp),))
-
-            sql = sql + \
-                selectCursor.mogrify(
-                    """ order by packet.marker_id, packet.id""")
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-            selectCursor.execute(sql)
-
-            for record in selectCursor:
-                if (record is not None):
-                    dbObject = self.getObjectFromRecord(record)
-                    result.append(dbObject)
-        selectCursor.close()
-        return result
-
-    def getLatestObjectByStationIdAndPosition(self, stationId, latitude, longitude, mapIdList, symbol=None, symbolTable=None, minTimestamp=0):
-        """Returns a packet object specified by station id and position (and map id, symbol and symbol table)
-        Args:
-            stationId (int):     Station id to look for
-            latitude (double):   Latitude
-            longitude (double):  Longitude
-            mapIdList (int):     Array of map id's to look for
-            symbol (str):        Symbol char
-            symbolTable (str):   Symbol table char
-            minTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-        packetTables = self.packetTableCreator.getPacketTables(minTimestamp)
-        for packetTable in reversed(packetTables):
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """
-                where station_id = %s
-                    and latitude = %s
-                    and longitude = %s
-                    and map_id in %s""", (stationId, latitude, longitude, tuple(mapIdList),))
-
-            if (minTimestamp != 0):
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ and timestamp > %s""", (int(minTimestamp),))
-
-            if (symbol is not None):
-                sql = sql + \
-                    selectCursor.mogrify(""" and symbol = %s""", (symbol,))
-
-            if (symbolTable is not None):
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ and symbol_table = %s""", (symbolTable,))
-
-            sql = sql + \
-                selectCursor.mogrify(
-                    """ order by marker_id desc, id desc limit 1""")
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-            selectCursor.execute(sql)
-            record = selectCursor.fetchone()
-
-            if (record is not None):
-                selectCursor.close()
-                return self.getObjectFromRecord(record)
-        selectCursor.close()
-        return self.create()
-
-    def getLatestConfirmedMovingObjectByStationId(self, stationId, minTimestamp=0):
-        """Returns the latest confirmed moving Packet specified by station id
-        Args:
-            stationId (int):     Station id to look for
-            minTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-        packetTables = self.packetTableCreator.getPacketTables(minTimestamp)
-        for packetTable in reversed(packetTables):
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """
-                where station_id = %s
-                    and is_moving = 1
-                    and map_id = 1""", (stationId,))
-
-            if (minTimestamp != 0):
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ and timestamp > %s""", (int(minTimestamp),))
-
-            sql = sql + \
-                selectCursor.mogrify(
-                    """ order by marker_id desc, id desc limit 1""")
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-            selectCursor.execute(sql)
-            record = selectCursor.fetchone()
-
-            if (record is not None):
-                selectCursor.close()
-                return self.getObjectFromRecord(record)
-        selectCursor.close()
-        return self.create()
-
-    def getLatestMovingObjectByStationId(self, stationId, minTimestamp=0):
-        """Returns the latest moving Packet specified by station id
-        Args:
-            stationId (int):     Station id to look for
-            minTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-        packetTables = self.packetTableCreator.getPacketTables(minTimestamp)
-        for packetTable in reversed(packetTables):
-            # We only look for map id 1 and 7 since we use this method to extend a moving marker
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """ packet
-                where station_id = %s
-                    and is_moving = 1
-                    and map_id in (1,7)""", (stationId,))
-
-            if (minTimestamp != 0):
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ and timestamp > %s""", (int(minTimestamp),))
-
-            sql = sql + \
-                selectCursor.mogrify(
-                    """ order by marker_id desc, id desc limit 1""")
-            # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-            selectCursor.execute(sql)
-
-            record = selectCursor.fetchone()
-            if (record is not None):
-                selectCursor.close()
-                return self.getObjectFromRecord(record)
-        selectCursor.close()
-        return self.create()
-
-    def getLatestConfirmedObjectByStationId(self, stationId, minTimestamp=0):
-        """Returns the latest confirmed packet object specified by station id
-        Args:
-            stationId (int):     Station id to look for
-            minTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-
-        sql = selectCursor.mogrify("""select *
-            from station
-            where station.id = %s""", (stationId,))
-
-        selectCursor.execute(sql)
-        record = selectCursor.fetchone()
-        selectCursor.close()
-
-        if (record is not None and record["latest_confirmed_packet_timestamp"] is not None and record["latest_confirmed_packet_timestamp"] >= minTimestamp):
-            return self.getObjectByIdAndTimestamp(record["latest_confirmed_packet_id"], record["latest_confirmed_packet_timestamp"])
-        else:
-            return self.create()
-
-    def getLatestObjectByStationId(self, stationId, minTimestamp=0):
-        """Returns the latest Packet specified by station id (that has a location)
-        Args:
-            stationId (int):     Station id to look for
-            minTimestamp (int):  Min requested unix timestamp
-
-        Returns:
-            Packet
-        """
-        selectCursor = self.db.cursor()
-
-        sql = selectCursor.mogrify("""select *
-            from station
-            where station.id = %s""", (stationId,))
-
-        selectCursor.execute(sql)
-        record = selectCursor.fetchone()
-        selectCursor.close()
-
-        if (record is not None and record["latest_location_packet_timestamp"] is not None and record["latest_location_packet_timestamp"] >= minTimestamp):
-            return self.getObjectByIdAndTimestamp(record["latest_location_packet_id"], record["latest_location_packet_timestamp"])
-        else:
-            return self.create()
-
-    def getMostRecentConfirmedObjectListByStationIdList(self, stationIdList, minTimestamp):
-        """Returns an array of the most recent confirmed Packet's specified by station id's
-
-        Note:
-            This method returnes the latest packet for moving stations and the latest packet for every uniqe position for stationary stations.
-
-        Args:
-            stationIdList (array): Station id's to look for
-            minTimestamp (int):    Min requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-        selectCursor = self.db.cursor()
-        result = []
-
-        # Stationary objects
-        packetTables = self.packetTableCreator.getPacketTables(minTimestamp)
-        for packetTable in packetTables:
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """
-                where station_id in %s
-                    and timestamp > %s
-                    and is_moving = 0
-                    and map_id = 1""", (tuple(stationIdList), int(minTimestamp),))
-            # Since we only should get one moving and all other should be stationary an "order by" should not be nessecery
-            selectCursor.execute(sql)
-
-            for record in selectCursor:
-                if (record is not None):
-                    packet = self.getObjectFromRecord(record)
-                    result.append(packet)
-
-        # Moving objects
-        for stationId in stationIdList:
-            packet = self.getLatestConfirmedMovingObjectByStationId(
-                stationId, minTimestamp)
-            if (packet.isExistingObject()):
-                result.append(packet)
-
-        selectCursor.close()
-        return result
-
-    def getMostRecentConfirmedObjectListByStationIdListAndTimeInterval(self, stationIdList, minTimestamp, maxTimestamp):
-        """Returns an array of the most recent confirmed Packet's specified by station id's
-
-        Note:
-            This method returnes the latest packet for moving stations and the latest packet for every uniqe position for stationary stations.
-
-        Args:
-            stationIdList (array): Station id's to look for
-            minTimestamp (int):    Min requested unix timestamp
-            maxTimestamp (int):    Max requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-
-        minTimestampRoundedQuarter = int(
-            minTimestamp) - (int(minTimestamp) % 900)
-        minTimestampRoundedDay = int(
-            minTimestamp) - (int(minTimestamp) % 86400)
-
-        selectCursor = self.db.cursor()
-        result = []
-        foundStationaryMarkerHashList = []
-        foundMovingMarkerStationIdList = []
-
-        packetTables = self.packetTableCreator.getPacketTables(
-            minTimestamp, maxTimestamp)
-        for packetTable in reversed(packetTables):
-            # Stationary objects
-            sql = selectCursor.mogrify("""select *
-                from """ + packetTable + """ packet
-                where id in (
-                    select max(id)
-                    from """ + packetTable + """ packet
-                    where station_id in %s
-                        and timestamp > %s
-                        and timestamp <= %s
-                        and is_moving = 0
-                        and map_id in (1,2,12)
-                    group by station_id, latitude, longitude, symbol, symbol_table
-                )""", (tuple(stationIdList), int(minTimestamp), int(maxTimestamp)))
-            # Since we only should get one moving and all other should be stationary an "order by" should not be nessecery
-            selectCursor.execute(sql)
-            for record in selectCursor:
-                if (record is not None):
-                    markerHash = hash(str(record['station_id']) + ';' + str(record['station_id']) + ';' + str(
-                        record['latitude']) + ';' + str(record['longitude']) + ';' + record['symbol'] + ';' + record['symbol_table'])
-                    if (markerHash not in foundStationaryMarkerHashList):
-                        foundStationaryMarkerHashList.append(markerHash)
-                        packet = self.getObjectFromRecord(record)
-                        result.append(packet)
-
-            # Moving objects
-            sql = selectCursor.mogrify("""select packet.*
-                from """ + packetTable + """ packet
-                where id in (
-                    select max(id)
-                    from """ + packetTable + """ packet
-                    where station_id in %s
-                        and map_id in (1,2,12)
-                        and packet.timestamp > %s
-                        and packet.timestamp <= %s
-                        and packet.is_moving = 1
-                    group by station_id
-                )""", (tuple(stationIdList), int(minTimestamp), int(maxTimestamp)))
-            # Since we only should get one moving and all other should be stationary an "order by" should not be nessecery
-
-            selectCursor.execute(sql)
-            for record in selectCursor:
-                if (record is not None):
-                    if (record['station_id'] not in foundMovingMarkerStationIdList):
-                        foundMovingMarkerStationIdList.append(
-                            record['station_id'])
-
-                        packet = self.getObjectFromRecord(record)
-                        result.append(packet)
-        selectCursor.close()
-        return result
-
-    def getLatestConfirmedObjectListByStationIdList(self, stationIdList, minTimestamp=0):
-        """Returns an array of the latest confirmed packet objects with specified station id's
-
-        Args:
-            stationIdList (array): station id's to look for
-            minTimestamp (int):    Min requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-
-        result = []
-        if (minTimestamp == 0):
-            # Apperantly we are looking for the latest no matter the age
-            for stationId in stationIdList:
-                packet = self.getLatestConfirmedObjectByStationId(stationId)
-                if (packet.isExistingObject()):
-                    result.append(packet)
-        else:
-            selectCursor = self.db.cursor()
-            packetTables = self.packetTableCreator.getPacketTables(
-                minTimestamp)
-
-            for packetTable in reversed(packetTables):
-                sql = selectCursor.mogrify("""select packet.*
-                    from """ + packetTable + """ packet, station
-                    where station.id in %s
-                        and station.latest_confirmed_packet_id = packet.id
-                        and station.latest_confirmed_packet_timestamp = packet.timestamp """, (tuple(stationIdList),))
-
-                if (minTimestamp != 0):
-                    sql = sql + selectCursor.mogrify(
-                        """ and station.latest_confirmed_packet_timestamp > %s""" % (int(minTimestamp),))
-
-                sql = sql + \
-                    selectCursor.mogrify(
-                        """ order by packet.marker_id, packet.id""")
-                # Sort by marker_id first and packet as second, otherwise client might render it wrong
-
-                selectCursor.execute(sql)
-
-                for record in selectCursor:
-                    if (record is not None):
-                        result.append(self.getObjectFromRecord(record))
-
-                if (len(result) >= len(stationIdList)):
-                    break
-
-            selectCursor.close()
-        return result
-
-    def getLatestObjectListByStationIdList(self, stationIdList, minTimestamp=0):
-        """Returns an array of the latest Packet's (that has a location) with specified station id's
-
-        Args:
-            stationIdList (array): station id's to look for
-            minTimestamp (int):    Min requested unix timestamp
-
-        Returns:
-            Array
-        """
-        if (len(stationIdList) == 0):
-            return []
-
-        result = []
-        if (minTimestamp == 0):
-            # Apperantly we are looking for the latest no matter the age
-            for stationId in stationIdList:
-                packet = self.getLatestObjectByStationId(stationId)
-                if (packet.isExistingObject()):
-                    result.append(packet)
-
-        else:
-            selectCursor = self.db.cursor()
-            packetTables = self.packetTableCreator.getPacketTables(
-                minTimestamp)
-            for packetTable in reversed(packetTables):
-                sql = selectCursor.mogrify("""select packet.*
-                    from """ + packetTable + """ packet, station
-                    where station.id in %s
-                        and station.latest_location_packet_id = packet.id
-                        and station.latest_confirmed_packet_timestamp = packet.timestamp """, (tuple(stationIdList),))
-
-                if (minTimestamp != 0):
-                    sql = sql + selectCursor.mogrify(
-                        """ and station.latest_location_packet_timestamp > %s""" % (int(minTimestamp),))
-
-                selectCursor.execute(sql)
-
-                for record in selectCursor:
-                    if (record is not None):
-                        result.append(self.getObjectFromRecord(record))
-
-                if (len(result) >= len(stationIdList)):
-                    break
-
-            selectCursor.close()
-        return result
-
-    def getObjectFromRecord(self, record):
-        """Returns a packet object from a record
-
-        Args:
-            record (dict):  Database record dict to convert to a packet object
-
-        Returns:
-            Packet
-        """
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.stationId = int(record["station_id"])
-            dbObject.senderId = int(record["sender_id"])
-            dbObject.packetTypeId = record["packet_type_id"]
-            dbObject.timestamp = int(record["timestamp"])
-
-            if (record["latitude"] is not None):
-                dbObject.latitude = float(record["latitude"])
-            else:
-                dbObject.latitude = None
-
-            if (record["longitude"] is not None):
-                dbObject.longitude = float(record["longitude"])
-            else:
-                dbObject.longitude = None
-
-            dbObject.posambiguity = record['posambiguity']
-            dbObject.symbol = record["symbol"]
-            dbObject.symbolTable = record["symbol_table"]
-            dbObject.mapSector = record["map_sector"]
-            dbObject.relatedMapSectors = record["related_map_sectors"]
-            dbObject.mapId = record["map_id"]
-            dbObject.sourceId = record["source_id"]
-            dbObject.markerId = record["marker_id"]
-            dbObject.speed = record["speed"]
-            dbObject.course = record["course"]
-            dbObject.altitude = record["altitude"]
-            dbObject.isMoving = record['is_moving']
-
-            if (record["reported_timestamp"] is not None):
-                dbObject.reportedTimestamp = int(record["reported_timestamp"])
-            else:
-                dbObject.reportedTimestamp = record["reported_timestamp"]
-
-            if (record["position_timestamp"] is not None):
-                dbObject.positionTimestamp = int(record["position_timestamp"])
-            else:
-                dbObject.positionTimestamp = record["position_timestamp"]
-
-            if ("packet_tail_timestamp" in record):
-                dbObject.packetTailTimestamp = record['packet_tail_timestamp']
-            else:
-                dbObject.packetTailTimestamp = dbObject.timestamp
-
-            if ("marker_counter" in record):
-                dbObject.markerCounter = record['marker_counter']
-            else:
-                dbObject.markerCounter = 1
-
-            if ("comment" in record):
-                dbObject.comment = record['comment']
-            else:
-                dbObject.comment = None
-
-            if ("raw_path" in record):
-                dbObject.rawPath = record['raw_path']
-            else:
-                dbObject.rawPath = None
-
-            if ("raw" in record):
-                dbObject.raw = record['raw']
-            else:
-                dbObject.raw = None
-
-            if ("phg" in record):
-                dbObject.phg = record['phg']
-            else:
-                dbObject.phg = None
-
-            if ("rng" in record):
-                dbObject.rng = record['rng']
-            else:
-                dbObject.rng = None
-
-            if ("latest_phg_timestamp" in record):
-                dbObject.latestPhgTimestamp = record['latest_phg_timestamp']
-            else:
-                dbObject.latestPhgTimestamp = None
-
-            if ("latest_rng_timestamp" in record):
-                dbObject.latestRngTimestamp = record['latest_rng_timestamp']
-            else:
-                dbObject.latestRngTimestamp = None
-        return dbObject
-
-    def create(self):
-        """Creates an empty Packet
-
-        Returns:
-            Packet
-        """
-        return Packet(self.db)
diff --git a/server/trackdirect/repositories/PacketTelemetryRepository.py b/server/trackdirect/repositories/PacketTelemetryRepository.py
deleted file mode 100644
index c816f6a87d86ca1bad6097359a66b95720429616..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/PacketTelemetryRepository.py
+++ /dev/null
@@ -1,127 +0,0 @@
-import time
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.PacketTelemetry import PacketTelemetry
-from trackdirect.database.PacketTelemetryTableCreator import PacketTelemetryTableCreator
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketTelemetryRepository(Repository):
-    """A Repository class for the PacketTelemetry class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):    Database connection
-        """
-        self.db = db
-        self.packetTelemetryTableCreator = PacketTelemetryTableCreator(self.db)
-        self.packetTelemetryTableCreator.disableCreateIfMissing()
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            PacketTelemetry
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from packet_telemetry where id = %s""", (id,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectByPacketIdAndTimestamp(self, id, timestamp):
-        """Returns an object based on the specified packet id in database
-
-        Args:
-            id (int):         Database row id
-            timestamp (int):  Unix timestamp for requested packet
-
-        Returns:
-            PacketTelemetry
-        """
-        try:
-            table = self.packetTelemetryTableCreator.getPacketTelemetryTable(
-                timestamp)
-            selectCursor = self.db.cursor()
-            selectCursor.execute("""select * from """ +
-                                 table + """ where packet_id = %s""", (id,))
-            record = selectCursor.fetchone()
-            selectCursor.close()
-            return self.getObjectFromRecord(record)
-        except TrackDirectMissingTableError as e:
-            return self.create()
-
-    def getObjectFromRecord(self, record):
-        """Returns a packet telemetry object from a record
-
-        Args:
-            record (dict):  Database record dict to convert to a packet telemetry object
-
-        Returns:
-            A packet telemetry object
-        """
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.packetId = int(record["packet_id"])
-            dbObject.stationId = int(record["station_id"])
-            dbObject.timestamp = int(record["timestamp"])
-            dbObject.val1 = int(record["val1"])
-            dbObject.val2 = int(record["val2"])
-            dbObject.val3 = int(record["val3"])
-            dbObject.val4 = int(record["val4"])
-            dbObject.val5 = int(record["val5"])
-            dbObject.bits = int(record["bits"])
-            dbObject.seq = int(record["seq"])
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            PacketTelemetry
-        """
-        newObject = self.create()
-        if ("telemetry" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.timestamp = int(time.time()) - 1
-
-            if ("vals" in data["telemetry"]):
-                newObject.val1 = data["telemetry"]["vals"][0]
-                newObject.val2 = data["telemetry"]["vals"][1]
-                newObject.val3 = data["telemetry"]["vals"][2]
-                newObject.val4 = data["telemetry"]["vals"][3]
-                newObject.val5 = data["telemetry"]["vals"][4]
-
-            if ("bits" in data["telemetry"]):
-                newObject.bits = data["telemetry"]["bits"]
-
-            if ("seq" in data["telemetry"]):
-                if isinstance(data["telemetry"]["seq"], str):
-                    try:
-                        newObject.seq = int(data["telemetry"]["seq"], 10)
-                    except ValueError:
-                        newObject.seq = None
-                elif isinstance(data["telemetry"]["seq"], int):
-                    newObject.seq = data["telemetry"]["seq"]
-        return newObject
-
-    def create(self):
-        """Creates an empty PacketTelemetry object
-
-        Returns:
-            PacketTelemetry
-        """
-        return PacketTelemetry(self.db)
diff --git a/server/trackdirect/repositories/PacketWeatherRepository.py b/server/trackdirect/repositories/PacketWeatherRepository.py
deleted file mode 100644
index df2f5058f6d5ff5467d1684227d566bc7013820f..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/PacketWeatherRepository.py
+++ /dev/null
@@ -1,139 +0,0 @@
-import datetime
-import time
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.PacketWeather import PacketWeather
-from trackdirect.database.PacketWeatherTableCreator import PacketWeatherTableCreator
-from trackdirect.exceptions.TrackDirectMissingTableError import TrackDirectMissingTableError
-
-
-class PacketWeatherRepository(Repository):
-    """A Repository class for the PacketWeather class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection):   Database connection
-        """
-        self.db = db
-        self.packetWeatherTableCreator = PacketWeatherTableCreator(self.db)
-        self.packetWeatherTableCreator.disableCreateIfMissing()
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            PacketWeather
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from packet_weather where id = %s""", (id,))
-        record = selectCursor.fetchone()
-        selectCursor.close()
-        return self.getObjectFromRecord(record)
-
-    def getObjectByPacketIdAndTimestamp(self, id, timestamp):
-        """Returns an object based on the specified packet id in database
-
-        Args:
-            id (int):         Database row id
-            timestamp (int):  Unix timestamp for requested packet (must be samt date as packet was received)
-
-        Returns:
-            PacketWeather
-        """
-        try:
-            table = self.packetWeatherTableCreator.getPacketWeatherTable(
-                timestamp)
-            selectCursor = self.db.cursor()
-            selectCursor.execute("""select * from """ +
-                                 table + """ where packet_id = %s""", (id,))
-            record = selectCursor.fetchone()
-            selectCursor.close()
-            return self.getObjectFromRecord(record)
-        except TrackDirectMissingTableError as e:
-            return self.create()
-
-    def getObjectFromRecord(self, record):
-        """Returns a packet weather object from a record
-
-        Args:
-            record (dict):  Database record dict to convert to a packet weather object
-
-        Returns:
-            A packet weather object
-        """
-        dbObject = PacketWeather(self.db)
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.packetId = int(record["packet_id"])
-            dbObject.stationId = int(record["station_id"])
-            dbObject.timestamp = int(record["timestamp"])
-            dbObject.humidity = record["humidity"]
-            dbObject.pressure = record["pressure"]
-            dbObject.rain1h = record["rain_1h"]
-            dbObject.rain24h = record["rain_24h"]
-            dbObject.rainSinceMidnight = record["rain_since_midnight"]
-            dbObject.temperature = record["temperature"]
-            dbObject.windDirection = record["wind_direction"]
-            dbObject.windGust = record["wind_gust"]
-            dbObject.windSpeed = record["wind_speed"]
-            dbObject.luminosity = record["luminosity"]
-            dbObject.snow = record["snow"]
-            dbObject.wxRawTimestamp = record["wx_raw_timestamp"]
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            PacketWeather
-        """
-        newObject = self.create()
-        if ("weather" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.timestamp = int(time.time()) - 1
-
-            if ("humidity" in data["weather"]):
-                newObject.humidity = data["weather"]["humidity"]
-            if ("pressure" in data["weather"]):
-                newObject.pressure = data["weather"]["pressure"]
-            if ("rain_1h" in data["weather"]):
-                newObject.rain1h = data["weather"]["rain_1h"]
-            if ("rain_24h" in data["weather"]):
-                newObject.rain24h = data["weather"]["rain_24h"]
-            if ("rain_since_midnight" in data["weather"]):
-                newObject.rainSinceMidnight = data["weather"]["rain_since_midnight"]
-            if ("temperature" in data["weather"]):
-                newObject.temperature = data["weather"]["temperature"]
-            if ("wind_direction" in data["weather"]):
-                newObject.windDirection = data["weather"]["wind_direction"]
-            if ("wind_gust" in data["weather"]):
-                newObject.windGust = data["weather"]["wind_gust"]
-            if ("wind_speed" in data["weather"]):
-                newObject.windSpeed = data["weather"]["wind_speed"]
-            if ("luminosity" in data["weather"]):
-                newObject.luminosity = data["weather"]["luminosity"]
-            if ("snow" in data["weather"]):
-                newObject.snow = data["weather"]["snow"]
-            if ("wx_raw_timestamp" in data["weather"]):
-                newObject.wxRawTimestamp = data["weather"]["wx_raw_timestamp"]
-        return newObject
-
-    def create(self):
-        """Creates an empty PacketWeather object
-
-        Returns:
-            PacketWeather
-        """
-        return PacketWeather(self.db)
diff --git a/server/trackdirect/repositories/SenderRepository.py b/server/trackdirect/repositories/SenderRepository.py
deleted file mode 100644
index 44edc83e03020d7f16f44155288a09529d76fad9..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/SenderRepository.py
+++ /dev/null
@@ -1,167 +0,0 @@
-import logging
-import collections
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.Sender import Sender
-from trackdirect.objects.Station import Station
-from trackdirect.exceptions.TrackDirectMissingSenderError import TrackDirectMissingSenderError
-
-
-class SenderRepository(Repository):
-    """A Repository class for the Sender class
-    """
-
-    # static class variables
-    senderIdCache = {}
-    senderNameCache = {}
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.logger = logging.getLogger('trackdirect')
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            Sender instance
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from sender where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = Sender(self.db)
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.name = record["name"]
-        else:
-            # sender do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectByName(self, name, createNewIfMissing=True, sourceId=None):
-        """Returns an object based on the specified name
-
-        Args:
-            name (str):                     Name of the requested sender
-            createNewIfMissing (boolean):   Set to true if sender should be created if it can not be found
-
-        Returns:
-            Sender instance
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from sender where name = %s""", (name.strip(),))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.name = record["name"]
-        elif (createNewIfMissing):
-            # sender do not exists, create it
-            dbObject.name = name
-            dbObject.save()
-
-            # Also create a related station
-            stationObject = Station(self.db)
-            stationObject.name = name
-            stationObject.sourceId = sourceId
-            stationObject.save()
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectByStationId(self, stationId):
-        """Returns an object based on the specified station id
-
-        Args:
-            stationId (int):     Id of the station
-
-        Returns:
-            Sender instance
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from sender where id in (select latest_sender_id from station where id = %s)""", (stationId,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.name = record["name"]
-
-        selectCursor.close()
-        return dbObject
-
-    def getCachedObjectById(self, senderId):
-        """Get Sender based on sender id
-
-        Args:
-            senderId (int):     Id of the sender
-
-        Returns:
-            Sender
-        """
-        if (senderId not in SenderRepository.senderIdCache):
-            sender = self.getObjectById(senderId)
-            if (sender.isExistingObject()):
-                maxNumberOfSenders = 100
-                if (len(SenderRepository.senderIdCache) > maxNumberOfSenders):
-                    # reset cache
-                    SenderRepository.senderIdCache = {}
-                SenderRepository.senderIdCache[senderId] = sender
-                return sender
-        else:
-            try:
-                return SenderRepository.senderIdCache[senderId]
-            except KeyError as e:
-                sender = self.getObjectById(senderId)
-                if (sender.isExistingObject()):
-                    return sender
-        raise TrackDirectMissingSenderError(
-            'No sender with specified id found')
-
-    def getCachedObjectByName(self, senderName):
-        """Get Sender based on sender name
-
-        Args:
-            senderName (string):  Sender name
-
-        Returns:
-            Sender
-        """
-        if (senderName not in SenderRepository.senderNameCache):
-            sender = self.getObjectByName(senderName, False)
-            if (sender.isExistingObject()):
-                maxNumberOfSenders = 100
-                if (len(SenderRepository.senderNameCache) > maxNumberOfSenders):
-                    # reset cache
-                    SenderRepository.senderNameCache = {}
-                SenderRepository.senderNameCache[senderName] = sender
-                return sender
-        else:
-            try:
-                return SenderRepository.senderNameCache[senderName]
-            except KeyError as e:
-                sender = self.getObjectByName(senderName, False)
-                if (sender.isExistingObject()):
-                    return sender
-        raise TrackDirectMissingSenderError(
-            'No sender with specified sender name found')
-
-    def create(self):
-        """Creates an empty Sender object
-
-        Returns:
-            Sender instance
-        """
-        return Sender(self.db)
diff --git a/server/trackdirect/repositories/StationRepository.py b/server/trackdirect/repositories/StationRepository.py
deleted file mode 100644
index 24adde4840be456067ad9ad031ff9910cc2ed623..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/StationRepository.py
+++ /dev/null
@@ -1,375 +0,0 @@
-import collections
-import datetime
-import time
-import calendar
-from math import sin, cos, sqrt, atan2, radians, floor, ceil
-
-import logging
-from twisted.python import log
-
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.Station import Station
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.database.PacketTableCreator import PacketTableCreator
-from trackdirect.exceptions.TrackDirectMissingStationError import TrackDirectMissingStationError
-
-
-class StationRepository(Repository):
-    """A Repository class for the Station class
-    """
-
-    # static class variables
-    stationIdCache = {}
-    stationNameCache = {}
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.logger = logging.getLogger('trackdirect')
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.packetTableCreator = PacketTableCreator(db)
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            Station
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from station where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-        else:
-            # station do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectListByStationIdList(self, stationIdList):
-        """Returns a list of station objects
-
-        Args:
-            stationIdList (int):           Array of station ids
-
-        Returns:
-            array
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from station where id in %s""", (tuple(stationIdList), ))
-
-        result = []
-        for record in selectCursor:
-            if (record is not None):
-                dbObject = self.getObjectFromRecord(record)
-                result.append(dbObject)
-
-        selectCursor.close()
-        return result
-
-    def getTinyObjectList(self):
-        """Returns a list of all station id's
-
-        Args:
-            None
-
-        Returns:
-            array
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select id, latest_packet_timestamp from station order by id""")
-
-        result = []
-        for record in selectCursor:
-            if (record is not None):
-                dbObject = self.create()
-                dbObject.id = int(record["id"])
-                dbObject.latestPacketTimestamp = record["latest_packet_timestamp"]
-                result.append(dbObject)
-        selectCursor.close()
-        return result
-
-    def getObjectList(self):
-        """Returns a list of all station object's
-
-        Args:
-            None
-
-        Returns:
-            array
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute("""select * from station order by id""")
-
-        result = []
-        for record in selectCursor:
-            dbObject = self.getObjectFromRecord(record)
-            result.append(dbObject)
-        selectCursor.close()
-        return result
-
-    def getObjectListByName(self, name, stationTypeId=None, sourceId=None, minTimestamp=None):
-        """Returns a list of stations based on the specified name
-
-        Args:
-            name (string):             Name of station
-            stationTypeId (int):       Station type id
-            sourceId (int):            Station source id
-
-        Returns:
-            array
-        """
-        if (sourceId is not None and sourceId == 3):
-            # If source is "APRS DUPLICATE" we use "APRS"
-            sourceId = 1
-
-        if (minTimestamp is None):
-            minTimestamp = 0
-
-        selectCursor = self.db.cursor()
-        if (sourceId is not None and sourceId is not None):
-            selectCursor.execute("""select *
-                from station
-                where station_type_id = %s
-                    and name = %s
-                    and (source_id = %s or source_id is null)
-                    and latest_confirmed_packet_timestamp > %s""", (stationTypeId, name, sourceId, minTimestamp,))
-        elif (sourceId is not None):
-            selectCursor.execute("""select *
-                from station
-                where station_type_id = %s
-                    and name = %s
-                    and latest_confirmed_packet_timestamp > %s""", (stationTypeId, name, minTimestamp,))
-        else:
-            selectCursor.execute("""select *
-                from station
-                where name = %s
-                    and latest_confirmed_packet_timestamp > %s""", (name, minTimestamp,))
-
-        result = []
-        for record in selectCursor:
-            dbObject = self.getObjectFromRecord(record)
-            result.append(dbObject)
-        selectCursor.close()
-        return result
-
-    def getObjectByName(self, name, sourceId, stationTypeId=1, createNewIfMissing=True):
-        """Returns an object based on the specified name of the station
-
-        Args:
-            name (str):                    Name of the station
-            sourceId (int):                Station source id
-            createNewIfMissing (boolean):  Set to true if a new station should be created if no one is found
-
-        Returns:
-            Station
-        """
-        if (sourceId == 3):
-            # If source is "APRS DUPLICATE" we use "APRS"
-            sourceId = 1
-
-        selectCursor = self.db.cursor()
-        if (sourceId is not None):
-            selectCursor.execute(
-                """select * from station where name = %s and (source_id is null or source_id = %s) order by id desc""", (name.strip(), sourceId))
-        else:
-            selectCursor.execute(
-                """select * from station where name = %s order by id desc""", (name.strip()))
-        record = selectCursor.fetchone()
-
-        # Make sure we at least have an empty object...
-        dbObject = self.create()
-        if (record is not None):
-            dbObject = self.getObjectFromRecord(record)
-            if (dbObject.sourceId is None and dbObject.sourceId != sourceId):
-                dbObject.sourceId = sourceId
-                dbObject.save()
-            if (dbObject.stationTypeId != stationTypeId and stationTypeId == 1):
-                dbObject.stationTypeId = stationTypeId
-                dbObject.save()
-
-        elif (createNewIfMissing):
-            # station do not exists, create it
-            dbObject.name = name
-            dbObject.sourceId = sourceId
-            dbObject.stationTypeId = stationTypeId
-            dbObject.save()
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectListBySearchParameter(self, searchParameter, minTimestamp, limit):
-        """Returns an array of the latest packet objects specified by searchParameter
-
-        Args:
-            searchParameter (str):  String to use when searching for packets (will be compared to station name)
-            minTimestamp (int):     Min unix timestamp
-            limit (int):            Max number of hits
-
-        Returns:
-            Array
-        """
-        searchParameter = searchParameter.strip().replace('%', '\%').replace('*', '%')
-        selectCursor = self.db.cursor()
-        result = []
-
-        # Search for ogn registration
-        if (self.dbObjectFinder.checkTableExists('ogn_device')):
-            selectCursor.execute("""select * from ogn_device limit 1""")
-            record = selectCursor.fetchone()
-            if (record is not None):
-                selectCursor.execute("""select * from station where latest_confirmed_packet_timestamp is not null and latest_confirmed_packet_timestamp > %s and latest_ogn_sender_address is not null and exists (select 1 from ogn_device where registration ilike %s and device_id = station.latest_ogn_sender_address) limit %s""", (minTimestamp, searchParameter, (limit - len(result)), ))
-                for record in selectCursor:
-                    dbObject = self.getObjectFromRecord(record)
-                    result.append(dbObject)
-
-            # Search for ogn sender address
-            if (len(result) < limit):
-                selectCursor.execute("""select * from station where latest_confirmed_packet_timestamp is not null and latest_confirmed_packet_timestamp > %s and latest_ogn_sender_address ilike %s limit %s""",
-                                     (minTimestamp, searchParameter, (limit - len(result)), ))
-                for record in selectCursor:
-                    dbObject = self.getObjectFromRecord(record)
-                    result.append(dbObject)
-
-        # Search for station name
-        if (len(result) < limit):
-            selectCursor.execute("""select * from station where latest_confirmed_packet_timestamp is not null and latest_confirmed_packet_timestamp > %s and name ilike %s limit %s""",
-                                 (minTimestamp, searchParameter, (limit - len(result)), ))
-            for record in selectCursor:
-                dbObject = self.getObjectFromRecord(record)
-                result.append(dbObject)
-
-        return result
-
-    def getCachedObjectById(self, stationId):
-        """Get Station based on station id
-
-        Args:
-            stationId (int):     Id of the station
-
-        Returns:
-            Station
-        """
-        if (stationId not in StationRepository.stationIdCache):
-            station = self.getObjectById(stationId)
-            if (station.isExistingObject()):
-                maxNumberOfStations = 100
-                if (len(StationRepository.stationIdCache) > maxNumberOfStations):
-                    # reset cache
-                    StationRepository.stationIdCache = {}
-                StationRepository.stationIdCache[stationId] = station
-                return station
-        else:
-            try:
-                return StationRepository.stationIdCache[stationId]
-            except KeyError as e:
-                station = self.getObjectById(stationId)
-                if (station.isExistingObject()):
-                    return station
-        raise TrackDirectMissingStationError(
-            'No station with specified id found')
-
-    def getCachedObjectByName(self, stationName, sourceId):
-        """Get Station based on station name
-
-        Args:
-            stationName (string): Station name
-            sourceId (int):       Station source id
-
-        Returns:
-            Station
-        """
-        if (sourceId == 3):
-            # If source is "APRS DUPLICATE" we use "APRS"
-            sourceId = 1
-
-        if (sourceId is not None):
-            key = hash(stationName + ';' + str(sourceId))
-        else:
-            key = hash(stationName)
-        if (key not in StationRepository.stationNameCache):
-            station = self.getObjectByName(stationName, sourceId, None, False)
-            if (station.isExistingObject()):
-                maxNumberOfStations = 100
-                if (len(StationRepository.stationNameCache) > maxNumberOfStations):
-                    # reset cache
-                    StationRepository.stationNameCache = {}
-                StationRepository.stationNameCache[key] = station
-                return station
-        else:
-            try:
-                return StationRepository.stationNameCache[key]
-            except KeyError as e:
-                station = self.getObjectByName(
-                    stationName, sourceId, None, False)
-                if (station.isExistingObject()):
-                    return station
-        raise TrackDirectMissingStationError(
-            'No station with specified station name found')
-
-    def getObjectFromRecord(self, record):
-        """Returns a station object based on the specified database record dict
-
-        Args:
-            record (dict):  A database record dict from the station database table
-
-        Returns:
-            Station
-        """
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = int(record["id"])
-            dbObject.name = record["name"]
-            if (record["latest_sender_id"] is not None):
-                dbObject.latestSenderId = int(record["latest_sender_id"])
-            dbObject.stationTypeId = int(record["station_type_id"])
-            if (record["source_id"] is not None):
-                dbObject.sourceId = int(record["source_id"])
-
-            dbObject.latestLocationPacketId = record["latest_location_packet_id"]
-            dbObject.latestLocationPacketTimestamp = record["latest_location_packet_timestamp"]
-
-            dbObject.latestConfirmedPacketId = record["latest_confirmed_packet_id"]
-            dbObject.latestConfirmedPacketTimestamp = record["latest_confirmed_packet_timestamp"]
-            dbObject.latestConfirmedSymbol = record["latest_confirmed_symbol"]
-            dbObject.latestConfirmedSymbolTable = record["latest_confirmed_symbol_table"]
-            dbObject.latestConfirmedLatitude = record["latest_confirmed_latitude"]
-            dbObject.latestConfirmedLongitude = record["latest_confirmed_longitude"]
-            dbObject.latestConfirmedMarkerId = record["latest_confirmed_marker_id"]
-
-            dbObject.latestPacketId = record["latest_packet_id"]
-            dbObject.latestPacketTimestamp = record["latest_packet_timestamp"]
-
-            dbObject.latestWeatherPacketId = record["latest_weather_packet_id"]
-            dbObject.latestWeatherPacketTimestamp = record["latest_weather_packet_timestamp"]
-
-            dbObject.latestTelemetryPacketId = record["latest_telemetry_packet_id"]
-            dbObject.latestTelemetryPacketTimestamp = record["latest_telemetry_packet_timestamp"]
-
-            dbObject.latestOgnPacketId = record["latest_ogn_packet_id"]
-            dbObject.latestOgnPacketTimestamp = record["latest_ogn_packet_timestamp"]
-            dbObject.latestOgnSenderAddress = record["latest_ogn_sender_address"]
-            dbObject.latestOgnAircraftTypeId = record["latest_ogn_aircraft_type_id"]
-            dbObject.latestOgnAddressTypeId = record["latest_ogn_address_type_id"]
-
-        return dbObject
-
-    def create(self):
-        """Creates an empty Station object
-
-        Returns:
-            Station
-        """
-        return Station(self.db)
diff --git a/server/trackdirect/repositories/StationTelemetryBitsRepository.py b/server/trackdirect/repositories/StationTelemetryBitsRepository.py
deleted file mode 100644
index 50dd87ec7f491935d1bc638a2e6e39932b603ea2..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/StationTelemetryBitsRepository.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import datetime
-import time
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.StationTelemetryBits import StationTelemetryBits
-
-
-class StationTelemetryBitsRepository(Repository):
-    """A Repository class for the StationTelemetryBits class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            StationTelemetryBits
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from station_telemetry_bits where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.stationId = record["station_id"]
-            dbObject.createdTs = record["created_ts"]
-            dbObject.latestTs = record["latest_ts"]
-            dbObject.validToTs = record["valid_to_ts"]
-            dbObject.bits = record["bits"]
-            dbObject.title = record["title"]
-        else:
-            # do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            StationTelemetryBits
-        """
-        newObject = self.create()
-        if ("tBITS" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.createdTs = int(time.time()) - 1
-            newObject.bits = data["tBITS"].replace('\x00', '')
-            newObject.title = data["title"].replace('\x00', '')
-        return newObject
-
-    def create(self):
-        """Creates an empty StationTelemetryBits object
-
-        Returns:
-            StationTelemetryBits
-        """
-        return StationTelemetryBits(self.db)
diff --git a/server/trackdirect/repositories/StationTelemetryEqnsRepository.py b/server/trackdirect/repositories/StationTelemetryEqnsRepository.py
deleted file mode 100644
index 40df56f53234b865ae70b00f8f213834bcedc8bc..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/StationTelemetryEqnsRepository.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import datetime
-import time
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.StationTelemetryEqns import StationTelemetryEqns
-
-
-class StationTelemetryEqnsRepository(Repository):
-    """A Repository class for the StationTelemetryEqns class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            StationTelemetryEqns
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from station_telemetry_eqns where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.stationId = record["station_id"]
-            dbObject.createdTs = record["created_ts"]
-            dbObject.latestTs = record["latest_ts"]
-            dbObject.validToTs = record["valid_to_ts"]
-            dbObject.a1 = record["a1"]
-            dbObject.b1 = record["b1"]
-            dbObject.c1 = record["c1"]
-            dbObject.a2 = record["a2"]
-            dbObject.b2 = record["b2"]
-            dbObject.c2 = record["c2"]
-            dbObject.a3 = record["a3"]
-            dbObject.b3 = record["b3"]
-            dbObject.c3 = record["c3"]
-            dbObject.a4 = record["a4"]
-            dbObject.b4 = record["b4"]
-            dbObject.c4 = record["c4"]
-            dbObject.a5 = record["a5"]
-            dbObject.b5 = record["b5"]
-            dbObject.c5 = record["c5"]
-        else:
-            # do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            StationTelemetryEqns
-        """
-        newObject = self.create()
-        if ("tEQNS" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.createdTs = int(time.time()) - 1
-
-            newObject.a1 = data["tEQNS"][0][0]
-            newObject.b1 = data["tEQNS"][0][1]
-            newObject.c1 = data["tEQNS"][0][2]
-
-            newObject.a2 = data["tEQNS"][1][0]
-            newObject.b2 = data["tEQNS"][1][1]
-            newObject.c2 = data["tEQNS"][1][2]
-
-            newObject.a3 = data["tEQNS"][2][0]
-            newObject.b3 = data["tEQNS"][2][1]
-            newObject.c3 = data["tEQNS"][2][2]
-
-            newObject.a4 = data["tEQNS"][3][0]
-            newObject.b4 = data["tEQNS"][3][1]
-            newObject.c4 = data["tEQNS"][3][2]
-
-            newObject.a5 = data["tEQNS"][4][0]
-            newObject.b5 = data["tEQNS"][4][1]
-            newObject.c5 = data["tEQNS"][4][2]
-        return newObject
-
-    def create(self):
-        """Creates an empty StationTelemetryEqns object
-
-        Returns:
-            StationTelemetryEqns
-        """
-        return StationTelemetryEqns(self.db)
diff --git a/server/trackdirect/repositories/StationTelemetryParamRepository.py b/server/trackdirect/repositories/StationTelemetryParamRepository.py
deleted file mode 100644
index 39679954b6ff1b2ef6aac9c5d18e9e71f4ea13c9..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/StationTelemetryParamRepository.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import datetime
-import time
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.StationTelemetryParam import StationTelemetryParam
-
-
-class StationTelemetryParamRepository(Repository):
-    """A Repository class for the StationTelemetryParam class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            StationTelemetryParam
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from station_telemetry_param where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.stationId = record["station_id"]
-            dbObject.createdTs = record["created_ts"]
-            dbObject.latestTs = record["latest_ts"]
-            dbObject.validToTs = record["valid_to_ts"]
-            dbObject.p1 = record["p1"]
-            dbObject.p2 = record["p2"]
-            dbObject.p3 = record["p3"]
-            dbObject.p4 = record["p4"]
-            dbObject.p5 = record["p5"]
-            dbObject.b1 = record["b1"]
-            dbObject.b2 = record["b2"]
-            dbObject.b3 = record["b3"]
-            dbObject.b4 = record["b4"]
-            dbObject.b5 = record["b5"]
-            dbObject.b6 = record["b6"]
-            dbObject.b7 = record["b7"]
-            dbObject.b8 = record["b8"]
-        else:
-            # do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            StationTelemetryParam
-        """
-        newObject = self.create()
-        if ("tPARM" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.createdTs = int(time.time()) - 1
-            newObject.p1 = data["tPARM"][0].replace('\x00', '')
-            newObject.p2 = data["tPARM"][1].replace('\x00', '')
-            newObject.p3 = data["tPARM"][2].replace('\x00', '')
-            newObject.p4 = data["tPARM"][3].replace('\x00', '')
-            newObject.p5 = data["tPARM"][4].replace('\x00', '')
-            newObject.b1 = data["tPARM"][5].replace('\x00', '')
-            newObject.b2 = data["tPARM"][6].replace('\x00', '')
-            newObject.b3 = data["tPARM"][7].replace('\x00', '')
-            newObject.b4 = data["tPARM"][8].replace('\x00', '')
-            newObject.b5 = data["tPARM"][9].replace('\x00', '')
-            newObject.b6 = data["tPARM"][10].replace('\x00', '')
-            newObject.b7 = data["tPARM"][11].replace('\x00', '')
-            newObject.b8 = data["tPARM"][12].replace('\x00', '')
-        return newObject
-
-    def create(self):
-        """Creates an empty StationTelemetryParam object
-
-        Returns:
-            StationTelemetryParam
-        """
-        return StationTelemetryParam(self.db)
diff --git a/server/trackdirect/repositories/StationTelemetryUnitRepository.py b/server/trackdirect/repositories/StationTelemetryUnitRepository.py
deleted file mode 100644
index 5ae6a4c8bb57f2f5a3decb83c49d5568921383a2..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/StationTelemetryUnitRepository.py
+++ /dev/null
@@ -1,99 +0,0 @@
-import datetime
-import time
-from trackdirect.common.Repository import Repository
-from trackdirect.objects.StationTelemetryUnit import StationTelemetryUnit
-
-
-class StationTelemetryUnitRepository(Repository):
-    """A Repository class for the StationTelemetryUnit class
-    """
-
-    def __init__(self, db):
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-
-    def getObjectById(self, id):
-        """The getObjectById method is supposed to return an object based on the specified id in database
-
-        Args:
-            id (int):  Database row id
-
-        Returns:
-            StationTelemetryUnit
-        """
-        selectCursor = self.db.cursor()
-        selectCursor.execute(
-            """select * from station_telemetry_unit where id = %s""", (id,))
-        record = selectCursor.fetchone()
-
-        dbObject = self.create()
-        if (record is not None):
-            dbObject.id = record["id"]
-            dbObject.stationId = record["station_id"]
-            dbObject.createdTs = record["created_ts"]
-            dbObject.latestTs = record["latest_ts"]
-            dbObject.validToTs = record["valid_to_ts"]
-            dbObject.u1 = record["u1"]
-            dbObject.u2 = record["u2"]
-            dbObject.u3 = record["u3"]
-            dbObject.u4 = record["u4"]
-            dbObject.u5 = record["u5"]
-            dbObject.l1 = record["l1"]
-            dbObject.l2 = record["l2"]
-            dbObject.l3 = record["l3"]
-            dbObject.l4 = record["l4"]
-            dbObject.l5 = record["l5"]
-            dbObject.l6 = record["l6"]
-            dbObject.l7 = record["l7"]
-            dbObject.l8 = record["l8"]
-        else:
-            # do not exists, return empty object
-            pass
-
-        selectCursor.close()
-        return dbObject
-
-    def getObjectFromPacketData(self, data):
-        """Create object from raw packet data
-
-        Note:
-            stationId will not be set
-
-        Args:
-            data (dict):  Raw packet data
-
-        Returns:
-            StationTelemetryUnit
-        """
-        newObject = self.create()
-        if ("tUNIT" in data):
-            # Remove one second since that will give us a more accurate timestamp
-            newObject.createdTs = int(time.time()) - 1
-
-            newObject.u1 = data["tUNIT"][0].replace('\x00', '')
-            newObject.u2 = data["tUNIT"][1].replace('\x00', '')
-            newObject.u3 = data["tUNIT"][2].replace('\x00', '')
-            newObject.u4 = data["tUNIT"][3].replace('\x00', '')
-            newObject.u5 = data["tUNIT"][4].replace('\x00', '')
-            newObject.l1 = data["tUNIT"][5].replace('\x00', '')
-            newObject.l2 = data["tUNIT"][6].replace('\x00', '')
-            newObject.l3 = data["tUNIT"][7].replace('\x00', '')
-            newObject.l4 = data["tUNIT"][8].replace('\x00', '')
-            newObject.l5 = data["tUNIT"][9].replace('\x00', '')
-            newObject.l6 = data["tUNIT"][10].replace('\x00', '')
-            newObject.l7 = data["tUNIT"][11].replace('\x00', '')
-            newObject.l8 = data["tUNIT"][12].replace('\x00', '')
-
-        return newObject
-
-    def create(self):
-        """Creates an empty StationTelemetryUnit object
-
-        Returns:
-            StationTelemetryUnit
-        """
-        return StationTelemetryUnit(self.db)
diff --git a/server/trackdirect/repositories/__init__.py b/server/trackdirect/repositories/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/repositories/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/websocket/WebsocketConnectionState.py b/server/trackdirect/websocket/WebsocketConnectionState.py
deleted file mode 100644
index 2b7837208b0336d405b2b5ba1c26a77d0055a484..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/WebsocketConnectionState.py
+++ /dev/null
@@ -1,369 +0,0 @@
-import time
-import trackdirect
-from math import ceil
-from trackdirect.parser.policies.MapSectorPolicy import MapSectorPolicy
-
-class WebsocketConnectionState():
-    """An WebsocketConnectionState instance contains information about the current state of a websocket connection
-    """
-
-    def __init__(self) :
-        """The __init__ method.
-        """
-        self.totalReset()
-        self.latestRequestType = None
-        self.latestRequestTimestamp = 0
-        self.latestRequestId = 0
-        self.latestHandledRequestId = 0
-        self.config = trackdirect.TrackDirectConfig()
-        self.noRealTime = False
-        self.disconnected = False
-
-
-    def isReset(self) :
-        """Returns true if state just has been reset
-
-        Returns:
-            Boolean
-        """
-        return (not self.stationsOnMapDict
-            and not self.maxCompleteStationTimestampDict
-            and not self.maxAllStationTimestampDict
-            and not self.maxMapSectorPacketTimestampDict
-            and not self.maxMapSectorOverwritePacketTimestampDict)
-
-
-    def reset(self) :
-        """This function will reset information related to what stations that has been added to map
-        (this is for example used when the number of minutes is changed by the client)
-        """
-        self.stationsOnMapDict = {}
-        self.maxCompleteStationTimestampDict = {}
-        self.maxAllStationTimestampDict = {}
-        self.maxMapSectorPacketTimestampDict = {}
-        self.maxMapSectorOverwritePacketTimestampDict = {}
-
-
-    def totalReset(self) :
-        """This function will reset everything
-        (this is for example used when client seems to be inactive and we just want to stop everything)
-        """
-        self.reset()
-        self.latestMinutesRequest = 60
-        self.latestTimeTravelRequest = None
-        self.onlyLatestPacketRequested = None
-        self.latestNeLat = 0
-        self.latestNeLng = 0
-        self.latestSwLat = 0
-        self.latestSwLng = 0
-        self.filterStationIdDict = {}
-
-
-    def isMapEmpty(self) :
-        """Returns true if map is empty
-
-        Returns:
-            Boolean
-        """
-        if (not self.maxMapSectorPacketTimestampDict
-                and not self.maxMapSectorOverwritePacketTimestampDict
-                and not self.maxCompleteStationTimestampDict
-                and not self.maxAllStationTimestampDict) :
-            return True
-        else :
-            return False
-
-
-    def isStationsOnMap(self, stationIds) :
-        """Returns true if all specified stations allready exists on map
-
-        Args:
-            stationIds (int):    The station id's that we are interested in
-
-        Returns:
-            boolean
-        """
-        for stationId in stationIds :
-            if (stationId not in self.stationsOnMapDict) :
-                return False
-        return True
-
-
-    def isStationHistoryOnMap(self, stationId) :
-        """Returns true if specified station allready has it's history on map
-
-        Args:
-            stationId (int):    The station id that we are interested in
-
-        Returns:
-            boolean
-        """
-        if (stationId not in self.maxCompleteStationTimestampDict) :
-            return False
-        else :
-            return True
-
-
-    def getStationLatestTimestampOnMap(self, stationId, onlyIncludeComplete = True) :
-        """Returns the timestamp of the latest sent packet to client
-
-        Args:
-            stationId (int):             The station id that we are interested in
-            onlyIncludeComplete (bool):  When true we only return timestamp data for complete stations
-
-        Returns:
-            boolean
-        """
-        if (not onlyIncludeComplete and stationId in self.maxAllStationTimestampDict) :
-            return self.maxAllStationTimestampDict[stationId]
-        elif (stationId in self.maxCompleteStationTimestampDict) :
-            return self.maxCompleteStationTimestampDict[stationId]
-        else :
-            return None
-
-
-    def isValidLatestPosition(self) :
-        """Returns true if latest requested map bounds is valid
-
-        Note:
-            If we received 0,0,0,0 as map bounds we should not send anything,
-            not even in filtering mode (filtering mode should send 90,180,-90,-180 when it wants data)
-
-        Returns:
-            Boolean
-        """
-        if (self.latestNeLat == 0
-                and self.latestNeLng == 0
-                and self.latestSwLat == 0
-                and self.latestSwLng == 0) :
-            return False
-        else :
-            return True
-
-
-    def isMapSectorKnown(self, mapSector):
-        """Returns True if we have added any stations with complete history to this map sector
-
-        Args:
-            mapSector (int):  The map sector that we are interested in
-
-        Returns:
-            Boolean
-        """
-        if (mapSector in self.maxMapSectorPacketTimestampDict) :
-            return True
-        else :
-            return False
-
-
-    def getMapSectorTimestamp(self, mapSector) :
-        """Returns the latest handled timestamp in specified map sector (as a Unix timestamp as an integer)
-
-        Args:
-            mapSector (int):  The map sector that we are interested in
-
-        Returns:
-            int
-        """
-        if (mapSector in self.maxMapSectorPacketTimestampDict) :
-            return self.maxMapSectorPacketTimestampDict[mapSector];
-        elif (self.onlyLatestPacketRequested and mapSector in self.maxMapSectorOverwritePacketTimestampDict) :
-            return self.maxMapSectorOverwritePacketTimestampDict[mapSector]
-        elif (self.latestTimeTravelRequest is not None) :
-            return int(self.latestTimeTravelRequest) - (int(self.latestMinutesRequest)*60)
-        else :
-            return int(time.time()) - (int(self.latestMinutesRequest)*60)
-
-
-    def getVisibleMapSectors(self) :
-        """Get the map sectors currently visible
-
-        Returns:
-            Array of map sectors (array of integers)
-        """
-        maxLat = self.latestNeLat
-        maxLng = self.latestNeLng
-        minLat = self.latestSwLat
-        minLng = self.latestSwLng
-
-        result = []
-        if (maxLng < minLng) :
-            result.extend(self.getMapSectorsByInterval(minLat, maxLat, minLng, 180.0));
-            minLng = -180.0;
-
-        result.extend(self.getMapSectorsByInterval(minLat, maxLat, minLng, maxLng))
-
-        # Add the world wide area code
-        # This seems to result in very bad performance....
-        #result.append(99999999)
-
-        return result[::-1]
-
-
-    def getMapSectorsByInterval(self, minLat, maxLat, minLng, maxLng) :
-        """Get the map sectors for specified interval
-
-        Returns:
-            Array of map sectors (array of integers)
-        """
-        result = []
-        mapSectorPolicy = MapSectorPolicy()
-        minAreaCode = mapSectorPolicy.getMapSector(minLat,minLng)
-        maxAreaCode = mapSectorPolicy.getMapSector(maxLat,maxLng)
-        if (minAreaCode is not None and maxAreaCode is not None) :
-            lngDiff = int(ceil(maxLng)) - int(ceil(minLng))
-            areaCode = minAreaCode
-            while (areaCode <= maxAreaCode) :
-                if (areaCode % 10 == 5) :
-                    result.append(areaCode)
-                else :
-                    result.append(areaCode)
-                    result.append(areaCode + 5)
-
-                for i in range(1, lngDiff+1) :
-                    if (areaCode % 10 == 5) :
-                        result.append(areaCode + (10*i) - 5)
-                        result.append(areaCode + (10*i))
-                    else :
-                        result.append(areaCode + (10*i))
-                        result.append(areaCode + (10*i) + 5)
-
-                # Lat takes 0.2 jumps
-                areaCode = areaCode + 20000
-
-        return result
-
-
-    def setLatestMinutes(self, minutes, referenceTime) :
-        """Set the latest requested number of minutes, returnes true if something has changed
-
-        Args:
-            minutes (int):           latest requested number of minutes
-            referenceTime (int):     latest requested reference time
-
-        Returns:
-            Boolean
-        """
-        if (minutes is None) :
-            minutes = 60
-        elif (len(self.filterStationIdDict) == 0
-                and int(minutes) > int(self.config.maxDefaultTime)) :
-            # max 24h
-            minutes = int(self.config.maxDefaultTime)
-        elif (len(self.filterStationIdDict) > 0
-                and int(minutes) > int(self.config.maxFilterTime)) :
-            # max 10 days
-            minutes = int(self.config.maxFilterTime)
-
-        if (not self.config.allowTimeTravel
-                and int(minutes) > int(1440)) :
-            # max 24h
-            minutes = 1440
-
-        if referenceTime is not None and referenceTime < 0 :
-            referenceTime = 0
-
-        changed = False
-        if (self.config.allowTimeTravel) :
-            if ((self.latestTimeTravelRequest is not None
-                        and referenceTime is not None
-                        and self.latestTimeTravelRequest != referenceTime)
-                    or (self.latestTimeTravelRequest is not None
-                        and referenceTime is None)
-                    or (self.latestTimeTravelRequest is None
-                        and referenceTime is not None)) :
-                self.latestTimeTravelRequest = referenceTime
-                self.reset()
-                changed = True
-
-        if (self.latestMinutesRequest is None
-                or self.latestMinutesRequest != minutes) :
-            self.latestMinutesRequest = minutes
-            self.reset()
-            changed = True
-        return changed
-
-
-    def setOnlyLatestPacketRequested(self, onlyLatestPacketRequested) :
-        """Set if only latest packets is requested or not
-
-        Args:
-            onlyLatestPacketRequested (Boolean):  Boolean that sys if
-
-        """
-        self.onlyLatestPacketRequested = onlyLatestPacketRequested
-
-
-    def setLatestMapBounds(self, neLat, neLng, swLat, swLng) :
-        """Set map bounds requested by client
-
-        Args:
-            neLat (float): Requested north east latitude
-            neLng (float): Requested north east longitude
-            swLat (float): Requested south west latitude
-            swLng (float): Requested south west longitude
-        """
-        if (neLat is None or neLng is None or swLat is None or swLng is None) :
-            self.latestNeLat = 0
-            self.latestNeLng = 0
-            self.latestSwLat = 0
-            self.latestSwLng = 0
-        else :
-            self.latestNeLat = neLat
-            self.latestNeLng = neLng
-            self.latestSwLat = swLat
-            self.latestSwLng = swLng
-
-
-    def setMapSectorLatestOverwriteTimeStamp(self, mapSector, timestamp) :
-        """Set a new latest handled timestamp for a map sector (in this case the overwritable type of packets)
-
-        Args:
-            mapSector (int):  The map sector that we should add a new timestamp to
-            timestamp (int):  The unix timestamp that should be added
-        """
-        if (mapSector not in self.maxMapSectorOverwritePacketTimestampDict or self.maxMapSectorOverwritePacketTimestampDict[mapSector] < timestamp) :
-            self.maxMapSectorOverwritePacketTimestampDict[mapSector] = timestamp
-
-
-    def setMapSectorLatestTimeStamp(self, mapSector, timestamp) :
-        """Set a new latest handled timestamp for a map sector
-
-        Args:
-            mapSector (int):  The map sector that we should add a new timestamp to
-            timestamp (int):  The unix timestamp that should be added
-        """
-        if (mapSector not in self.maxMapSectorPacketTimestampDict or self.maxMapSectorPacketTimestampDict[mapSector] < timestamp) :
-            # To avoid that we miss packet that was recived later during the same second we mark map-sector to be complete for the previous second.
-            # This may result in that we sent the same apcket twice but client will handle that.
-            self.maxMapSectorPacketTimestampDict[mapSector] = timestamp - 1
-
-
-    def setCompleteStationLatestTimestamp(self, stationId, timestamp) :
-        """Set a new latest handled timestamp for a complete station (a station with all packets added to map)
-
-        Args:
-            stationId (int):  The station that we add want to add a new timestamp for
-            timestamp (int):  The unix timestamp that should be added
-        """
-        if (stationId not in self.maxCompleteStationTimestampDict or self.maxCompleteStationTimestampDict[stationId] < timestamp) :
-            # For stations we do not need to set the previous second since a station is rarly sending several packets the same second
-            self.maxCompleteStationTimestampDict[stationId] = timestamp
-
-
-    def setStationLatestTimestamp(self, stationId, timestamp) :
-        """Set a new latest handled timestamp for station
-
-        Args:
-            stationId (int):  The station that we add want to add a new timestamp for
-            timestamp (int):  The unix timestamp that should be added
-        """
-        if (stationId not in self.maxAllStationTimestampDict or self.maxAllStationTimestampDict[stationId] < timestamp) :
-            # For stations we do not need to set the previous second since a station is rarly sending several packets the same second
-            self.maxAllStationTimestampDict[stationId] = timestamp
-
-
-    def disableRealTime(self) :
-        """Disable real time functionality
-        """
-        self.noRealTime = True
\ No newline at end of file
diff --git a/server/trackdirect/websocket/WebsocketResponseCreator.py b/server/trackdirect/websocket/WebsocketResponseCreator.py
deleted file mode 100644
index a572edc809adfa7715632c000afee97c2313eff7..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/WebsocketResponseCreator.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import logging
-from twisted.python import log
-
-from math import floor, ceil
-import datetime, time
-
-import psycopg2, psycopg2.extras
-
-from trackdirect.websocket.responses.FilterResponseCreator import FilterResponseCreator
-from trackdirect.websocket.responses.HistoryResponseCreator import HistoryResponseCreator
-from trackdirect.websocket.responses.FilterHistoryResponseCreator import FilterHistoryResponseCreator
-
-class WebsocketResponseCreator():
-    """The WebsocketResponseCreator will make sure that we create a response for every valid received request
-    """
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):    WebsocketConnectionState instance that contains current state
-            db (psycopg2.Connection):            Database connection (with autocommit)
-        """
-        self.state = state
-
-        self.logger = logging.getLogger('trackdirect')
-
-        self.filterResponseCreator = FilterResponseCreator(state, db)
-        self.historyResponseCreator = HistoryResponseCreator(state, db)
-        self.filterHistoryResponseCreator = FilterHistoryResponseCreator(state, db)
-
-    def getResponses(self, request, requestId) :
-        """Process a received request
-
-        Args:
-            request (dict):    The request to process
-            requestId (int):   Request id of processed request
-
-        Returns:
-            generator
-        """
-        try:
-            if (self.state.isReset()) :
-                yield self._getResetResponse()
-
-            if (request["payload_request_type"] == 1 or request["payload_request_type"] == 11) :
-                yield self._getLoadingResponse()
-                if (len(self.state.filterStationIdDict) > 0) :
-                    response = self.filterHistoryResponseCreator.getResponse()
-                    if (response is not None) :
-                        yield response
-                else :
-                    for response in self.historyResponseCreator.getResponses(request, requestId) :
-                        yield response
-
-            elif (request["payload_request_type"] == 7) :
-                # Update request for single station
-                for response in self.historyResponseCreator.getResponses(request, requestId) :
-                    yield response
-
-            elif (request["payload_request_type"] in [4, 6, 8]) :
-                yield self._getLoadingResponse()
-                for response in self.filterResponseCreator.getResponses(request) :
-                    yield response
-
-            else :
-                self.logger.error('Request is not supported')
-                self.logger.error(request)
-
-        except psycopg2.InterfaceError as e:
-            # Connection to database is lost, better just exit
-            raise e
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-
-    def _getLoadingResponse(self) :
-        """This method creates a loading response
-
-        Returns:
-            Dict
-        """
-        return {'payload_response_type': 32}
-
-    def _getResetResponse(self) :
-        """This method creates a reset response
-
-        Returns:
-            Dict
-        """
-        payload =  {'payload_response_type': 40}
-        return payload
diff --git a/server/trackdirect/websocket/__init__.py b/server/trackdirect/websocket/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/websocket/aprsis/AprsISPayloadCreator.py b/server/trackdirect/websocket/aprsis/AprsISPayloadCreator.py
deleted file mode 100644
index 6f1158eb0d9ce4ef5b00bd8cacbb3c30cf17218f..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/aprsis/AprsISPayloadCreator.py
+++ /dev/null
@@ -1,175 +0,0 @@
-import logging
-
-import time
-
-import aprslib
-
-from trackdirect.parser.AprsPacketParser import AprsPacketParser
-
-
-import trackdirect
-
-from trackdirect.exceptions.TrackDirectParseError import TrackDirectParseError
-
-from trackdirect.websocket.responses.ResponseDataConverter import ResponseDataConverter
-from trackdirect.websocket.responses.HistoryResponseCreator import HistoryResponseCreator
-
-
-class AprsISPayloadCreator():
-    """The AprsISPayloadCreator creates a payload to send to client based on data received form the APRS-IS server
-    """
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (ConnectionState):   Instance of ConnectionState which contains the current state of the connection
-            db (psycopg2.Connection):  Database connection (with autocommit)
-        """
-        self.logger = logging.getLogger('trackdirect')
-        self.state = state
-        self.db = db
-        self.responseDataConverter = ResponseDataConverter(state, db)
-        self.historyResponseCreator = HistoryResponseCreator(state, db)
-        self.config = trackdirect.TrackDirectConfig()
-        self.stationHashTimestamps = {}
-
-        self.saveOgnStationsWithMissingIdentity = False
-        if (self.config.saveOgnStationsWithMissingIdentity) :
-            self.saveOgnStationsWithMissingIdentity = True
-
-
-    def getPayloads(self, line, sourceId):
-        """Takes a raw packet and returnes a dict with the parsed result
-
-        Args:
-            line (string):        The raw packet as a string
-            sourceId (int):       The id of the source
-
-        Returns:
-            generator
-        """
-        try :
-            packet = self._parse(line, sourceId)
-            if (not self._isPacketValid(packet)) :
-                return
-
-            if (packet.stationId not in self.state.stationsOnMapDict) :
-                self.state.stationsOnMapDict[packet.stationId] = True
-
-            if (len(self.state.filterStationIdDict) > 0 and packet.stationId in self.state.filterStationIdDict) :
-                for response in self._getPreviousPacketsPayload(packet):
-                    yield response
-
-            yield self._getRealTimePacketPayload(packet)
-        except (aprslib.ParseError, aprslib.UnknownFormat, TrackDirectParseError) as exp:
-            # We could send the raw part even if we failed to parse it...
-            pass
-        except (UnicodeDecodeError) as exp:
-            # just forget about this packet
-            pass
-
-
-    def _parse(self, line, sourceId) :
-        """Parse packet raw
-
-        Args:
-            line (string):   The raw packet as a string
-            sourceId (int):  The id of the source
-
-        Returns:
-            Packet
-        """
-        basicPacketDict = aprslib.parse(line)
-        parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
-        parser.setDatabaseWriteAccess(False)
-        parser.setSourceId(sourceId)
-        try :
-            packet = parser.getPacket(basicPacketDict)
-            if (packet.mapId == 15) :
-                return None
-
-            if (packet.mapId == 4) :
-                # Looks like we don't have enough info in db to get a markerId, wait some and try again
-                time.sleep(1)
-                return parser.getPacket(basicPacketDict)
-
-            return packet
-        except (aprslib.ParseError, aprslib.UnknownFormat, TrackDirectParseError) as exp:
-            return None
-
-
-    def _isPacketValid(self, packet) :
-        """Returns True if specified packet is valid to send to client
-
-        Args:
-            packet (Packet):   Found packet that we may want to send to client
-
-        Returns:
-            True if specified packet is valid to send to client
-        """
-        if (packet is None) :
-            return False
-
-        if (packet.mapId == 4) :
-            return False
-
-        if (packet.stationId is None) :
-            return False
-
-        if (packet.markerId is None or packet.markerId == 1) :
-            return False
-
-        if (packet.latitude is None or packet.longitude is None) :
-            return False
-
-        if (len(self.state.filterStationIdDict) > 0) :
-            if (packet.stationId not in self.state.filterStationIdDict) :
-                # This packet does not belong to the station Id that the user is filtering on
-                return False
-        return True
-
-
-    def _getRealTimePacketPayload(self, packet) :
-        """Takes a packet received directly from APRS-IS and a creates a payload response
-
-        Args:
-            packet (Packet):     The packet direclty received from APRS-IS
-
-        Returns:
-            Dict
-        """
-        options = ["realtime"]
-        data = self.responseDataConverter.getResponseData([packet], None, options)
-        payload = {'payload_response_type': 2, 'data': data}
-        return payload
-
-
-    def _getPreviousPacketsPayload(self, packet) :
-        """Creates payload that contains previous packets for the station that has sent the specified packet
-
-        Args:
-            packet (Packet):   The packet direclty received from APRS-IS
-
-        Returns:
-            generator
-        """
-        latestTimestampOnMap = self.state.getStationLatestTimestampOnMap(packet.stationId)
-        if (latestTimestampOnMap is None) :
-            latestTimestampOnMap = 0
-        latestTimestampOnMap = latestTimestampOnMap + 5
-        if (self.state.isStationHistoryOnMap(packet.stationId)
-                and packet.markerPrevPacketTimestamp is not None
-                and packet.timestamp > latestTimestampOnMap
-                and packet.markerPrevPacketTimestamp > latestTimestampOnMap) :
-            # Ups! We got a problem, the previous packet for this station has not been sent to client
-            # If no packets at all had been sent we would have marked the realtime-packet to be overwritten,
-            # but now we have a missing packet from current station that may never be sent!
-            # Send it now! This may result in that we send the same packet twice (but client should handle that)
-            request = {}
-            request["station_id"] = packet.stationId
-            request["payload_request_type"] = 7
-
-            # This request will send all packets that is missing (maybe also this real-time packet, but we can live with that...)
-            for response in self.historyResponseCreator.getResponses(request, None) :
-                yield response
diff --git a/server/trackdirect/websocket/aprsis/AprsISReader.py b/server/trackdirect/websocket/aprsis/AprsISReader.py
deleted file mode 100644
index a5be779c2b23bd221f376f3d6808b5401747c912..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/aprsis/AprsISReader.py
+++ /dev/null
@@ -1,174 +0,0 @@
-import logging
-import trackdirect
-
-from trackdirect.parser.AprsISConnection import AprsISConnection
-from trackdirect.repositories.SenderRepository import SenderRepository
-
-class AprsISReader():
-    """The AprsISReader class will connect to a APRS-IS server and listen for APRS-packets
-    """
-
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (ConnectionState):   Instance of ConnectionState which contains the current state of the connection
-            db (psycopg2.Connection):  Database connection (with autocommit)
-        """
-        self.state = state
-        self.latestRealTimeFilter = None
-
-        self.senderRepository = SenderRepository(db)
-
-        self.aprsISConnection1 = None
-        self.aprsISConnection2 = None
-
-        self.logger = logging.getLogger('trackdirect')
-        self.config = trackdirect.TrackDirectConfig()
-
-
-    def start(self):
-        """Connect to APRS-IS servers based on current state
-        """
-        self._connect()
-        self._modifyFilter()
-
-
-    def read(self, callback) :
-        """Read data from the APRS-IS servers, specified callback will be called once for every waiting packet
-
-        Args:
-            callback (method):    Method to call when we read a packet from the APRS IS connection
-
-        Note:
-            Callback function is expecting to take 2 arguments, the "packet raw" as a string and a "source id" as an integer
-        """
-        try :
-            if (self.aprsISConnection1 is not None or self.aprsISConnection2 is not None) :
-                def aprsISCallback1(line) :
-                    callback(line, self.config.websocketAprsSourceId1)
-
-                def aprsISCallback2(line) :
-                    callback(line, self.config.websocketAprsSourceId2)
-
-                if (self.aprsISConnection2 is not None) :
-                    self.aprsISConnection2.filteredConsumer(aprsISCallback2, False, True)
-
-                if (self.aprsISConnection1 is not None) :
-                    self.aprsISConnection1.filteredConsumer(aprsISCallback1, False, True)
-        except IOError as e:
-            callback(None, None)
-        except Exception as e:
-            self.logger.error(e, exc_info=1)
-            callback(None, None)
-
-
-    def pause(self) :
-        """Pause without closing the aprsISConnection, we just set filter to nothing, that will result in no received packets
-        """
-        if (self.aprsISConnection1 is not None) :
-            self.latestRealTimeFilter = None
-            self.aprsISConnection1.set_filter('')
-
-        if (self.aprsISConnection2 is not None) :
-            self.latestRealTimeFilter = None
-            self.aprsISConnection2.set_filter('')
-
-
-    def stop(self):
-        """Kill the connections to the APRS-IS servers
-        """
-        if (self.aprsISConnection2 is not None) :
-            self.aprsISConnection2.close()
-            self.aprsISConnection2 = None
-
-        if (self.aprsISConnection1 is not None) :
-            self.aprsISConnection1.close()
-            self.aprsISConnection1 = None
-
-
-    def clear(self, limit = None):
-        """Clear the socket from all waiting lines
-
-        Args:
-            limit (int):  Max number of packets to clear (per connection)
-        """
-        counter1 = 0
-        counter2 = 0
-        if (self.aprsISConnection2 is not None) :
-            for line in self.aprsISConnection1._socket_readlines(False):
-                counter1 += 1
-                if (limit is not None and counter1 >= limit) :
-                    break
-        if (self.aprsISConnection1 is not None) :
-            for line in self.aprsISConnection1._socket_readlines(False):
-                counter2 += 1
-                if (limit is not None and counter2 >= limit) :
-                    break
-        return counter1 + counter2
-
-
-    def _connect(self):
-        """Connect to APRS-IS servers (if not allready connected)
-        """
-        if (self.aprsISConnection1 is None) :
-            self.latestRealTimeFilter = None
-            # Avoid using a verified user since server will not accept two verfied users with same name
-            if (self.config.websocketAprsHost1 is not None) :
-                try:
-                    self.aprsISConnection1 = AprsISConnection("NOCALL", "-1", self.config.websocketAprsHost1, self.config.websocketAprsPort1)
-                    if (self.config.websocketFrequencyLimit != 0) :
-                        self.aprsISConnection1.setFrequencyLimit(self.config.websocketFrequencyLimit)
-                    self.aprsISConnection1.connect()
-                except Exception as e:
-                    self.logger.error(e, exc_info=1)
-
-        if (self.aprsISConnection2 is None) :
-            self.latestRealTimeFilter = None
-            # Avoid using a verified user since server will not accept two verfied users with same name
-            if (self.config.websocketAprsHost2 is not None) :
-                try:
-                    self.aprsISConnection2 = AprsISConnection("NOCALL", "-1", self.config.websocketAprsHost2, self.config.websocketAprsPort2)
-                    if (self.config.websocketFrequencyLimit != 0) :
-                        self.aprsISConnection2.setFrequencyLimit(self.config.websocketFrequencyLimit)
-                    self.aprsISConnection2.connect()
-                except Exception as e:
-                    self.logger.error(e, exc_info=1)
-
-
-    def _modifyFilter(self) :
-        """Set a new filter for the APRS-IS connections according to the latest requested map bounds
-        """
-        newFilter = self._getNewFilter()
-        if (self.latestRealTimeFilter is not None and newFilter == self.latestRealTimeFilter) :
-            # If new filter is equal to latest, do not do anything
-            return
-
-        # Just empty any waiting data on socket
-        self.clear()
-
-        self.latestRealTimeFilter = newFilter
-        if (self.aprsISConnection1 is not None) :
-            self.aprsISConnection1.set_filter(newFilter)
-
-        if (self.aprsISConnection2 is not None) :
-            self.aprsISConnection2.set_filter(newFilter)
-
-
-    def _getNewFilter(self) :
-        """Create new APRS-IS filter based latest requested map bounds
-        """
-        if (len(self.state.filterStationIdDict) > 0) :
-            filter = "b"
-            for stationId in self.state.filterStationIdDict:
-                sender = self.senderRepository.getObjectByStationId(stationId)
-                if (sender.name is not None) :
-                    call, sep, ssid = sender.name.partition('-')
-                    filter = filter + "/" + sender.name
-        else :
-            # We add some area arround current view
-            #filter = "a/" + str(self.state.latestNeLat+1) + "/" + str(self.state.latestSwLng-2) + "/" + str(self.state.latestSwLat-1) + "/" + str(self.state.latestNeLng+2)
-            filter = "a/" + str(self.state.latestNeLat+0.1) + "/" + str(self.state.latestSwLng-0.1) + "/" + str(self.state.latestSwLat-0.1) + "/" + str(self.state.latestNeLng+0.1)
-
-        return filter
diff --git a/server/trackdirect/websocket/aprsis/__init__.py b/server/trackdirect/websocket/aprsis/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/aprsis/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/websocket/queries/MissingPacketsQuery.py b/server/trackdirect/websocket/queries/MissingPacketsQuery.py
deleted file mode 100644
index 9a836c924b831ad5f3280144439765ebdf906802..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/queries/MissingPacketsQuery.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import datetime, time, calendar
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.repositories.StationRepository import StationRepository
-from trackdirect.parser.policies.MapSectorPolicy import MapSectorPolicy
-
-class MissingPacketsQuery() :
-    """This query class is used to find a packet for all stations that we are missing a packet for (when we rely need a packet for them)
-
-    Note:
-        If no packet are found we will simulate them
-    """
-
-    def __init__(self, state, db) :
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):   The current state for a websocket connection
-            db (psycopg2.Connection):           Database connection
-        """
-        self.state = state
-        self.db = db
-        self.packetRepository = PacketRepository(db)
-        self.stationRepository = StationRepository(db)
-        self.simulateEmptyStation = False
-
-
-    def enableSimulateEmptyStation(self) :
-        """Enable simulation even if we have no packet from station at all
-        """
-        self.simulateEmptyStation = True
-
-
-    def getMissingPackets(self, stationIds, foundPackets) :
-        """Fetch latest packets for stations that has no packet in foundPackets
-
-        Args:
-            stationIds (array):   An array of all stations we should filter on
-            foundPackets (array): Packets that we have found
-
-        Returns:
-            array
-        """
-        foundMissingPackets = []
-        for stationId in stationIds :
-            foundStationPacket = False
-            for packet in foundPackets :
-                if packet.stationId == stationId :
-                    foundStationPacket = True
-                    break # will go to next stationId
-
-            # Get latest packet for this station
-            if (not foundStationPacket) :
-                missingPacket = self._getLatestPacket(stationId)
-                if (missingPacket is not None) :
-                    foundMissingPackets.append(missingPacket)
-
-        def getSortKey(item) :
-            return item.timestamp
-        return sorted(foundMissingPackets, key = getSortKey)
-
-
-    def _getLatestPacket(self, stationId) :
-        """This method tries to find a packet for the specified station, in worst case a packet will be simulated based on old data
-
-        Args:
-            stationId (int): Stations id that we need a packet for
-
-        Returns:
-            Packet
-        """
-        if (self.state.latestTimeTravelRequest is not None) :
-            ts = int(self.state.latestTimeTravelRequest) - (30*24*60*60) # For time travelers we need a limit
-            olderPackets = self.packetRepository.getLatestObjectListByStationIdListAndTimeInterval([stationId], ts, self.state.latestTimeTravelRequest)
-        else :
-            olderPackets = self.packetRepository.getLatestConfirmedObjectListByStationIdList([stationId], 0)
-
-        if (len(olderPackets) > 0) :
-            return olderPackets[0] # The lastet is the first in array
-        else :
-            # Lets try not confirmed packets
-            if (self.state.latestTimeTravelRequest is not None) :
-                ts = int(self.state.latestTimeTravelRequest) - (30*24*60*60) # For time travelers we need a limit
-                olderNonConfirmedPackets = self.packetRepository.getLatestObjectListByStationIdListAndTimeInterval([stationId], ts, self.state.latestTimeTravelRequest, False)
-            else :
-                olderNonConfirmedPackets = self.packetRepository.getLatestObjectListByStationIdList([stationId], 0)
-
-            if (len(olderNonConfirmedPackets) > 0) :
-                # Make this ghost-packet visible...
-                packet = olderNonConfirmedPackets[0]
-                packet.mapId = 1
-                packet.sourceId = 0 #simulated
-                return packet
-            else :
-                # We still do not have packets for this station, just get what we have from the station-table
-                return self._getSimulatedPacket(stationId)
-        return None
-
-
-    def _getSimulatedPacket(self, stationId) :
-        """Creates a simulated packet based on data saved in the station table
-
-        Args:
-            stationId (int):                  The station that we want a packet from
-
-        Returns:
-            Packet
-        """
-        station = self.stationRepository.getObjectById(stationId)
-        if (station.isExistingObject()
-                and (station.latestConfirmedPacketId is not None
-                        or self.simulateEmptyStation)) :
-            packet = self.packetRepository.create()
-            packet.stationId = station.id
-            packet.senderId = station.latestSenderId
-            packet.sourceId = station.sourceId
-            packet.ogn_sender_address = station.latestOgnSenderAddress
-
-            if (station.latestConfirmedPacketId is not None) :
-                packet.id = station.latestConfirmedPacketId
-            else :
-                packet.id = -station.id # simulate a packet id that is uniqe
-
-            if (station.latestConfirmedMarkerId is not None) :
-                packet.markerId = station.latestConfirmedMarkerId
-            else :
-                packet.markerId = -station.id # simulate a marker id
-
-            packet.isMoving = 0
-            packet.packetTypeId = 1 # Assume it was a position packet...
-
-            if (station.latestConfirmedLatitude is not None and station.latestConfirmedLongitude is not None) :
-                packet.latitude = station.latestConfirmedLatitude
-                packet.longitude = station.latestConfirmedLongitude
-            else :
-                packet.latitude = float(0.0)
-                packet.longitude = float(0.0)
-
-            if (self.state.latestTimeTravelRequest is not None) :
-                packet.timestamp = 0 # don't know anything better to set here...
-            elif (station.latestConfirmedPacketTimestamp is not None) :
-                packet.timestamp = station.latestConfirmedPacketTimestamp
-            else :
-                packet.timestamp = 0
-
-            packet.reportedTimestamp = None
-            packet.positionTimestamp = packet.timestamp
-            packet.posambiguity = 0
-
-            if (station.latestConfirmedSymbol is not None and station.latestConfirmedSymbolTable is not None) :
-                packet.symbol = station.latestConfirmedSymbol
-                packet.symbolTable = station.latestConfirmedSymbolTable
-            else :
-                packet.symbol = None
-                packet.symbolTable = None
-
-            mapSectorPolicy = MapSectorPolicy()
-            packet.mapSector = mapSectorPolicy.getMapSector(packet.latitude, packet.longitude)
-            packet.relatedMapSectors = []
-            packet.mapId = 1
-            packet.speed = None
-            packet.course = None
-            packet.altitude = None
-            packet.packetTailTimestamp = packet.timestamp
-            packet.comment = None
-            packet.rawPath = None
-            packet.raw = None
-
-            return packet
-        return None
diff --git a/server/trackdirect/websocket/queries/MostRecentPacketsQuery.py b/server/trackdirect/websocket/queries/MostRecentPacketsQuery.py
deleted file mode 100644
index ca2a4f63136e882798552cf2030c734ebd05b024..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/queries/MostRecentPacketsQuery.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import datetime, time, calendar
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.websocket.queries.MissingPacketsQuery import MissingPacketsQuery
-
-
-class MostRecentPacketsQuery() :
-    """This query class returnes the latest packet for moving stations and the latest packet for every uniqe position for stationary stations.
-
-    Note:
-        If no packet are found we will simulate them
-    """
-
-    def __init__(self, state, db) :
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):   The current state for a websocket connection
-            db (psycopg2.Connection):           Database connection
-        """
-        self.state = state
-        self.db = db
-        self.packetRepository = PacketRepository(db)
-        self.simulateEmptyStation = False
-
-
-    def enableSimulateEmptyStation(self) :
-        """Enable simulation even if we have no packet from station at all
-        """
-        self.simulateEmptyStation = True
-
-
-    def getPackets(self, stationIds) :
-        """Fetch the most recent packets for the specified stations.
-        Returns the latest packet for moving stations and the latest packet for every uniqe position for stationary stations.
-
-        Args:
-            stationIds (array):   An array of all stations we want packets for
-
-        Returns:
-            array
-        """
-        if (self.state.latestTimeTravelRequest is not None) :
-            timestamp = int(self.state.latestTimeTravelRequest) - (int(self.state.latestMinutesRequest)*60)
-            packets = self.packetRepository.getMostRecentConfirmedObjectListByStationIdListAndTimeInterval(stationIds, timestamp, self.state.latestTimeTravelRequest)
-        else :
-            timestamp = int(time.time()) - (int(self.state.latestMinutesRequest)*60)
-            packets = self.packetRepository.getMostRecentConfirmedObjectListByStationIdList(stationIds, timestamp)
-
-        if (len(packets) < len(stationIds)) :
-            # If we have no recent markers we just send the latest that we have
-            query = MissingPacketsQuery(self.state, self.db)
-            if (self.simulateEmptyStation) :
-                query.enableSimulateEmptyStation()
-
-            foundMissingPackets = query.getMissingPackets(stationIds, packets)
-            if (foundMissingPackets) :
-                foundMissingPackets.extend(packets)
-                packets = foundMissingPackets
-        return packets
diff --git a/server/trackdirect/websocket/queries/StationIdByMapSectorQuery.py b/server/trackdirect/websocket/queries/StationIdByMapSectorQuery.py
deleted file mode 100644
index 2a44a0fef9a34dbd537518c4636d5c6f2a179dc1..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/queries/StationIdByMapSectorQuery.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import datetime, time, calendar
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-
-
-class StationIdByMapSectorQuery() :
-    """A query class used to find station ids in a map sector
-    """
-
-    def __init__(self, db) :
-        """The __init__ method.
-
-        Args:
-            db (psycopg2.Connection): Database connection
-        """
-        self.db = db
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-
-    def getStationIdListByMapSector(self, mapSector, startPacketTimestamp, endPacketTimestamp) :
-        """Returns a list station ids  based on the specified map sector and time interval
-
-        Args:
-            mapSector (int):                    Map sector integer
-            startPacketTimestamp (int):         Min unix timestamp
-            endPacketTimestamp (int):           Max unix timestamp
-
-        Returns:
-            array
-        """
-        result = {}
-        selectCursor = self.db.cursor()
-
-        # Create list of packet tables to look in
-        # After testing I have realized that this query is faster if you query one child table at the time
-
-        if (endPacketTimestamp is None):
-            endPacketTimestamp = int(time.time())
-        endDateTime = datetime.datetime.utcfromtimestamp(int(endPacketTimestamp))
-        endDateTime = endDateTime.replace(hour=0, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
-        endTimestamp = calendar.timegm(endDateTime.timetuple())
-
-        packetTables = []
-        ts = startPacketTimestamp
-        while (ts < endTimestamp) :
-            date = datetime.datetime.utcfromtimestamp(int(ts)).strftime('%Y%m%d')
-            datePacketTable = 'packet' + date
-            if (self.dbObjectFinder.checkTableExists(datePacketTable)) :
-                packetTables.append(datePacketTable)
-            ts = ts + 86400 # 1 day in seconds
-
-        # Go through packet tables and search for stations
-        for packetTable in reversed(packetTables) :
-            sql1 = selectCursor.mogrify("""select distinct station_id id
-                from """ + packetTable + """
-                where map_sector = %s
-                    and timestamp > %s
-                    and timestamp <= %s
-                    and map_id in (1,5,7,9)""", (mapSector, startPacketTimestamp, endPacketTimestamp))
-
-            selectCursor.execute(sql1)
-            for record in selectCursor :
-                if (record is not None) :
-                    result[int(record["id"])] = True
-
-            sql2 = selectCursor.mogrify("""select distinct station_id id
-                from """ + packetTable + """
-                where map_sector = %s
-                    and position_timestamp <= %s
-                    and timestamp > %s
-                    and map_id in (12)""", (mapSector, endPacketTimestamp, startPacketTimestamp))
-
-            selectCursor.execute(sql2)
-            for record in selectCursor :
-                if (record is not None) :
-                    result[int(record["id"])] = True
-
-        selectCursor.close()
-        return list(result.keys())
\ No newline at end of file
diff --git a/server/trackdirect/websocket/queries/__init__.py b/server/trackdirect/websocket/queries/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/queries/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/server/trackdirect/websocket/responses/FilterHistoryResponseCreator.py b/server/trackdirect/websocket/responses/FilterHistoryResponseCreator.py
deleted file mode 100644
index 122e7c5b6c35b24bcaa777a69c218ff72438dbfd..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/responses/FilterHistoryResponseCreator.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import logging
-from twisted.python import log
-
-from math import floor, ceil
-import datetime, time
-import psycopg2, psycopg2.extras
-
-from trackdirect.repositories.PacketRepository import PacketRepository
-
-from trackdirect.websocket.queries.MissingPacketsQuery import MissingPacketsQuery
-from trackdirect.websocket.responses.ResponseDataConverter import ResponseDataConverter
-
-class FilterHistoryResponseCreator():
-    """The FilterHistoryResponseCreator class creates history responses for stations that we are filtering on
-    """
-
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):    WebsocketConnectionState instance that contains current state
-            db (psycopg2.Connection):            Database connection (with autocommit)
-        """
-        self.state = state
-        self.logger = logging.getLogger('trackdirect')
-
-        self.db = db
-        self.responseDataConverter = ResponseDataConverter(state, db)
-        self.packetRepository = PacketRepository(db)
-
-
-    def getResponse(self) :
-        """Returns a filter history response
-
-        Returns:
-            Dict
-        """
-        filterStationIds = self.state.filterStationIdDict.keys()
-
-        # When filtering we send everything in the same packet
-        # We need to do this since we do not send related objects,
-        # if user is filtering on two related OBJECTS they need to be sent together
-        packets = self._getPackets(filterStationIds)
-
-        # If map is empty we need to make sure that all specified stations is included
-        if (self.state.isMapEmpty()) :
-            query = MissingPacketsQuery(self.state, self.db)
-            query.enableSimulateEmptyStation()
-            sortedFoundMissingPackets = query.getMissingPackets(filterStationIds, packets)
-            sortedFoundMissingPackets.extend(packets)
-            packets = sortedFoundMissingPackets
-
-        if (packets) :
-            data = self.responseDataConverter.getResponseData(packets, [])
-            payload = {'payload_response_type': 2, 'data': data}
-            return payload
-
-
-    def _getPackets(self, stationIds) :
-        """Returns packets to be used in a filter history response
-
-        Args:
-            stationIds (array):    The station id's that we want history data for
-
-        Returns:
-            array
-        """
-        minTimestamp = None
-        if (len(stationIds) > 0) :
-            minTimestamp = self.state.getStationLatestTimestampOnMap(list(stationIds)[0])
-        if (minTimestamp is None) :
-            minTimestamp = self.state.getMapSectorTimestamp(None) # None as argument is useful even when not dealing with map-sectors
-        if (len(stationIds) > 1) :
-            for stationId in stationIds :
-                timestamp = self.state.getStationLatestTimestampOnMap(stationId)
-                if (timestamp is not None and timestamp > minTimestamp) :
-                    minTimestamp = timestamp
-
-        if (self.state.latestTimeTravelRequest is not None) :
-            if (not self.state.isStationsOnMap(stationIds)) :
-                return self.packetRepository.getObjectListByStationIdListAndTimeInterval(stationIds, minTimestamp, self.state.latestTimeTravelRequest)
-        else :
-            return self.packetRepository.getObjectListByStationIdList(stationIds, minTimestamp)
diff --git a/server/trackdirect/websocket/responses/FilterResponseCreator.py b/server/trackdirect/websocket/responses/FilterResponseCreator.py
deleted file mode 100644
index e4a5508dd55f1e33f7aaba5d410b91d5e5c086a4..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/responses/FilterResponseCreator.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import logging
-
-import time
-
-
-import trackdirect
-
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.repositories.StationRepository import StationRepository
-
-from trackdirect.websocket.queries.MostRecentPacketsQuery import MostRecentPacketsQuery
-from trackdirect.websocket.responses.ResponseDataConverter import ResponseDataConverter
-
-
-class FilterResponseCreator():
-    """The FilterResponseCreator is used to create filter responses, a response sent to client when client wants to filter on a station
-    """
-
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):    WebsocketConnectionState instance that contains current state
-            db (psycopg2.Connection):            Database connection (with autocommit)
-        """
-        self.state = state
-        self.db = db
-        self.logger = logging.getLogger('trackdirect')
-        self.responseDataConverter = ResponseDataConverter(state, db)
-        self.packetRepository = PacketRepository(db)
-        self.stationRepository = StationRepository(db)
-        self.config = trackdirect.TrackDirectConfig()
-
-
-    def getResponses(self, request) :
-        """Creates responses related to a filter request
-
-        Args:
-            request (dict):    The request to process
-
-        Returns:
-            generator
-        """
-        self._updateState(request)
-        if (self.state.isReset()) :
-            yield self._getResetResponse()
-        yield self._getFilterResponse()
-
-
-    def _updateState(self, request) :
-        """Update connection state based on filter request
-
-        Args:
-            request (dict):    The request to process
-        """
-        if (request["payload_request_type"] == 4 and "list" in request) :
-            if (len(request["list"]) > 0) :
-                for stationId in request["list"]:
-                    # Only send data about specified objects
-                    self.state.filterStationIdDict[int(stationId)] = True
-            else :
-                # User wants to see everything again
-                self.state.filterStationIdDict = {}
-                self.state.setLatestMapBounds(0, 0, 0, 0)
-                self.state.setLatestMinutes(60, None)
-            self.state.reset()
-
-        elif (request["payload_request_type"] == 6 and "station_id" in request) :
-            self.state.filterStationIdDict.pop(int(request["station_id"]), None)
-            self.state.reset()
-
-        elif (request["payload_request_type"] == 8 and "namelist" in request) :
-            if (len(request["namelist"]) > 0) :
-                minTimestamp = int(time.time()) - (10*365*24*60*60)
-                if (not self.config.allowTimeTravel) :
-                    minTimestamp = int(time.time()) - (24*60*60)
-
-                for stationName in request["namelist"]:
-                    # Only send data about specified objects
-                    stations = self.stationRepository.getObjectListByName(stationName, None, None, minTimestamp)
-                    for station in stations:
-                        self.state.filterStationIdDict[int(station.id)] = True
-            else :
-                # User wants to see everything again
-                self.state.filterStationIdDict = {}
-                self.state.setLatestMapBounds(0, 0, 0, 0)
-                self.state.setLatestMinutes(60, None)
-            self.state.reset()
-
-    def _getResetResponse(self) :
-        """This method creates a reset response
-
-        Returns:
-            Dict
-        """
-        payload =  {'payload_response_type': 40}
-        return payload
-
-
-    def _getFilterResponse(self) :
-        """This method creates a filter response
-
-        Returns:
-            Dict
-        """
-        data = []
-        if (self.state.filterStationIdDict) :
-            filterStationIds = list(self.state.filterStationIdDict.keys())
-            data = self._getFilterResponseData(filterStationIds)
-
-        payload =  {'payload_response_type': 5, 'data': data}
-        return payload
-
-
-    def _getFilterResponseData(self, filterStationIds) :
-        """Creates data to be included in a filter response
-
-        Args:
-            filterStationIds (array):   An array of all stations we should filter on
-        """
-        if (self.state.latestTimeTravelRequest is not None) :
-            timestamp = int(self.state.latestTimeTravelRequest) - (int(self.state.latestMinutesRequest)*60)
-        else :
-            timestamp = int(time.time()) - (int(self.state.latestMinutesRequest)*60)
-
-        query = MostRecentPacketsQuery(self.state, self.db)
-        query.enableSimulateEmptyStation()
-        packets = query.getPackets(filterStationIds)
-        data = self.responseDataConverter.getResponseData(packets, [])
-        self.state.reset() # Reset to make sure client will get the same packet on history request
-        result = []
-        for packetData in data :
-            if (self.config.allowTimeTravel or packetData['timestamp'] > int(time.time()) - (24*60*60)) :
-                packetData['overwrite'] = 1
-                packetData['realtime'] = 0
-                packetData['packet_order_id'] = 1 # Last packet for this station in this response
-                packetData['requested_timestamp'] = timestamp
-                if packetData['station_id'] in filterStationIds:
-                    packetData['related'] = 0
-                else :
-                    packetData['related'] = 1
-                result.append(packetData)
-        return result
diff --git a/server/trackdirect/websocket/responses/HistoryResponseCreator.py b/server/trackdirect/websocket/responses/HistoryResponseCreator.py
deleted file mode 100644
index 71c521ba6008c4dc371ca3dbb533fed6f5fd75c0..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/responses/HistoryResponseCreator.py
+++ /dev/null
@@ -1,235 +0,0 @@
-import logging
-from twisted.python import log
-
-from math import floor, ceil
-import datetime, time
-import psycopg2, psycopg2.extras
-
-from trackdirect.repositories.PacketRepository import PacketRepository
-
-from trackdirect.websocket.queries.StationIdByMapSectorQuery import StationIdByMapSectorQuery
-from trackdirect.websocket.responses.ResponseDataConverter import ResponseDataConverter
-
-
-class HistoryResponseCreator():
-    """The HistoryResponseCreator class creates websocket history responses for the latest websocket request
-    """
-
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):    WebsocketConnectionState instance that contains current state
-            db (psycopg2.Connection):            Database connection (with autocommit)
-        """
-        self.state = state
-        self.logger = logging.getLogger('trackdirect')
-
-        self.db = db
-        self.packetRepository = PacketRepository(db)
-        self.responseDataConverter = ResponseDataConverter(state, db)
-
-
-    def getResponses(self, request, requestId) :
-        """Create all history responses for the current request
-
-        Args:
-            request (dict):    The request to process
-            requestId (int):   Request id of processed request
-
-        Returns:
-            generator
-        """
-        if (request["payload_request_type"] == 1 or request["payload_request_type"] == 11) :
-            if (not self.state.isValidLatestPosition()) :
-                return
-
-            if (self.state.latestNeLat >= 90
-                    and self.state.latestNeLng >= 180
-                    and self.state.latestSwLat <= -90
-                    and self.state.latestSwLng <= -180) :
-                # request is requesting to much
-                return
-
-            for response in self._getMapSectorHistoryResponses(requestId) :
-                yield response
-
-        elif (request["payload_request_type"] == 7 and "station_id" in request) :
-            for response in self._getStationHistoryResponses([request["station_id"]], None, True) :
-                yield response
-
-        else :
-            self.logger.error('Request is not supported')
-            self.logger.error(request)
-
-
-    def _getMapSectorHistoryResponses(self, requestId) :
-        """Creates all needed history responses for the currently visible map sectors
-
-        Args:
-            requestId (int):   Request id of processed request
-
-        Returns:
-            generator
-        """
-        mapSectorArray = self.state.getVisibleMapSectors()
-        if (len(mapSectorArray) > 20000) :
-            # Our client will never send a request like this
-            self.logger.error("To many map sectors requested!")
-            return
-
-        handledStationIdDict = {}
-        for mapSector in mapSectorArray :
-            try:
-                # Handle one map sector at the time
-                if (requestId is not None and self.state.latestRequestId > requestId) :
-                    # If new request is recived we want to skip this one (this request is not that important)
-                    # As long as we handle a complete map sector everything is ok
-                    return
-
-                foundStationIds = self._getStationIdsByMapSector(mapSector)
-                stationIds = []
-                for stationId in foundStationIds :
-                    if (stationId not in handledStationIdDict) :
-                        stationIds.append(stationId)
-                        handledStationIdDict[stationId] = True
-
-                if (stationIds) :
-                    for response in self._getStationHistoryResponses(stationIds, mapSector, False) :
-                        yield response
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                self.logger.error(e, exc_info=1)
-
-
-    def _getStationHistoryResponses(self, stationIds, mapSector, includeCompleteHistory = False) :
-        """Creates one history response per station
-
-        Args:
-            stationIds (array):                 An array of the stations that we want history data for
-            mapSector (int):                    The map sector that we want history data for
-            includeCompleteHistory (boolean):   Include all previous packets (even if we currently only request the latest packets)
-
-        Returns:
-            generator
-        """
-        # Important to fetch map sector timestamp before loop (may be updated in loop)
-        minTimestamp = self.state.getMapSectorTimestamp(mapSector)
-        for stationId in stationIds:
-            try:
-                if (self.state.latestTimeTravelRequest is not None) :
-                    response = self._getPastHistoryResponse(stationId, mapSector, minTimestamp, includeCompleteHistory)
-                else :
-                    response = self._getRecentHistoryResponse(stationId, mapSector, minTimestamp, includeCompleteHistory)
-                if (response is not None) :
-                    yield response
-            except psycopg2.InterfaceError as e:
-                # Connection to database is lost, better just exit
-                raise e
-            except Exception as e:
-                self.logger.error(e, exc_info=1)
-
-
-    def _getRecentHistoryResponse(self, stationId, mapSector, minTimestamp, includeCompleteHistory = False) :
-        """Creates a history response for the specified station, includes all packets from minTimestamp until now
-
-        Args:
-            stationId (int):                    The station id that we want history data for
-            mapSector (int):                    The map sector that we want history data for
-            minTimestamp (int):                 The map sector min timestamp to use in query
-            includeCompleteHistory (boolean):   Include all previous packets (even if we currently only request the latest packets)
-
-        Returns:
-            Dict
-        """
-        packets = []
-        onlyLatestPacketFetched = False
-        currentStationIds = [stationId]
-
-        currentMinTimestamp = self.state.getStationLatestTimestampOnMap(stationId)
-        if (currentMinTimestamp is None) :
-            currentMinTimestamp = minTimestamp
-        else :
-            # Since station already exists on map we should continue adding all packets
-            includeCompleteHistory = True
-
-        if (not self.state.onlyLatestPacketRequested or includeCompleteHistory) :
-            packets = self.packetRepository.getObjectListByStationIdList(currentStationIds, currentMinTimestamp)
-        else :
-            # We could call getMostRecentConfirmedObjectListByStationIdList, would take longer time but would show all positions for a station
-            packets = self.packetRepository.getLatestConfirmedObjectListByStationIdList(currentStationIds, currentMinTimestamp)
-            if (packets) :
-                packets = [packets[-1]] # we only need the latest
-            onlyLatestPacketFetched = True
-
-        if (packets) :
-            flags = []
-            if (onlyLatestPacketFetched) :
-                flags = ["latest"]
-            data = self.responseDataConverter.getResponseData(packets, [mapSector], flags)
-            payload = {'payload_response_type': 2, 'data': data}
-            return payload
-
-
-    def _getPastHistoryResponse(self, stationId, mapSector, minTimestamp, includeCompleteHistory = False) :
-        """Creates a history response for the specified station, includes all packets between minTimestamp and the current latestTimeTravelRequest timestamp
-
-        Args:
-            stationId (int):                    The station id that we want history data for
-            mapSector (int):                    The map sector that we want history data for
-            minTimestamp (int):                 The map sector min timestamp to use in query
-            includeCompleteHistory (boolean):   Include all previous packets (even if we currently only request the latest packets)
-
-        Returns:
-            Dict
-        """
-        packets = []
-        onlyLatestPacketFetched = False
-        currentStationIds = [stationId]
-
-        currentMinTimestamp = self.state.getStationLatestTimestampOnMap(stationId)
-        if (currentMinTimestamp is None) :
-            currentMinTimestamp = minTimestamp
-
-        if (self.state.onlyLatestPacketRequested and not includeCompleteHistory) :
-            if (stationId not in self.state.stationsOnMapDict) :
-                # we only need to fetch latest packet for a time-travel request if station is not on map
-                onlyLatestPacketFetched = True
-                packets = self.packetRepository.getLatestObjectListByStationIdListAndTimeInterval(currentStationIds, currentMinTimestamp, self.state.latestTimeTravelRequest)
-        else :
-            if (not self.state.isStationHistoryOnMap(stationId)) :
-                packets = self.packetRepository.getObjectListByStationIdListAndTimeInterval(currentStationIds, currentMinTimestamp, self.state.latestTimeTravelRequest)
-
-        if (packets) :
-            flags = []
-            if (onlyLatestPacketFetched) :
-                flags = ["latest"]
-            data = self.responseDataConverter.getResponseData(packets, [mapSector], flags)
-            payload = {'payload_response_type': 2, 'data': data}
-            return payload
-
-
-    def _getStationIdsByMapSector(self, mapSector) :
-        """Returns the station Id's in specified map sector
-
-        Args:
-            mapSector (int):   The map sector that we are interested in
-
-        Returns:
-            array of ints
-        """
-        query = StationIdByMapSectorQuery(self.db)
-        if (self.state.latestTimeTravelRequest is not None) :
-            if (self.state.isMapSectorKnown(mapSector)) :
-                # This map sector is under control
-                return []
-            else :
-                startTimestamp = self.state.latestTimeTravelRequest - (int(self.state.latestMinutesRequest)*60)
-                endTimestamp = self.state.latestTimeTravelRequest;
-                return query.getStationIdListByMapSector(mapSector, startTimestamp, endTimestamp)
-        else :
-            timestamp = self.state.getMapSectorTimestamp(mapSector)
-            return query.getStationIdListByMapSector(mapSector, timestamp, None)
diff --git a/server/trackdirect/websocket/responses/ResponseDataConverter.py b/server/trackdirect/websocket/responses/ResponseDataConverter.py
deleted file mode 100644
index 9ad3c1a8862ce5fb6dd19e25d41e3b5bfa9b412d..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/responses/ResponseDataConverter.py
+++ /dev/null
@@ -1,377 +0,0 @@
-import logging
-from twisted.python import log
-
-from math import floor, ceil
-import datetime, time
-
-import psycopg2, psycopg2.extras
-
-from trackdirect.repositories.PacketRepository import PacketRepository
-from trackdirect.repositories.StationRepository import StationRepository
-from trackdirect.repositories.PacketWeatherRepository import PacketWeatherRepository
-from trackdirect.repositories.PacketOgnRepository import PacketOgnRepository
-from trackdirect.repositories.OgnDeviceRepository import OgnDeviceRepository
-
-from trackdirect.database.DatabaseObjectFinder import DatabaseObjectFinder
-from trackdirect.database.DatabaseConnection import DatabaseConnection
-
-from trackdirect.websocket.queries.MostRecentPacketsQuery import MostRecentPacketsQuery
-from trackdirect.websocket.queries.MissingPacketsQuery import MissingPacketsQuery
-
-
-class ResponseDataConverter():
-    """An ResponseDataConverter instance is used to create response content data based on packet objects
-    """
-
-
-    def __init__(self, state, db):
-        """The __init__ method.
-
-        Args:
-            state (WebsocketConnectionState):
-            db (psycopg2.Connection):            Database connection (with autocommit)
-        """
-        self.state = state
-        self.logger = logging.getLogger('trackdirect')
-
-        self.db = db
-        self.packetRepository = PacketRepository(db)
-        self.stationRepository = StationRepository(db)
-        self.packetWeatherRepository = PacketWeatherRepository(db)
-        self.dbObjectFinder = DatabaseObjectFinder(db)
-        self.packetOgnRepository = PacketOgnRepository(db)
-        self.ognDeviceRepository = OgnDeviceRepository(db)
-
-
-    def getResponseData(self, packets, mapSectorList = None, flags = [], iterationCounter = 0) :
-        """Create response data based on specified packets
-
-        Args:
-            packets (array):                    An array of the Packet's that should be converted to packet dict responses
-            mapSectorList (array):              An array of the current handled map sectors
-            flags (array):                      An array with additional flags (like "realtime", "latest")
-            iterationCounter (int)              This functionality will call itself to find related packets, this argument is used to remember the number of iterations
-
-        Returns:
-            An array of packet dicts
-        """
-        responseData = []
-        for index, packet in enumerate(packets) :
-            packetDict = packet.getDict(True)
-            packetDict['packet_order_id'] = self._getPacketOrderId(packets, index, flags)
-
-            self._updateState(packet, mapSectorList, flags)
-            self._addOverwriteStatus(packetDict)
-            if (("latest" not in flags and "realtime" not in flags) or self.state.isStationHistoryOnMap(packet.stationId)) :
-                if (packetDict['packet_order_id'] == 1) :
-                    self._addStationWeatherData(packetDict)
-                    self._addStationTelemetryData(packetDict)
-                    if (packet.sourceId == 5) :
-                        self._addStationOgnData(packetDict)
-                if (packet.sourceId == 5) :
-                    self._addStationOgnDeviceData(packetDict)
-                self._addPacketPhgRng(packetDict)
-
-            if ("realtime" not in flags) :
-                self._addStationIdPath(packetDict)
-
-            self._setFlags(packetDict, flags)
-            responseData.append(packetDict)
-        return self._extendResponseWithMorePackets(responseData, flags, iterationCounter)
-
-
-    def _getPacketOrderId(self, packets, index, flags) :
-        """Returns the order id of the packet at specified index
-
-        Args:
-            packets (array):     An array of the Packet's that should be converted to packet dict responses
-            index (int):         Index of the packet that we want an order id for
-            flags (array):       An array with additional flags (like "realtime", "latest")
-
-        Returns:
-            int
-        """
-        if ("realtime" in flags) :
-            return 1
-        elif (len(packets) -1 == index):
-            # This is the last packet of all
-            return 1 # Last packet in response for this marker
-        elif (packets[index].markerId != packets[index + 1].markerId) :
-            # This is the last packet for this marker
-            return 1 # Last packet in response for this marker
-        elif (index == 0 or packets[index].markerId != packets[index - 1].markerId) :
-            # This is the first packet for this marker
-            return 3 # First packet in response for this marker
-        else :
-            return 2 # Middle packet in response for this marker
-
-
-    def _updateState(self, packet, mapSectorList, flags) :
-        """Update connection state based on packet on the way to client
-
-        Args:
-            packet (Packet):                     The packet that is on the way to client
-            mapSectorList (array):               An array of the current handled map sectors
-            flags (array):                       An array with additional flags (like "realtime", "latest")
-        """
-        self.state.setStationLatestTimestamp(packet.stationId, packet.timestamp)
-
-        if (packet.stationId not in self.state.stationsOnMapDict) :
-            # Station should be added to stationsOnMapDict even if only latest packet is added
-            self.state.stationsOnMapDict[packet.stationId] = True
-
-        # self.state.setCompleteStationLatestTimestamp
-        # Note that we depend on that the real-time aprs-is sender make sure to send previous missing packets when a new is sent
-        if (self.state.isStationHistoryOnMap(packet.stationId)) :
-            self.state.setCompleteStationLatestTimestamp(packet.stationId, packet.timestamp)
-        elif ("latest" not in flags and "realtime" not in flags and "related" not in flags) :
-            self.state.setCompleteStationLatestTimestamp(packet.stationId, packet.timestamp)
-        elif ("related" in flags and packet.packetTailTimestamp == packet.timestamp) :
-            self.state.setCompleteStationLatestTimestamp(packet.stationId, packet.timestamp)
-
-        if (mapSectorList and packet.mapSector is not None and packet.mapSector in mapSectorList) :
-            if "latest" not in flags:
-                self.state.setMapSectorLatestTimeStamp(packet.mapSector, packet.timestamp)
-            else :
-                self.state.setMapSectorLatestOverwriteTimeStamp(packet.mapSector, packet.timestamp)
-
-
-    def _setFlags(self, packetDict, flags) :
-        """Set additional flags that will tell client a bit more about the packet
-
-        Args:
-            packetDict (dict):   The packet to which we should modify
-            flags (array):       An array with additional flags (like "realtime", "latest")
-        """
-        if ("realtime" in flags) :
-            packetDict["db"] = 0
-            packetDict["realtime"] = 1
-        else :
-            packetDict["db"] = 1
-            packetDict["realtime"] = 0
-
-    def _addOverwriteStatus(self, packetDict) :
-        """Set packet overwrite status
-
-        Args:
-            packetDict (dict):                  The packet to which we should modify
-        """
-        packetDict['overwrite'] = 0
-
-        # We assume that this method is called after the "complete station on map"-state has been updated
-        if (not self.state.isStationHistoryOnMap(packetDict["station_id"])) :
-            packetDict['overwrite'] = 1
-
-
-    def _addPacketPhgRng(self, packetDict) :
-        """Add previous reported phg and rng to the specified packet
-
-        Args:
-            packetDict (dict):  The packet to which we should modify
-        """
-        if ('phg' in packetDict and 'rng' in packetDict) :
-            if (packetDict['phg'] is None and packetDict['latest_phg_timestamp'] is not None and packetDict['latest_phg_timestamp'] < packetDict['timestamp']) :
-                relatedPacket = self.packetRepository.getObjectByStationIdAndTimestamp(packetDict['station_id'], packetDict['latest_phg_timestamp'])
-                if (relatedPacket.phg is not None and relatedPacket.markerId == packetDict['marker_id']) :
-                    packetDict['phg'] = relatedPacket.phg
-
-            if (packetDict['rng'] is None and packetDict['latest_rng_timestamp'] is not None and packetDict['latest_rng_timestamp'] < packetDict['timestamp']) :
-                relatedPacket = self.packetRepository.getObjectByStationIdAndTimestamp(packetDict['station_id'], packetDict['latest_rng_timestamp'])
-                if (relatedPacket.rng is not None and relatedPacket.markerId == packetDict['marker_id']) :
-                    packetDict['rng'] = relatedPacket.rng
-
-
-    def _addStationOgnData(self, packetDict) :
-        """Add OGN data to packet
-
-        Args:
-            packetDict (dict):  The packet to which we should add the related data
-        """
-        if ('ogn' not in packetDict or packetDict['ogn'] is None) :
-            station = self.stationRepository.getObjectById(packetDict['station_id'])
-            ts = int(packetDict['timestamp']) - (24*60*60)
-            if (station.latestOgnPacketTimestamp is not None
-                    and station.latestOgnPacketTimestamp > ts) :
-                packetDict['latest_ogn_packet_timestamp'] = station.latestOgnPacketTimestamp
-
-                relatedPacketDict = None
-                if (station.latestOgnPacketId == packetDict['id']) :
-                    relatedPacketDict = packetDict
-                else :
-                    relatedPacket = self.packetRepository.getObjectByIdAndTimestamp(station.latestOgnPacketId, station.latestOgnPacketTimestamp)
-                    if (relatedPacket.isExistingObject()) :
-                        relatedPacketDict = relatedPacket.getDict()
-
-                if (relatedPacketDict is not None) :
-                    if (relatedPacketDict['marker_id'] is not None and relatedPacketDict['marker_id'] == packetDict['marker_id']) :
-                        packetOgn = self.packetOgnRepository.getObjectByPacketIdAndTimestamp(station.latestOgnPacketId, station.latestOgnPacketTimestamp)
-                        if (packetOgn.isExistingObject()) :
-                            packetDict['ogn'] = packetOgn.getDict()
-
-
-    def _addStationOgnDeviceData(self, packetDict) :
-        """Add OGN device data to packet
-
-        Args:
-            packetDict (dict):  The packet to which we should add the related data
-        """
-        station = self.stationRepository.getObjectById(packetDict['station_id'])
-        if (station.latestOgnSenderAddress is not None) :
-            ognDevice = self.ognDeviceRepository.getObjectByDeviceId(station.latestOgnSenderAddress)
-            if (ognDevice.isExistingObject()) :
-                packetDict['ogn_device'] = ognDevice.getDict()
-
-
-    def _addStationWeatherData(self, packetDict) :
-        """Add weather data to packet
-
-        Args:
-            packetDict (dict):  The packet to which we should add the related data
-        """
-        if ('weather' not in packetDict or packetDict['weather'] is None) :
-            station = self.stationRepository.getObjectById(packetDict['station_id'])
-            ts = int(packetDict['timestamp']) - (24*60*60)
-            if (station.latestWeatherPacketTimestamp is not None
-                    and station.latestWeatherPacketTimestamp > ts) :
-                packetDict['latest_weather_packet_timestamp'] = station.latestWeatherPacketTimestamp
-
-                relatedPacketDict = None
-                if (station.latestWeatherPacketId == packetDict['id']) :
-                    relatedPacketDict = packetDict
-                else :
-                    relatedPacket = self.packetRepository.getObjectByIdAndTimestamp(station.latestWeatherPacketId, station.latestWeatherPacketTimestamp)
-                    if (relatedPacket.isExistingObject()) :
-                        relatedPacketDict = relatedPacket.getDict()
-
-                if (relatedPacketDict is not None) :
-                    if (relatedPacketDict['marker_id'] is not None and relatedPacketDict['marker_id'] == packetDict['marker_id']) :
-                        packetWeather = self.packetWeatherRepository.getObjectByPacketIdAndTimestamp(station.latestWeatherPacketId, station.latestWeatherPacketTimestamp)
-                        if (packetWeather.isExistingObject()) :
-                            packetDict['weather'] = packetWeather.getDict()
-
-
-    def _addStationTelemetryData(self, packetDict) :
-        """Add telemetry data to packet
-
-        Args:
-            packetDict (dict):  The packet to which we should add the related data
-        """
-        if ('telemetry' not in packetDict or packetDict['telemetry'] is None) :
-            station = self.stationRepository.getObjectById(packetDict['station_id'])
-            ts = int(packetDict['timestamp']) - (24*60*60)
-            if (station.latestTelemetryPacketTimestamp is not None
-                    and station.latestTelemetryPacketTimestamp > ts) :
-                packetDict['latest_telemetry_packet_timestamp'] = station.latestTelemetryPacketTimestamp
-
-
-    def _addStationIdPath(self, packetDict) :
-        """Add the station id path to the specified packet
-
-        Args:
-            packetDict (dict):  The packet to which we should add the related station id path
-        """
-        stationIdPath = []
-        stationNamePath = []
-        stationLocationPath = []
-
-        if (packetDict['raw_path'] is not None and "TCPIP*" not in packetDict['raw_path'] and "TCPXX*" not in packetDict['raw_path']) :
-            packetDate = datetime.datetime.utcfromtimestamp(int(packetDict['timestamp'])).strftime('%Y%m%d')
-            datePacketTable = 'packet' + packetDate
-            datePacketPathTable = datePacketTable + '_path'
-
-            if (self.dbObjectFinder.checkTableExists(datePacketPathTable)) :
-                selectCursor = self.db.cursor()
-                sql = """select station_id, station.name station_name, latitude, longitude from """ + datePacketPathTable + """, station where station.id = station_id and packet_id = %s order by number""" % (packetDict['id'])
-                selectCursor.execute(sql)
-
-                for record in selectCursor :
-                    stationIdPath.append(record[0])
-                    stationNamePath.append(record[1])
-                    stationLocationPath.append([record[2], record[3]])
-                selectCursor.close()
-        packetDict['station_id_path'] = stationIdPath
-        packetDict['station_name_path'] = stationNamePath
-        packetDict['station_location_path'] = stationLocationPath
-
-
-    def getDictListFromPacketList(self, packets) :
-        """Returns a packet dict list from a packet list
-
-        Args:
-            packets (array):  Array of Packet instances
-
-        Returns:
-            A array och packet dicts
-        """
-        packetDicts = []
-        for packet in packets :
-            packetDicts.append(packet.getDict())
-        return packetDicts
-
-
-    def _extendResponseWithMorePackets(self, packetDicts, flags, iterationCounter) :
-        """Extend the specified array with related packets
-
-        Args:
-            packetDicts (array):     An array of the packet response dicts
-            flags (array):           An array with additional flags (like "realtime", "latest")
-            iterationCounter (int):  This functionality will call itself to find related packets, this argument is used to remember the number of iterations
-
-        Returns:
-            The modified packet array
-        """
-        allPacketDicts = []
-        hasSeveralSendersForOneStation = False
-
-        # Add related packets (stations that the original packets depend on)
-        if (packetDicts) :
-            relatedStationIds = {}
-            for index, packetDict in enumerate(packetDicts) :
-                if (packetDict['is_moving'] == 1 or packetDict['packet_order_id'] == 1) :
-                    # Only fetch related stations for the last stationary packet (in some cases query will return older packets)
-                    if (packetDict['station_id_path']) :
-                        # Also add latest packets from stations that has been involved in sending any packets in array "packets"
-                        for stationId in packetDict['station_id_path'] :
-                            if (stationId not in self.state.stationsOnMapDict) :
-                                relatedStationIds[stationId] = True
-
-            for index, packetDict in enumerate(packetDicts) :
-                if (packetDict['station_id'] in relatedStationIds) :
-                    del relatedStationIds[packetDict['station_id']]
-
-            if (relatedStationIds) :
-                relatedStationPackets = self._getRelatedStationPacketsByStationIds(list(relatedStationIds.keys()))
-
-                # To avoid infinit loop we mark all related stations as added to map even we we failed doing it
-                for relatedStationId in list(relatedStationIds.keys()):
-                    if (relatedStationId not in self.state.stationsOnMapDict) :
-                        self.state.stationsOnMapDict[relatedStationId] = True
-
-                if (relatedStationPackets) :
-                    if ("latest" in flags) :
-                        relatedStationPacketDicts = self.getResponseData(relatedStationPackets, None, ["latest", "related"], iterationCounter + 1)
-                    else :
-                        relatedStationPacketDicts = self.getResponseData(relatedStationPackets, None, ["related"], iterationCounter + 1)
-                    allPacketDicts.extend(relatedStationPacketDicts)
-
-        # Add original packets
-        allPacketDicts.extend(packetDicts)
-
-        #return allPacketDicts.sort(key=lambda x: x['id'], reverse=False)
-        return allPacketDicts
-
-    def _getRelatedStationPacketsByStationIds(self, relatedStationIdList) :
-        """Returns a list of the latest packet for the specified stations, this method should be used to find packets for a packet's related stations
-
-        Args:
-            relatedStationIdList (array):  Array of related station id's
-
-        Returns:
-            An array of the latest packet for the specified stations
-        """
-        if (relatedStationIdList) :
-            query = MostRecentPacketsQuery(self.state, self.db)
-            query.enableSimulateEmptyStation()
-            return query.getPackets(relatedStationIdList)
-        return []
-
diff --git a/server/trackdirect/websocket/responses/__init__.py b/server/trackdirect/websocket/responses/__init__.py
deleted file mode 100644
index 984c177fb076a4043052fbf54a72dea7dbc0a8ba..0000000000000000000000000000000000000000
--- a/server/trackdirect/websocket/responses/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-__version__ = "1.0"
-__author__ = "Per Qvarforth"
diff --git a/trackdirect-python.dockerfile b/trackdirect-python.dockerfile
deleted file mode 100644
index fb1dae36c0fdf20bc30ba5faf580fdea2c7a1cdc..0000000000000000000000000000000000000000
--- a/trackdirect-python.dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-
-FROM ubuntu:20.04
-RUN apt-get update && apt-get install -y \
-  python3 \
-  python3-dev \
-  python3-pip \
-  python-is-python3 \
-  git \
-  && rm -rf /var/lib/apt/lists/*
-
-COPY . /root/trackdirect
-
-RUN pip install -r /root/trackdirect/requirements.txt