Created the placeholder for the contact_printer dev server. This will accept a post from the ESP32 with a report after each run. This data can be used in developing features.
This commit is contained in:
parent
d3da5705f3
commit
2ea7cb2e8d
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
.env
|
|
@ -0,0 +1,35 @@
|
||||||
|
# contact printer dev server
|
||||||
|
|
||||||
|
The purpose of this project is to host a dev server that development branches of the contact printer can post reports to after running.
|
||||||
|
This can be used for profiling the operation with different settings, hardware and conditions.
|
||||||
|
Reports will log data as it is needed without a specific goal from the outset, largely looking at speed of motors over time compared to PWM and can be used to improve performance or documentation.
|
||||||
|
|
||||||
|
The server has no frontend and simply accepts a post from the ESP32 running the contact printer and inserts the data into the SQLite database.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
Install the node dependencies for running the server.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --omit=dev
|
||||||
|
```
|
||||||
|
|
||||||
|
If you would like to develop the server, install the complete set of dependencies.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node dist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Developing
|
||||||
|
|
||||||
|
If you make changes to the Typescript in source, recompile the server code.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run compile
|
||||||
|
```
|
|
@ -0,0 +1 @@
|
||||||
|
PORT=9999
|
|
@ -0,0 +1,32 @@
|
||||||
|
"use strict";
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
require("dotenv/config");
|
||||||
|
const express_1 = __importDefault(require("express"));
|
||||||
|
const body_parser_1 = __importDefault(require("body-parser"));
|
||||||
|
const log_1 = require("./log");
|
||||||
|
const PORT = typeof process.env['PORT'] !== 'undefined' ? parseInt(process.env['PORT'], 10) : 9999;
|
||||||
|
let db;
|
||||||
|
const app = (0, express_1.default)();
|
||||||
|
const log = (0, log_1.createLog)('server');
|
||||||
|
app.use(body_parser_1.default.json());
|
||||||
|
app.use(body_parser_1.default.urlencoded({ extended: true }));
|
||||||
|
async function setup() {
|
||||||
|
//db = new Database('./data.sqlite');
|
||||||
|
}
|
||||||
|
async function report(req, res, next) {
|
||||||
|
//
|
||||||
|
log.info(`Added record`);
|
||||||
|
res.json({ success: true });
|
||||||
|
}
|
||||||
|
app.post('/', report);
|
||||||
|
async function main() {
|
||||||
|
await setup();
|
||||||
|
app.listen(PORT, async () => {
|
||||||
|
log.info(`contact_printer_dev_server running on port ${PORT}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,yBAAuB;AACvB,sDAA8B;AAK9B,8DAAqC;AAGrC,+BAAiC;AAGjC,MAAM,IAAI,GAAY,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAE5G,IAAI,EAAa,CAAC;AAClB,MAAM,GAAG,GAAa,IAAA,iBAAO,GAAE,CAAC;AAChC,MAAM,GAAG,GAAY,IAAA,eAAS,EAAC,QAAQ,CAAC,CAAC;AAEzC,GAAG,CAAC,GAAG,CAAC,qBAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3B,GAAG,CAAC,GAAG,CAAC,qBAAU,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAGnD,KAAK,UAAU,KAAK;IACnB,qCAAqC;AACtC,CAAC;AAED,KAAK,UAAU,MAAM,CAAE,GAAa,EAAE,GAAa,EAAE,IAAmB;IACvE,EAAE;IACF,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAG,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAGtB,KAAK,UAAU,IAAI;IAClB,MAAM,KAAK,EAAE,CAAC;IACd,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;QAC3B,GAAG,CAAC,IAAI,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@ -0,0 +1,50 @@
|
||||||
|
'use strict';
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.createLog = void 0;
|
||||||
|
/** @module log */
|
||||||
|
/** Wrapper for winston that tags streams and optionally writes files with a simple interface. */
|
||||||
|
/** Module now also supports optional papertrail integration, other services to follow */
|
||||||
|
const winston_1 = require("winston");
|
||||||
|
const { SPLAT } = require('triple-beam');
|
||||||
|
const { isObject } = require('lodash');
|
||||||
|
const APP_NAME = process.env.APP_NAME || 'default';
|
||||||
|
let winstonPapertrail;
|
||||||
|
function formatObject(param) {
|
||||||
|
if (isObject(param)) {
|
||||||
|
return JSON.stringify(param);
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
const all = (0, winston_1.format)((info) => {
|
||||||
|
const splat = info[SPLAT] || [];
|
||||||
|
const message = formatObject(info.message);
|
||||||
|
const rest = splat.map(formatObject).join(' ');
|
||||||
|
info.message = `${message} ${rest}`;
|
||||||
|
return info;
|
||||||
|
});
|
||||||
|
const myFormat = winston_1.format.printf(({ level, message, label, timestamp }) => {
|
||||||
|
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
* Returns a winston logger configured to service
|
||||||
|
*
|
||||||
|
* @param {string} label Label appearing on logger
|
||||||
|
* @param {string} filename Optional file to write log to
|
||||||
|
*
|
||||||
|
* @returns {object} Winston logger
|
||||||
|
*/
|
||||||
|
function createLog(label, filename = null) {
|
||||||
|
const tports = [new (winston_1.transports.Console)()];
|
||||||
|
const fmat = winston_1.format.combine(all(), winston_1.format.label({ label }), winston_1.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }), winston_1.format.colorize(), myFormat);
|
||||||
|
let papertrailOpts;
|
||||||
|
if (filename !== null) {
|
||||||
|
tports.push(new (winston_1.transports.File)({ filename }));
|
||||||
|
}
|
||||||
|
return (0, winston_1.createLogger)({
|
||||||
|
format: fmat,
|
||||||
|
transports: tports
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.createLog = createLog;
|
||||||
|
module.exports = { createLog };
|
||||||
|
//# sourceMappingURL=log.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAEZ,kBAAkB;AAClB,iGAAiG;AACjG,yFAAyF;AAEzF,qCAA2D;AAC3D,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;AACzC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvC,MAAM,QAAQ,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC;AAE5D,IAAI,iBAAiB,CAAC;AAEtB,SAAS,YAAY,CAAE,KAAW;IAChC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,GAAG,GAAG,IAAA,gBAAM,EAAC,CAAC,IAAU,EAAE,EAAE;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,gBAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAQ,EAAE,EAAE;IAC5E,OAAO,GAAG,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,OAAO,EAAE,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH;;;;;;;EAOE;AACF,SAAgB,SAAS,CAAE,KAAc,EAAE,WAAoB,IAAI;IAC/D,MAAM,MAAM,GAAW,CAAE,IAAI,CAAC,oBAAU,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC;IACtD,MAAM,IAAI,GAAS,gBAAM,CAAC,OAAO,CAC7B,GAAG,EAAE,EACL,gBAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,EACvB,gBAAM,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,yBAAyB,EAAC,CAAC,EACrD,gBAAM,CAAC,QAAQ,EAAE,EACjB,QAAQ,CACX,CAAC;IACF,IAAI,cAAoB,CAAC;IAEzB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAE,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAE,CAAC;IACvD,CAAC;IAED,OAAO,IAAA,sBAAY,EAAC;QAChB,MAAM,EAAG,IAAI;QACb,UAAU,EAAG,MAAM;KACtB,CAAC,CAAC;AACP,CAAC;AAnBD,8BAmBC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,SAAS,EAAE,CAAC"}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "contact_printer_dev_server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Server for receiving data from contact printer for profiling performance.",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"compile": "./node_modules/.bin/tsc -p tsconfig.json",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git.sixteenmillimeter.com/16mm/contact_printer.git"
|
||||||
|
},
|
||||||
|
"author": "mmcwilliams",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/multer": "^1.4.11",
|
||||||
|
"@types/node": "^20.11.20",
|
||||||
|
"@types/uuid": "^9.0.8",
|
||||||
|
"@types/winston": "^2.4.4",
|
||||||
|
"typescript": "^5.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.20.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"sqlite3": "^5.1.7",
|
||||||
|
"triple-beam": "^1.4.1",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS queue (
|
||||||
|
id TEXT(36) PRIMARY KEY,
|
||||||
|
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'dotenv/config';
|
||||||
|
import express from 'express';
|
||||||
|
import { Express, Request, Response, NextFunction } from 'express'
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { Database } from 'sqlite3';
|
||||||
|
import bodyParser from 'body-parser';
|
||||||
|
import multer from 'multer';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import { createLog } from './log'
|
||||||
|
import type { Logger } from 'winston';
|
||||||
|
|
||||||
|
const PORT : number = typeof process.env['PORT'] !== 'undefined' ? parseInt(process.env['PORT'], 10) : 9999;
|
||||||
|
|
||||||
|
let db : Database;
|
||||||
|
const app : Express = express();
|
||||||
|
const log : Logger = createLog('server');
|
||||||
|
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.use(bodyParser.urlencoded({ extended: true }));
|
||||||
|
|
||||||
|
|
||||||
|
async function setup () {
|
||||||
|
//db = new Database('./data.sqlite');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function report (req : Request, res: Response, next : NextFunction) {
|
||||||
|
//
|
||||||
|
log.info(`Added record`);
|
||||||
|
res.json({ success : true });
|
||||||
|
}
|
||||||
|
|
||||||
|
app.post('/', report);
|
||||||
|
|
||||||
|
|
||||||
|
async function main () {
|
||||||
|
await setup();
|
||||||
|
app.listen(PORT, async () => {
|
||||||
|
log.info(`contact_printer_dev_server running on port ${PORT}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
|
@ -0,0 +1,63 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/** @module log */
|
||||||
|
/** Wrapper for winston that tags streams and optionally writes files with a simple interface. */
|
||||||
|
/** Module now also supports optional papertrail integration, other services to follow */
|
||||||
|
|
||||||
|
import { format, transports, createLogger } from 'winston';
|
||||||
|
const { SPLAT } = require('triple-beam');
|
||||||
|
const { isObject } = require('lodash');
|
||||||
|
|
||||||
|
const APP_NAME : string = process.env.APP_NAME || 'default';
|
||||||
|
|
||||||
|
let winstonPapertrail;
|
||||||
|
|
||||||
|
function formatObject (param : any) {
|
||||||
|
if (isObject(param)) {
|
||||||
|
return JSON.stringify(param);
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
const all = format((info : any) => {
|
||||||
|
const splat = info[SPLAT] || [];
|
||||||
|
const message = formatObject(info.message);
|
||||||
|
const rest = splat.map(formatObject).join(' ');
|
||||||
|
info.message = `${message} ${rest}`;
|
||||||
|
return info;
|
||||||
|
});
|
||||||
|
|
||||||
|
const myFormat = format.printf(({ level, message, label, timestamp } : any) => {
|
||||||
|
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a winston logger configured to service
|
||||||
|
*
|
||||||
|
* @param {string} label Label appearing on logger
|
||||||
|
* @param {string} filename Optional file to write log to
|
||||||
|
*
|
||||||
|
* @returns {object} Winston logger
|
||||||
|
*/
|
||||||
|
export function createLog (label : string, filename : string = null) {
|
||||||
|
const tports : any[] = [ new (transports.Console)() ];
|
||||||
|
const fmat : any = format.combine(
|
||||||
|
all(),
|
||||||
|
format.label({ label }),
|
||||||
|
format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
|
||||||
|
format.colorize(),
|
||||||
|
myFormat,
|
||||||
|
);
|
||||||
|
let papertrailOpts : any;
|
||||||
|
|
||||||
|
if (filename !== null) {
|
||||||
|
tports.push( new (transports.File)({ filename }) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return createLogger({
|
||||||
|
format : fmat,
|
||||||
|
transports : tports
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { createLog };
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"target": "ES2020",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": true,
|
||||||
|
"removeComments" : false,
|
||||||
|
"baseUrl" : "dist",
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"rootDir" : "./src/",
|
||||||
|
"paths" : {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude" : [
|
||||||
|
"./dist"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue