Original project changes: GPS: add normalized signal quality level, add web UI live status info
This commit is contained in:
parent
efb2404917
commit
84293ed725
|
@ -191,12 +191,28 @@ void GsmNMEA::IncomingLine(const std::string line)
|
|||
*StdMetrics.ms_v_pos_gpsmode = (std::string) mode;
|
||||
*StdMetrics.ms_v_pos_satcount = (int) satcnt;
|
||||
*StdMetrics.ms_v_pos_gpshdop = (float) hdop;
|
||||
|
||||
// Derive signal quality from lock status, satellite count and HDOP:
|
||||
// quality ~ satcnt / hdop
|
||||
*StdMetrics.ms_v_pos_gpssq = (int) LIMIT_MAX(gpslock * LIMIT_MIN(satcnt-1,0) / LIMIT_MIN(hdop,0.1) * 10, 100);
|
||||
// Quality raises by satellite count and drops by HDOP. HDOP 1.0 = perfect.
|
||||
// The calculation is designed to get 50% as the threshold for a "good" signal.
|
||||
// GPS needs at least 4 satellites in view to get a position, but that will need
|
||||
// HDOP << 1 to be considered reliable. 6 satellites are on the edge to "good"
|
||||
// (with HDOP=1). Samples:
|
||||
// 4 satellites / HDOP 1.0 → SQ 30%
|
||||
// 4 satellites / HDOP 0.6 → SQ 50%
|
||||
// 6 satellites / HDOP 1.0 → SQ 50%
|
||||
// 9 satellites / HDOP 1.0 → SQ 80%
|
||||
// 10 satellites / HDOP 0.9 → SQ 100%
|
||||
// 10 satellites / HDOP 1.8 → SQ 50%
|
||||
|
||||
if (gpslock)
|
||||
{
|
||||
*StdMetrics.ms_v_pos_latitude = (float) lat;
|
||||
*StdMetrics.ms_v_pos_longitude = (float) lon;
|
||||
*StdMetrics.ms_v_pos_altitude = (float) alt;
|
||||
*StdMetrics.ms_v_pos_gpstime = (int) time(NULL);
|
||||
}
|
||||
|
||||
// upodate gpslock last, so listeners will see updated lat/lon values:
|
||||
|
@ -281,6 +297,12 @@ void GsmNMEA::Shutdown(bool hard)
|
|||
{
|
||||
ESP_LOGI(TAG, "Shutdown (direct)");
|
||||
|
||||
*StdMetrics.ms_v_pos_gpsmode = (std::string) "";
|
||||
*StdMetrics.ms_v_pos_gpsspeed = (float) 0;
|
||||
*StdMetrics.ms_v_pos_satcount = (int) 0;
|
||||
*StdMetrics.ms_v_pos_gpshdop = (float) 500;
|
||||
*StdMetrics.ms_v_pos_gpssq = (int) 0;
|
||||
|
||||
if (StdMetrics.ms_v_pos_gpslock->AsBool())
|
||||
{
|
||||
*StdMetrics.ms_v_pos_gpslock = (bool) false;
|
||||
|
|
|
@ -439,7 +439,10 @@ void location_status(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int ar
|
|||
writer->printf("(%sGPS lock", MyLocations.m_gpslock ? "" : "without ");
|
||||
n = StandardMetrics.ms_v_pos_satcount->AsInt();
|
||||
if (n > 0)
|
||||
writer->printf(", %d satellite%s", n, n == 1 ? "" : "s");
|
||||
{
|
||||
writer->printf(", %d satellite%s, %s", n, n == 1 ? "" : "s",
|
||||
MyLocations.m_gpsgood ? "reliable" : "unreliable");
|
||||
}
|
||||
writer->puts(")");
|
||||
|
||||
if ((MyLocations.m_park_latitude != 0) || (MyLocations.m_park_longitude != 0))
|
||||
|
@ -618,6 +621,8 @@ OvmsLocations::OvmsLocations()
|
|||
|
||||
m_ready = false;
|
||||
m_gpslock = false;
|
||||
m_gpssq = 0;
|
||||
m_gpsgood = false;
|
||||
m_latitude = 0;
|
||||
m_longitude = 0;
|
||||
m_park_latitude = 0;
|
||||
|
@ -671,8 +676,8 @@ OvmsLocations::OvmsLocations()
|
|||
using std::placeholders::_1;
|
||||
using std::placeholders::_2;
|
||||
MyMetrics.RegisterListener(TAG, MS_V_POS_GPSLOCK, std::bind(&OvmsLocations::UpdatedGpsLock, this, _1));
|
||||
MyMetrics.RegisterListener(TAG, MS_V_POS_LATITUDE, std::bind(&OvmsLocations::UpdatedLatitude, this, _1));
|
||||
MyMetrics.RegisterListener(TAG, MS_V_POS_LONGITUDE, std::bind(&OvmsLocations::UpdatedLongitude, this, _1));
|
||||
MyMetrics.RegisterListener(TAG, MS_V_POS_GPSSQ, std::bind(&OvmsLocations::UpdatedGpsSQ, this, _1));
|
||||
MyMetrics.RegisterListener(TAG, MS_V_POS_GPSTIME, std::bind(&OvmsLocations::UpdatedPosition, this, _1));
|
||||
MyMetrics.RegisterListener(TAG, MS_V_ENV_ON, std::bind(&OvmsLocations::UpdatedVehicleOn, this, _1));
|
||||
MyEvents.RegisterEvent(TAG,"config.mounted", std::bind(&OvmsLocations::UpdatedConfig, this, _1, _2));
|
||||
MyEvents.RegisterEvent(TAG,"config.changed", std::bind(&OvmsLocations::UpdatedConfig, this, _1, _2));
|
||||
|
@ -696,12 +701,6 @@ void OvmsLocations::UpdatedGpsLock(OvmsMetric* metric)
|
|||
m_gpslock = m->AsBool();
|
||||
if (m_gpslock)
|
||||
{
|
||||
if (!m_ready)
|
||||
{
|
||||
UpdateParkPosition();
|
||||
m_ready = true;
|
||||
}
|
||||
UpdateLocations();
|
||||
MyEvents.SignalEvent("gps.lock.acquired", NULL);
|
||||
}
|
||||
else
|
||||
|
@ -710,22 +709,36 @@ void OvmsLocations::UpdatedGpsLock(OvmsMetric* metric)
|
|||
}
|
||||
}
|
||||
|
||||
void OvmsLocations::UpdatedLatitude(OvmsMetric* metric)
|
||||
void OvmsLocations::UpdatedGpsSQ(OvmsMetric* metric)
|
||||
{
|
||||
OvmsMetricFloat* m = (OvmsMetricFloat*)metric;
|
||||
m_latitude = m->AsFloat();
|
||||
if (m_gpslock)
|
||||
m_gpssq = StdMetrics.ms_v_pos_gpssq->AsInt();
|
||||
int level_good = MyConfig.GetParamValueInt("vehicle", "gps.sq.good", 60);
|
||||
int level_bad = MyConfig.GetParamValueInt("vehicle", "gps.sq.bad", 40);
|
||||
if (level_bad >= level_good) level_bad = level_good - 1;
|
||||
|
||||
if (!m_gpsgood && m_gpssq >= level_good)
|
||||
{
|
||||
m_gpsgood = true;
|
||||
if (!m_ready)
|
||||
{
|
||||
UpdateParkPosition();
|
||||
m_ready = true;
|
||||
}
|
||||
UpdateLocations();
|
||||
CheckTheft();
|
||||
MyEvents.SignalEvent("gps.sq.good", NULL);
|
||||
}
|
||||
else if (m_gpsgood && m_gpssq <= level_bad)
|
||||
{
|
||||
m_gpsgood = false;
|
||||
MyEvents.SignalEvent("gps.sq.bad", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void OvmsLocations::UpdatedLongitude(OvmsMetric* metric)
|
||||
void OvmsLocations::UpdatedPosition(OvmsMetric* metric)
|
||||
{
|
||||
OvmsMetricFloat* m = (OvmsMetricFloat*)metric;
|
||||
m_longitude = m->AsFloat();
|
||||
if (m_gpslock)
|
||||
m_latitude = StdMetrics.ms_v_pos_latitude->AsFloat();
|
||||
m_longitude = StdMetrics.ms_v_pos_longitude->AsFloat();
|
||||
if (m_gpsgood)
|
||||
{
|
||||
UpdateLocations();
|
||||
CheckTheft();
|
||||
|
@ -753,13 +766,13 @@ void OvmsLocations::UpdateParkPosition()
|
|||
{
|
||||
m_park_latitude = m_latitude;
|
||||
m_park_longitude = m_longitude;
|
||||
m_park_invalid = (!m_gpslock || StdMetrics.ms_v_pos_latitude->IsStale() || StdMetrics.ms_v_pos_longitude->IsStale());
|
||||
m_park_invalid = (!m_gpsgood || StdMetrics.ms_v_pos_latitude->IsStale() || StdMetrics.ms_v_pos_longitude->IsStale());
|
||||
m_last_alarm = 0;
|
||||
ESP_LOGI(TAG, "UpdateParkPosition: vehicle is parking @%0.6f,%0.6f gpslock=%d satcount=%d hdop=%.1f invalid=%d",
|
||||
ESP_LOGI(TAG, "UpdateParkPosition: vehicle is parking @%0.6f,%0.6f gpslock=%d satcount=%d hdop=%.1f sq=%d invalid=%d",
|
||||
m_park_latitude, m_park_longitude, m_gpslock,
|
||||
StdMetrics.ms_v_pos_satcount->AsInt(),
|
||||
StdMetrics.ms_v_pos_gpshdop->AsFloat(),
|
||||
m_park_invalid);
|
||||
m_gpssq, m_park_invalid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,7 +826,7 @@ void OvmsLocations::ReloadMap()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_gpslock) UpdateLocations();
|
||||
if (m_gpsgood) UpdateLocations();
|
||||
}
|
||||
|
||||
void OvmsLocations::UpdateLocations()
|
||||
|
|
|
@ -96,6 +96,8 @@ class OvmsLocations
|
|||
public:
|
||||
bool m_ready;
|
||||
bool m_gpslock;
|
||||
int m_gpssq;
|
||||
bool m_gpsgood;
|
||||
float m_latitude;
|
||||
float m_longitude;
|
||||
float m_park_latitude;
|
||||
|
@ -113,8 +115,8 @@ class OvmsLocations
|
|||
|
||||
public:
|
||||
void UpdatedGpsLock(OvmsMetric* metric);
|
||||
void UpdatedLatitude(OvmsMetric* metric);
|
||||
void UpdatedLongitude(OvmsMetric* metric);
|
||||
void UpdatedGpsSQ(OvmsMetric* metric);
|
||||
void UpdatedPosition(OvmsMetric* metric);
|
||||
void UpdatedVehicleOn(OvmsMetric* metric);
|
||||
void UpdatedConfig(std::string event, void* data);
|
||||
};
|
||||
|
|
|
@ -1182,6 +1182,7 @@ void OvmsServerV2::TransmitMsgGPS(bool always)
|
|||
StandardMetrics.ms_v_pos_direction->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_altitude->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_gpslock->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_gpssq->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_gpsmode->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_gpshdop->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
StandardMetrics.ms_v_pos_satcount->IsModifiedAndClear(MyOvmsServerV2Modifier) |
|
||||
|
@ -1198,10 +1199,7 @@ void OvmsServerV2::TransmitMsgGPS(bool always)
|
|||
if ((!always)&&(!modified)) return;
|
||||
|
||||
bool stale =
|
||||
StandardMetrics.ms_v_pos_latitude->IsStale() ||
|
||||
StandardMetrics.ms_v_pos_longitude->IsStale() ||
|
||||
StandardMetrics.ms_v_pos_direction->IsStale() ||
|
||||
StandardMetrics.ms_v_pos_altitude->IsStale();
|
||||
StandardMetrics.ms_v_pos_gpstime->IsStale();
|
||||
|
||||
char drivemode[10];
|
||||
sprintf(drivemode, "%x", StandardMetrics.ms_v_env_drivemode->AsInt());
|
||||
|
@ -1244,6 +1242,8 @@ void OvmsServerV2::TransmitMsgGPS(bool always)
|
|||
<< StandardMetrics.ms_v_pos_gpshdop->AsString("0", Native, 1)
|
||||
<< ","
|
||||
<< StandardMetrics.ms_v_pos_gpsspeed->AsString("0", units_speed, 1)
|
||||
<< ","
|
||||
<< StandardMetrics.ms_v_pos_gpssq->AsInt()
|
||||
;
|
||||
|
||||
Transmit(buffer.str().c_str());
|
||||
|
|
|
@ -101,6 +101,13 @@ void OvmsWebServer::HandleStatus(PageEntry_t& p, PageContext_t& c)
|
|||
"<div class=\"metric number\" data-metric=\"m.net.sq\"><span class=\"value\">?</span><span class=\"unit\">dBm</span></div>"
|
||||
"</td>"
|
||||
"</tr>"
|
||||
"<tr>"
|
||||
"<th>GPS</th>"
|
||||
"<td>"
|
||||
"<div class=\"metric number\" data-metric=\"v.p.satcount\"><span class=\"value\">?</span><span class=\"unit\">Satellites</span></div>"
|
||||
"<div class=\"metric number\" data-metric=\"v.p.gpssq\"><span class=\"value\">?</span><span class=\"unit\">%</span></div>"
|
||||
"</td>"
|
||||
"</tr>"
|
||||
"<tr>"
|
||||
"<th>Main battery</th>"
|
||||
"<td>"
|
||||
|
@ -137,7 +144,7 @@ void OvmsWebServer::HandleStatus(PageEntry_t& p, PageContext_t& c)
|
|||
output = ExecuteCommand("stat");
|
||||
c.printf("<samp class=\"monitor\" id=\"vehicle-status\" data-updcmd=\"stat\" data-events=\"vehicle.charge\">%s</samp>", _html(output));
|
||||
output = ExecuteCommand("location status");
|
||||
c.printf("<samp class=\"monitor\" data-updcmd=\"location status\" data-events=\"gps.lock|location\">%s</samp>", _html(output));
|
||||
c.printf("<samp class=\"monitor\" data-updcmd=\"location status\" data-events=\"gps.lock|gps.sq|location\">%s</samp>", _html(output));
|
||||
c.panel_end(
|
||||
"<ul class=\"list-inline\">"
|
||||
"<li><button type=\"button\" class=\"btn btn-default btn-sm\" data-target=\"#vehicle-cmdres\" data-cmd=\"charge start\">Start charge</button></li>"
|
||||
|
@ -1399,7 +1406,6 @@ void OvmsWebServer::HandleCfgServerV2(PageEntry_t& p, PageContext_t& c)
|
|||
c.input_text("Server", "server", server.c_str(), "Enter host name or IP address",
|
||||
"<p>Public OVMS V2 servers:</p>"
|
||||
"<ul>"
|
||||
"<li><code>ovms-server.bit-cloud.de</code> <a href=\"https://ovms.bit-cloud.de/user/register\" target=\"_blank\">Registration</a></li>"
|
||||
"<li><code>api.openvehicles.com</code> <a href=\"https://www.openvehicles.com/user/register\" target=\"_blank\">Registration</a></li>"
|
||||
"<li><code>ovms.dexters-web.de</code> <a href=\"https://dexters-web.de/?action=NewAccount\" target=\"_blank\">Registration</a></li>"
|
||||
"</ul>");
|
||||
|
@ -2643,7 +2649,6 @@ void OvmsWebServer::HandleCfgFirmware(PageEntry_t& p, PageContext_t& c)
|
|||
"<p>Automatic updates are normally only done if a wifi connection is available at the time. Before allowing updates via modem, be aware a single firmware image has a size of around 3 MB, which may lead to additional costs on your data plan.</p>");
|
||||
c.print(
|
||||
"<datalist id=\"server-list\">"
|
||||
"<option value=\"https://ovms-ota.bit-cloud.de\">"
|
||||
"<option value=\"https://api.openvehicles.com/firmware/ota\">"
|
||||
"<option value=\"https://ovms.dexters-web.de/firmware/ota\">"
|
||||
"</datalist>"
|
||||
|
@ -2654,7 +2659,7 @@ void OvmsWebServer::HandleCfgFirmware(PageEntry_t& p, PageContext_t& c)
|
|||
"</datalist>"
|
||||
);
|
||||
c.input_text("Update server", "server", server.c_str(), "Specify or select from list (clear to see all options)",
|
||||
"<p>Default is <code>https://ovms-ota.bit-cloud.de</code>.</p>",
|
||||
"<p>Default is <code>https://api.openvehicles.com/firmware/ota</code>.</p>",
|
||||
"list=\"server-list\"");
|
||||
c.input_text("Version tag", "tag", tag.c_str(), "Specify or select from list (clear to see all options)",
|
||||
"<p>Default is <code>main</code> for standard releases. Use <code>eap</code> (early access program) for stable or <code>edge</code> for bleeding edge developer builds.</p>",
|
||||
|
|
|
@ -257,6 +257,8 @@ MetricsStandard::MetricsStandard()
|
|||
ms_v_pos_gpsmode = new OvmsMetricString(MS_V_POS_GPSMODE, SM_STALE_MIN);
|
||||
ms_v_pos_gpshdop = new OvmsMetricFloat(MS_V_POS_GPSHDOP, SM_STALE_MIN);
|
||||
ms_v_pos_satcount= new OvmsMetricInt(MS_V_POS_SATCOUNT, SM_STALE_MIN);
|
||||
ms_v_pos_gpssq = new OvmsMetricInt(MS_V_POS_GPSSQ, SM_STALE_MIN, Percentage);
|
||||
ms_v_pos_gpstime = new OvmsMetricInt(MS_V_POS_GPSTIME, SM_STALE_MIN, Seconds);
|
||||
ms_v_pos_latitude = new OvmsMetricFloat(MS_V_POS_LATITUDE, SM_STALE_MIN, Other, true);
|
||||
ms_v_pos_longitude = new OvmsMetricFloat(MS_V_POS_LONGITUDE, SM_STALE_MIN, Other, true);
|
||||
ms_v_pos_location = new OvmsMetricString(MS_V_POS_LOCATION, SM_STALE_MID);
|
||||
|
|
|
@ -230,6 +230,8 @@
|
|||
#define MS_V_POS_GPSMODE "v.p.gpsmode"
|
||||
#define MS_V_POS_GPSHDOP "v.p.gpshdop"
|
||||
#define MS_V_POS_SATCOUNT "v.p.satcount"
|
||||
#define MS_V_POS_GPSSQ "v.p.gpssq"
|
||||
#define MS_V_POS_GPSTIME "v.p.gpstime"
|
||||
#define MS_V_POS_LATITUDE "v.p.latitude"
|
||||
#define MS_V_POS_LONGITUDE "v.p.longitude"
|
||||
#define MS_V_POS_LOCATION "v.p.location"
|
||||
|
@ -491,6 +493,8 @@ class MetricsStandard
|
|||
OvmsMetricString* ms_v_pos_gpsmode; // <GPS><GLONASS>; N/A/D/E (None/Autonomous/Differential/Estimated)
|
||||
OvmsMetricFloat* ms_v_pos_gpshdop; // Horizontal dilution of precision (smaller=better)
|
||||
OvmsMetricInt* ms_v_pos_satcount;
|
||||
OvmsMetricInt* ms_v_pos_gpssq; // GPS signal quality [%] (<30 unusable, >50 good, >80 excellent)
|
||||
OvmsMetricInt* ms_v_pos_gpstime; // Time (UTC) of GPS coordinates [Seconds]
|
||||
OvmsMetricFloat* ms_v_pos_latitude;
|
||||
OvmsMetricFloat* ms_v_pos_longitude;
|
||||
OvmsMetricString* ms_v_pos_location; // Name of current location if defined
|
||||
|
|
Loading…
Reference in a new issue