├── VERSION
├── anern_monitoring
├── __init__.py
├── anern_inverter
│ ├── __init__.py
│ └── inverter.py
└── app.py
├── setup.cfg
├── requirements.txt
├── .gitignore
├── grafana
├── config.monitoring
└── provisioning
│ ├── dashboards
│ ├── dashboard.yml
│ └── power_monitoring.json
│ └── datasources
│ └── datasource.yml
├── Dockerfile
├── setup.py
├── prometheus
└── prometheus.yml
├── Makefile
├── compose.yml
└── LICENSE
/VERSION:
--------------------------------------------------------------------------------
1 | 0.1
--------------------------------------------------------------------------------
/anern_monitoring/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/anern_monitoring/anern_inverter/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | universal = 1
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohttp==3.8.3
2 | pyserial==3.5
3 | gunicorn==20.1.0
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | venv
2 | .env
3 | build
4 | dist
5 | *.build
6 | *.dist
7 | __pycache__
8 | *.egg-info
9 | .idea
--------------------------------------------------------------------------------
/grafana/config.monitoring:
--------------------------------------------------------------------------------
1 | GF_SECURITY_ADMIN_USER=admin
2 | GF_SECURITY_ADMIN_PASSWORD=foobar
3 | GF_USERS_ALLOW_SIGN_UP=false
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM library/python:3.9-slim
2 |
3 | WORKDIR /app
4 | ADD . /app
5 |
6 | RUN python setup.py install
7 |
8 | EXPOSE 8081
9 |
--------------------------------------------------------------------------------
/grafana/provisioning/dashboards/dashboard.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 1
2 |
3 | providers:
4 | - name: 'Prometheus'
5 | orgId: 1
6 | folder: ''
7 | type: file
8 | disableDeletion: false
9 | editable: true
10 | options:
11 | path: /etc/grafana/provisioning/dashboards
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 |
4 | def _get_version():
5 | with open('VERSION') as fd:
6 | return fd.read().strip()
7 |
8 |
9 | install_requires = [
10 | 'aiohttp==3.8.3',
11 | 'pyserial==3.5',
12 | 'gunicorn==20.1.0',
13 | ]
14 |
15 | setup(
16 | name='anern_monitoring',
17 | version=_get_version(),
18 | include_package_data=True,
19 | install_requires=install_requires,
20 | packages=find_packages(),
21 | )
22 |
--------------------------------------------------------------------------------
/prometheus/prometheus.yml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 1m
3 | scrape_timeout: 10s
4 | evaluation_interval: 15s
5 | alerting:
6 | alertmanagers:
7 | - static_configs:
8 | - targets: [ ]
9 | scheme: http
10 | timeout: 10s
11 | api_version: v1
12 | scrape_configs:
13 | - job_name: anern_monitoring
14 | honor_timestamps: true
15 | metrics_path: /metrics
16 | scheme: http
17 | static_configs:
18 | - targets:
19 | - 'anern_monitoring:8081'
20 | - job_name: prometheus
21 | static_configs:
22 | - targets:
23 | - 'localhost:9090'
--------------------------------------------------------------------------------
/anern_monitoring/app.py:
--------------------------------------------------------------------------------
1 | from aiohttp import web
2 |
3 | from .anern_inverter.inverter import Inverter
4 |
5 | _inverter = None
6 |
7 |
8 | async def health(request):
9 | return web.Response(text="
Async Rest API using aiohttp : Health OK
",
10 | content_type='text/html')
11 |
12 |
13 | def get_inverter() -> Inverter:
14 | global _inverter
15 | if _inverter is None:
16 | _inverter = Inverter('/dev/ttyUSB0')
17 | return _inverter
18 |
19 |
20 | async def get_metrics(request):
21 | inverter = get_inverter()
22 | data = inverter.get_qpigs()
23 | return web.Response(
24 | text='\n'.join([f'{key} {value}' for key, value in data.items()]),
25 | content_type='text/plain'
26 | )
27 |
28 |
29 | def init():
30 | app = web.Application()
31 | app.router.add_get("/", health)
32 | app.router.add_get("/metrics", get_metrics)
33 | return app
34 |
35 |
36 | monitoring_app = init()
37 |
38 | if __name__ == "__main__":
39 | web.run_app(monitoring_app, port=8000)
40 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: deps install clean build_clean dist_clean tests dist docker
2 |
3 | ENV=.env
4 | PYTHON_VERSION=3
5 | PYTHON=python${PYTHON_VERSION}
6 | SITE_PACKAGES=${ENV}/lib/${PYTHON}/site-packages
7 | IN_ENV=. ${ENV}/bin/activate;
8 | PACKAGE_VERSION=$(shell cat VERSION)
9 |
10 | default: ${ENV} deps
11 |
12 | ${ENV}:
13 | @echo "Creating Python environment..." >&2
14 | @${PYTHON} -m venv ${ENV}
15 | @echo "Updating pip..." >&2
16 | @${IN_ENV} ${PYTHON} -m pip install -U pip setuptools
17 |
18 | ${SITE_PACKAGES}/aiohttp: ${ENV}
19 | @${IN_ENV} ${PYTHON} -m pip install -r requirements.txt
20 |
21 | ${SITE_PACKAGES}/anern_monitoring: ${ENV} install
22 |
23 | deps: ${SITE_PACKAGES}/aiohttp
24 |
25 | install: default
26 | @${IN_ENV} ${PYTHON} -m pip install -e .
27 |
28 | wheel: ${ENV}
29 | @${IN_ENV} ${PYTHON} -m pip install -U wheel
30 | @${IN_ENV} ${PYTHON} setup.py bdist_wheel
31 |
32 | dist: wheel
33 |
34 | dist_clean:
35 | @rm -rf dist
36 |
37 | build_clean:
38 | @rm -rf build
39 |
40 | clean: build_clean dist_clean
41 | @rm -rf ${ENV} dist build __pycache__ *.egg-info
42 |
43 | docker: build_clean dist_clean wheel
44 | @docker build -t anern_monitoring:${PACKAGE_VERSION} .
45 | @docker tag anern_monitoring:${PACKAGE_VERSION} anern_monitoring:latest
--------------------------------------------------------------------------------
/compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.2'
2 |
3 | services:
4 | anern_monitoring:
5 | build: .
6 | privileged: true
7 | volumes:
8 | - ./:/app
9 | - /dev:/dev
10 | command: gunicorn anern_monitoring.app:monitoring_app -b :8081 --worker-class aiohttp.GunicornWebWorker --reload --access-logfile -
11 | ports:
12 | - "8081:8081"
13 |
14 | prometheus:
15 | image: prom/prometheus:latest
16 | volumes:
17 | - ./prometheus:/etc/prometheus
18 | - ~/prometheus_data:/prometheus
19 | command:
20 | - '--config.file=/etc/prometheus/prometheus.yml'
21 | - '--storage.tsdb.path=/prometheus'
22 | - '--web.console.libraries=/usr/share/prometheus/console_libraries'
23 | - '--web.console.templates=/usr/share/prometheus/consoles'
24 | links:
25 | - anern_monitoring
26 | ports:
27 | - 9090:9090
28 |
29 | grafana:
30 | image: grafana/grafana
31 | user: '472'
32 | restart: always
33 | environment:
34 | GF_INSTALL_PLUGINS: 'grafana-clock-panel,grafana-simple-json-datasource'
35 | volumes:
36 | - ~/grafana_data:/var/lib/grafana
37 | - ./grafana/provisioning/:/etc/grafana/provisioning/
38 | env_file:
39 | - ./grafana/config.monitoring
40 | ports:
41 | - 3000:3000
42 | depends_on:
43 | - prometheus
--------------------------------------------------------------------------------
/grafana/provisioning/datasources/datasource.yml:
--------------------------------------------------------------------------------
1 | # config file version
2 | apiVersion: 1
3 |
4 | # list of datasources that should be deleted from the database
5 | deleteDatasources:
6 | - name: Prometheus
7 | orgId: 1
8 |
9 | # list of datasources to insert/update depending
10 | # whats available in the database
11 | datasources:
12 | # name of the datasource. Required
13 | - name: Prometheus
14 | # datasource type. Required
15 | type: prometheus
16 | # access mode. direct or proxy. Required
17 | access: proxy
18 | # org id. will default to orgId 1 if not specified
19 | orgId: 1
20 | # url
21 | url: http://prometheus:9090
22 | # database password, if used
23 | password:
24 | # database user, if used
25 | user:
26 | # database name, if used
27 | database:
28 | # enable/disable basic auth
29 | basicAuth: false
30 | # basic auth username, if used
31 | basicAuthUser:
32 | # basic auth password, if used
33 | basicAuthPassword:
34 | # enable/disable with credentials headers
35 | withCredentials:
36 | # mark as default datasource. Max one per org
37 | isDefault: true
38 | #