crypto-reporter/main.py

90 lines
2.7 KiB
Python

# !/usr/bin/env python3
"""Crypto reporter"""
import json
import logging
import os
import requests
import time
from dotenv import load_dotenv
import paho.mqtt.client as mqtt
load_dotenv() # Cargamos las variables de entorno necesarias
LOG_LEVEL = os.getenv('LOG_LEVEL', logging.INFO)
logging.basicConfig(level=LOG_LEVEL, format='[%(levelname)s] %(asctime)s - %(message)s')
BASE_API = 'https://api.coingecko.com/api/v3'
MQTT_TOPIC_DATA = os.getenv('MQTT_TOPIC_DATA', 'crypto-reporter/data')
MQTT_TOPIC_STATE = os.getenv('MQTT_TOPIC_STATE', 'crypto-reporter/state')
MQTT_PUBLISH_DELAY = int(os.getenv('MQTT_PUBLISH_DELAY', 60))
MQTT_CLIENT_ID = os.getenv('MQTT_CLIENT_ID', 'crypto-reporter')
MQTT_SERVER = os.getenv('MQTT_SERVER', 'localhost')
MQTT_PORT = int(os.getenv('MQTT_PORT', '1883'))
MQTT_USER = os.getenv('MQTT_USER', '')
MQTT_PASSWORD = os.getenv('MQTT_PASSWORD', '')
CRYPTOS_TO_PUBLISH = os.getenv('CRYPTOS_TO_PUBLISH', 'bitcoin')
CURRENCIES = os.getenv('CURRENCIES', 'eur')
def on_connect(client, userdata, flags, rc):
logging.info("Connected to MQTT server.")
client.publish(MQTT_TOPIC_STATE, 'connected', 1, True)
def main():
logging.info(f'Connecting to MQTT host {MQTT_SERVER}:{MQTT_PORT}...')
mqttc = mqtt.Client(MQTT_CLIENT_ID)
mqttc.username_pw_set(MQTT_USER, MQTT_PASSWORD)
mqttc.will_set(MQTT_TOPIC_STATE, 'disconnected', 1, True)
mqttc.on_connect = on_connect
mqttc.connect(MQTT_SERVER, MQTT_PORT, 60)
mqttc.loop_start()
last_msg_time = time.time()
while True:
try:
x = requests.get(BASE_API + '/simple/price',
params={'ids': CRYPTOS_TO_PUBLISH,
'vs_currencies': CURRENCIES})
logging.debug(f'HTTP response: {x.status_code}')
publish_data(mqttc, x.text)
delay_gap = time.time() - last_msg_time
if delay_gap < MQTT_PUBLISH_DELAY:
time.sleep(MQTT_PUBLISH_DELAY - delay_gap)
last_msg_time = time.time()
except KeyboardInterrupt:
logging.info("exiting...")
exit(0)
except Exception:
logging.exception("something went wrong.")
exit(1)
def publish_data(mqttc, raw):
try:
logging.debug(f'RAW message to publish: {raw}')
data = json.loads(raw)
for crypto in data:
currencies = data[crypto]
for currency in currencies:
mqttc.publish(MQTT_TOPIC_DATA + f'/{crypto}/{currency}', data[crypto][currency], 1, True)
except AttributeError:
logging.exception("Error decoding JSON")
if __name__ == '__main__':
logging.info('Starting crypto broker')
main()