Various improvements
* Remove werkplaats, as the sensor topic was incorrect * Catch exceptions from subscribe.simple * Make MQTT_HOST configurable * Terminate if env vars are unset
This commit is contained in:
parent
274adf9f32
commit
3c4439454b
1 changed files with 44 additions and 29 deletions
65
main.py
65
main.py
|
@ -2,30 +2,51 @@
|
||||||
|
|
||||||
# Bitlair HobbyBot
|
# Bitlair HobbyBot
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
from typing import Optional
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from string import Template
|
from string import Template
|
||||||
from discord import Intents
|
from discord import Intents
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_webhook import DiscordWebhook, DiscordEmbed
|
from discord_webhook import DiscordWebhook, DiscordEmbed
|
||||||
import datetime
|
from datetime import datetime
|
||||||
import pytz
|
import pytz
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
import paho.mqtt.subscribe as subscribe
|
import paho.mqtt.subscribe as subscribe
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
mqtt_host = os.getenv('MQTT_HOST')
|
||||||
|
if not mqtt_host:
|
||||||
|
print('MQTT_HOST unset')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
token = os.getenv('DISCORD_TOKEN')
|
token = os.getenv('DISCORD_TOKEN')
|
||||||
|
if not token:
|
||||||
|
print('DISCORD_TOKEN unset')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
webhook_url = os.getenv('DISCORD_WEBHOOK_URL')
|
webhook_url = os.getenv('DISCORD_WEBHOOK_URL')
|
||||||
description = 'Bitlair Bot'
|
if not webhook_url:
|
||||||
state_template = Template('$topic is now $state')
|
print('DISCORD_WEBHOOK_URL unset')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
timezone = pytz.timezone('Europe/Amsterdam')
|
timezone = pytz.timezone('Europe/Amsterdam')
|
||||||
|
|
||||||
# Discord bot stuff
|
# Discord bot stuff
|
||||||
intents = Intents.default()
|
intents = Intents.default()
|
||||||
intents.message_content = True
|
intents.message_content = True
|
||||||
intents.members = True
|
intents.members = True
|
||||||
HobbyBot = commands.Bot(command_prefix='!', description=description, intents=intents)
|
HobbyBot = commands.Bot(command_prefix='!', description='Bitlair Bot', intents=intents)
|
||||||
|
|
||||||
|
def mqtt_get_one(topic):
|
||||||
|
try:
|
||||||
|
msg = subscribe.simple(topic, hostname=mqtt_host, keepalive=10)
|
||||||
|
return msg.payload.decode()
|
||||||
|
except err:
|
||||||
|
print(err)
|
||||||
|
return ''
|
||||||
|
|
||||||
# Define bot commands
|
# Define bot commands
|
||||||
@HobbyBot.event
|
@HobbyBot.event
|
||||||
|
@ -36,7 +57,7 @@ async def on_ready():
|
||||||
@HobbyBot.command(description='Bitlair Space State')
|
@HobbyBot.command(description='Bitlair Space State')
|
||||||
async def state(ctx):
|
async def state(ctx):
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
spaceState = subscribe.simple("bitlair/state", hostname="bitlair.nl").payload.decode()
|
spaceState = mqtt_get_one("bitlair/state")
|
||||||
if spaceState == "open":
|
if spaceState == "open":
|
||||||
await ctx.send("Bitlair is OPEN! :sunglasses:")
|
await ctx.send("Bitlair is OPEN! :sunglasses:")
|
||||||
elif spaceState == "closed":
|
elif spaceState == "closed":
|
||||||
|
@ -46,24 +67,21 @@ async def state(ctx):
|
||||||
@HobbyBot.command(description='co2 levels')
|
@HobbyBot.command(description='co2 levels')
|
||||||
async def co2(ctx):
|
async def co2(ctx):
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/co2_ppm", hostname="bitlair.nl").payload.decode()
|
hoofdruimte = mqtt_get_one("bitlair/climate/hoofdruimte_ingang/co2_ppm")
|
||||||
werkplaats = subscribe.simple("bitlair/climate/werkplaats/co2_ppm", hostname="bitlair.nl").payload.decode()
|
await ctx.send("Hoofdruimte: %s ppm\n" % hoofdruimte)
|
||||||
await ctx.send("Hoofdruimte: " + hoofdruimte + " ppm\nWerkplaats: " + werkplaats + " ppm")
|
|
||||||
# !temp
|
# !temp
|
||||||
@HobbyBot.command(description='Temperature')
|
@HobbyBot.command(description='Temperature')
|
||||||
async def temp(ctx):
|
async def temp(ctx):
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/temperature_c", hostname="bitlair.nl").payload.decode()
|
hoofdruimte = mqtt_get_one("bitlair/climate/hoofdruimte_ingang/temperature_c")
|
||||||
werkplaats = subscribe.simple("bitlair/climate/werkplaats/temperature_c", hostname="bitlair.nl").payload.decode()
|
await ctx.send("Hoofdruimte: %s °C\n" % hoofdruimte )
|
||||||
await ctx.send("Hoofdruimte: " + hoofdruimte + "°C\nWerkplaats: " + werkplaats + "°C")
|
|
||||||
|
|
||||||
# !humid
|
# !humid
|
||||||
@HobbyBot.command(description='Humidity')
|
@HobbyBot.command(description='Humidity')
|
||||||
async def humid(ctx):
|
async def humid(ctx):
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
hoofdruimte = subscribe.simple("bitlair/climate/hoofdruimte_ingang/humidity_pct", hostname="bitlair.nl").payload.decode()
|
hoofdruimte = mqtt_get_one("bitlair/climate/hoofdruimte_ingang/humidity_pct")
|
||||||
werkplaats = subscribe.simple("bitlair/climate/werkplaats/humidity_pct", hostname="bitlair.nl").payload.decode()
|
await ctx.send("Hoofdruimte: %s pct\n" % hoofdruimte)
|
||||||
await ctx.send("Hoofdruimte: " + hoofdruimte + " pct\nWerkplaats: " + werkplaats + " pct")
|
|
||||||
|
|
||||||
# !np
|
# !np
|
||||||
@HobbyBot.command(description='Now Playing')
|
@HobbyBot.command(description='Now Playing')
|
||||||
|
@ -85,19 +103,16 @@ def on_message(client, userdata, msg):
|
||||||
topic = msg.topic
|
topic = msg.topic
|
||||||
msg = msg.payload.decode()
|
msg = msg.payload.decode()
|
||||||
|
|
||||||
|
state_template = Template('$topic is now $state')
|
||||||
if topic == "bitlair/state/bitlair":
|
if topic == "bitlair/state/bitlair":
|
||||||
topic = topic.split("/")[2].capitalize()
|
msg = state_template.substitute(topic='Bitlair', state=msg.upper())
|
||||||
msg = state_template.substitute(topic=topic, state=msg.upper())
|
|
||||||
elif topic == "bitlair/state/djo":
|
elif topic == "bitlair/state/djo":
|
||||||
topic = topic.split("/")[2].upper()
|
msg = state_template.substitute(topic='DJO', state=msg.upper())
|
||||||
msg = state_template.substitute(topic=topic, state=msg.upper())
|
else:
|
||||||
else: return
|
return
|
||||||
webhook = DiscordWebhook(url=webhook_url, rate_limit_retry=True)
|
webhook = DiscordWebhook(url=webhook_url, rate_limit_retry=True, content=msg)
|
||||||
embed = DiscordEmbed(title='MQTT', description=msg, color=15105570, timestamp=datetime.datetime.now(tz = timezone).isoformat())
|
|
||||||
webhook.add_embed(embed)
|
|
||||||
webhook.execute()
|
webhook.execute()
|
||||||
# prevent triggering rate limits
|
sleep(1) # Prevent triggering rate limits.
|
||||||
sleep(1)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
@ -105,7 +120,7 @@ def on_message(client, userdata, msg):
|
||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
client.on_message = on_message
|
client.on_message = on_message
|
||||||
client.connect("bitlair.nl", 1883, 60)
|
client.connect(mqtt_host, 1883, 60)
|
||||||
|
|
||||||
# Start mqtt loop and discord bot
|
# Start mqtt loop and discord bot
|
||||||
client.loop_start()
|
client.loop_start()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue