commit b8a3058012a96ec4928f7a19e65cd819eaf2e857 Author: Wanda Gusdya Date: Wed Jan 4 15:06:42 2023 +0700 first commit diff --git a/.env b/.env new file mode 100644 index 0000000..c6f3186 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +BASE_URL=http://localhost:3001/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..db8605a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,124 @@ +{ + "name": "weather-mock-generator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "weather-mock-generator", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "cron": "^2.1.0", + "csv": "^6.2.5", + "dotenv": "^16.0.3", + "moment": "^2.29.4", + "node-fetch": "^2.6.7" + } + }, + "node_modules/cron": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-2.1.0.tgz", + "integrity": "sha512-Hq7u3P8y7UWYvsZbSKHHJDVG0VO9O7tp2qljxzTScelcTODBfCme8AIhnZsFwmQ9NchZ3hr2uNr+s3DSms7q6w==", + "dependencies": { + "luxon": "^1.23.x" + } + }, + "node_modules/csv": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/csv/-/csv-6.2.5.tgz", + "integrity": "sha512-T+K0H7MIrlrnP6KxYKo3lK+uLl6OC2Gmwdd81TG/VdkhKvpatl35sR7tyRSpDLGl22y2T+q9KvNHnVtn4OAscQ==", + "dependencies": { + "csv-generate": "^4.2.1", + "csv-parse": "^5.3.3", + "csv-stringify": "^6.2.3", + "stream-transform": "^3.2.1" + }, + "engines": { + "node": ">= 0.1.90" + } + }, + "node_modules/csv-generate": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-4.2.1.tgz", + "integrity": "sha512-w6GFHjvApv6bcJ2xdi9JGsH6ZvUBfC+vUdfefnEzurXG6hMRwzkBLnhztU2H7v7+zfCk1I/knnQ+tGbgpxWrBw==" + }, + "node_modules/csv-parse": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.3.3.tgz", + "integrity": "sha512-kEWkAPleNEdhFNkHQpFHu9RYPogsFj3dx6bCxL847fsiLgidzWg0z/O0B1kVWMJUc5ky64zGp18LX2T3DQrOfw==" + }, + "node_modules/csv-stringify": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.2.3.tgz", + "integrity": "sha512-4qGjUMwnlaRc00gc2jrIYh2w/h1fo25B0mTuY9K8fBiIgtmCX3LcgUbrEGViL98Ci4Se/F5LFEtu8k+dItJVZQ==" + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/luxon": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==", + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/stream-transform": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-3.2.1.tgz", + "integrity": "sha512-ApK+WTJ5bCOf0A2tlec1qhvr8bGEBM/sgXXB7mysdCYgZJO5DZeaV3h3G+g0HnAQ372P5IhiGqnW29zoLOfTzQ==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ad57c86 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "weather-mock-generator", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node src/app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Wanda Gusdya", + "license": "ISC", + "dependencies": { + "cron": "^2.1.0", + "csv": "^6.2.5", + "dotenv": "^16.0.3", + "moment": "^2.29.4", + "node-fetch": "^2.6.7" + } +} diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..2ccddaf --- /dev/null +++ b/src/app.js @@ -0,0 +1,72 @@ +require('dotenv').config() +const env = process.env + +const moment = require('moment') +const fetch = require('node-fetch') +const fs = require("fs"); +const { parse } = require("csv-parse/sync"); + +const WeatherApi = require('./networks/weather-api') + +class App { + sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + } + + readFile() { + this.data = fs.readFileSync('./csv/weatherHistory.csv', + {encoding:'utf8', flag:'r'}) + } + readCsv() { + this.records = parse(this.data, { + delimiter: ",", from_line: 2 + }); + } + + async postData() { + const weatherApi = new WeatherApi(fetch, env.BASE_URL) + const devices = ["001", "002", "003", "004", "005"] + let row = 0 + while (true) { + let i + for (i = 0; i < devices.length; i++) + { + const device = devices[i] + const record = this.records[row] + const body = { + deviceId: device, + date: moment().format('YYYY-MM-DD HH:mm:ss'), + summary: record[1], + precipType: record[2], + temperature: record[3], + apparentTemperature: record[4], + humidity: record[5], + windSpeed: record[6], + windBearing: record[7], + visibility: record[8], + loudCover: record[9], + pressure: record[10], + dailySummary: record[11], + } + weatherApi.post(body) + row++ + if (row >= this.records.length) { + row = 0 + } + + await this.sleep(60000) + } + } + } + async start() + { + this.readFile() + this.readCsv() + await this.postData() + } +} + +const app = new App() +app.start() \ No newline at end of file diff --git a/src/networks/weather-api.js b/src/networks/weather-api.js new file mode 100644 index 0000000..36f8624 --- /dev/null +++ b/src/networks/weather-api.js @@ -0,0 +1,27 @@ +'use strict' + +class WeatherApi { + constructor(fetch, baseUrl) { + this.fetch = fetch + this.baseUrl = baseUrl + } + + async post(body) + { + const headers = { + 'Content-Type': 'application/json' + } + console.log('requesting', `${this.baseUrl}api/v1/weather`) + const response = await this.fetch(`${this.baseUrl}api/v1/weather`, { + method: 'post', + body: JSON.stringify(body), + headers: headers + }).catch((exception) => { + throw exception + }) + + return response.json() + } +} + +module.exports = WeatherApi \ No newline at end of file