From f897b3bf50b021816011f51dd9e8861ef308e196 Mon Sep 17 00:00:00 2001 From: norman-andrians Date: Mon, 4 Mar 2024 20:34:35 +0700 Subject: [PATCH] Piezo music, setup socket events --- src/controller/led.ts | 17 +----------- src/controller/piezo.ts | 52 +++++++++++++++++++++++++++++------ src/controller/pin.ts | 14 ---------- src/controller/servo.ts | 0 src/handlers/socketHandler.ts | 17 ++++++++++++ src/index.ts | 3 ++ src/middleware/pin.ts | 15 +++++++++- src/routes/api.ts | 15 ++++++---- 8 files changed, 88 insertions(+), 45 deletions(-) create mode 100644 src/controller/servo.ts create mode 100644 src/handlers/socketHandler.ts diff --git a/src/controller/led.ts b/src/controller/led.ts index c9e9c9d..e091c26 100644 --- a/src/controller/led.ts +++ b/src/controller/led.ts @@ -1,7 +1,6 @@ import { Request, Response } from "express"; import { board } from "../setup"; import { ChannelPins, digitalValue, voltage } from "."; -import { analogRead, digitalRead } from "../promises"; import { Led } from "johnny-five"; @@ -9,13 +8,6 @@ export async function readLed (req: Request, res: Response) { const { p } = req.params; const pin: number = Number.parseInt(p); - if (Number.isNaN(pin)) { - return res.status(400).json({ - status: 400, - message: 'Invalid pin param, it should be integer' - }); - } - const pinState: digitalValue = board.pins[pin].value == 1 ? 'ON' : 'OFF'; return res.status(200).json({ @@ -35,13 +27,6 @@ export async function writeLed (req: Request, res: Response) { let volt: voltage; try { - if (Number.isNaN(pin)) { - return res.status(400).json({ - status: 400, - message: 'Invalid pin param, it should be integer' - }); - } - switch (act) { case 'on': state = 'ON'; @@ -126,7 +111,7 @@ export async function writeRgbLed (req: Request, res: Response) { const rgbLeds: ChannelPins[] = Object.values({ r, g, b }); try { - rgbLeds.forEach((led, i) => { + rgbLeds.forEach(led => { if (Number.isNaN(led.pin)) { return res.status(400).json({ status: 400, diff --git a/src/controller/piezo.ts b/src/controller/piezo.ts index a0c42b1..f921f54 100644 --- a/src/controller/piezo.ts +++ b/src/controller/piezo.ts @@ -2,17 +2,10 @@ import { Request, Response } from "express"; import { Piezo } from "johnny-five"; import { Pitch } from "../melodies"; -export function piezoTone (req: Request, res: Response) { +export function piezoTone (req: Request, res: Response): Response { const pin: number = Number.parseInt(req.params.p); const note: string = req.params.n; - if (Number.isNaN(pin)) { - return res.status(400).json({ - status: 400, - message: 'Invalid pin param, it should be integer' - }); - } - const piezo = new Piezo(pin); piezo.play({ @@ -25,4 +18,47 @@ export function piezoTone (req: Request, res: Response) { status: 200, message: `Piezo ${pin} tone ${note}` }); +} + +export function piezoNoTone (req: Request, res: Response): Response { + const pin: number = Number.parseInt(req.params.p); + if (Number.isNaN(pin)) { + return res.status(400).json({ + status: 400, + message: 'Invalid pin param, it should be integer' + }); + } + + new Piezo(pin).noTone(); + + return res.sendStatus(200); +} + +interface MusicSheet { + notes: string[]; + beats: number; + tempo: 100 +} + +export function piezoPlayNotes (req: Request, res: Response): Response { + const pin: number = Number.parseInt(req.params.p); + const { notes, beats, tempo }: MusicSheet = req.body; + + if (Number.isNaN(pin)) { + return res.status(400).json({ + status: 400, + message: 'Invalid pin param, it should be integer' + }); + } + + const piezo: Piezo = new Piezo(pin); + const song: [frequency: string, duration: number][] = notes.map((note): [frequency: string, duration: number] => { return [note, beats]}); + const notesS: string = notes.join(", "); + + piezo.play({ song, tempo }); + + return res.status(200).json({ + status: 200, + message: `Piezo ${pin} play notes ${notesS}` + }); } \ No newline at end of file diff --git a/src/controller/pin.ts b/src/controller/pin.ts index dcc6b23..5bd8f8d 100644 --- a/src/controller/pin.ts +++ b/src/controller/pin.ts @@ -6,13 +6,6 @@ import { Pin } from "johnny-five"; export function readPin (req: Request, res: Response) { const pin: number = Number.parseInt(req.params.p); - if (Number.isNaN(pin)) { - return res.status(400).json({ - status: 400, - message: 'Invalid pin param, it should be integer' - }); - } - const { mode } = board.pins[pin]; return res.status(200).json({ @@ -27,13 +20,6 @@ export function readPin (req: Request, res: Response) { export function setPin (req: Request, res: Response) { const pin: number = Number.parseInt(req.params.p); const mode: sPinModes | string = req.params.m.toUpperCase(); - - if (Number.isNaN(pin)) { - return res.status(400).json({ - status: 400, - message: 'Invalid pin param, it should be integer' - }); - } board.pinMode(pin, Pin[mode]); diff --git a/src/controller/servo.ts b/src/controller/servo.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/handlers/socketHandler.ts b/src/handlers/socketHandler.ts new file mode 100644 index 0000000..58a96b6 --- /dev/null +++ b/src/handlers/socketHandler.ts @@ -0,0 +1,17 @@ +import { Socket } from "socket.io"; +import { board } from "../setup"; + +export default (socket: Socket) => { + console.log(`${socket.id} | ${socket.client.request.headers.host} | Joined`); + + socket.on("control-servo", (pin: number, angle: number) => { + board.servoWrite(pin, angle); + console.log(); + }) + + socket.on("read-photoresistor", (pin: string) => { + board.analogRead(pin, (value) => { + socket.emit("read-photoresistor", value); + }); + }) +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 5b92770..7fba74b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import { isBoardConnected } from './middleware/connection'; import view from './routes/view'; import api from './routes/api'; import { selectPort } from './ports'; +import socketHandler from './handlers/socketHandler'; const app = express(); const server = http.createServer(app); @@ -20,6 +21,8 @@ const port = 3000; app.use(express.json()); app.use(express.static('client')); +io.on('connection', socketHandler); + app.use('/', view); app.use('/api-arduino', isBoardConnected, api); diff --git a/src/middleware/pin.ts b/src/middleware/pin.ts index cfbb3bb..85af50c 100644 --- a/src/middleware/pin.ts +++ b/src/middleware/pin.ts @@ -1,7 +1,20 @@ import { NextFunction, Request, Response } from "express"; import { suBoard } from "../setup"; -export function isPinBeingUsed(req: Request, res: Response, next: NextFunction) { +export function isPinNumeric (req: Request, res: Response, next: NextFunction) { + const pin: number = Number.parseInt(req.params.p); + + if (Number.isNaN(pin)) { + return res.status(400).json({ + status: 400, + message: 'Invalid pin param, it should be integer' + }); + } + + next(); +} + +export function isPinBeingUsed (req: Request, res: Response, next: NextFunction) { const pin: number = Number.parseInt(req.params.p); if (Number.isNaN(pin)) { diff --git a/src/routes/api.ts b/src/routes/api.ts index d358b6e..6b2af8f 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -3,7 +3,8 @@ import { Router } from "express"; import { readLed, readRgbLed, writeLed, writeRgbLed } from "../controller/led"; import { readPin, setPin } from "../controller/pin"; -import { piezoTone } from "../controller/piezo"; +import { piezoNoTone, piezoPlayNotes, piezoTone } from "../controller/piezo"; +import { isPinNumeric } from "../middleware/pin"; const router: Router = Router(); @@ -11,15 +12,17 @@ router.get('/hello', (req, res: Response): Response => { return res.status(200).send("Hello"); }) -router.get('/pin/:p', readPin); -router.patch('/pin/:p/:m', setPin); +router.get('/pin/:p', isPinNumeric, readPin); +router.patch('/pin/:p/:m', isPinNumeric, setPin); -router.get('/led/:p', readLed); -router.patch('/led/:p/:a', writeLed); +router.get('/led/:p', isPinNumeric, readLed); +router.patch('/led/:p/:a', isPinNumeric, writeLed); router.get('/rgb-led', readRgbLed); router.patch('/rgb-led/', writeRgbLed); -router.patch('/piezo/:p/:n', piezoTone); +router.patch('/piezo/:p/:n', isPinNumeric, piezoTone); +router.patch('/piezo/stop/:p/', isPinNumeric, piezoNoTone); +router.patch('/piezo/music/:p', isPinNumeric, piezoPlayNotes); export default router; \ No newline at end of file