Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3 from myoung34/influxdb
Browse files Browse the repository at this point in the history
Add support for InfluxDB emitter
  • Loading branch information
myoung34 authored Feb 14, 2020
2 parents 4d369a9 + 833ec42 commit 7db786b
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 28 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@ This will capture those whenever theyre transmitted and emit them to a backend o
The Tilt supports writing to a google doc which you could use with something like IFTTT or Zapier, but this is much lighter and lets you decide how you want to push that out with a pluggable backend system.


## TODO ##
## Supported Emitters ##

Right now all it does is log to STDOUT.
As it progresses it will have pluggablel emitters such as:

* InfluxDb
* Webhooks
* SNS

etc
* Webhooks
* InfluxDB


## Usage ##
Expand All @@ -38,6 +33,13 @@ sleep_interval = 10
url = http://www.foo.com
payload_template = {"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}
method = GET
[influxdb]
url = influxdb.corp.com
port = 80
database = tilty
gravity_payload_template = {"measurement": "gravity", "tags": {"color": "{{ color }}"}, "fields": {"value": {{ gravity }}}}
temperature_payload_template = {"measurement": "temperature", "tags": {"color": "{{ color }}"}, "fields": {"value": {{ temp }}}}
EOF
$ tilty
```
Expand Down
52 changes: 50 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ click = "^7.0"
pybluez = "^0.22.0"
requests = "^2.22"
jinja2 = "^2.11.1"
influxdb = "^5.2.3"

[tool.poetry.dev-dependencies]
flake8 = "^3.7"
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ filelock==3.0.12
flake8==3.7.9
idna==2.8
importlib-metadata==1.3.0
influxdb==5.2.3
isort==4.3.21
Jinja2==2.11.1
lazy-object-proxy==1.4.3
Expand All @@ -25,6 +26,8 @@ pylint==2.4.4
pyparsing==2.4.5
pytest==5.3.2
pytest-cov==2.8.1
python-dateutil==2.8.1
pytz==2019.3
requests==2.22.0
six==1.13.0
toml==0.10.0
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
packages=find_packages(exclude=['tests*']),
install_requires=[
'Click',
'influxdb',
'Jinja2',
'pybluez',
'requests',
Expand Down
29 changes: 19 additions & 10 deletions tests/mock_config_parser.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# -*- coding: utf-8 -*-
class MockConfigParser:
def __init__(self):
pass
def __init__(self, section):
self.section = section

def __getitem__(self, key):
return {
'url': 'http://www.google.com',
'headers': {'Content-Type': 'application/json'},
'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}',
'method': 'GET'
}
if self.section == 'webhook':
return {
'url': 'http://www.google.com',
'headers': {'Content-Type': 'application/json'},
'payload_template': '{"color": "{{ color }}", "gravity": {{ gravity }}, "temp": {{ temp }}, "timestamp": "{{ timestamp }}"}', # noqa
'method': 'GET'
}
if self.section == 'influxdb':
return {
'url': 'http://www.google.com',
'database': 'foo',
'gravity_payload_template': 'gravity,color={{ color }} value={{ gravity }} {{timestamp}}', # noqa
'temperature_payload_template': 'temperature,scale=fahrenheit,color={{ color }} value={{ temp }} {{timestamp}}', # noqa
}
return None

def has_section(*args, **kwargs):
return True
def has_section(self, *args, **kwargs):
return self.section in args
14 changes: 14 additions & 0 deletions tests/test_common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from tilty import common


def test_safe_get_key_no_fallback():
assert common.safe_get_key({}, 'foo') is None


def test_safe_get_key_fallback():
assert common.safe_get_key({}, 'foo', 'wut') == 'wut'


def test_safe_get_key_valid():
assert common.safe_get_key({'foo': 'asdf'}, 'foo', 'wut') == 'asdf'
40 changes: 40 additions & 0 deletions tests/test_influxdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from unittest import mock

from tilty.emitters import influxdb


@mock.patch('tilty.emitters.influxdb.InfluxDBClient')
def test_influxdb(
mock_influx_client,
):
config = {
'url': 'http://www.google.com',
'database': 'foo',
'gravity_payload': '{"measurement": "gravity", "tags": {"color": "Black"}, "fields": {"value": 1.054}}', # noqa
'temperature_payload': '{"measurement": "temperature", "tags": {"color": "Black", "scale": "fahrenheight"}, "fields": {"value": 32}}', # noqa
}
influxdb.InfluxDB(config=config).emit()
assert mock_influx_client.mock_calls == [
mock.call(
'http://www.google.com',
80,
None,
None,
'foo'
),
mock.call().write_points([
{
'measurement': 'temperature',
'tags': {'color': 'Black', 'scale': 'fahrenheight'},
'fields': {'value': 32}
}
]),
mock.call().write_points([
{
'measurement': 'gravity',
'tags': {'color': 'Black'},
'fields': {'value': 1.054}
}
])
]
31 changes: 26 additions & 5 deletions tests/test_tilty.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from unittest import mock

from tilty import tilt_device, tilty
from mock_config_parser import MockConfigParser
from tilty import tilt_device, tilty


@mock.patch('tilty.blescan.parse_events', return_value=[{'uuid': 'foo', 'major': 2, 'minor': 1}]) # noqa
Expand All @@ -13,12 +13,11 @@ def test_scan_for_tilt_data(
t.scan_for_tilt_data()



@mock.patch('tilty.emitters.webhook.Webhook')
def test_scan_for_tilt_data(
def test_scan_for_tilt_data_parse_webhook(
mock_webhook,
):
config = MockConfigParser()
config = MockConfigParser('webhook')
tilty.emit(
config,
{'color': 'black', 'gravity': 1, 'temp': 32, 'timestamp': 155558888}
Expand All @@ -29,7 +28,29 @@ def test_scan_for_tilt_data(
'url': 'http://www.google.com',
'headers': {'Content-Type': 'application/json'},
'method': 'GET',
'payload': {'color': 'black', 'gravity': 1, 'temp': 32, 'timestamp': '155558888'}
'payload': {'color': 'black', 'gravity': 1, 'temp': 32, 'timestamp': '155558888'} # noqa
}
),
mock.call().emit()
]


@mock.patch('tilty.emitters.influxdb.InfluxDB')
def test_scan_for_tilt_data_parse_influxdb(
mock_influxdb,
):
config = MockConfigParser('influxdb')
tilty.emit(
config,
{'color': 'black', 'gravity': 1, 'temp': 32, 'timestamp': 155558888}
)
assert mock_influxdb.mock_calls == [
mock.call(
config={
'url': 'http://www.google.com',
'database': 'foo',
'temperature_payload': 'temperature,scale=fahrenheit,color=black value=32 155558888', # noqa
'gravity_payload': 'gravity,color=black value=1 155558888'
}
),
mock.call().emit()
Expand Down
45 changes: 44 additions & 1 deletion tests/test_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def test_webhook_get(
config = {
'url': 'http://www.google.com',
'headers': {'Content-Type': 'application/json'},
'payload': {'b': 'b1'}, 'method': 'GET'
'payload': {'b': 'b1'},
'method': 'GET',
}
webhook.Webhook(config=config).emit()
assert mock_requests.mock_calls == [
Expand All @@ -26,6 +27,48 @@ def test_webhook_get(
]


@mock.patch('tilty.emitters.webhook.METHODS')
def test_webhook_post_json(
mock_requests,
):
config = {
'url': 'http://www.google.com',
'headers': {'Content-Type': 'application/json'},
'payload': {'b': 'b1'},
'method': 'POST',
}
webhook.Webhook(config=config).emit()
assert mock_requests.mock_calls == [
mock.call.get('POST'),
mock.call.get()(
json={'b': 'b1'},
headers={'Content-Type': 'application/json'},
url='http://www.google.com'
)
]


@mock.patch('tilty.emitters.webhook.METHODS')
def test_webhook_post_data(
mock_requests,
):
config = {
'url': 'http://www.google.com',
'headers': {'Content-Type': 'text/plain'},
'payload': 'foo',
'method': 'POST',
}
webhook.Webhook(config=config).emit()
assert mock_requests.mock_calls == [
mock.call.get('POST'),
mock.call.get()(
data='foo',
headers={'Content-Type': 'text/plain'},
url='http://www.google.com'
)
]


def test_webhook_invalid_method():
config = {
'url': 'http://www.google.com',
Expand Down
11 changes: 11 additions & 0 deletions tilty/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
""" Common methods """


def safe_get_key(config, key, fallback=None):
""" Class to safely pull key from config or a fallback value """
try:
return config[key]
except KeyError:
pass
return fallback
Loading

0 comments on commit 7db786b

Please sign in to comment.