Skip to content

Commit ab57629

Browse files
author
William C Bonner
committed
--restart option to attempt to recover when bluetooth stops reporting events #80
1 parent ee32397 commit ab57629

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ endif()
2323
add_compile_definitions(_BLUEZ_HCI_)
2424

2525
project (GoveeBTTempLogger
26-
VERSION 3.20250720.0
26+
VERSION 3.20250818.0
2727
DESCRIPTION "Listen and log Govee Thermometer Bluetooth Low Energy Advertisments via BlueZ and DBus"
2828
HOMEPAGE_URL https://github.com/wcbonner/GoveeBTTempLogger
2929
)

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ ExecStart=/usr/local/bin/goveebttemplogger \
120120
--verbose 0 \
121121
--log /var/log/goveebttemplogger \
122122
--time 60 \
123-
--download 14 \
123+
--download 7 \
124+
--restart 3 \
124125
--svg /var/www/html/goveebttemplogger --battery 8 --minmax 8 \
125126
--cache /var/cache/goveebttemplogger
126127
KillSignal=SIGINT
@@ -172,6 +173,7 @@ sudo apt install bluetooth bluez libbluetooth-dev -y
172173
* -d (--download) Sets the number of days between attempts to connect and download stored data
173174
* -n (--no-bluetooth) Monitor Logging Directory and process logs without Bluetooth Scanning
174175
* -M (--monitor) Monitor Logged Data for updated data
176+
* -R (--restart) Maximum minutes without bluetooth advertisments before attempting to restart
175177
* -H (--HCI) Prefer deprecated BlueZ HCI interface over modern DBus communication
176178
* -p (--passive) Bluetooth LE Passive Scanning
177179

