Laser Lens

29 views
Skip to first unread message

Jim Rawson

unread,
May 15, 2025, 9:46:57 AMMay 15
to milwaukee...@googlegroups.com
A potential solution to the lenses not being inspected and cleaned before and after use could be solved with an App that requires the user to upload a photo before and after.  It would probably add a minute or 2 to each session and cause Tony W. and Dan many headaches. I inquired (asked) Grok about this and here is what it suggested.   


Me: My makerspace has laser cutters. We are able to access them by swiping our RFID badge. Not everyone inspects and cleans the lenses before and after use. Can you help write an app that would require the user to upload a photo of the lens before and after use?


Grok: I’ll help you create a web-based app that requires users to upload photos of a laser cutter’s lens before and after use, tied to their RFID badge swipe. The app will be built using HTML, JavaScript, and a simple backend with Node.js and Express to handle file uploads and store data. For simplicity, I’ll assume you have a basic server setup and a way to integrate RFID data (e.g., a database or API providing user IDs). The app will store images with timestamps and user IDs in a server directory and log the data in a JSON file.


Here’s the plan:

- **Frontend**: A single-page HTML app with a form to input the RFID badge ID, select a laser cutter (1–6), and upload two images (before and after). Users must upload a “before” photo to start and an “after” photo to complete the session.

- **Backend**: A Node.js/Express server to handle image uploads, store them in a folder, and log session details (user ID, cutter number, timestamps, image paths) in a JSON file.

- **Assumptions**:

- RFID badge swipe provides a unique user ID (e.g., via a database or API you can query).

- Images are stored on the server in a folder (e.g., `uploads/`).

- No image analysis is required (just upload and store).

- Basic security (no authentication beyond RFID ID for simplicity).

- **Tech Stack**:

- Frontend: HTML, JavaScript, Tailwind CSS (via CDN for styling).

- Backend: Node.js, Express, `multer` for file uploads, `fs` for file handling.

- Storage: Images in a folder, metadata in a JSON file.

- **Limitations**:

- You’ll need to set up the server (Node.js) and ensure it’s accessible to your makerspace network.

- RFID integration is assumed to be handled externally (e.g., you provide the user ID).

- No database; a JSON file is used for simplicity. For production, consider a database like SQLite or MongoDB.


Below is the code for the app, split into two artifacts: the frontend (`index.html`) and the backend (`server.js`). I’ll also provide setup instructions.


### Frontend (index.html)

This creates a simple web page where users input their RFID ID, select a laser cutter, and upload before/after photos. JavaScript handles form submission and sends data to the backend.


```html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Laser Cutter Lens Photo App</title>

<script src="https://cdn.tailwindcss.com"></script>

</head>

<body class="bg-gray-100 flex items-center justify-center min-h-screen">

<div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-md">

<h1 class="text-2xl font-bold mb-6 text-center">Laser Cutter Lens Photo Upload</h1>

<form id="lensForm" enctype="multipart/form-data" class="space-y-4">

<div>

<label for="rfid" class="block text-sm font-medium text-gray-700">RFID Badge ID</label>

<input type="text" id="rfid" name="rfid" required class="mt-1 block w-full p-2 border border-gray-300 rounded-md">

</div>

<div>

<label for="cutter" class="block text-sm font-medium text-gray-700">Laser Cutter</label>

<select id="cutter" name="cutter" required class="mt-1 block w-full p-2 border border-gray-300 rounded-md">

<option value="">Select a cutter</option>

<option value="1">Cutter 1</option>

<option value="2">Cutter 2</option>

<option value="3">Cutter 3</option>

<option value="4">Cutter 4</option>

<option value="5">Cutter 5</option>

<option value="6">Cutter 6</option>

</select>

</div>

<div>

<label for="beforePhoto" class="block text-sm font-medium text-gray-700">Before Use Photo</label>

<input type="file" id="beforePhoto" name="beforePhoto" accept="image/*" required class="mt-1 block w-full p-2 border border-gray-300 rounded-md">

</div>

<div>

<label for="afterPhoto" class="block text-sm font-medium text-gray-700">After Use Photo</label>

<input type="file" id="afterPhoto" name="afterPhoto" accept="image/*" class="mt-1 block w-full p-2 border border-gray-300 rounded-md">

</div>

<button type="submit" class="w-full bg-blue-600 text-white p-2 rounded-md hover:bg-blue-700">Submit</button>

</form>

<p id="message" class="mt-4 text-center text-sm text-gray-600"></p>

</div>


<script>

const form = document.getElementById('lensForm');

const message = document.getElementById('message');


form.addEventListener('submit', async (e) => {

e.preventDefault();

const formData = new FormData(form);


// Check if beforePhoto is provided

if (!formData.get('beforePhoto').name) {

message.textContent = 'Please upload a "Before Use" photo.';

return;

}


try {

const response = await fetch('http://localhost:3000/upload', {

method: 'POST',

body: formData,

});

const result = await response.json();

if (response.ok) {

message.textContent = result.message;

form.reset();

} else {

message.textContent = result.error || 'An error occurred.';

}

} catch (err) {

message.textContent = 'Failed to connect to the server.';

}

});

</script>

</body>

</html>

```


