Added carbon API!
This commit is contained in:
parent
75d5a3c664
commit
81c299dffb
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
*.json
|
||||
*.txt
|
||||
*.png
|
||||
__pycache__
|
80
api/carbon.py
Normal file
80
api/carbon.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
import requests
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import datetime
|
||||
from util import logging
|
||||
|
||||
def current_level() -> []:
|
||||
url = "https://api.carbonintensity.org.uk/intensity"
|
||||
response = requests.get(url)
|
||||
|
||||
if not response.ok:
|
||||
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
|
||||
|
||||
data = response.json()["data"][0]
|
||||
return [data["from"], data["intensity"]["forecast"], data["intensity"]["actual"], data["intensity"]["index"]]
|
||||
|
||||
def level_at(date: str) -> []:
|
||||
url = f"https://api.carbonintensity.org.uk/intensity/date/{date}"
|
||||
response = requests.get(url)
|
||||
|
||||
if not response.ok:
|
||||
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
|
||||
return []
|
||||
|
||||
if len(response.json()["data"]) == 0:
|
||||
return []
|
||||
|
||||
data = response.json()["data"][0]
|
||||
return [data["from"], data["intensity"]["forecast"], data["intensity"]["actual"], data["intensity"]["index"]]
|
||||
|
||||
def level_from_to(start: str, stop: str) -> str:
|
||||
url = f"https://api.carbonintensity.org.uk/intensity/{start}/{stop}"
|
||||
response = requests.get(url)
|
||||
|
||||
if not response.ok:
|
||||
logging.error(f"Failed to access Carbon API: {response.status_code} [{url}]")
|
||||
return ""
|
||||
|
||||
if len(response.json()["data"]) == 0:
|
||||
return []
|
||||
|
||||
data = response.json()["data"]
|
||||
|
||||
x = []
|
||||
measured = []
|
||||
indices = []
|
||||
|
||||
for i in range(len(data)):
|
||||
intensity = data[i]["intensity"]
|
||||
x.append(datetime.datetime.strptime(data[i]["from"], "%Y-%m-%dT%H:%MZ"))
|
||||
measured.append(intensity["actual"])
|
||||
indices.append(intensity["index"])
|
||||
|
||||
curr_color = indices[0]
|
||||
curr_color_index = 0
|
||||
for i in range(len(measured)):
|
||||
if indices[i] != curr_color:
|
||||
color = ""
|
||||
if curr_color == "very low":
|
||||
color = "#5bcc32"
|
||||
if curr_color == "low":
|
||||
color = "#87cc32"
|
||||
if curr_color == "moderate":
|
||||
color = "#ccc932"
|
||||
if curr_color == "high":
|
||||
color = "#cc8e32"
|
||||
if curr_color == "very high":
|
||||
color = "#cc4f32"
|
||||
|
||||
plt.plot(x[curr_color_index:i+1], measured[curr_color_index:i+1], color)
|
||||
curr_color_index = i
|
||||
curr_color = indices[i]
|
||||
|
||||
plt.xlabel("Time & Date")
|
||||
plt.ylabel("Carbon Intensity [gCO2/kWh]")
|
||||
plt.xticks(rotation=45)
|
||||
plt.gcf().subplots_adjust(bottom=0.2)
|
||||
plt.savefig("plot.png")
|
||||
plt.clf()
|
||||
return "plot.png"
|
38
cogs/api/carbon.py
Normal file
38
cogs/api/carbon.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from api import carbon
|
||||
from util import embed
|
||||
|
||||
class Carbon(commands.Cog):
|
||||
|
||||
def __init__(self, client: discord.Client):
|
||||
self.client = client
|
||||
|
||||
@commands.group(name="carbon", usage="carbon [subcommand]", description="Can accumulate data about carbon levels in the UK")
|
||||
async def carbon(self, ctx):
|
||||
pass
|
||||
|
||||
@carbon.command(name="now", usage="carbon now", description="Gets the latest available carbon intensity data")
|
||||
async def now(self, ctx):
|
||||
data = carbon.current_level()
|
||||
await ctx.send(embed=embed.make_embed_fields_footer("Carbon intensity in the UK", f"The current carbon intensity is considered **{data[3]}**.", f"{data[0]} | All values in gCO2/kWh", ("Measured", data[2]), ("Predicted", data[1])))
|
||||
|
||||
@carbon.command(name="at", usage="carbon at <Date>", description="Gets the carbon levels at the given date (YYYY-MM-DD)")
|
||||
async def at(self, ctx: discord.Client, date: str):
|
||||
data = carbon.level_at(date)
|
||||
if len(data) == 0:
|
||||
await ctx.send(embed=embed.make_error_embed(f"There is no data available for {date}."))
|
||||
else:
|
||||
await ctx.send(embed=embed.make_embed_fields_footer("Carbon intensity in the UK", f"The carbon intensity for that date is considered **{data[3]}**.", f"{data[0]} | All values in gCO2/kWh", ("Measured", data[2]), ("Predicted", data[1])))
|
||||
|
||||
@carbon.command(name="during", usage="carbon during <Start> <Stop>", description="Creates a diagram about carbon levels in the given time period (YYYY-MM-DD)")
|
||||
async def during(self, ctx: discord.Client, start: str, stop: str):
|
||||
path = carbon.level_from_to(start, stop)
|
||||
if path == "":
|
||||
await ctx.send(embed=embed.make_error_embed(f"There is no data available for the given time period."))
|
||||
else:
|
||||
data = embed.make_embed_image("Carbon intensity in the UK", path)
|
||||
await ctx.send(embed=data[0], file=data[1])
|
||||
|
||||
def setup(client: discord.Client):
|
||||
client.add_cog(Carbon(client))
|
29
cogs/help.py
29
cogs/help.py
|
@ -20,7 +20,29 @@ class Help(commands.MinimalHelpCommand):
|
|||
await self.context.send(embed=embed.make_error_embed("Command not found"))
|
||||
|
||||
async def send_group_help(self, group):
|
||||
await self.context.send(embed=embed.make_error_embed("Command not found"))
|
||||
try:
|
||||
subcmds = ""
|
||||
if group.commands != []:
|
||||
for command in group.commands:
|
||||
subcmds += "`" + command.name + "`, "
|
||||
subcmds = subcmds[:-2]
|
||||
else:
|
||||
subcmds = "`None`"
|
||||
|
||||
alias = ""
|
||||
if group.aliases != []:
|
||||
for i in range(len(group.aliases)):
|
||||
if i == len(group.aliases) - 1:
|
||||
alias = alias + '`' + group.aliases[i] + '`'
|
||||
else:
|
||||
alias = alias + '`' + group.aliases[i] + '`' + ', '
|
||||
else:
|
||||
alias = "`None`"
|
||||
|
||||
await self.context.send(embed=embed.make_embed_fields_ninl(group.name, group.description, ("Usage", f"`{config.settings['prefix']}{group.usage}`"), ("Aliases", alias), ("Subcommands", subcmds)))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
await self.context.send(embed=embed.make_error_embed("Command not found"))
|
||||
|
||||
async def send_command_help(self, command):
|
||||
try:
|
||||
|
@ -34,7 +56,10 @@ class Help(commands.MinimalHelpCommand):
|
|||
else:
|
||||
alias = "`None`"
|
||||
|
||||
await self.context.send(embed=embed.make_embed_fields_ninl(command.name, command.description, ("Usage", f"`{config.settings['prefix']}{command.usage}`"), ("Aliases", alias)))
|
||||
command_name = command.name
|
||||
if command.parent != None:
|
||||
command_name += f" ({command.parent})"
|
||||
await self.context.send(embed=embed.make_embed_fields_ninl(command_name, command.description, ("Usage", f"`{config.settings['prefix']}{command.usage}`"), ("Aliases", alias)))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
await self.context.send(embed=embed.make_error_embed("Command not found"))
|
||||
|
|
|
@ -20,9 +20,22 @@ def make_embed_fields(title: str, desc: str, *fields: tuple) -> discord.Embed:
|
|||
embed.add_field(name=name, value=value)
|
||||
return embed
|
||||
|
||||
|
||||
def make_embed_fields_footer(title: str, desc: str, footer: str, *fields: tuple) -> discord.Embed:
|
||||
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16))
|
||||
embed.set_footer(text=footer)
|
||||
for name, value in fields:
|
||||
embed.add_field(name=name, value=value)
|
||||
return embed
|
||||
|
||||
def make_embed_fields_ninl(title: str, desc: str, *fields: tuple) -> discord.Embed:
|
||||
embed = discord.Embed(title=title, description=desc, colour=int(config.settings["color"], 16), inline=False)
|
||||
for name, value in fields:
|
||||
embed.add_field(name=name, value=value)
|
||||
return embed
|
||||
embed.add_field(name=name, value=value, inline=False)
|
||||
return embed
|
||||
|
||||
def make_embed_image(title: str, path: str) -> (discord.Embed, discord.File):
|
||||
embed = discord.Embed(title=title, colour=int(config.settings["color"], 16))
|
||||
attachment = discord.File(path, filename="image.png")
|
||||
embed.set_image(url='attachment://image.png')
|
||||
|
||||
return (embed, attachment)
|
Loading…
Reference in a new issue