From a666eff8f4fa490c81911aa15968c68deaefd469 Mon Sep 17 00:00:00 2001 From: raj Date: Tue, 12 Sep 2023 09:06:16 +0000 Subject: [PATCH] Added new feature --- src/.gitignore | 3 + src/controllers/tanksController.js | 207 ++++++++++++++++++++++++++--- src/handlers/supplierHandler.js | 2 +- src/handlers/tanksHandler.js | 0 src/index.js | 57 +++++++- src/models/User.js | 24 +++- src/models/tanks.js | 2 + src/routes/tanksRoute.js | 3 +- 8 files changed, 277 insertions(+), 21 deletions(-) create mode 100644 src/.gitignore delete mode 100644 src/handlers/tanksHandler.js diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..1039aeb4 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,3 @@ +src/api-docs/api.html +src/config/swagger.js +node_modules/ \ No newline at end of file diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index 17de5c42..a2cd01ac 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -87,7 +87,10 @@ async function deleteOldRecords() { exports.addTanks = async (req, reply) => { try { + + + const customerId = req.params.customerId; const { hardwareId, tankhardwareId,tankName,tankLocation } = req.body; @@ -114,6 +117,8 @@ exports.addTanks = async (req, reply) => { capacity: req.body.capacity, typeOfWater: req.body.typeOfWater, tankLocation: req.body.tankLocation.toLowerCase(), + waterCapacityPerCm:req.body.waterCapacityPerCm, + height:req.body.height // ... other fields }; @@ -937,6 +942,70 @@ exports.consumption = async (req, reply) => { // }; +// exports.calculateCapacity = async (req, reply) => { +// try { +// const shape = req.body.shape; +// if (shape === "rectangle") { +// const { length, width, height } = req.body; + +// // Convert input units from feet to meters +// const length_m = length * 0.3048; +// const width_m = width * 0.3048; +// const height_m = height * 0.3048; +// console.log(length_m,width_m,height_m) +// // Ensure all parameters are valid numbers +// if (isNaN(length_m) || isNaN(width_m) || isNaN(height_m)) { +// reply.code(400).send("Invalid input parameters"); +// return; +// } + +// // Calculate the capacity of the water tank in liters +// const capacity = length_m * width_m * height_m * 1000; + +// reply.send({ status_code: 200, capacity: capacity }); + +// return { message: "success" }; +// } +// if (shape === "cylinder") { +// console.log("hii1"); +// const { length, diameter } = req.body; + +// // Convert input units from feet to meters +// const length_m = length * 0.3048; +// const diameter_m = diameter * 0.3048; + +// // Ensure all parameters are valid numbers +// if (isNaN(length_m) || isNaN(diameter_m)) { +// reply.code(400).send("Invalid input parameters"); +// return; +// } + +// // Calculate the capacity of the water tank in liters +// const radius = diameter_m / 2; +// const volume = Math.PI * Math.pow(radius, 2) * length_m; +// const capacity = volume * 1000; + +// reply.send({ status_code: 200, capacity: capacity }); + +// return { message: "success" }; +// } + +// // Add similar conversions for other shapes if necessary + +// if (shape === "userdefined") { +// const capacity = req.body; + +// reply.send({ status_code: 200, capacity: capacity }); + +// return { message: "success" }; +// } +// } catch (err) { +// throw boom.boomify(err); +// } +// }; + + + exports.calculateCapacity = async (req, reply) => { try { const shape = req.body.shape; @@ -947,7 +1016,7 @@ exports.calculateCapacity = async (req, reply) => { const length_m = length * 0.3048; const width_m = width * 0.3048; const height_m = height * 0.3048; - console.log(length_m,width_m,height_m) + // Ensure all parameters are valid numbers if (isNaN(length_m) || isNaN(width_m) || isNaN(height_m)) { reply.code(400).send("Invalid input parameters"); @@ -957,12 +1026,14 @@ exports.calculateCapacity = async (req, reply) => { // Calculate the capacity of the water tank in liters const capacity = length_m * width_m * height_m * 1000; - reply.send({ status_code: 200, capacity: capacity }); + // Calculate the water capacity for a 1 centimeter height + const waterCapacityPerCm = length_m * width_m * 0.01 * 1000; + + reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } if (shape === "cylinder") { - console.log("hii1"); const { length, diameter } = req.body; // Convert input units from feet to meters @@ -980,7 +1051,10 @@ exports.calculateCapacity = async (req, reply) => { const volume = Math.PI * Math.pow(radius, 2) * length_m; const capacity = volume * 1000; - reply.send({ status_code: 200, capacity: capacity }); + // Calculate the water capacity for a 1 centimeter height + const waterCapacityPerCm = Math.PI * Math.pow(radius, 2) * 0.01 * 1000; + + reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } @@ -988,9 +1062,12 @@ exports.calculateCapacity = async (req, reply) => { // Add similar conversions for other shapes if necessary if (shape === "userdefined") { - const capacity = req.body; + const capacity = req.body.capacity; // Assuming capacity is provided directly + + // Calculate the water capacity for a 1 centimeter height + const waterCapacityPerCm = capacity / req.body.height; // Assuming height of the shape is provided - reply.send({ status_code: 200, capacity: capacity }); + reply.send({ status_code: 200, capacity: capacity, waterCapacityPerCm: waterCapacityPerCm }); return { message: "success" }; } @@ -1001,6 +1078,53 @@ exports.calculateCapacity = async (req, reply) => { +// exports.IotDevice = async (req, reply) => { +// try { +// const { hardwareId, mode, tanks } = req.body; + +// // create a new tank document with the current date and time +// const currentDate = new Date(); +// const date = currentDate.toISOString(); // save the date as an ISO string +// const time = currentDate.toLocaleTimeString('en-IN', { hour12: false, timeZone: 'Asia/Kolkata' }); + +// // Create an array of tank documents +// const tankDocuments = tanks.map(tank => ({ +// tankhardwareId: tank.tankhardwareId, +// tankHeight: tank.tankHeight, +// maxLevel: tank.maxLevel, +// minLevel: tank.minLevel, +// date: date, +// time: time +// })); + + +// // create a new IotData document with the provided data +// const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); + +// // save the document to MongoDB +// await ottank.save(); + +// // delete previous records except the three latest ones +// const previousRecords = await IotData.find({ hardwareId }) +// .sort({ date: -1, time: -1 }) +// .skip(3); // skip the three latest documents + +// for (const record of previousRecords) { +// await record.remove(); +// } + +// // get the latest three documents sorted in descending order of date and time +// const latestOttanks = await IotData.find({ hardwareId }) +// .sort({ date: -1, time: -1 }) +// .limit(3); + +// // send the latest documents +// reply.code(200).send({ latestOttanks }); +// } catch (err) { +// // send an error response +// reply.code(500).send({ error: err.message }); +// } +// }; exports.IotDevice = async (req, reply) => { try { @@ -1021,28 +1145,80 @@ exports.IotDevice = async (req, reply) => { time: time })); - // create a new IotData document with the provided data const ottank = new IotData({ hardwareId, mode, tanks: tankDocuments, date, time }); // save the document to MongoDB await ottank.save(); - // delete previous records except the three latest ones - const previousRecords = await IotData.find({ hardwareId }) + // Delete excess records (keep only the latest three records) + const recordsToKeep = 3; + const recordsToDelete = await IotData.find({ hardwareId }) .sort({ date: -1, time: -1 }) - .skip(3); // skip the three latest documents + .skip(recordsToKeep); - for (const record of previousRecords) { + for (const record of recordsToDelete) { await record.remove(); } - // get the latest three documents sorted in descending order of date and time + // Update waterlevel in tanksSchema for each tank + for (const tank of tanks) { + const { tankhardwareId, tankHeight } = tank; + + // Find the corresponding tank in tanksSchema + const existingTank = await Tank.findOne({ hardwareId, tankhardwareId }); + + + + if (existingTank) { + // Update the waterlevel using the tankHeight value + + const tank_height1 = (parseInt(existingTank.height.replace(/,/g, ''), 10)) * 30.48; + console.log(tank_height1, 25); + + // The value of tank_height1 is a number, not a string, so you cannot use replace on it. + // If you want to format it with commas, you can create a function to add commas to a number. + function numberWithCommas(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + } + + // Now you can use the function to format the tank_height1 value with commas. + const formatted_tank_height1 = numberWithCommas(tank_height1); + console.log(formatted_tank_height1, 25); + + const tank_height = parseInt(formatted_tank_height1.replace(/,/g, ''), 10); + console.log(tank_height); + // console.log(tank_height,1) + const water_level_height = tank_height - tankHeight + console.log(water_level_height,2) + + const waterCapacityPerCm = parseInt(existingTank.waterCapacityPerCm.replace(/,/g, ''), 10) + console.log(waterCapacityPerCm,3) + const water_level = water_level_height * waterCapacityPerCm; +console.log(water_level, 4); + +// Function to add commas to a number +function numberWithCommas(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} + +const formatted_water_level = numberWithCommas(water_level); +console.log(formatted_water_level, 4); + +existingTank.waterlevel = parseInt(formatted_water_level.replace(/,/g, ''), 10); +console.log(existingTank.waterlevel); + + + + // Save the updated tank document + await existingTank.save(); + } + } + + // Send the latest three documents const latestOttanks = await IotData.find({ hardwareId }) - .sort({ date: -1, time: -1 }) - .limit(3); + .sort({ date: -1, time: -1 }); - // send the latest documents reply.code(200).send({ latestOttanks }); } catch (err) { // send an error response @@ -1051,7 +1227,6 @@ exports.IotDevice = async (req, reply) => { }; - // exports.getIotD = async(req, reply) => { // try { // await IotData.find({hardwareId: req.query.hardwareId}) diff --git a/src/handlers/supplierHandler.js b/src/handlers/supplierHandler.js index 14b7ed5f..da48a7a9 100644 --- a/src/handlers/supplierHandler.js +++ b/src/handlers/supplierHandler.js @@ -1573,4 +1573,4 @@ fastify.get('/api/users/profile-picture-supplier/:supplierId', async (req, res) } catch (error) { res.status(500).send({ error: error.message }); } -}); \ No newline at end of file +}); diff --git a/src/handlers/tanksHandler.js b/src/handlers/tanksHandler.js deleted file mode 100644 index e69de29b..00000000 diff --git a/src/index.js b/src/index.js index e3585748..c40a2383 100644 --- a/src/index.js +++ b/src/index.js @@ -536,6 +536,61 @@ fastify.post('/api/uploads/:supplierId', async (request, reply) => { }); + +fastify.post('/api/uploads-user/:customerId', async (request, reply) => { + try { + const customerId = request.params.customerId; + const data = await request.file(); + + // Generate a unique file name + + const fileName = `${data.filename}`; + + + // Define the destination bucket and file path + const bucketName = 'arminta_profile_pictures'; + const filePath = `arminta_user_profiles/${fileName}`; + + // Create a write stream to the destination file in the bucket + const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); + + // Pipe the file data to the write stream + data.file.pipe(writeStream); + + writeStream.on('finish', async () => { + try { + // Make the uploaded file publicly accessible + await storage.bucket(bucketName).file(filePath).makePublic(); + + const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; + + ProfilePicture.findOneAndUpdate( + { customerId }, + { picture: publicUrl }, + { new: true, upsert: true }, + (error, picture) => { + if (error) { + reply.code(500).send({ error: 'Failed to update database' }); + } else { + // Return the public URL + reply.send({ picture: publicUrl }); + } + } + ); + } catch (error) { + reply.code(500).send({ error: 'Failed to make file public' }); + } + }); + + + writeStream.on('error', (err) => { + reply.code(500).send({ error: 'Failed to move file' }); + }); + } catch (err) { + reply.code(500).send({ error: 'An error occurred' }); + } +}); + // Run the server! const start = async () => { @@ -550,4 +605,4 @@ const start = async () => { process.exit(1); } }; -start(); \ No newline at end of file +start(); diff --git a/src/models/User.js b/src/models/User.js index 12ad61a1..2d3f1c43 100644 --- a/src/models/User.js +++ b/src/models/User.js @@ -146,6 +146,26 @@ const userSchema = new mongoose.Schema( // } // }); +// const profilePictureSchema = new Schema({ +// customerId: { +// type: String, +// unique: true, +// required: true +// }, +// picture: { +// type: Buffer, // Store the file as binary data +// required: true, +// validate: { +// validator: function (value) { +// const supportedFormats = ['jpg', 'jpeg', 'png']; +// const fileExtension = value.split('.').pop().toLowerCase(); +// return supportedFormats.includes(fileExtension); +// }, +// message: 'Picture must be a JPEG, PNG, or JPG image' +// } +// } +// }); + const profilePictureSchema = new Schema({ customerId: { type: String, @@ -153,7 +173,7 @@ const profilePictureSchema = new Schema({ required: true }, picture: { - type: Buffer, // Store the file as binary data + type: String, // Change the type to String required: true, validate: { validator: function (value) { @@ -165,7 +185,7 @@ const profilePictureSchema = new Schema({ } } }); - + const ProfilePicture = mongoose.model('ProfilePicture', profilePictureSchema); const Counter = mongoose.model('Counter', CounterSchema); diff --git a/src/models/tanks.js b/src/models/tanks.js index f8761aaf..fe18720a 100644 --- a/src/models/tanks.js +++ b/src/models/tanks.js @@ -39,6 +39,8 @@ const tanksSchema = new mongoose.Schema({ tankName: { type: String, default: null }, blockName: { type: String, default: null }, capacity: { type: String, default: "0" }, + height: { type: String, default: "0" }, + waterCapacityPerCm:{ type: String, default: "0" }, typeOfWater: { type: String, default: null }, waterlevel: { type: String, default: "0" }, tankLocation: { type: String, default: null }, diff --git a/src/routes/tanksRoute.js b/src/routes/tanksRoute.js index 5621e99b..f3532c38 100644 --- a/src/routes/tanksRoute.js +++ b/src/routes/tanksRoute.js @@ -30,8 +30,9 @@ module.exports = function (fastify, opts, next) { blockName: { type: "string"}, capacity: { type: "string" }, typeOfWater: { type: "string" }, - + waterCapacityPerCm:{ type: "string" }, tankLocation: { type: "string" }, + height:{ type: "string" }, }, }, security: [