commit ee24c7c18f3f6002cee4e610ee89c87bdbe3a3b3 Author: Max Date: Tue Apr 18 22:02:17 2023 +0200 init diff --git a/main.py b/main.py new file mode 100644 index 0000000..bef21f4 --- /dev/null +++ b/main.py @@ -0,0 +1,118 @@ +# Bitlair HobbyBot +# +# Requirements: +# - pytz +# - python3 +# - discord_webhook +# - paho-mqtt +# - discord.py + +from time import sleep +from string import Template +from discord import Intents +from discord.ext import commands +from discord_webhook import DiscordWebhook,DiscordEmbed +import datetime +import pytz +import paho.mqtt.client as mqtt +import paho.mqtt.subscribe as subscribe + +# hunter2 +token = "" +webhook_url = "" +description = 'Bitlair Bot' +state_template = Template('$topic is now $state') +timezone = pytz.timezone('Europe/Amsterdam') + +# Discord bot stuff +intents = Intents.default() +intents.message_content = True +intents.members = True +HobbyBot = commands.Bot(command_prefix='!', description=description, intents=intents) + +# Define bot commands +@HobbyBot.event +async def on_ready(): + print(f'Logged in as {HobbyBot.user} (ID: {HobbyBot.user.id})') + +# !state +@HobbyBot.command(description='Bitlair Space State') +async def state(ctx): + async with ctx.typing(): + spaceState = subscribe.simple("bitlair/state/bitlair", hostname="bitlair.nl").payload.decode() + if spaceState == "open": + await ctx.send("Bitlair is OPEN! :sunglasses:") + elif spaceState == "closed": + await ctx.send("Bitlair is closed :pensive:") + +# !co2 +@HobbyBot.command(description='co2 levels') +async def co2(ctx): + async with ctx.typing(): + hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/co2_ppm", hostname="bitlair.nl").payload.decode() + werkplaats = subscribe.simple("bitlair/climate/werkplaats/co2_ppm", hostname="bitlair.nl").payload.decode() + await ctx.send("Hoofdruimte: " + hoofdruimte + " ppm\nWerkplaats: " + werkplaats + " ppm") +# !temp +@HobbyBot.command(description='Temperature') +async def temp(ctx): + async with ctx.typing(): + hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/temperature_c", hostname="bitlair.nl").payload.decode() + werkplaats = subscribe.simple("bitlair/climate/werkplaats/temperature_c", hostname="bitlair.nl").payload.decode() + await ctx.send("Hoofdruimte: " + hoofdruimte + "°C\nWerkplaats: " + werkplaats + "°C") + +# !humid +@HobbyBot.command(description='Humidity') +async def humid(ctx): + async with ctx.typing(): + hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/humidity_pct", hostname="bitlair.nl").payload.decode() + werkplaats = subscribe.simple("bitlair/climate/werkplaats/humidity_pct", hostname="bitlair.nl").payload.decode() + await ctx.send("Hoofdruimte: " + hoofdruimte + " pct\nWerkplaats: " + werkplaats + " pct") + +# !np +@HobbyBot.command(description='Now Playing') +async def np(ctx): + async with ctx.typing(): + await ctx.send("Now playing: Darude - Sandstorm") + + +# define mqtt client stuff +# +# subscribe to topics +def on_connect(client, userdata, flags, rc): + client.subscribe("bitlair/state/bitlair") + client.subscribe("bitlair/state/djo") + +# post to mqtt discord channel when state changes +def on_message(client, userdata, msg): + try: + topic = msg.topic + msg = msg.payload.decode() + + if topic == "bitlair/state/bitlair": + topic = topic.split("/")[2].capitalize() + msg = state_template.substitute(topic=topic, state=msg.upper()) + elif topic == "bitlair/state/djo": + topic = topic.split("/")[2].upper() + msg = state_template.substitute(topic=topic, state=msg.upper()) + else: return + webhook = DiscordWebhook(url=webhook_url, rate_limit_retry=True) + embed = DiscordEmbed(title='MQTT', description=msg, color=15105570, timestamp=datetime.datetime.now(tz = timezone).isoformat()) + webhook.add_embed(embed) + webhook.execute() + # prevent triggering rate limits + sleep(1) + except Exception as e: + print(e) + + +client = mqtt.Client() +client.on_connect = on_connect +client.on_message = on_message +client.connect("bitlair.nl", 1883, 60) + +# Start mqtt loop and discord bot +client.loop_start() +HobbyBot.run(token) + +# Exit when bot crashes +client.loop_stop(force=True) \ No newline at end of file