Initial commit

Added basic functionality
This commit is contained in:
Tim Staat 2025-08-27 18:52:12 +02:00
commit 99e0c88e1d
5 changed files with 896 additions and 0 deletions

View File

@ -0,0 +1,197 @@
#include <U8g2lib.h>
#include <TinyGPSMinus.h>
#include <Wire.h>
#include <QMC5883LCompass.h>
#include "wifi_save.h"
#include <HTTPClient.h>
#include <Arduino_JSON.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // if you use Hardware I2C port, full framebuffer, size = 1024 bytes
QMC5883LCompass compass;
#define RXD2 16
#define TXD2 17
// ID 1 = Julia; ID 2 = Tim
#define OWN_ID 1
#define REQ_ID 2
#define GPS_BAUD 9600
String webserviceAddress = "http://192.168.179.2:65133/updateGPS";
bool connected = false;
HardwareSerial gpsSerial(2);
TinyGPSMinus gps;
byte triangles[][6] = {
{ 10, 48, 30, 48, 20, 16 },
{ 5, 43, 23, 51, 26, 17 },
{ 2, 36, 16, 50, 31, 21 },
{ 1, 29, 9, 47, 35, 26 },
{ 4, 22, 4, 42, 36, 32 },
{ 9, 17, 1, 35, 35, 38 },
{ 16, 14, 2, 28, 31, 43 },
{ 23, 13, 5, 21, 26, 47 },
{ 30, 16, 10, 16, 20, 48 },
{ 35, 21, 17, 13, 14, 47 },
{ 38, 28, 24, 14, 9, 43 },
{ 39, 35, 31, 17, 5, 38 },
{ 36, 42, 36, 22, 4, 32 },
{ 31, 47, 39, 29, 5, 26 },
{ 24, 50, 38, 36, 9, 21 },
{ 17, 51, 35, 43, 14, 17 },
{ 10, 48, 30, 48, 20, 16 }
};
void setup(void) {
Serial.begin(115200);
if (wifi_set_main())
{
Serial.println("Connect WIFI SUCCESS");
connected = true;
}
else
{
Serial.println("Connect WIFI FAULT");
}
compass.init();
u8g2.begin(); // start a display.
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void drawTriangles(byte i, char* time, char* distanceString) {
u8g2.clearBuffer();
u8g2.drawTriangle(triangles[i][0], triangles[i][1], triangles[i][2], triangles[i][3], triangles[i][4], triangles[i][5]);
u8g2.sendBuffer();
u8g2.setFont(u8g2_font_helvR08_tr);
u8g2.drawButtonUTF8(48, 64-40, U8G2_BTN_BW0, 0, 0, 0, "Last Update:");
u8g2.drawButtonUTF8(48, 64-30, U8G2_BTN_BW0, 0, 0, 0, time);
u8g2.drawButtonUTF8(48, 64-16, U8G2_BTN_BW0, 0, 0, 0, distanceString);
u8g2.sendBuffer();
delay(2000);
}
bool doHttpRequest(const char* payload, char* latitude, char* longitude, char* gpsTime) {
HTTPClient http;
// Change space to 0
*(latitude + 6) = 0;
String serverPath = webserviceAddress + "?long=" + *longitude + "&lat=" + *latitude + "&id=" + OWN_ID + "&req_id=" + REQ_ID + "&gpsDateTime=" + *gpsTime;
Serial.println(serverPath);
// Your Domain name with URL path or IP address with path
http.begin(serverPath.c_str());
// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString().c_str();
Serial.println(payload);
return true;
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
return false;
}
}
byte calculateBearing(float bearing) {
int relativeAngle = (int)(bearing - (360 - compass.getAzimuth()));
relativeAngle += 360;
relativeAngle %= 360;
return compass.getBearing(relativeAngle);
}
void setDistanceBearingString(char *distance, byte *bearing, const char *payload) {
JSONVar jsonPayload = JSON.parse(payload);
*distance = jsonPayload["dist"];
*bearing = calculateBearing(String(jsonPayload["bearing"]).toFloat());
}
void loop(void) {
while (gpsSerial.available() > 0){
// get the byte data from the GPS
char gpsData = gpsSerial.read();
if (gps.encode(gpsData)) {
Serial.print(gpsData);
break;
}
}
long unsigned date, time, age;
char *longitude, *latitude, *dateTime;
longitude = gps.get_longitude();
latitude = gps.get_latitude();
gps.get_datetime(&date, &time, &age);
Serial.println(latitude);
Serial.println(longitude);
const char *myPayloadResponse;
char timeString[10], dateString[8], dateTimeString[18];
ltoa(time, timeString, 10);
ltoa(date, dateString, 8);
for (int i = 0; i < 18 ;i++){
if(i < 8)
dateTimeString[i] = dateString[i];
else
dateTimeString[i] = timeString[i-8];
}
byte triangleIndex = 0;
char distanceArray[] = { 'N', 'o', ' ', 'S', 'e', 'r', 'v', 'e', 'r', '\0'};
char *distanceString = &(distanceArray[0]);
if(doHttpRequest(myPayloadResponse, latitude, longitude, dateTimeString))
setDistanceBearingString(distanceString, &triangleIndex, myPayloadResponse);
Serial.println();
Serial.println("Time: ");
Serial.println(time);
Serial.println("Date: ");
Serial.println(date);
drawTriangles(triangleIndex, timeString, distanceString);
Serial.println("-------------------------------");
int a;
compass.read();
//Calculate heading
a = compass.getAzimuth();
float heading = compass.getBearing(a);
char myArray[3];
compass.getDirection(myArray, a);
Serial.print("A: ");
Serial.print(a);
Serial.print("Heading: ");
Serial.print(heading);
Serial.print(" - ");
Serial.print(myArray);
Serial.println();
Serial.println("-------------------------------");
delay(1000);
}