### Backend (server.js)

This sets up a Node.js/Express server to handle image uploads, store them in an `uploads/` folder, and log session details in a `sessions.json` file.


```javascript

const express = require('express');

const multer = require('multer');

const fs = require('fs');

const path = require('path');

const app = express();

const port = 3000;


// Ensure uploads directory exists

const uploadDir = path.join(__dirname, 'uploads');

if (!fs.existsSync(uploadDir)) {

fs.mkdirSync(uploadDir);

}


// Configure multer for file uploads

const storage = multer.diskStorage({

destination: (req, file, cb) => {

cb(null, uploadDir);

},

filename: (req, file, cb) => {

const timestamp = Date.now();

const prefix = file.fieldname === 'beforePhoto' ? 'before' : 'after';

cb(null, `${prefix}-${req.body.rfid}-${req.body.cutter}-${timestamp}${path.extname(file.originalname)}`);

},

});

const upload = multer({ storage });


// Serve static files (e.g., index.html)

app.use(express.static(__dirname));


// Handle file uploads

app.post('/upload', upload.fields([

{ name: 'beforePhoto', maxCount: 1 },

{ name: 'afterPhoto', maxCount: 1 },

]), (req, res) => {

const { rfid, cutter } = req.body;

if (!rfid || !cutter || !req.files.beforePhoto) {

return res.status(400).json({ error: 'RFID, cutter number, and before photo are required.' });

}


// Prepare session data

const session = {

rfid,

cutter,

timestamp: new Date().toISOString(),

beforePhoto: req.files.beforePhoto ? req.files.beforePhoto[0].path : null,

afterPhoto: req.files.afterPhoto ? req.files.afterPhoto[0].path : null,

};


// Append to sessions.json

const sessionsFile = path.join(__dirname, 'sessions.json');

let sessions = [];

if (fs.existsSync(sessionsFile)) {

sessions = JSON.parse(fs.readFileSync(sessionsFile));

}

sessions.push(session);

fs.writeFileSync(sessionsFile, JSON.stringify(sessions, null, 2));


res.json({ message: 'Photos uploaded successfully.' });

});


app.listen(port, () => {

console.log(`Server running at http://localhost:${port}`);

});

```


### Setup Instructions

1. **Install Node.js**: Ensure Node.js is installed on your server (download from nodejs.org).

2. **Create Project Folder**:

- Create a folder (e.g., `lens-photo-app`).

- Save `index.html` and `server.js` in this folder.

3. **Install Dependencies**:

- Open a terminal in the project folder.

- Run:

```

npm init -y

npm install express multer

```

4. **Create Uploads Folder**:

- In the project folder, create a folder named `uploads` (case-sensitive).

5. **Run the Server**:

- Run:

```

