From adc1a26856525d849d5cea3c65775dd0478749b0 Mon Sep 17 00:00:00 2001 From: Carsten Keller Date: Fri, 16 Feb 2024 18:43:13 +0100 Subject: [PATCH] Webserver und Datenbank starten sowie Datenabrufen von ioBroker --- Server/server/DataHandler.ts | 51 +++++++++++++++++++ Server/server/DataRequester.ts | 27 ++++++++++ Server/server/FileHandler.ts | 87 ++++++++++++++++++--------------- Server/server/LocalDatabase.ts | 63 ++++++++++++++++++++++++ Server/server/RequestHandler.ts | 46 +++++++++++------ Server/server/Webserver.ts | 28 ++++++----- Server/server/main.ts | 11 ++++- 7 files changed, 244 insertions(+), 69 deletions(-) create mode 100644 Server/server/DataHandler.ts create mode 100644 Server/server/DataRequester.ts create mode 100644 Server/server/LocalDatabase.ts diff --git a/Server/server/DataHandler.ts b/Server/server/DataHandler.ts new file mode 100644 index 0000000..20d0412 --- /dev/null +++ b/Server/server/DataHandler.ts @@ -0,0 +1,51 @@ +import { cfg } from "./Config"; +import { Database } from "./LocalDatabase"; + +export class DataHandler { + private db: &Database; + + constructor(db: &Database) { + this.db = db; + } + + valid_uri(uri: string) { + let found: boolean = false; + for(const key of Object.keys(cfg)) { + if(cfg[key].uri == uri) { + found = true; + break; + } + } + return found; + } + + get_data_json(uri: string): string { + let found: boolean = false; + let data: string = '{'; + let dp; + for(const key of Object.keys(cfg)) { + if(cfg[key].uri == uri) { + found = true; + dp = cfg[key]; + break; + } + } + + let add_comma: boolean = false; + let o = Object.keys(dp); + o.forEach(d => { + let s = this.db.get(dp[d]); + if(s != null) { + if(add_comma) { + data += "," + } + data += '"' + d + '":"' + s + '"'; + add_comma = true; + } + }); + + data += '}'; + + return data; + } +} \ No newline at end of file diff --git a/Server/server/DataRequester.ts b/Server/server/DataRequester.ts new file mode 100644 index 0000000..ca0b590 --- /dev/null +++ b/Server/server/DataRequester.ts @@ -0,0 +1,27 @@ +import { IncomingMessage, request } from "http"; +import { Database } from "./LocalDatabase"; + +export function request_data(id: string, self: &Database): void { + let url: string = 'http://192.168.178.34:8082/getBulk/' + id; + let data: string = ""; + + let req = request(url, (res: IncomingMessage) => { + res.setEncoding('utf8'); + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + let d = JSON.parse(data); + d.forEach(element => { + self.add(element.id, element.val) + }); + }); + }); + + req.on('error', (e) => { + console.error(`problem with request: ${e.message}`); + }); + req.end(); +} \ No newline at end of file diff --git a/Server/server/FileHandler.ts b/Server/server/FileHandler.ts index 1419df9..c1829bc 100644 --- a/Server/server/FileHandler.ts +++ b/Server/server/FileHandler.ts @@ -1,21 +1,10 @@ import { existsSync, readFileSync } from 'node:fs'; -import { www_folder, index_alias } from './Webserver'; -class Mapping { +interface Mapping { ending: string; encoding: string; } -const mappings: Mapping[] = [ - { ending: 'html', encoding: 'text/html' }, - { ending: 'js', encoding: 'text/javascript' }, - { ending: 'css', encoding: 'text/css' }, - { ending: 'json', encoding: 'application/json' }, - { ending: 'ico', encoding: 'image/x-icon' }, - { ending: 'svg', encoding: 'image/svg+xml' }, - { ending: 'txt', encoding: 'text/plain' }, -] - export class File { type: string; content: Buffer; @@ -26,37 +15,55 @@ export class File { } } -export function file_allowed(url: string): boolean { - let allowed: boolean = false; - let m = url.match('\\.\\.'); - if (m == null) { - allowed = true; - } - return allowed; -} +export class FileHandler { -export function file_exists(url: string): boolean { - if(url == '/') { - url = index_alias; - } - return existsSync(www_folder + url); -} + private www_folder: string = '/home/carsten/Dokumente/SmartHomeDashboard/html/'; + private index_alias: string = 'index.html'; -export function file_get(url: string): File { - if(url == '/') { - url = index_alias; - } - return new File(get_type(url), readFileSync(www_folder + url)); -} + private mappings: Mapping[] = [ + { ending: 'html', encoding: 'text/html' }, + { ending: 'js', encoding: 'text/javascript' }, + { ending: 'css', encoding: 'text/css' }, + { ending: 'json', encoding: 'application/json' }, + { ending: 'ico', encoding: 'image/x-icon' }, + { ending: 'svg', encoding: 'image/svg+xml' }, + { ending: 'txt', encoding: 'text/plain' }, + ] -function get_type(url: string): string { - if(url == '/') { - url = index_alias; + + + file_allowed(url: string): boolean { + let allowed: boolean = false; + let m = url.match('\\.\\.'); + if (m == null) { + allowed = true; + } + return allowed; } - let type: string = 'application/octet-stream'; - let m: Mapping = mappings.find((e) => e.ending == url.split('.').pop()); - if(m != undefined) { - type = m.encoding; + + file_exists(url: string): boolean { + if(url == '/') { + url = this.index_alias; + } + return existsSync(this.www_folder + url); + } + + file_get(url: string): File { + if(url == '/') { + url = this.index_alias; + } + return new File(this.get_type(url), readFileSync(this.www_folder + url)); + } + + private get_type(url: string): string { + if(url == '/') { + url = this.index_alias; + } + let type: string = 'application/octet-stream'; + let m: Mapping = this.mappings.find((e) => e.ending == url.split('.').pop()); + if(m != undefined) { + type = m.encoding; + } + return type; } - return type; } \ No newline at end of file diff --git a/Server/server/LocalDatabase.ts b/Server/server/LocalDatabase.ts new file mode 100644 index 0000000..6067047 --- /dev/null +++ b/Server/server/LocalDatabase.ts @@ -0,0 +1,63 @@ +import { Config, cfg } from "./Config"; +import { request_data } from "./DataRequester"; + +export class Database { + private db: Datapoint[] = []; + + constructor() { + let groups = Object.keys(cfg); + groups.forEach(group => { + let members = Object.keys(cfg[group]); + members.forEach(member => { + if((member != "text") && (member != "uri")) { + this.add(cfg[group][member]) + } + }); + }); + } + + add(id: string, value?: string, type?: string): void { + let found: boolean = false; + this.db.forEach(element => { + if(element.id == id) { + element.value = value; + element.type = type + found = true; + } + }); + if(!found) { + this.db.push(new Datapoint(id, value, type)); + } + } + + get(id: string): string { + for(const el of this.db) { + if(el.id == id) { + return el.value; + } + } + return null; + } + + start(): void { + setInterval(this.cyclic_requets, 1000, this); + } + + cyclic_requets(self: &Database): void { + self.db.forEach(element => { + request_data(element.id, self) + }); + } +} + +class Datapoint { + id: string; + value: string; + type: string; + + constructor(id: string, value: string, type: string) { + this.id = id; + this.type = type; + this.value = value; + } +} diff --git a/Server/server/RequestHandler.ts b/Server/server/RequestHandler.ts index 937a8d0..f5797ef 100644 --- a/Server/server/RequestHandler.ts +++ b/Server/server/RequestHandler.ts @@ -1,19 +1,35 @@ import { IncomingMessage, ServerResponse } from "node:http"; -import { file_allowed, file_exists, file_get, File } from "./FileHandler"; +import { FileHandler, File } from "./FileHandler"; +import { DataHandler } from "./DataHandler"; +import { Database } from "./LocalDatabase"; -export function new_request(req: IncomingMessage, res: ServerResponse): void { - if(file_allowed(req.url)) { - if(file_exists(req.url)) { - res.statusCode = 200; - let f: File = file_get(req.url) - res.setHeader('Content-Type', f.type); - res.end(f.content); - } else { - res.statusCode = 404; - } - } else { - res.statusCode = 403; +export class RequestHandler { + static dh: DataHandler; + private fh: FileHandler; + + constructor(db: &Database) { + RequestHandler.dh = new DataHandler(db); + } + + new_request(req: IncomingMessage, res: ServerResponse): void { + if(RequestHandler.dh.valid_uri(req.url)) { + res.statusCode = 200; + res.setHeader('Content-Type', 'application/json'); + res.end(RequestHandler.dh.get_data_json(req.url)); + } + else if(this.fh.file_allowed(req.url)) { + if(this.fh.file_exists(req.url)) { + res.statusCode = 200; + let f: File = this.fh.file_get(req.url) + res.setHeader('Content-Type', f.type); + res.end(f.content); + } else { + res.statusCode = 404; + } + } else { + res.statusCode = 403; + } + console.log(req.url, res.statusCode); + res.end(); } - console.log(req.url, res.statusCode); - res.end(); } diff --git a/Server/server/Webserver.ts b/Server/server/Webserver.ts index 8c31ebb..583ee94 100644 --- a/Server/server/Webserver.ts +++ b/Server/server/Webserver.ts @@ -1,18 +1,22 @@ import { createServer } from 'node:http' -import { new_request } from './RequestHandler'; +import { RequestHandler } from './RequestHandler'; +import { Database } from './LocalDatabase'; +export class Webserver { + private port: number = 8080; + private hostname: string = '0.0.0.0'; + private rh: RequestHandler; -export const www_folder: string = '/home/carsten/Dokumente/SmartHomeDashboard/html/'; -export const index_alias: string = 'index.html'; -const port: number = 8080; -const hostname: string = '0.0.0.0'; + constructor(db: &Database) { + this.rh = new RequestHandler(db); + } + start_server(): void { -export function start_server(): void { - const server = createServer(new_request); - - server.listen(port, hostname, () => { - console.log('Server running at http://' + hostname + ':' + port); - }); -} + const server = createServer(this.rh.new_request); + server.listen(this.port, this.hostname, () => { + console.log('Server running at http://' + this.hostname + ':' + this.port); + }); + } +} \ No newline at end of file diff --git a/Server/server/main.ts b/Server/server/main.ts index f235402..7877ae8 100644 --- a/Server/server/main.ts +++ b/Server/server/main.ts @@ -1,4 +1,11 @@ -import { start_server } from "./Webserver"; +import { Webserver } from "./Webserver"; +import { Database } from "./LocalDatabase"; -start_server(); +let db = new Database(); +let ws = new Webserver(db); + +ws.start_server(); console.log("Server started"); + +db.start(); +console.log("DB started");