View File

@ -0,0 +1,495 @@
#include "wifi_save.h"
WiFiServer server(80);
int client_count = 0;
int record_rst_time()
{
int rst_time = 0;
// 初始化NVS并检查初始化情况
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
// 如果NVS分区被占用则对其进行擦除
// 并再次初始化
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
// Open 打开NVS文件
printf("\n");
printf("Opening Non-Volatile Storage (NVS) handle... ");
nvs_handle my_handle; // 定义不透明句柄
err = nvs_open("storage", NVS_READWRITE, &my_handle); // 打开文件
if (err != ESP_OK)
{
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
}
else
{
printf("Done\n");
// Read
printf("Reading restart counter from NVS ... ");
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);
switch (err)
{
case ESP_OK:
printf("Done\n");
printf("Restart counter = %d\n", restart_counter);
rst_time = restart_counter;
break;
case ESP_ERR_NVS_NOT_FOUND:
printf("The value is not initialized yet!\n");
break;
default:
printf("Error (%s) reading!\n", esp_err_to_name(err));
}
// Write
printf("Updating restart counter in NVS ... ");
restart_counter++;
err = nvs_set_i32(my_handle, "restart_counter", restart_counter);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Commit written value.
// After setting any values, nvs_commit() must be called to ensure changes are written
// to flash storage. Implementations may write to storage at other times,
// but this is not guaranteed.
printf("Committing updates in NVS ... ");
err = nvs_commit(my_handle);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Close
nvs_close(my_handle);
}
printf("\n");
return rst_time;
}
void record_wifi(char *ssid, char *password)
{
// 初始化NVS并检查初始化情况
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
// 如果NVS分区被占用则对其进行擦除
// 并再次初始化
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
// Open 打开NVS文件
printf("\n");
printf("Opening Non-Volatile Wifi (NVS) handle... ");
nvs_handle my_handle; // 定义不透明句柄
err = nvs_open("Wifi", NVS_READWRITE, &my_handle); // 打开文件
if (err != ESP_OK)
{
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
}
else
{
printf("Done\n");
// Write
printf("Updating ssid in NVS ... ");
err = nvs_set_str(my_handle, "ssid", ssid);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
printf("Updating password in NVS ... ");
err = nvs_set_str(my_handle, "password", password);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Commit written value.
// After setting any values, nvs_commit() must be called to ensure changes are written
// to flash storage. Implementations may write to storage at other times,
// but this is not guaranteed.
printf("Committing updates in NVS ... ");
err = nvs_commit(my_handle);
printf((err != ESP_OK) ? "Failed!\n" : "Done\n");
// Close
nvs_close(my_handle);
}
printf("\n");
}
//检测ssid名称
void check_wifi(char *ssid, char *password)
{
char saved_ssid[SSID_LENGTH];
size_t ssid_length = SSID_LENGTH;
char saved_password[SSID_LENGTH];
size_t password_length = SSID_LENGTH;
// 初始化NVS并检查初始化情况
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
// 如果NVS分区被占用则对其进行擦除
// 并再次初始化
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
// Open 打开NVS文件
printf("\n");
printf("Opening Non-Volatile Wifi (NVS) handle... \n");
nvs_handle my_handle; // 定义不透明句柄
err = nvs_open("Wifi", NVS_READWRITE, &my_handle); // 打开文件
if (err != ESP_OK)
{
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
}
else
{
printf("Done\n");
// Read
printf("Reading ssid and password from NVS ... \n");
err = nvs_get_str(my_handle, "ssid", saved_ssid, &ssid_length);
switch (err)
{
case ESP_OK:
printf("Done\n");
printf("ssid: %s\n", saved_ssid);
printf("ssid length= %d\n", ssid_length);
strcpy(ssid, saved_ssid);
break;
case ESP_ERR_NVS_NOT_FOUND:
printf("The value is not initialized yet!\n");
break;
default:
printf("Error (%s) reading!\n", esp_err_to_name(err));
}
err = nvs_get_str(my_handle, "password", saved_password, &password_length);
switch (err)
{
case ESP_OK:
printf("Done\n");
printf("password: %s\n", saved_password);
printf("password length= %d\n", password_length);
strcpy(password, saved_password);
break;
case ESP_ERR_NVS_NOT_FOUND:
printf("The value is not initialized yet!\n");
break;
default:
printf("Error (%s) reading!\n", esp_err_to_name(err));
}
// Close
nvs_close(my_handle);
}
printf("\n");
return;
}
void ap_init()
{
//WiFi.softAP(ssid, password);
WiFi.softAP("Makerfabs_ap");
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
}
int wifi_config_server()
{
WiFiClient client = server.available(); // listen for incoming clients
if (client) // if you get a client,
{
Serial.println("---------------------------------------------------");
Serial.printf("Index:%d\n", client_count);
client_count++;
Serial.println("New Client."); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected())
{ // loop while the client's connected
if (client.available())
{ // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
if (c == '\n')
{ // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0)
{
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// the content of the HTTP response follows the header:
client.print("<h1>Makerfabs</h1><br><h2>ESP32 WIFI CONFIG</h2><br>");
client.print("Click <a href=\"/wifi_set\">here</a> to set WIFI.<br>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
else
{ // if you got a newline, then clear currentLine:
currentLine = "";
}
}
else if (c != '\r')
{ // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
//show wifiset page
if (currentLine.endsWith("GET /wifi_set"))
{
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print("<h1>Makerfabs</h1><br><h2>ESP32 WIFI CONFIG</h2><br>");
client.print("<form action=\"/set_over\">SSID:<br><input type=\"text\" name=\"ssid\"><br>PASSWORD:<br><input type=\"text\" name=\"password\"><br><br>");
client.print("<input type=\"submit\" value=\"Set\"></form>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
if (currentLine.endsWith("GET /set_over"))
{
String get_request = "";
//read GET next line
while (1)
{
char c_get = client.read();
Serial.write(c_get);
if (c_get == '\n')
{
break;
}
else
{
get_request += c_get;
}
}
//set_wifi_from_url(server.uri());
set_wifi_from_url(get_request);
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print("<h1>Makerfabs</h1><br><h2>ESP32 WIFI CONFIG</h2><br>");
client.print("Set Successful<br>");
client.println();
client.stop();
Serial.println("Client Disconnected.");
return 0;
}
}
}
// close the connection:
client.stop();
Serial.println("Client Disconnected.");
}
return 1;
}
void set_wifi_from_url(String get_url)
{
//get_url = "http://192.168.4.1/set_over?ssid=Makerfabs&password=20160704"
int str_len = 0;
int ssid_add = 0;
int pwd_add = 0;
int end_add = 0;
String ssid = "";
String pwd = "";
str_len = get_url.length();
ssid_add = get_url.indexOf('?');
pwd_add = get_url.indexOf('&');
end_add = get_url.indexOf(' ');
ssid = get_url.substring(ssid_add + 6, pwd_add);
pwd = get_url.substring(pwd_add + 10, end_add);
Serial.println();
Serial.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
Serial.println("Get ssid and password from url:");
Serial.println(get_url);
Serial.println(ssid);
Serial.println(pwd);
Serial.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
record_wifi((char *)ssid.c_str(), (char *)pwd.c_str());
}
// int wifi_set_main()
// {
// char ssid[SSID_LENGTH];
// char password[SSID_LENGTH];
// pinMode(WIFI_SET_PIN, INPUT_PULLUP);
// check_wifi(ssid, password);
// if (strcmp(ssid, "NULL") == 0 )
// {
// //检查SSID是否为NULL
// Serial.println("Check SSID is NULL,please connect \"Makerfabs_ap\".");
// Serial.println("And visit 192.168.4.1 to set WIFI.");
// ap_init();
// while (wifi_config_server())
// ;
// //设置完成后休眠3秒重启
// delay(3000);
// esp_restart();
// }
// else
// {
// //3秒内拉低WIFI_SET_PIN则恢复出场设置并重启
// Serial.println("Check WIFI_SET_PIN");
// int runtime = millis();
// int starttime = runtime;
// while ((runtime - starttime) < 3000)
// {
// if (digitalRead(WIFI_SET_PIN) == LOW)
// {
// Serial.println("Init WIFI to default \"NULL\"");
// record_wifi("NULL", "NULL0000");
// delay(1000);
// esp_restart();
// }
// Serial.print(".");
// delay(100);
// runtime = millis();
// }
// Serial.println();
// //Connect wifi
// Serial.println("Connecting WIFI");
// WiFi.begin(ssid, password);
// int connect_count = 0;
// //10S未连接上自动跳过并返回0
// while (WiFi.status() != WL_CONNECTED)
// {
// delay(500);
// Serial.print(".");
// connect_count++;
// if(connect_count > 10)
// return 0;
// }
// // 成功连接上WIFI则输出IP并返回1
// Serial.println("");
// Serial.println("WiFi connected");
// Serial.println("IP address: ");
// Serial.println(WiFi.localIP());
// return 1;
// }
// }
int wifi_set_main()
{
char ssid[SSID_LENGTH];
char password[SSID_LENGTH];
pinMode(WIFI_SET_PIN, INPUT_PULLUP);
check_wifi(ssid, password);
//3秒内拉低WIFI_SET_PIN则恢复出场设置并重启
Serial.println("Check WIFI_SET_PIN");
int runtime = millis();
int starttime = runtime;
while ((runtime - starttime) < 3000)
{
if (digitalRead(WIFI_SET_PIN) == LOW)
{
Serial.println("Please connect \"Makerfabs_ap\".");
Serial.println("And visit 192.168.4.1 to set WIFI.");
ap_init();
while (wifi_config_server())
;
delay(3000);
esp_restart();
return 0;
}
Serial.print(".");
delay(100);
runtime = millis();
}
Serial.println();
//Connect wifi
Serial.println("Connecting WIFI");
WiFi.begin(ssid, password);
int connect_count = 0;
//10S未连接上自动跳过并返回0
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
connect_count++;
if (connect_count > 10)
return 0;
}
// 成功连接上WIFI则输出IP并返回1
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
return 1;
}
void nvs_test()
{
char ssid[SSID_LENGTH] = "";
char password[SSID_LENGTH] = "";
int rst_time = 0;
check_wifi(ssid, password);
rst_time = record_rst_time();
sprintf(ssid, "ssid_%d", rst_time);
sprintf(password, "password_%d", rst_time);
record_wifi(ssid, password);
// Restart module
for (int i = 10; i >= 0; i--)
{
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}

View File

@ -0,0 +1,47 @@
/*
Author : Vincent
Create : 2021/2/5
if ESP32开机检测SSID == NULL
ESP32通过AP模式访192.168.4.1SSID和PASSWORD
NVS存储到FLASH中
else
FLASH的SSID和PASSWORD连接wifi
while &&
NVS设置为NULL
()
*/
#include <Arduino.h>
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#define SSID_LENGTH 40
#define WIFI_SET_PIN 27
int record_rst_time();
void nvs_test();
void record_wifi(char *ssid, char *password);
void check_wifi(char *ssid, char *password);
void ap_init();
int wifi_config_server();
void set_wifi_from_url(String get_url);
int wifi_set_main();

69
festival_finder.ino Normal file
View File

@ -0,0 +1,69 @@
#include <U8g2lib.h>
#define SDA_1 15
#define SCL_1 16
#define SDA_2 17
#define SCL_2 18
U8G2_SSD1315_128X64_NONAME_1_HW_I2C(U8G2_R1)
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
#define GPS_BAUD 9600
#define RXD2 16
#define TXD2 17
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
void setup() {
u8g2.begin();
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
}
void loop() {
// put your main code here, to run repeatedly:
sensors_event_t event;
mag.getEvent(&event);
while (gpsSerial.available() > 0){
// get the byte data from the GPS
char gpsData = gpsSerial.read();
Serial.print(gpsData);
}
delay(1000);
Serial.println("-------------------------------");
/* Display some basic information on this sensor */
displaySensorDetails();
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
float heading = atan2(event.magnetic.y, event.magnetic.x);
// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 0.22;
heading += declinationAngle;
// Correct for when signs are reversed.
if(heading < 0)
heading += 2*PI;
// Check for wrap due to addition of declination.
if(heading > 2*PI)
heading -= 2*PI;
// Convert radians to degrees for readability.
float headingDegrees = heading * 180/M_PI;
}

88
server/python_server.py Normal file
View File

@ -0,0 +1,88 @@
from flask import Flask, request, jsonify
from datetime import datetime
import pint
import sqlite3
from pyproj import Geod
app = Flask(__name__)
with sqlite3.connect('location.db', check_same_thread=False) as conn:
cur = conn.cursor()
cur.execute("""CREATE TABLE IF NOT EXISTS location_data (
row_id INTEGER PRIMARY KEY,
sender_id INTEGER,
lat REAL,
long REAL,
gpsDateTime INTEGER,
insertDateTime TEXT DEFUALT CURRENT_TIMESTAMP
);"""
)
ureg = pint.UnitRegistry()
geodesic = Geod(ellps='WGS84')
@app.route('/')
def hello():
return 'Hello!'
@app.route('/updateGPS')
def getGpsDistance():
own_id = request.args.get('id')
req_id = request.args.get('req_id')
lat = dm(request.args.get('lat'))
long = dm(request.args.get('long'))
try:
gpsDateTime = datetime.strptime(request.args.get('gpsDateTime')[:11], '%d%m%y%H%M%S')
except ValueError:
print("No gpsDateTime")
gpsDateTime = datetime.now()
print(request.args)
with sqlite3.connect('location.db', check_same_thread=False) as conn:
cur = conn.cursor()
cur.execute(f'INSERT INTO location_data(sender_id, lat, long, gpsDateTime) VALUES({own_id}, {lat}, {long}, "{gpsDateTime}");')
conn.commit()
try:
res = cur.execute(f'SELECT lat, long, gpsDateTime, insertDateTime FROM location_data WHERE sender_id = {req_id} ORDER BY insertDateTime DESC')
req_lat, req_long, req_dateTime, insertDateTime = res.fetchone()
except sqlite3.Error as error:
print("Failed to read data from table, using default values", error)
req_lat = 0.0
req_long = 0.0
req_dateTime = datetime.now()
print(f'lat: {lat}, long: {long}, req_lat: {req_lat}, req_long: {req_long}, req_dateTime: {req_dateTime}')
fwd_azimuth, back_azimuth, distance = geodesic.inv(long, lat, req_long, req_lat)
distance = distance * ureg.meter
prettyDistance = f"{distance:.1f~#P}"
print(f'fwd: {fwd_azimuth}, bwd: {back_azimuth}, dist: {prettyDistance}')
return jsonify({'distance': prettyDistance, 'azimuth': fwd_azimuth})
def dm(ddmm: str):
south = False
south = 'S' in str(ddmm) or 'W' in str(ddmm)
ddmm = float(str(ddmm)[:-1])
degrees = int(ddmm) // 100
minutes = ddmm - 100*degrees
x = degrees + minutes/60
if south:
x = -x
return x