node server.js

```

- The server will start at `http://localhost:3000`.

6. **Access the App**:

- Open a browser and go to `http://localhost:3000`.

- Users can enter their RFID ID, select a cutter, and upload photos.

7. **RFID Integration**:

- You’ll need to integrate the RFID system to provide the user ID. For example:

- Pre-fill the RFID field via a script if the badge swipe populates it.

- Or validate the RFID ID against a database in `server.js` before processing uploads.

8. **Storage**:

- Images are saved in the `uploads/` folder with names like `before-<rfid>-<cutter>-<timestamp>.jpg`.

- Session details (RFID, cutter, timestamps, image paths) are appended to `sessions.json`.


### Usage

- **Before Use**: Users swipe their RFID badge, enter the ID, select a laser cutter (1–6), and upload a “before” photo of the lens. The app requires the “before” photo to proceed.

- **After Use**: Users can upload an “after” photo (optional in the same form for simplicity). The backend logs both photos (if provided) with timestamps.

- **Output**: Check `uploads/` for images and `sessions.json` for session logs, e.g.:

```json

[

{

"rfid": "12345",

"cutter": "1",

"timestamp": "2025-05-15T<grok>2025-05-15T12:00:00.000Z",

"beforePhoto": "uploads/before-12345-1-1621234567890.jpg",

"afterPhoto": null

}

]

```


### Notes

- **Security**: This is a basic app. For production, add:

- Authentication to verify RFID IDs.

- Input validation to prevent malicious uploads.

- A proper database (e.g., SQLite) instead of a JSON file.

- HTTPS for secure communication.

- **Scalability**: The JSON file and disk storage work for small setups. For heavy use, consider a database and cloud storage (e.g., AWS S3).

- **RFID Integration**: If your RFID system provides an API or database, modify `server.js` to validate IDs before processing uploads.

- **Photo Verification**: Currently, users upload any image. For lens verification, you could add manual review or integrate image analysis (e.g., check for lens-like features), but this adds complexity.

- **Network**: Ensure the server is accessible on your makerspace network (e.g., update the server address in `index.html` if not `localhost`).


If you need help with specific integrations (e.g., RFID API, database, image analysis), let me know, and I can tailor the solution further!

Markus Schneider

unread,
May 15, 2025, 9:57:44 AMMay 15
to milwaukee...@googlegroups.com
A different possibility might be to have switch that requires you to insert the lens. So that at least it forces people to take out the lens. The switch box could then also take a photo witch a simple camera. It wouldn't require anything to be changed on the key fob system.

It would give time stamped photos of the lens before each use. With the fob reader data it could provide the same information.

It would keep it simple enough from a user perspective to not need to deal with uploading pictures etc.

Although I also don't know if we want to always use technology to fix social/behavior problems. In my mind while annoying and disappointing I don't know it's worth the effort compared to replacing lenses. (Provided we unstick the old one and replacing it with an American photonics one)


--
Friends of Milwaukee Makerspace - A group for reaching a Midwest regional audience dedicated to making. Be kind, keep it on topic, and please do not use this group for the sale of items. Remember that members@ is the list for internal to MMS discussions - reach out to info@ if you are a member and not on that list.
---
You received this message because you are subscribed to the Google Groups "Friends of MMS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to milwaukeemakers...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/milwaukeemakerspace/CAGiNDVSkWQ68hvyhpt9Sg9Nk61qz_PPdx%3DLnEur-aQVD2URc1Q%40mail.gmail.com.

Anna Kirch

unread,
May 15, 2025, 1:59:42 PMMay 15
to milwaukee...@googlegroups.com
Hey guys. This doesn't have anything to do with not cleaning the lens. This is literally people dropping the lens (you can see the chips) and possibly from abusing power settings on KP and melting the plastic.  





~ Anna "Captain SaH" Kirch ~
       Laser Champ
    "I can make that!" 

Reply all
Reply to author
Forward
0 new messages