Compare commits

...

11 Commits

7 changed files with 80 additions and 4 deletions

View File

@ -10,7 +10,7 @@ TODO
### Database ### Database
**Change name of database and credentials as you like!** **Change name of database and credentials as you like!**
- Create new database: `CREATE DATABASE locationhub;` - Create new database: `CREATE DATABASE dev_locationhub;`
- Create new user for database: `GRANT ALL PRIVILEGES ON dev_locationhub.* TO 'dbuser'@'localhost' IDENTIFIED BY '1234';` - Create new user for database: `GRANT ALL PRIVILEGES ON dev_locationhub.* TO 'dbuser'@'localhost' IDENTIFIED BY '1234';`
- Import tables: `/usr/bin/mariadb -u dbuser -p1234 dev_locationhub < server/sql/tables.sql` - Import tables: `/usr/bin/mariadb -u dbuser -p1234 dev_locationhub < server/sql/tables.sql`

View File

@ -46,6 +46,8 @@ CREATE TABLE IF NOT EXISTS location (
wifi_longitude DOUBLE, wifi_longitude DOUBLE,
gnss_latitude DOUBLE, gnss_latitude DOUBLE,
gnss_longitude DOUBLE, gnss_longitude DOUBLE,
ttn_gw_latitude DOUBLE,
ttn_gw_longitude DOUBLE,
created_at_utc TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at_utc TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at_utc TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, updated_at_utc TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (lp_ttn_end_device_uplinks_id) REFERENCES lp_ttn_end_device_uplinks(lp_ttn_end_device_uplinks_id) FOREIGN KEY (lp_ttn_end_device_uplinks_id) REFERENCES lp_ttn_end_device_uplinks(lp_ttn_end_device_uplinks_id)

View File

@ -28,7 +28,8 @@ router.post(
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
try { try {
const message = req.body as TtnMessage; const message = req.body as TtnMessage;
const { lp_ttn_end_device_uplinks_id } = // Create uplink record
const { lp_ttn_end_device_uplinks_id, latitude, longitude } =
await lpTtnEndDeviceUplinksService.createUplink({ await lpTtnEndDeviceUplinksService.createUplink({
device_id: message.end_device_ids.device_id, device_id: message.end_device_ids.device_id,
application_ids: application_ids:
@ -78,6 +79,7 @@ router.post(
latitude: g.latitude, latitude: g.latitude,
longitude: g.longitude, longitude: g.longitude,
})), })),
gnssLocation: { latitude, longitude }
}; };
domainEventEmitter.emit(TtnMessageReceivedEventName, event); domainEventEmitter.emit(TtnMessageReceivedEventName, event);

View File

@ -11,4 +11,8 @@ export type TtnMessageReceivedEvent = {
longitude: number; longitude: number;
altitude: number; altitude: number;
}[]; }[];
gnssLocation: {
latitude: number | undefined;
longitude: number | undefined;
}
}; };

View File

@ -3,11 +3,69 @@ import {
TtnMessageReceivedEvent, TtnMessageReceivedEvent,
TtnMessageReceivedEventName, TtnMessageReceivedEventName,
} from "../event/ttnMessageReceivedEvent"; } from "../event/ttnMessageReceivedEvent";
import { container } from "tsyringe";
import { LocationService } from "../services/locationService";
const locationService = container.resolve(LocationService);
domainEventEmitter.on( domainEventEmitter.on(
TtnMessageReceivedEventName, TtnMessageReceivedEventName,
async (event: TtnMessageReceivedEvent) => { async (event: TtnMessageReceivedEvent) => {
console.log(event); console.log(event);
// TODO Hendrik 🚀
var wifi_based_latitude: number;
var wifi_based_longitude: number;
var gnss_based_latitude: number | undefined = undefined;
var gnss_based_longitude: number | undefined = undefined;
var ttn_gw_based_latitude: number | undefined = undefined;
var ttn_gw_based_longitude: number | undefined = undefined;
if (!event.ttnGateways || event.ttnGateways.length === 0) {
console.log("No TTN Gateway location received!")
} else {
let totalWeight = 0;
let weightedLatitude = 0;
let weightedLongitude = 0;
event.ttnGateways.forEach(gw => {
const weight = 1 / Math.abs(gw.rssi); // Higher RSSI (closer to 0) gives more weight
totalWeight += weight;
weightedLatitude += gw.latitude * weight;
weightedLongitude += gw.longitude * weight;
});
// Calculate the weighted average to get the virtual location
const virtualLocation = {
latitude: weightedLatitude / totalWeight,
longitude: weightedLongitude / totalWeight
};
console.log("Tracker location based on TTN Gateway location:", virtualLocation);
ttn_gw_based_latitude = virtualLocation.latitude;
ttn_gw_based_longitude = virtualLocation.longitude;
}
{
// TODO: parse Wifi location here
}
if ((event.gnssLocation.latitude) && (event.gnssLocation.longitude)) {
gnss_based_latitude = event.gnssLocation.latitude;
gnss_based_longitude = event.gnssLocation.longitude;
} else {
console.log("No GNSS location received!")
}
const newLocation = await locationService.createLocation({
lp_ttn_end_device_uplinks_id: event.lp_ttn_end_device_uplinks_id,
ttn_gw_latitude: ttn_gw_based_latitude,
ttn_gw_longitude: ttn_gw_based_longitude,
gnss_latitude: gnss_based_latitude,
gnss_longitude: gnss_based_longitude,
});
console.log(newLocation)
} }
); );

View File

@ -25,5 +25,5 @@ app.use("/api/locations", locationRoutes);
app.use("/api/ttn", ttnRoutes); app.use("/api/ttn", ttnRoutes);
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`🚀 Server läuft auf http://localhost:${PORT}`); console.log(`🚀 Server runs here: http://localhost:${PORT}`);
}); });

View File

@ -8,6 +8,8 @@ export class Location extends Model {
public wifi_longitude!: number; public wifi_longitude!: number;
public gnss_latitude!: number; public gnss_latitude!: number;
public gnss_longitude!: number; public gnss_longitude!: number;
public ttn_gw_latitude!: number;
public ttn_gw_longitude!: number;
public created_at_utc!: Date; public created_at_utc!: Date;
public updated_at_utc!: Date; public updated_at_utc!: Date;
} }
@ -40,6 +42,14 @@ Location.init(
type: DataTypes.NUMBER, type: DataTypes.NUMBER,
allowNull: true, allowNull: true,
}, },
ttn_gw_latitude: {
type: DataTypes.NUMBER,
allowNull: true,
},
ttn_gw__longitude: {
type: DataTypes.NUMBER,
allowNull: true,
},
created_at_utc: { created_at_utc: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: DataTypes.NOW, defaultValue: DataTypes.NOW,