Initial code commit
This commit is contained in:
commit
d5a422ca10
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.vscode/
|
||||||
|
__pycache__/
|
||||||
|
.pyenv/
|
20
Dockerfile
Normal file
20
Dockerfile
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
FROM python:3.8-slim-buster
|
||||||
|
|
||||||
|
# Keeps Python from generating .pyc files in the container
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
|
||||||
|
# Turns off buffering for easier container logging
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
ADD requirements.txt .
|
||||||
|
RUN python -m pip install -r requirements.txt
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY main.py /app
|
||||||
|
|
||||||
|
RUN useradd appuser && chown -R appuser /app
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
ENTRYPOINT ["python", "main.py"]
|
4
README.md
Normal file
4
README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Carbon Exporter
|
||||||
|
Pulls carbon intensity data from [carbonintensity.org.uk](https://carbonintensity.org.uk) and provides it in Prometheus-style exporter format over HTTP.
|
||||||
|
|
||||||
|
Used to monitor a UK region's carbon intensity over time.
|
9
docker-compose.yaml
Normal file
9
docker-compose.yaml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
carbon-exporter:
|
||||||
|
image: carbon-exporter:latest
|
||||||
|
container_name: carbon-exporter
|
||||||
|
environment:
|
||||||
|
- CARBON_POSTCODE=<first 3 characters of UK postcode>
|
||||||
|
restart: unless-stopped
|
79
main.py
Normal file
79
main.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
"""
|
||||||
|
Present observational weather data to Prometheus
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
import requests # type: ignore
|
||||||
|
from flask import Flask, Response # type: ignore
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_carbon_data(postcode: str) -> Dict:
|
||||||
|
"""
|
||||||
|
Fetch current data for the carbon intensity of the provided region
|
||||||
|
"""
|
||||||
|
|
||||||
|
obs_data = requests.get(
|
||||||
|
f'https://api.carbonintensity.org.uk/regional/postcode/{postcode}'
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.loads(obs_data.content)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/metrics')
|
||||||
|
def metrics():
|
||||||
|
"""
|
||||||
|
Output Prometheus-style metrics
|
||||||
|
"""
|
||||||
|
postcode = os.environ.get('CARBON_POSTCODE')
|
||||||
|
|
||||||
|
latest_data = fetch_carbon_data(postcode)['data'][0]
|
||||||
|
|
||||||
|
ret_data: List = list()
|
||||||
|
for generation in latest_data['data'][0]['generationmix']:
|
||||||
|
ret_data.append(
|
||||||
|
{
|
||||||
|
'key': f'sensor_carbon_generation_{generation["fuel"]}_perc',
|
||||||
|
'labels': {
|
||||||
|
'region': latest_data['dnoregion'],
|
||||||
|
},
|
||||||
|
'type': 'gauge',
|
||||||
|
'value': float(generation['perc'])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ret_data.append(
|
||||||
|
{
|
||||||
|
'key': 'sensor_carbon_intensity_forecast',
|
||||||
|
'labels': {
|
||||||
|
'region': latest_data['dnoregion'],
|
||||||
|
},
|
||||||
|
'type': 'gauge',
|
||||||
|
'value': float(latest_data['data'][0]['intensity']['forecast']),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ret_strs = list()
|
||||||
|
for item in ret_data:
|
||||||
|
ret_strs.append(f'# HELP {item["key"]} Carbon metric')
|
||||||
|
ret_strs.append(f'# TYPE {item["key"]} {item["type"]}')
|
||||||
|
ret_strs.append(
|
||||||
|
item["key"]
|
||||||
|
+ '{'
|
||||||
|
+ " ".join([f'{key}="{val}"' for key, val in item["labels"].items()])
|
||||||
|
+ '} '
|
||||||
|
+ str(item["value"])
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = Response('\n'.join(ret_strs))
|
||||||
|
resp.headers['Content-type'] = 'text/plain'
|
||||||
|
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0')
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
flask
|
||||||
|
requests
|
Loading…
Reference in a new issue