diff options
Diffstat (limited to 'apps/sm-get-value.h')
-rw-r--r-- | apps/sm-get-value.h | 153 |
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; + } + } +}; + +} +} |