# !/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()