Skip to content

Commit

Permalink
Move stream name to command line arg
Browse files Browse the repository at this point in the history
  • Loading branch information
anders617 committed Oct 10, 2020
1 parent 467a12a commit 941c554
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,63 @@
# govee

This application uses bluetooth to scan for [Govee H5075](https://www.amazon.com/Govee-Temperature-Humidity-Notification-Monitor/dp/B07Y36FWTT) devices and pushes the data to an AWS Kinesis stream. Works well on a raspberry pi.

The format of the uploaded data is:
```javascript
{
"timestamp": 1594685154057511200, // time since unix epoch in nanoseconds
"temp": 77.8111, // temperature in Fahrenheit
"humidity": 50.6, // relative humidity %
"battery": 100, // battery %
"name": "GVH5075_XXXX" // the id associated with the device the measurement is from
}
```

# Building
[Install AWS](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/setup.html) (For raspberry pi you need to build from source)

Install bluez:
```shell
```bash
sudo apt-get install libbluetooth-dev
```

Run `make` from the govee directory and the executable should end up at `build/apps/govee`

# Installing as a system service
(These instructions are also in `install.sh`)

Change the ExecStart line in `govee.service` to match your AWS kinesis stream name:
```
ExecStart=/bin/govee --streamname=YOUR_STREAM_NAME
```

Copy `govee.service` to `/etc/systemd/system/govee.service`:
```shell
```bash
sudo cp govee.service /etc/systemd/system/govee.service
```

Restart the systemd daemon to load the service file:
```shell
```bash
sudo systemctl daemon-reload
```

Copy the `govee` executable to `/bin/govee`:
```shell
```bash
sudo cp build/apps/govee /bin/govee
```

Enable the service to automatically start at boot:
```shell
```bash
sudo systemctl enable govee.service
```

Or just start/stop the service manually:
```shell
```bash
sudo systemctl start govee.service
sudo systemctl stop govee.service
```

Then to view logs:
```shell
```bash
sudo journalctl -u govee.service
```
2 changes: 1 addition & 1 deletion govee.service
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Description=Govee service
[Service]
Type=simple
User=root
ExecStart=/bin/govee
ExecStart=/bin/govee --streamname=govee-data
Restart=always
RestartSec=5
StartLimitBurst=5
Expand Down
14 changes: 12 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Install aws: https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/setup.html
#!/bin/bash

sudo apt-get install libbluetooth-dev
make

sudo cp govee.service /etc/systemd/system/govee.service

sudo systemctl daemon-reload

sudo cp build/apps/govee /bin/govee

sudo systemctl enable govee.service

sudo systemctl start govee.service
48 changes: 43 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <thread>
#include <map>
#include <unordered_map>
#include <getopt.h>

#include <aws/core/Aws.h>
#include <aws/kinesis/KinesisClient.h>
Expand All @@ -20,6 +21,36 @@
#include "GoveeEventHandler.h"
#include "GoveeData.h"

struct Args {
std::optional<std::string> stream_name;
};

void print_help() {
Log("Usage: govee --streamname govee-data");
}

Args parse_args(int argc, char *argv[]) {
const struct option longopts[] = {
{"help", no_argument, 0, 'h'},
{"streamname", required_argument, 0, 's'},
{0,0,0,0},
};
Args args;
int index;
int iarg=0;
while(iarg != -1) {
switch (iarg = getopt_long(argc, argv, "hs:", longopts, &index)) {
case 'h':
print_help();
break;
case 's':
args.stream_name = std::string(optarg);
break;
}
}
return args;
}

// How often data is retrieved from the sensors
const std::chrono::seconds::rep UPDATE_PERIOD = 60;

Expand All @@ -37,12 +68,12 @@ std::atomic<bool> running = true;

// Uploads data in json format to AWS Kinesis
void put_temperatures(
std::shared_ptr<Aws::Kinesis::KinesisClient> kinesis_client) {
std::shared_ptr<Aws::Kinesis::KinesisClient> kinesis_client, std::string stream_name) {
for (const auto &[addr, data] : govee_data) {
std::string json = to_json(data);
auto result = kinesis_client->PutRecord(
Aws::Kinesis::Model::PutRecordRequest()
.WithStreamName(Aws::String("govee-data"))
.WithStreamName(Aws::String(stream_name))
.WithData(Aws::Utils::ByteBuffer(
reinterpret_cast<unsigned char *>(json.data()), json.length()))
.WithPartitionKey("testing"));
Expand Down Expand Up @@ -101,15 +132,22 @@ void signal_handler(int signal) {
running = false;
}

int main() {
int main(int argc, char *argv[]) {
std::signal(SIGINT, signal_handler);

Args args = parse_args(argc, argv);

if (!args.stream_name) {
print_help();
return 0;
}

// Setup AWS
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info;
Aws::InitAPI(options);
Defer shutdownAws([=] { Aws::ShutdownAPI(options); });
auto kinesis_client = Aws::MakeShared<Aws::Kinesis::KinesisClient>("test");
auto kinesis_client = Aws::MakeShared<Aws::Kinesis::KinesisClient>("KinesisClient");
std::vector<std::thread> awsThreads;

// Govee event parser
Expand All @@ -126,7 +164,7 @@ int main() {
scanner.scan(govee_event_parser, SCAN_DURATION);

// Upload temperatures
awsThreads.emplace_back(put_temperatures, kinesis_client);
awsThreads.emplace_back(put_temperatures, kinesis_client, *args.stream_name);

// Wait until next update
for (int i = 0; i < UPDATE_PERIOD - SCAN_DURATION; i++) {
Expand Down

0 comments on commit 941c554

Please sign in to comment.