goveebttemplogger.cpp

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ std::filesystem::path SVGIndexFilename;
226226
int LogFileTime(60);
227227
int MinutesAverage(5);
228228
int DaysBetweenDataDownload(0);
229+
int MaxMinutesBetweenBluetoothAdvertisments(0);
229230
// The following details were taken from https://github.com/oetiker/mrtg
230231
const size_t DAY_COUNT(600); /* 400 samples is 33.33 hours */
231232
const size_t WEEK_COUNT(600); /* 400 samples is 8.33 days */
@@ -3615,16 +3616,18 @@ void BlueZ_HCI_MainLoop(std::string& ControllerAddress, std::set<bdaddr_t>& BT_W
36153616
if (bMonitorLoggingDirectory)
36163617
MonitorLoggedData();
36173618
}
3618-
const int MaxMinutesBetweenBluetoothAdvertisments(3);
3619-
if (difftime(TimeNow, TimeAdvertisment) > MaxMinutesBetweenBluetoothAdvertisments * 60) // Hack to force scanning restart regularly
3619+
if (MaxMinutesBetweenBluetoothAdvertisments > 0)
36203620
{
3621-
if (ConsoleVerbosity > 0)
3622-
std::cout << "[" << getTimeISO8601(true) << "] No recent Bluetooth LE Advertisments! (> " << MaxMinutesBetweenBluetoothAdvertisments << " Minutes)" << std::endl;
3623-
btRVal = bt_LEScan(BlueToothDevice_Handle, true, BT_WhiteList, HCI_Passive_Scanning);
3624-
if (btRVal < 0)
3621+
if (difftime(TimeNow, TimeAdvertisment) > MaxMinutesBetweenBluetoothAdvertisments * 60) // Hack to force scanning restart regularly
36253622
{
3626-
bRun = false; // rely on inetd to restart entire process
3627-
ExitValue = EXIT_FAILURE;
3623+
if (ConsoleVerbosity > 0)
3624+
std::cout << "[" << getTimeISO8601(true) << "] No recent Bluetooth LE Advertisments! (> " << MaxMinutesBetweenBluetoothAdvertisments << " Minutes)" << std::endl;
3625+
btRVal = bt_LEScan(BlueToothDevice_Handle, true, BT_WhiteList, HCI_Passive_Scanning);
3626+
if (btRVal < 0)
3627+
{
3628+
bRun = false; // rely on inetd to restart entire process
3629+
ExitValue = EXIT_FAILURE;
3630+
}
36283631
}
36293632
}
36303633
}
@@ -5356,10 +5359,10 @@ time_t ConnectAndDownload(DBusConnection* dbus_conn, const char* adapter_path, c
53565359
return(TimeDownloadStart);
53575360
}
53585361
/////////////////////////////////////////////////////////////////////////////
5359-
int BlueZ_DBus_Mainloop(std::string& ControllerAddress, std::set<bdaddr_t>& BT_WhiteList, bool bMonitorLoggingDirectory)
5362+
int BlueZ_DBus_Mainloop(std::string& ControllerAddress, std::set<bdaddr_t>& BT_WhiteList, int& ExitValue, bool bMonitorLoggingDirectory)
53605363
{
53615364
int rVal(0);
5362-
time_t TimeStart(0), TimeLog(0), TimeSVG(0);
5365+
time_t TimeStart(0), TimeLog(0), TimeSVG(0), TimeAdvertisment(0);
53635366
std::ostringstream ssOutput;
53645367
// Main loop
53655368
bRun = true;
@@ -5474,6 +5477,7 @@ int BlueZ_DBus_Mainloop(std::string& ControllerAddress, std::set<bdaddr_t>& BT_W
54745477
{
54755478
const std::string dbus_msg_Member(dbus_message_get_member(dbus_msg)); // https://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html#gaf5c6b705c53db07a5ae2c6b76f230cf9
54765479
bdaddr_t localBTAddress({ 0 });
5480+
TimeAdvertisment = TimeNow;
54775481
if (!dbus_msg_Member.compare("InterfacesAdded"))
54785482
bluez_dbus_msg_InterfacesAdded(dbus_msg, localBTAddress, BT_WhiteList, TimeNow);
54795483
else if (!dbus_msg_Member.compare("PropertiesChanged"))
@@ -5547,6 +5551,20 @@ int BlueZ_DBus_Mainloop(std::string& ControllerAddress, std::set<bdaddr_t>& BT_W
55475551
for (auto& [UUID, Path] : PathUUID)
55485552
std::cout << "[-------------------] [" << ba2string(btAddress) << "] " << UUID << " " << Path << std::endl;
55495553
}
5554+
if (MaxMinutesBetweenBluetoothAdvertisments > 0)
5555+
{
5556+
if (difftime(TimeNow, TimeAdvertisment) > MaxMinutesBetweenBluetoothAdvertisments * 60) // Hack to force scanning restart regularly
5557+
{
5558+
if (ConsoleVerbosity > 0)
5559+
std::cout << "[" << getTimeISO8601(true) << "] No recent Bluetooth LE Advertisments! (> " << MaxMinutesBetweenBluetoothAdvertisments << " Minutes)" << std::endl;
5560+
//btRVal = bt_LEScan(BlueToothDevice_Handle, true, BT_WhiteList, HCI_Passive_Scanning);
5561+
//if (btRVal < 0)
5562+
//{
5563+
bRun = false; // rely on inetd to restart entire process
5564+
ExitValue = EXIT_FAILURE;
5565+
//}
5566+
}
5567+
}
55505568
#ifdef DEBUG
55515569
} while (bRun && difftime(TimeNow, TimeStart) < 300); // Maintain DBus connection for no more than 5 minutes
55525570
#else
@@ -5619,13 +5637,14 @@ static void usage(int argc, char **argv)
56195637
std::cout << " -d | --download days Periodically attempt to connect and download stored data" << std::endl;
56205638
std::cout << " -n | --no-bluetooth Monitor Logging Directory and process logs without Bluetooth Scanning" << std::endl;
56215639
std::cout << " -M | --monitor Monitor Logging Directory" << std::endl;
5622-
#ifdef _BLUEZ_HCI_
5640+
std::cout << " -r | --restart Maximum minutes between Bluetooth advertisments [" << MaxMinutesBetweenBluetoothAdvertisments << "]" << std::endl;
5641+
#ifdef _BLUEZ_HCI_
56235642
std::cout << " -H | --HCI Prefer deprecated BlueZ HCI interface instead of DBus" << std::endl;
56245643
std::cout << " -p | --passive Bluetooth LE Passive Scanning" << std::endl;
56255644
#endif // _BLUEZ_HCI_
56265645
std::cout << std::endl;
56275646
}
5628-
static const char short_options[] = "hl:t:v:m:o:C:a:f:s:i:T:cb:x:d::pnHM";
5647+
static const char short_options[] = "hl:t:v:m:o:C:a:f:s:i:T:cb:x:d::pnHMR:";
56295648
static const struct option long_options[] = {
56305649
{ "help", no_argument, NULL, 'h' },
56315650
{ "log", required_argument, NULL, 'l' },
@@ -5647,6 +5666,7 @@ static const struct option long_options[] = {
56475666
{ "no-bluetooth",no_argument, NULL, 'n' },
56485667
{ "HCI", no_argument, NULL, 'H' },
56495668
{ "monitor",no_argument, NULL, 'M' },
5669+
{ "restart",required_argument, NULL, 'R' },
56505670
{ 0, 0, 0, 0 }
56515671
};
56525672
/////////////////////////////////////////////////////////////////////////////
@@ -5767,6 +5787,11 @@ int main(int argc, char **argv)
57675787
case 'M':
57685788
bMonitorLoggingDirectory = true;
57695789
break;
5790+
case 'R':
5791+
try { MaxMinutesBetweenBluetoothAdvertisments = std::stoi(optarg); }
5792+
catch (const std::invalid_argument& ia) { std::cerr << "Invalid argument: " << ia.what() << std::endl; exit(EXIT_FAILURE); }
5793+
catch (const std::out_of_range& oor) { std::cerr << "Out of Range error: " << oor.what() << std::endl; exit(EXIT_FAILURE); }
5794+
break;
57705795
default:
57715796
usage(argc, argv);
57725797
exit(EXIT_FAILURE);
@@ -5841,7 +5866,7 @@ int main(int argc, char **argv)
58415866
SignalHandlerPointer previousHandlerSIGHUP = std::signal(SIGHUP, SignalHandlerSIGHUP); // Install Hangup signal handler
58425867
///////////////////////////////////////////////////////////////////////////////////////////////
58435868
if (!bUse_HCI_Interface) // BlueZ over DBus is the recommended method of Bluetooth
5844-
bUse_HCI_Interface = (0 != BlueZ_DBus_Mainloop(ControllerAddress, BT_WhiteList, bMonitorLoggingDirectory));
5869+
bUse_HCI_Interface = (0 != BlueZ_DBus_Mainloop(ControllerAddress, BT_WhiteList, ExitValue, bMonitorLoggingDirectory));
58455870
#ifdef _BLUEZ_HCI_
58465871
if (bUse_HCI_Interface) // The HCI interface for bluetooth is deprecated, with BlueZ over DBus being preferred
58475872
BlueZ_HCI_MainLoop(ControllerAddress, BT_WhiteList, ExitValue, bMonitorLoggingDirectory, bUse_HCI_Passive);

goveebttemplogger.service

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ ExecStart=/usr/local/bin/goveebttemplogger \
2626
--log /var/log/goveebttemplogger \
2727
--time 60 \
2828
--download 7 \
29+
--restart 3 \
2930
--svg /var/www/html/goveebttemplogger --battery 8 --minmax 8 \
3031
--cache /var/cache/goveebttemplogger
3132
KillSignal=SIGINT

0 commit comments

Comments
 (0)