Initial commit
This commit is contained in:
commit
5e8a9cc55c
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/node_modules/
|
||||
/dist/
|
||||
/.parcel-cache/
|
17
biome.json
Normal file
17
biome.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.4.0/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 4
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"all": true
|
||||
}
|
||||
}
|
||||
}
|
27
flake.lock
Normal file
27
flake.lock
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703992652,
|
||||
"narHash": "sha256-C0o8AUyu8xYgJ36kOxJfXIroy9if/G6aJbNOpA5W0+M=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "32f63574c85fbc80e4ba1fbb932cde9619bad25e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
17
flake.nix
Normal file
17
flake.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
};
|
||||
|
||||
outputs = {nixpkgs, ...}: let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
biome
|
||||
nodejs
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
3690
package-lock.json
generated
Normal file
3690
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
9
package.json
Normal file
9
package.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@parcel/transformer-sass": "^2.10.3",
|
||||
"parcel": "^2.10.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"bulma": "^0.9.4"
|
||||
}
|
||||
}
|
15
src/index.html
Normal file
15
src/index.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="index.scss">
|
||||
<title>Energiepreise</title>
|
||||
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="application-name" content="Energiepreise">
|
||||
</head>
|
||||
<body>
|
||||
<script type="module" src="index.ts"></script>
|
||||
</body>
|
||||
</html>
|
32
src/index.scss
Normal file
32
src/index.scss
Normal file
|
@ -0,0 +1,32 @@
|
|||
@import 'npm:bulma/bulma.sass';
|
||||
|
||||
.table td {
|
||||
border-bottom-width: 0;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:first-child {
|
||||
font-size: 10lvh;
|
||||
background: white !important;
|
||||
|
||||
& > td:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& > td:nth-child(-n+2) {
|
||||
position: relative;
|
||||
left: 25%;
|
||||
|
||||
&::after {
|
||||
content: "Eur/MWh";
|
||||
vertical-align: sub;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
71
src/index.ts
Normal file
71
src/index.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
interface MarketSlice {
|
||||
startTimestamp: Date;
|
||||
endTimestamp: Date;
|
||||
marketPrice: number;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
interface MarketData {
|
||||
object: string;
|
||||
url: string;
|
||||
data: MarketSlice[];
|
||||
}
|
||||
|
||||
const TIME_FORMAT = Intl.DateTimeFormat(undefined, {
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
});
|
||||
|
||||
async function getMarketData(): Promise<MarketData> {
|
||||
const request = await fetch("https://api.awattar.at/v1/marketdata");
|
||||
const data = await request.json();
|
||||
|
||||
return {
|
||||
object: data.object,
|
||||
url: data.url,
|
||||
data: data.data.map((slice) => {
|
||||
return {
|
||||
startTimestamp: new Date(slice.start_timestamp),
|
||||
endTimestamp: new Date(slice.end_timestamp),
|
||||
marketPrice: slice.marketprice,
|
||||
unit: slice.unit,
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
async function writeTable() {
|
||||
const data = await getMarketData();
|
||||
const table = document.createElement("table");
|
||||
table.classList.add("table", "is-striped", "is-hoverable", "is-fullwidth");
|
||||
const body = document.createElement("tbody");
|
||||
|
||||
for (const slice of data.data) {
|
||||
const tr = document.createElement("tr");
|
||||
const timeCell = document.createElement("td");
|
||||
const priceCell = document.createElement("td");
|
||||
|
||||
// How green the price should be; ~100€/MWh seems to be a
|
||||
// pretty expensive price, so that or worse is 100% red, while
|
||||
// 0 or lower is 0% red
|
||||
const redPercent = Math.max(Math.min(slice.marketPrice / 100, 1), 0);
|
||||
console.info(redPercent);
|
||||
|
||||
timeCell.innerText = TIME_FORMAT.format(slice.startTimestamp);
|
||||
priceCell.innerHTML = slice.marketPrice.toString();
|
||||
priceCell.style.color = `color-mix(in lch, green, red ${
|
||||
redPercent * 100
|
||||
}%)`;
|
||||
|
||||
tr.appendChild(timeCell);
|
||||
tr.appendChild(priceCell);
|
||||
body.appendChild(tr);
|
||||
}
|
||||
|
||||
table.appendChild(body);
|
||||
document.body.appendChild(table);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", writeTable);
|
Loading…
Reference in a new issue