90 lines
2.7 KiB
Python
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()
|