Added OpenAPI spec and UI
This commit is contained in:
parent
b68c4a60e0
commit
b2d07139c8
10 changed files with 695 additions and 62 deletions
|
@ -3,6 +3,7 @@ import { sassPlugin } from "esbuild-sass-plugin";
|
||||||
import htmlPlugin from '@chialab/esbuild-plugin-html';
|
import htmlPlugin from '@chialab/esbuild-plugin-html';
|
||||||
import handlebarsPlugin from "esbuild-plugin-handlebars";
|
import handlebarsPlugin from "esbuild-plugin-handlebars";
|
||||||
import { clean } from 'esbuild-plugin-clean';
|
import { clean } from 'esbuild-plugin-clean';
|
||||||
|
import { copy } from 'esbuild-plugin-copy';
|
||||||
|
|
||||||
import postcss from "postcss";
|
import postcss from "postcss";
|
||||||
import autoprefixer from "autoprefixer";
|
import autoprefixer from "autoprefixer";
|
||||||
|
@ -11,7 +12,7 @@ const hbsOptions = {
|
||||||
additionalHelpers: { splitText: "helpers.js" },
|
additionalHelpers: { splitText: "helpers.js" },
|
||||||
additionalPartials: {},
|
additionalPartials: {},
|
||||||
precompileOptions: {}
|
precompileOptions: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
esbuild
|
esbuild
|
||||||
.build({
|
.build({
|
||||||
|
@ -29,7 +30,7 @@ esbuild
|
||||||
plugins: [
|
plugins: [
|
||||||
clean({
|
clean({
|
||||||
patterns: ['./build/*']
|
patterns: ['./build/*']
|
||||||
}),
|
}),
|
||||||
htmlPlugin(),
|
htmlPlugin(),
|
||||||
sassPlugin({
|
sassPlugin({
|
||||||
async transform(source) {
|
async transform(source) {
|
||||||
|
@ -40,7 +41,15 @@ esbuild
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
handlebarsPlugin(hbsOptions),
|
handlebarsPlugin(hbsOptions),
|
||||||
|
copy({
|
||||||
|
// this is equal to process.cwd(), which means we use cwd path as base path to resolve `to` path
|
||||||
|
// if not specified, this plugin uses ESBuild.build outdir/outfile options as base path.
|
||||||
|
resolveFrom: 'cwd',
|
||||||
|
assets: {
|
||||||
|
from: ['./src/api.*'],
|
||||||
|
to: ['./build'],
|
||||||
|
},
|
||||||
|
})
|
||||||
],
|
],
|
||||||
minify: true,
|
minify: true,
|
||||||
metafile: false,
|
metafile: false,
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
"esbuild-plugin-clean": "^1.0.1",
|
"esbuild-plugin-clean": "^1.0.1",
|
||||||
|
"esbuild-plugin-copy": "^2.1.1",
|
||||||
"esbuild-plugin-handlebars": "^1.0.2",
|
"esbuild-plugin-handlebars": "^1.0.2",
|
||||||
"esbuild-sass-plugin": "^2.16.0",
|
"esbuild-sass-plugin": "^2.16.0",
|
||||||
"handlebars": "^4.7.7",
|
"handlebars": "^4.7.7",
|
||||||
|
|
31
data/src/api.html
Normal file
31
data/src/api.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="SwaggerUI"
|
||||||
|
/>
|
||||||
|
<title>BTClock API</title>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
<script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js" crossorigin></script>
|
||||||
|
<script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-standalone-preset.js" crossorigin></script>
|
||||||
|
<script>
|
||||||
|
window.onload = () => {
|
||||||
|
window.ui = SwaggerUIBundle({
|
||||||
|
url: 'api.json',
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
345
data/src/api.json
Normal file
345
data/src/api.json
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
{
|
||||||
|
"openapi": "3.0.3",
|
||||||
|
"info": {
|
||||||
|
"title": "BTClock API",
|
||||||
|
"version": "3.0",
|
||||||
|
"description": "BTClock V3 API"
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "/api/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/status": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Get current status",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/system_status": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Get system status",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/settings": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Get current settings",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Save current settings",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/action/pause": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"timer"
|
||||||
|
],
|
||||||
|
"summary": "Pause screen rotation",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/action/timer_restart": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"timer"
|
||||||
|
],
|
||||||
|
"summary": "Restart screen rotation",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/show/screen/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"screens"
|
||||||
|
],
|
||||||
|
"summary": "Set screen to show",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "id",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"description": "ID of screen to show"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/show/text/{text}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"screens"
|
||||||
|
],
|
||||||
|
"summary": "Set text to show",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "text",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "text"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"description": "Text to show"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/show/custom": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"screens"
|
||||||
|
],
|
||||||
|
"summary": "Set text to show (advanced)",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CustomText"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/full_refresh": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Force full refresh of all displays",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/lights/{color}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"lights"
|
||||||
|
],
|
||||||
|
"summary": "Turn on LEDs with specific color",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "color",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "FFCC00"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"description": "Color in RGB hex"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/lights/off": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"lights"
|
||||||
|
],
|
||||||
|
"summary": "Turn LEDs off",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/restart": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"summary": "Restart BTClock",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Settings": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"fetchEurPrice": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Fetch EUR price instead of USD"
|
||||||
|
},
|
||||||
|
"fgColor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": 16777215,
|
||||||
|
"description": "ePaper foreground (text) color"
|
||||||
|
},
|
||||||
|
"bgColor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": 0,
|
||||||
|
"description": "ePaper background color"
|
||||||
|
},
|
||||||
|
"ledTestOnPower": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Do LED test on power-on"
|
||||||
|
},
|
||||||
|
"ledFlashOnUpd": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Flash LEDs on new block"
|
||||||
|
},
|
||||||
|
"mdnsEnabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Enable mDNS"
|
||||||
|
},
|
||||||
|
"otaEnabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Enable over-the-air updates"
|
||||||
|
},
|
||||||
|
"stealFocusOnBlock": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Steal focus on new block"
|
||||||
|
},
|
||||||
|
"mcapBigChar": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Use big characters for market cap screen"
|
||||||
|
},
|
||||||
|
"mempoolInstance": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "mempool.space",
|
||||||
|
"description": "Mempool.space instance to connect to"
|
||||||
|
},
|
||||||
|
"ledBrightness": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 128,
|
||||||
|
"description": "Brightness of LEDs"
|
||||||
|
},
|
||||||
|
"fullRefreshMin": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 60,
|
||||||
|
"description": "Full refresh time of ePaper displays in minutes"
|
||||||
|
},
|
||||||
|
"screen[0]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"screen[1]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"screen[2]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"screen[3]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"screen[4]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"screen[5]": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"tzOffset": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 60,
|
||||||
|
"description": "Timezone offset in minutes"
|
||||||
|
},
|
||||||
|
"minSecPriceUpd": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 30,
|
||||||
|
"description": "Minimum time between price updates in seconds"
|
||||||
|
},
|
||||||
|
"timePerScreen": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 30,
|
||||||
|
"description": "Time between screens when rotating in minutes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CustomText": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"minItems": 7,
|
||||||
|
"maxItems": 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,7 +87,8 @@ div#output .btclock {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
.digit,
|
.digit,
|
||||||
.splitText {
|
.splitText,
|
||||||
|
.mediumText {
|
||||||
border: 2px solid gold;
|
border: 2px solid gold;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,18 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar">
|
<nav class="navbar navbar-expand">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<span class="navbar-brand mb-0 h1">₿TClock</span>
|
<span class="navbar-brand mb-0 h1">₿TClock</span>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" target="_blank" href="api.html">API</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
<script id="entry-template" type="text/x-handlebars-template">
|
<script id="entry-template" type="text/x-handlebars-template">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
|
@ -181,7 +189,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="minSecPriceUpd" class="col-sm-6 col-form-label col-form-label-sm">Time between price updates</label>
|
<label for="minSecPriceUpd" class="col-sm-6 col-form-label col-form-label-sm">Time between price
|
||||||
|
updates</label>
|
||||||
<div class="col-sm-6 mb-3">
|
<div class="col-sm-6 mb-3">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<input type="number" name="minSecPriceUpd" min="1" id="minSecPriceUpd" class="form-control">
|
<input type="number" name="minSecPriceUpd" min="1" id="minSecPriceUpd" class="form-control">
|
||||||
|
@ -201,7 +210,7 @@
|
||||||
<div class="form-text">A restart is required to apply TZ offset.</div>
|
<div class="form-text">A restart is required to apply TZ offset.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-sm-6 col-form-label col-form-label-sm" for="ledBrightness">LED brightness</label>
|
<label class="col-sm-6 col-form-label col-form-label-sm" for="ledBrightness">LED brightness</label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
|
|
227
data/src/swagger.yaml
Normal file
227
data/src/swagger.yaml
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: BTClock API
|
||||||
|
version: "3.0"
|
||||||
|
description: BTClock V3 API
|
||||||
|
servers:
|
||||||
|
- url: /api/
|
||||||
|
paths:
|
||||||
|
/status:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Get current status
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/system_status:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Get system status
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/settings:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Get current settings
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Save current settings
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Settings'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/action/pause:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- timer
|
||||||
|
summary: Pause screen rotation
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/action/timer_restart:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- timer
|
||||||
|
summary: Restart screen rotation
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/show/screen/{id}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- screens
|
||||||
|
summary: Set screen to show
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 1
|
||||||
|
required: true
|
||||||
|
description: ID of screen to show
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/show/text/{text}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- screens
|
||||||
|
summary: Set text to show
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: text
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
default: "text"
|
||||||
|
required: true
|
||||||
|
description: Text to show
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/show/custom:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- screens
|
||||||
|
summary: Set text to show (advanced)
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CustomText'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/full_refresh:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Force full refresh of all displays
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/lights/{color}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- lights
|
||||||
|
summary: Turn on LEDs with specific color
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: color
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
default: FFCC00
|
||||||
|
required: true
|
||||||
|
description: Color in RGB hex
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/lights/off:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- lights
|
||||||
|
summary: Turn LEDs off
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
/restart:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
summary: Restart BTClock
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Settings:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
fetchEurPrice:
|
||||||
|
type: boolean
|
||||||
|
description: Fetch EUR price instead of USD
|
||||||
|
fgColor:
|
||||||
|
type: string
|
||||||
|
default: 0xFFFFFF
|
||||||
|
description: ePaper foreground (text) color
|
||||||
|
bgColor:
|
||||||
|
type: string
|
||||||
|
default: 0x000000
|
||||||
|
description: ePaper background color
|
||||||
|
ledTestOnPower:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
description: Do LED test on power-on
|
||||||
|
ledFlashOnUpd:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
description: Flash LEDs on new block
|
||||||
|
mdnsEnabled:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
description: Enable mDNS
|
||||||
|
otaEnabled:
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
description: Enable over-the-air updates
|
||||||
|
stealFocusOnBlock:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
description: Steal focus on new block
|
||||||
|
mcapBigChar:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
description: Use big characters for market cap screen
|
||||||
|
mempoolInstance:
|
||||||
|
type: string
|
||||||
|
default: mempool.space
|
||||||
|
description: Mempool.space instance to connect to
|
||||||
|
ledBrightness:
|
||||||
|
type: integer
|
||||||
|
default: 128
|
||||||
|
description: Brightness of LEDs
|
||||||
|
fullRefreshMin:
|
||||||
|
type: integer
|
||||||
|
default: 60
|
||||||
|
description: Full refresh time of ePaper displays in minutes
|
||||||
|
screen[0]:
|
||||||
|
type: boolean
|
||||||
|
screen[1]:
|
||||||
|
type: boolean
|
||||||
|
screen[2]:
|
||||||
|
type: boolean
|
||||||
|
screen[3]:
|
||||||
|
type: boolean
|
||||||
|
screen[4]:
|
||||||
|
type: boolean
|
||||||
|
screen[5]:
|
||||||
|
type: boolean
|
||||||
|
tzOffset:
|
||||||
|
type: integer
|
||||||
|
default: 60
|
||||||
|
description: Timezone offset in minutes
|
||||||
|
minSecPriceUpd:
|
||||||
|
type: integer
|
||||||
|
default: 30
|
||||||
|
description: Minimum time between price updates in seconds
|
||||||
|
timePerScreen:
|
||||||
|
type: integer
|
||||||
|
default: 30
|
||||||
|
description: Time between screens when rotating in minutes
|
||||||
|
CustomText:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
minItems: 7
|
||||||
|
maxItems: 7
|
|
@ -1,48 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<meta name="description" content="">
|
|
||||||
<link href="/css/style.css" rel="stylesheet">
|
|
||||||
<title>₿TClock WiFi Settings</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<nav class="navbar navbar-light bg-light">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<span class="navbar-brand mb-0 h1">₿TClock WiFi Settings</span>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="h-100 p-3 border bg-light">
|
|
||||||
<h1>WiFi Settings</h1>
|
|
||||||
<form name="customText" id="customTextForm" method="post" action="/setup/wifi">
|
|
||||||
<div class="row">
|
|
||||||
<label for="ssid" class="col-sm-4 col-form-label">SSID</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="text" class="form-control" id="ssid" name="ssid" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<label for="password" class="col-sm-4 col-form-label">Password</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="text" class="form-control" id="password" name="password" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<button type="submit" class="btn btn-primary">Save and connect</button>
|
|
||||||
<p><small>The BTClock will restart and connect to your network. If it doesn't, reset to factory settings by holding the red button while booting to retry.</small></p>
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -610,7 +610,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"chokidar@npm:>=3.0.0 <4.0.0":
|
"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.5.3":
|
||||||
version: 3.5.3
|
version: 3.5.3
|
||||||
resolution: "chokidar@npm:3.5.3"
|
resolution: "chokidar@npm:3.5.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -767,6 +767,7 @@ __metadata:
|
||||||
bootstrap: ^5.3.2
|
bootstrap: ^5.3.2
|
||||||
esbuild: 0.19.4
|
esbuild: 0.19.4
|
||||||
esbuild-plugin-clean: ^1.0.1
|
esbuild-plugin-clean: ^1.0.1
|
||||||
|
esbuild-plugin-copy: ^2.1.1
|
||||||
esbuild-plugin-handlebars: ^1.0.2
|
esbuild-plugin-handlebars: ^1.0.2
|
||||||
esbuild-sass-plugin: ^2.16.0
|
esbuild-sass-plugin: ^2.16.0
|
||||||
handlebars: ^4.7.7
|
handlebars: ^4.7.7
|
||||||
|
@ -959,6 +960,20 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"esbuild-plugin-copy@npm:^2.1.1":
|
||||||
|
version: 2.1.1
|
||||||
|
resolution: "esbuild-plugin-copy@npm:2.1.1"
|
||||||
|
dependencies:
|
||||||
|
chalk: ^4.1.2
|
||||||
|
chokidar: ^3.5.3
|
||||||
|
fs-extra: ^10.0.1
|
||||||
|
globby: ^11.0.3
|
||||||
|
peerDependencies:
|
||||||
|
esbuild: ">= 0.14.0"
|
||||||
|
checksum: d0122fa059e1cf8b80c3aa2cba1dee94ca28a992bb28ea5a4690399aa1fefdc6522c177e90a8373aa676c5fbd878f234a72cc004207c1262a6d334277a1e1368
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"esbuild-plugin-handlebars@npm:^1.0.2":
|
"esbuild-plugin-handlebars@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "esbuild-plugin-handlebars@npm:1.0.2"
|
resolution: "esbuild-plugin-handlebars@npm:1.0.2"
|
||||||
|
@ -1172,6 +1187,17 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"fs-extra@npm:^10.0.1":
|
||||||
|
version: 10.1.0
|
||||||
|
resolution: "fs-extra@npm:10.1.0"
|
||||||
|
dependencies:
|
||||||
|
graceful-fs: ^4.2.0
|
||||||
|
jsonfile: ^6.0.1
|
||||||
|
universalify: ^2.0.0
|
||||||
|
checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"fs-minipass@npm:^2.0.0":
|
"fs-minipass@npm:^2.0.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "fs-minipass@npm:2.1.0"
|
resolution: "fs-minipass@npm:2.1.0"
|
||||||
|
@ -1277,7 +1303,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"globby@npm:^11.0.1":
|
"globby@npm:^11.0.1, globby@npm:^11.0.3":
|
||||||
version: 11.1.0
|
version: 11.1.0
|
||||||
resolution: "globby@npm:11.1.0"
|
resolution: "globby@npm:11.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1291,7 +1317,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6":
|
"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6":
|
||||||
version: 4.2.11
|
version: 4.2.11
|
||||||
resolution: "graceful-fs@npm:4.2.11"
|
resolution: "graceful-fs@npm:4.2.11"
|
||||||
checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7
|
checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7
|
||||||
|
@ -1614,6 +1640,19 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"jsonfile@npm:^6.0.1":
|
||||||
|
version: 6.1.0
|
||||||
|
resolution: "jsonfile@npm:6.1.0"
|
||||||
|
dependencies:
|
||||||
|
graceful-fs: ^4.1.6
|
||||||
|
universalify: ^2.0.0
|
||||||
|
dependenciesMeta:
|
||||||
|
graceful-fs:
|
||||||
|
optional: true
|
||||||
|
checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"lodash._reinterpolate@npm:^3.0.0":
|
"lodash._reinterpolate@npm:^3.0.0":
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
resolution: "lodash._reinterpolate@npm:3.0.0"
|
resolution: "lodash._reinterpolate@npm:3.0.0"
|
||||||
|
@ -2522,6 +2561,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"universalify@npm:^2.0.0":
|
||||||
|
version: 2.0.1
|
||||||
|
resolution: "universalify@npm:2.0.1"
|
||||||
|
checksum: ecd8469fe0db28e7de9e5289d32bd1b6ba8f7183db34f3bfc4ca53c49891c2d6aa05f3fb3936a81285a905cc509fb641a0c3fc131ec786167eff41236ae32e60
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"update-browserslist-db@npm:^1.0.13":
|
"update-browserslist-db@npm:^1.0.13":
|
||||||
version: 1.0.13
|
version: 1.0.13
|
||||||
resolution: "update-browserslist-db@npm:1.0.13"
|
resolution: "update-browserslist-db@npm:1.0.13"
|
||||||
|
|
|
@ -12,7 +12,6 @@ void setupWebserver()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
events.onConnect([](AsyncEventSourceClient *client)
|
events.onConnect([](AsyncEventSourceClient *client)
|
||||||
{ client->send("welcome", NULL, millis(), 1000); });
|
{ client->send("welcome", NULL, millis(), 1000); });
|
||||||
server.addHandler(&events);
|
server.addHandler(&events);
|
||||||
|
@ -20,6 +19,8 @@ void setupWebserver()
|
||||||
server.serveStatic("/css", LittleFS, "/css/");
|
server.serveStatic("/css", LittleFS, "/css/");
|
||||||
server.serveStatic("/js", LittleFS, "/js/");
|
server.serveStatic("/js", LittleFS, "/js/");
|
||||||
server.serveStatic("/font", LittleFS, "/font/");
|
server.serveStatic("/font", LittleFS, "/font/");
|
||||||
|
server.serveStatic("/api.json", LittleFS, "/api.json");
|
||||||
|
server.serveStatic("/api.html", LittleFS, "/api.html");
|
||||||
|
|
||||||
server.on("/", HTTP_GET, onIndex);
|
server.on("/", HTTP_GET, onIndex);
|
||||||
|
|
||||||
|
@ -52,6 +53,8 @@ void setupWebserver()
|
||||||
server.onNotFound(onNotFound);
|
server.onNotFound(onNotFound);
|
||||||
|
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||||
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
|
||||||
|
|
||||||
server.begin();
|
server.begin();
|
||||||
|
|
||||||
|
@ -177,6 +180,10 @@ void onApiFullRefresh(AsyncWebServerRequest *request)
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Api
|
||||||
|
* @Path("/api/show/screen")
|
||||||
|
*/
|
||||||
void onApiShowScreen(AsyncWebServerRequest *request)
|
void onApiShowScreen(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
if (request->hasParam("s"))
|
if (request->hasParam("s"))
|
||||||
|
@ -523,9 +530,12 @@ void onApiLightsSetColor(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
String rgbColor = request->getParam("c")->value();
|
String rgbColor = request->getParam("c")->value();
|
||||||
|
|
||||||
if (rgbColor.compareTo("off") == 0) {
|
if (rgbColor.compareTo("off") == 0)
|
||||||
|
{
|
||||||
setLights(0, 0, 0);
|
setLights(0, 0, 0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uint r, g, b;
|
uint r, g, b;
|
||||||
sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b);
|
sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b);
|
||||||
setLights(r, g, b);
|
setLights(r, g, b);
|
||||||
|
@ -538,7 +548,9 @@ void onIndex(AsyncWebServerRequest *request) { request->send(LittleFS, "/index.h
|
||||||
|
|
||||||
void onNotFound(AsyncWebServerRequest *request)
|
void onNotFound(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
if (request->method() == HTTP_OPTIONS)
|
// Access-Control-Request-Method == POST might be better
|
||||||
|
|
||||||
|
if (request->method() == HTTP_OPTIONS || request->hasHeader("Sec-Fetch-Mode"))
|
||||||
{
|
{
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue