aboutsummaryrefslogtreecommitdiff
path: root/apps/sm-get-value.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/sm-get-value.h')
-rw-r--r--apps/sm-get-value.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/apps/sm-get-value.h b/apps/sm-get-value.h
new file mode 100644
index 0000000..e0275c1
--- /dev/null
+++ b/apps/sm-get-value.h
@@ -0,0 +1,153 @@
+#include <iostream>
+#include <iomanip>
+#include <chrono>
+#include <boost/uuid/uuid_io.hpp>
+#include <thread>
+#include "ble/Bluetooth.h"
+#include "SoilMoisture.h"
+#include "trygvis/sensor.h"
+#include "json.hpp"
+#include "apps.h"
+
+// I'm lazy
+using namespace std;
+using namespace std::chrono;
+using namespace trygvis::apps;
+using namespace trygvis::bluetooth;
+using namespace trygvis::sensor;
+using json = nlohmann::json;
+
+bool loop;
+sample_format_type format;
+time_point<system_clock> targetTime;
+unsigned int sleepTime;
+vector<unsigned int> sensors;
+
+void withConnection(BluetoothGatt &gatt) {
+ SoilMoisture soilMoisture = SoilMoisture::create(gatt);
+
+ const int sensorCount = soilMoisture.getSensorCount();
+
+ if (sensorCount == 0) {
+ throw runtime_error("Sensor count is 0");
+ }
+
+ // If the user didn't specify any sensors, add all.
+ if (sensors.size() == 0) {
+ for (int i = 0; i < sensorCount; i++) {
+ sensors.push_back(i);
+ }
+ }
+
+ auto device = gatt.getDevice().getMac();
+
+ targetTime = system_clock::now();
+
+ do {
+ for (auto sensor : sensors) {
+ if (sensor >= sensorCount) {
+ // Ignore invalid sensors
+ continue;
+ }
+
+ auto epoch = system_clock::now().time_since_epoch();
+ auto timestamp = duration_cast<seconds>(epoch).count();
+ uint16_t value = soilMoisture.getValue((uint8_t) sensor);
+
+ if (format == sample_format_type::KEY_VALUE) {
+ cout << "device=" << device.str()
+ << ", sensor=" << to_string(sensor)
+ << ", timestamp=" << to_string(timestamp)
+ << ", value=" << (int) value << endl;
+ } else if (format == sample_format_type::JSON) {
+ json j;
+ j["device"] = device.str();
+ j["sensor"] = sensor;
+ j["timestamp"] = timestamp;
+ j["value"] = value;
+ cout << j << endl;
+ } else if (format == sample_format_type::SQL) {
+ cout << "INSERT INTO soil_moisture_sample(device, sensor, timestamp, value) VALUES("
+ << "'" << device.str() << "', "
+ << sensor << ", "
+ << timestamp << ", "
+ << value << ";" << endl;
+ }
+ }
+
+ targetTime = targetTime + seconds(sleepTime);
+ this_thread::sleep_until(targetTime);
+ } while (loop);
+}
+
+namespace trygvis {
+namespace apps {
+
+class sm_get_value : public app {
+
+public:
+ sm_get_value() : app("sm-get-value") {
+ }
+
+ ~sm_get_value() = default;
+
+ void add_options(po::options_description_easy_init &options) override {
+ auto default_sleep = po::value<>(&sleepTime)->default_value(0);
+
+ options("help", "produce help message")
+ ("device", po::value<string>()->required(), "MAC of device to poll")
+ ("sensor", po::value<vector<unsigned int>>(&sensors)->multitoken(), "Sensor to poll, defaults to all")
+ ("sleep", default_sleep, "How long to sleep in seconds between each poll. If not given, it will exit after first poll")
+ ("format", po::value<sample_format_type>(&format)->default_value(sample_format_type::KEY_VALUE),
+ "Output format");
+ }
+
+ int main(app_execution &execution) override {
+ __attribute__((unused))
+ BluetoothSystem bluetoothSystem;
+
+ auto desc = execution.desc;
+ auto vm = execution.vm;
+
+ try {
+ if (!vm.count("device")) {
+ cerr << "Missing required option: device" << endl;
+ cerr << desc << "\n";
+ return EXIT_FAILURE;
+ }
+
+ auto MAC = vm["device"].as<string>();
+
+ Mac mac = Mac::parseMac(MAC);
+
+ auto &adapter = getAdapter(0);
+
+ auto &device = adapter.getDevice(mac);
+
+ loop = sleepTime > 0;
+
+ do {
+ LOG4CPLUS_INFO(execution.logger, "Connecting to device: " + device.getMac().str());
+
+ auto &gatt = device.connectGatt();
+ try {
+ withConnection(gatt);
+ } catch (runtime_error &e) {
+ cout << "exception: " << e.what() << endl;
+ }
+ gatt.disconnect();
+ } while (loop);
+
+ return EXIT_SUCCESS;
+ } catch (std::runtime_error ex) {
+ cout << "std::runtime_error: " << ex.what() << endl;
+ return EXIT_FAILURE;
+ } catch (std::exception ex) {
+ cout << "std::exception: " << ex.what() << endl;
+ return EXIT_FAILURE;
+ }
+ }
+};
+
+}
+}