Compare commits
12 Commits
205ee1f0e5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 84a9ce3f4c | |||
| 6fe3050c1c | |||
| 70c534c204 | |||
| a619733a08 | |||
| ba54730f2f | |||
| 20b7691b8b | |||
| e2d1c4f681 | |||
| 5c55b915e1 | |||
| 677ee6325f | |||
| 4edef06212 | |||
| e2ffbc5435 | |||
| 7d8d6ed2b9 |
74
config/dbConnCron.js
Normal file
74
config/dbConnCron.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
const mysql = require("mysql2")
|
||||||
|
const pool = mysql.createPool({
|
||||||
|
host: process.env.DBHOST,
|
||||||
|
port: process.env.DBPORT,
|
||||||
|
user: process.env.DBUSER,
|
||||||
|
password: process.env.DBPASSWORD,
|
||||||
|
database: process.env.DATABASE,
|
||||||
|
connectionLimit: 100,
|
||||||
|
multipleStatements: true,
|
||||||
|
// waitForConnections: true,
|
||||||
|
maxIdle: 10, // max idle connections, the default value is the same as `connectionLimit`
|
||||||
|
idleTimeout: 60000, // idle connections timeout, in milliseconds, the default value 60000
|
||||||
|
queueLimit: 50,
|
||||||
|
// enableKeepAlive: true,
|
||||||
|
// keepAliveInitialDelay: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const connection = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
pool.getConnection((err, connection) => {
|
||||||
|
if (err) {
|
||||||
|
// Log the error and reject the promise
|
||||||
|
console.error("Error getting connection from pool:", err)
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
const query = (sql, binding) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
connection.query(sql, binding, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
// Log the query error for debugging
|
||||||
|
console.error("Error executing query:", err, { sql, binding })
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
resolve(result)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const release = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (err) {
|
||||||
|
// Log error in release method if exists
|
||||||
|
console.error("Error during connection release:", err)
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
resolve(connection.release())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
query,
|
||||||
|
release,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = (sql, binding) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
pool.query(sql, binding, (err, result, fields) => {
|
||||||
|
if (err) {
|
||||||
|
// Log the error for debugging
|
||||||
|
console.error("Error executing pooled query:", err, { sql, binding })
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
resolve(result)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
pool,
|
||||||
|
connection,
|
||||||
|
query,
|
||||||
|
}
|
||||||
@ -1,283 +1,596 @@
|
|||||||
require("dotenv").config({ path: "../.env" });
|
require("dotenv").config({ path: "../.env" })
|
||||||
const LibWinston = require("../library/LibWinston");
|
const LibWinston = require("../library/LibWinston")
|
||||||
const moment = require("moment");
|
const moment = require("moment")
|
||||||
const axios = require("axios").default;
|
const axios = require("axios").default
|
||||||
const url = require("url");
|
const url = require("url")
|
||||||
const request = require("../config/request");
|
const request = require("../config/request")
|
||||||
const GpsTracksModels = require("../models/GpsTracksModels");
|
const GpsTracksModels = require("../models/GpsTracksModels")
|
||||||
const RegionModels = require("../models/RegionModels");
|
const RegionModels = require("../models/RegionModels")
|
||||||
const { stringify } = require("flatted");
|
const { stringify } = require("flatted")
|
||||||
|
|
||||||
const schedulerName = process.env.REDIS_SCHEDULER_REVERSE_GEO;
|
const schedulerName = process.env.REDIS_SCHEDULER_REVERSE_GEO
|
||||||
const Logger = LibWinston.initialize(schedulerName);
|
const Logger = LibWinston.initialize(schedulerName)
|
||||||
|
|
||||||
const go = async () => {
|
const go = async () => {
|
||||||
try {
|
try {
|
||||||
Logger.log("info", `${schedulerName} running: ${moment().format("YYYY-MM-DD HH:mm:ss")}`);
|
Logger.log("info", `${schedulerName} running: ${moment().format("YYYY-MM-DD HH:mm:ss")}`)
|
||||||
// (async function() {
|
// (async function() {
|
||||||
try {
|
try {
|
||||||
let loop = process.env.SCHEDULE_REVERSE_GEO_MAX_LOOP;
|
let loop = process.env.SCHEDULE_REVERSE_GEO_MAX_LOOP
|
||||||
for (let x = 0; x < loop; x++) {
|
for (let x = 0; x < loop; x++) {
|
||||||
|
const axInstance = axios.create({
|
||||||
|
proxy: {
|
||||||
|
host: process.env.PROXY_URL,
|
||||||
|
port: Number(process.env.PROXY_PORT),
|
||||||
|
},
|
||||||
|
timeout: 15_000,
|
||||||
|
// headers: { "User-Agent": "movana-fleet-management/1.0 (emirsyafmun@gmail.com)" },
|
||||||
|
})
|
||||||
|
const urlBase = request.osm_reverse_geo.urlFull
|
||||||
|
|
||||||
// let tracks = [];
|
// let tracks = [];
|
||||||
let tracks = await GpsTracksModels.get2ForReverseGeo(1);
|
let tracks = await GpsTracksModels.get2ForReverseGeo(10)
|
||||||
for (let i = 0; i < tracks.length; i++) {
|
|
||||||
console.log("tracks[i] :", tracks[i].id, tracks[i].device_id, tracks[i].latitude, tracks[i].longitude);
|
|
||||||
let now = moment().unix();
|
|
||||||
let updtData = {};
|
|
||||||
let respReverseGeo = null;
|
|
||||||
try {
|
|
||||||
const sameAddr = await GpsTracksModels.select2Address(tracks[i].latitude, tracks[i].longitude);
|
|
||||||
|
|
||||||
if (sameAddr.length > 0) {
|
function processTrack(track, i) {
|
||||||
let addrData = {
|
return (async () => {
|
||||||
device_id: tracks[i].device_id,
|
console.log("track:", track.id, track.device_id, track.latitude, track.longitude)
|
||||||
master_id: tracks[i].id,
|
let now = moment().unix()
|
||||||
type: sameAddr[0].type,
|
let updtData = {}
|
||||||
lat: tracks[i].latitude,
|
let respReverseGeo = null
|
||||||
lng: tracks[i].longitude,
|
|
||||||
country_id: sameAddr[0].country_id,
|
|
||||||
country_code: sameAddr[0].country_code,
|
|
||||||
country_text: sameAddr[0].country_text,
|
|
||||||
state_id: sameAddr[0].state_id,
|
|
||||||
state_text: sameAddr[0].state_text,
|
|
||||||
city_id: sameAddr[0].city_id,
|
|
||||||
city_text: sameAddr[0].city_text,
|
|
||||||
district_id: sameAddr[0].district_id,
|
|
||||||
district_text: sameAddr[0].district_text,
|
|
||||||
village_id: sameAddr[0].village_id,
|
|
||||||
village_text: sameAddr[0].village_text,
|
|
||||||
postcode: sameAddr[0].postcode,
|
|
||||||
streets: sameAddr[0].streets,
|
|
||||||
fulladdress: encodeURIComponent(decodeURIComponent(sameAddr[0].fulladdress)),
|
|
||||||
type_reverse_geo: sameAddr[0].type_reverse_geo,
|
|
||||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
|
||||||
log_reverse_geo: sameAddr[0].log_reverse_geo,
|
|
||||||
crt: now,
|
|
||||||
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
};
|
|
||||||
GpsTracksModels.create2Address(addrData);
|
|
||||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC;
|
|
||||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = new url.URLSearchParams({
|
const params = new url.URLSearchParams({
|
||||||
lat: tracks[i].latitude,
|
lat: track.latitude,
|
||||||
lon: tracks[i].longitude,
|
lon: track.longitude,
|
||||||
format: "geojson",
|
format: "geojson",
|
||||||
});
|
})
|
||||||
//const axInstance = axios.create()
|
|
||||||
const axInstance = axios.create({
|
try {
|
||||||
proxy: {
|
const sameAddr = await GpsTracksModels.select2Address(track.latitude, track.longitude)
|
||||||
host: process.env.PROXY_URL,
|
if (sameAddr.length > 0) {
|
||||||
port: process.env.PROXY_PORT,
|
let addrData = {
|
||||||
},
|
device_id: track.device_id,
|
||||||
});
|
master_id: track.id,
|
||||||
axios.defaults.timeout = 10000;
|
type: sameAddr[0].type,
|
||||||
axios.defaults.crossDomain = true;
|
lat: track.latitude,
|
||||||
// respReverseGeo = await axios({
|
lng: track.longitude,
|
||||||
// url: request.osm_reverse_geo.urlFull,
|
country_id: sameAddr[0].country_id,
|
||||||
// method: request.osm_reverse_geo.method,
|
country_code: sameAddr[0].country_code,
|
||||||
// params: params,
|
country_text: sameAddr[0].country_text,
|
||||||
// responseType: 'json',
|
state_id: sameAddr[0].state_id,
|
||||||
// });
|
state_text: sameAddr[0].state_text,
|
||||||
// respReverseGeo = await axInstance.get(request.osm_reverse_geo.urlFull + "?" + params.toString(), {
|
city_id: sameAddr[0].city_id,
|
||||||
// timeout: 10000,
|
city_text: sameAddr[0].city_text,
|
||||||
// });
|
district_id: sameAddr[0].district_id,
|
||||||
respReverseGeo = await axInstance.get(request.osm_reverse_geo.urlFull + "?" + params.toString(), {
|
district_text: sameAddr[0].district_text,
|
||||||
timeout: 10000,
|
village_id: sameAddr[0].village_id,
|
||||||
headers: {
|
village_text: sameAddr[0].village_text,
|
||||||
"User-Agent": "movana-fleet-management/1.0 (emirsyafmun@gmail.com)",
|
postcode: sameAddr[0].postcode,
|
||||||
},
|
streets: sameAddr[0].streets,
|
||||||
});
|
fulladdress: encodeURIComponent(decodeURIComponent(sameAddr[0].fulladdress)),
|
||||||
console.log("respReverseGeo: ", respReverseGeo.data || null);
|
type_reverse_geo: sameAddr[0].type_reverse_geo,
|
||||||
let respData = respReverseGeo.data || {};
|
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||||
if (respReverseGeo.status == 200) {
|
log_reverse_geo: sameAddr[0].log_reverse_geo,
|
||||||
if (respData.features.length < 1) {
|
crt: now,
|
||||||
|
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
}
|
||||||
|
GpsTracksModels.create2Address(addrData)
|
||||||
|
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC
|
||||||
|
await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
console.log("skip same address:", track.id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await axInstance.get(`${urlBase}?${params.toString()}`, {
|
||||||
|
headers: { "User-Agent": `movana-fleet-management-` + i },
|
||||||
|
})
|
||||||
|
const respData = resp.data || {}
|
||||||
|
if (resp.status === 200) {
|
||||||
|
console.log("SUCCESS respReverseGeo:", track.id)
|
||||||
|
if (respData.features.length < 1) {
|
||||||
|
GpsTracksModels.create2Address({
|
||||||
|
device_id: track.device_id,
|
||||||
|
master_id: track.id,
|
||||||
|
lat: track.latitude,
|
||||||
|
lng: track.longitude,
|
||||||
|
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_LOST,
|
||||||
|
log_reverse_geo: JSON.stringify(respData),
|
||||||
|
crt: now,
|
||||||
|
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
})
|
||||||
|
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_LOST
|
||||||
|
await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
} else {
|
||||||
|
let respAddr = respData.features[0].properties.address
|
||||||
|
let addrData = {
|
||||||
|
device_id: track.device_id,
|
||||||
|
master_id: track.id,
|
||||||
|
lat: track.latitude,
|
||||||
|
lng: track.longitude,
|
||||||
|
country_id: GpsTracksModels.DEFAULT_COUNTRY_ID,
|
||||||
|
country_code: respAddr.country_code,
|
||||||
|
country_text: respAddr.country
|
||||||
|
? respAddr.country.toUpperCase()
|
||||||
|
: respAddr.country || null,
|
||||||
|
state_id: null,
|
||||||
|
city_id: null,
|
||||||
|
district_id: null,
|
||||||
|
village_id: null,
|
||||||
|
postcode: respAddr.postcode,
|
||||||
|
fulladdress: encodeURIComponent(respData.features[0].properties.display_name),
|
||||||
|
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||||
|
log_reverse_geo: respData.features[0].properties
|
||||||
|
? JSON.stringify(respData.features[0].properties)
|
||||||
|
: null,
|
||||||
|
crt: now,
|
||||||
|
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
}
|
||||||
|
if (respAddr.state || respAddr.city) {
|
||||||
|
addrData.state_text =
|
||||||
|
respAddr.region ||
|
||||||
|
respAddr.state ||
|
||||||
|
respAddr.state_district ||
|
||||||
|
respAddr.county ||
|
||||||
|
respAddr.city ||
|
||||||
|
""
|
||||||
|
addrData.state_text = addrData.state_text
|
||||||
|
? addrData.state_text.toUpperCase()
|
||||||
|
: addrData.state_text || null
|
||||||
|
addrData.state_text = addrData.state_text || null
|
||||||
|
}
|
||||||
|
if (respAddr.city_district || respAddr.city) {
|
||||||
|
addrData.city_text = respAddr.city_district || respAddr.city || ""
|
||||||
|
addrData.city_text = addrData.city_text
|
||||||
|
? addrData.city_text.toUpperCase()
|
||||||
|
: addrData.city_text || null
|
||||||
|
addrData.city_text = addrData.city_text || null
|
||||||
|
}
|
||||||
|
if (respAddr.suburb || respAddr.subdistrict) {
|
||||||
|
addrData.district_text =
|
||||||
|
respAddr.suburb || respAddr.subdistrict || respAddr.subdivision || ""
|
||||||
|
addrData.district_text = addrData.district_text
|
||||||
|
? addrData.district_text.toUpperCase()
|
||||||
|
: addrData.district_text || null
|
||||||
|
addrData.district_text = addrData.district_text || null
|
||||||
|
}
|
||||||
|
if (respAddr.village) {
|
||||||
|
addrData.village_text = respAddr.village || respAddr.neighbourhood || ""
|
||||||
|
addrData.village_text = addrData.village_text
|
||||||
|
? addrData.village_text.toUpperCase()
|
||||||
|
: addrData.village_text || null
|
||||||
|
addrData.village_text = addrData.village_text || null
|
||||||
|
}
|
||||||
|
if (respAddr.amenity || respAddr.road || respAddr.city_block) {
|
||||||
|
addrData.streets = ""
|
||||||
|
addrData.streets += respAddr.amenity ? respAddr.amenity + ", " : ""
|
||||||
|
addrData.streets += respAddr.road ? respAddr.road + ", " : ""
|
||||||
|
addrData.streets += respAddr.house_number ? respAddr.house_number + ", " : ""
|
||||||
|
addrData.streets += respAddr.house_name ? respAddr.house_name + ", " : ""
|
||||||
|
addrData.streets += respAddr.city_block ? respAddr.city_block + ", " : ""
|
||||||
|
addrData.streets += addrData.streets || null
|
||||||
|
if (addrData.streets) {
|
||||||
|
addrData.streets = encodeURIComponent(addrData.streets.slice(0, -2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let byAll = await RegionModels.whereLike({
|
||||||
|
nmProvinsiKel: addrData.state_text,
|
||||||
|
nmKotamadyaKel: addrData.city_text,
|
||||||
|
nmKecamatanKel: addrData.district_text,
|
||||||
|
nmKelurahan: addrData.village_text,
|
||||||
|
})
|
||||||
|
if (byAll.length > 1) {
|
||||||
|
addrData.state_id = byAll[0].kodeProv
|
||||||
|
addrData.city_id = byAll[0].kodeKab
|
||||||
|
addrData.district_id = byAll[0].kodeKec
|
||||||
|
addrData.village_id = byAll[0].kodeKel
|
||||||
|
}
|
||||||
|
|
||||||
|
let byKel = await RegionModels.whereLike({
|
||||||
|
nmKelurahan: addrData.village_text,
|
||||||
|
})
|
||||||
|
if (byAll.length < 1 && byKel.length > 0) {
|
||||||
|
addrData.state_id = byKel[0].kodeProv
|
||||||
|
addrData.city_id = byKel[0].kodeKab
|
||||||
|
addrData.district_id = byKel[0].kodeKec
|
||||||
|
addrData.village_id = byKel[0].kodeKel
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrData.state_id === null) {
|
||||||
|
let byPr = await RegionModels.whereLike({ nmProvinsiKel: addrData.state_text })
|
||||||
|
if (byPr.length > 0) {
|
||||||
|
addrData.state_id = byPr[0].kodeProv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrData.state_id !== null && addrData.city_id === null) {
|
||||||
|
let byKt = await RegionModels.whereLike({ nmKotamadyaKel: addrData.city_text })
|
||||||
|
if (byKt.length > 0) {
|
||||||
|
addrData.city_id = byKt[0].kodeKab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
addrData.state_id !== null &&
|
||||||
|
addrData.city_id !== null &&
|
||||||
|
addrData.district_id === null
|
||||||
|
) {
|
||||||
|
let byKc = await RegionModels.whereLike({
|
||||||
|
nmKecamatanKel: addrData.district_text,
|
||||||
|
})
|
||||||
|
if (byKc.length > 0) {
|
||||||
|
addrData.district_id = byKc[0].kodeKec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
addrData.state_id !== null &&
|
||||||
|
addrData.city_id !== null &&
|
||||||
|
addrData.district_id !== null &&
|
||||||
|
addrData.village_id === null
|
||||||
|
) {
|
||||||
|
let byKl = await RegionModels.whereLike({ nmKelurahan: addrData.village_text })
|
||||||
|
if (byKl.length > 0) {
|
||||||
|
addrData.village_id = byKl[0].kodeKel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GpsTracksModels.create2Address(addrData).catch((e) => {
|
||||||
|
Logger.log(
|
||||||
|
"error",
|
||||||
|
`${schedulerName} running_error: ${JSON.stringify(
|
||||||
|
e,
|
||||||
|
Object.getOwnPropertyNames(e)
|
||||||
|
)}`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC
|
||||||
|
await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("FAILED respReverseGeo:", resp.status, resp.statusText)
|
||||||
GpsTracksModels.create2Address({
|
GpsTracksModels.create2Address({
|
||||||
device_id: tracks[i].device_id,
|
device_id: track.device_id,
|
||||||
master_id: tracks[i].id,
|
master_id: track.id,
|
||||||
lat: tracks[i].latitude,
|
lat: track.latitude,
|
||||||
lng: tracks[i].longitude,
|
lng: track.longitude,
|
||||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_LOST,
|
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||||
log_reverse_geo: JSON.stringify(respData),
|
log_reverse_geo: JSON.stringify(respData),
|
||||||
crt: now,
|
crt: now,
|
||||||
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
});
|
})
|
||||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_LOST;
|
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER
|
||||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
await GpsTracksModels.update2(track.id, updtData)
|
||||||
} else {
|
}
|
||||||
let respAddr = respData.features[0].properties.address;
|
} catch (e) {
|
||||||
let addrData = {
|
console.log("FAILED reverse geo for track", track.id, e.message)
|
||||||
device_id: tracks[i].device_id,
|
let respData = {}
|
||||||
master_id: tracks[i].id,
|
if (respReverseGeo) {
|
||||||
lat: tracks[i].latitude,
|
if (respReverseGeo.status != 200) {
|
||||||
lng: tracks[i].longitude,
|
respData.data = respReverseGeo.data
|
||||||
country_id: GpsTracksModels.DEFAULT_COUNTRY_ID,
|
} else {
|
||||||
country_code: respAddr.country_code,
|
respData.msg = e.message
|
||||||
country_text: respAddr.country ? respAddr.country.toUpperCase() : respAddr.country || null,
|
}
|
||||||
state_id: null,
|
} else if (typeof e.response != "undefined") {
|
||||||
city_id: null,
|
respData.data = e.response
|
||||||
district_id: null,
|
} else {
|
||||||
village_id: null,
|
respData.msg = e.message
|
||||||
postcode: respAddr.postcode,
|
|
||||||
fulladdress: encodeURIComponent(respData.features[0].properties.display_name),
|
|
||||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
|
||||||
log_reverse_geo: respData.features[0].properties ? JSON.stringify(respData.features[0].properties) : null,
|
|
||||||
crt: now,
|
|
||||||
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
};
|
|
||||||
if (respAddr.state || respAddr.city) {
|
|
||||||
addrData.state_text = respAddr.region || respAddr.state || respAddr.state_district || respAddr.county || respAddr.city || "";
|
|
||||||
addrData.state_text = addrData.state_text ? addrData.state_text.toUpperCase() : addrData.state_text || null;
|
|
||||||
addrData.state_text = addrData.state_text || null;
|
|
||||||
}
|
|
||||||
if (respAddr.city_district || respAddr.city) {
|
|
||||||
addrData.city_text = respAddr.city_district || respAddr.city || "";
|
|
||||||
addrData.city_text = addrData.city_text ? addrData.city_text.toUpperCase() : addrData.city_text || null;
|
|
||||||
addrData.city_text = addrData.city_text || null;
|
|
||||||
}
|
|
||||||
if (respAddr.suburb || respAddr.subdistrict) {
|
|
||||||
addrData.district_text = respAddr.suburb || respAddr.subdistrict || respAddr.subdivision || "";
|
|
||||||
addrData.district_text = addrData.district_text ? addrData.district_text.toUpperCase() : addrData.district_text || null;
|
|
||||||
addrData.district_text = addrData.district_text || null;
|
|
||||||
}
|
|
||||||
if (respAddr.village) {
|
|
||||||
addrData.village_text = respAddr.village || respAddr.neighbourhood || "";
|
|
||||||
addrData.village_text = addrData.village_text ? addrData.village_text.toUpperCase() : addrData.village_text || null;
|
|
||||||
addrData.village_text = addrData.village_text || null;
|
|
||||||
}
|
|
||||||
if (respAddr.amenity || respAddr.road || respAddr.city_block) {
|
|
||||||
addrData.streets = "";
|
|
||||||
addrData.streets += respAddr.amenity ? respAddr.amenity + ", " : "";
|
|
||||||
addrData.streets += respAddr.road ? respAddr.road + ", " : "";
|
|
||||||
addrData.streets += respAddr.house_number ? respAddr.house_number + ", " : "";
|
|
||||||
addrData.streets += respAddr.house_name ? respAddr.house_name + ", " : "";
|
|
||||||
addrData.streets += respAddr.city_block ? respAddr.city_block + ", " : "";
|
|
||||||
addrData.streets += addrData.streets || null;
|
|
||||||
if (addrData.streets) {
|
|
||||||
addrData.streets = encodeURIComponent(addrData.streets.slice(0, -2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let byAll = await RegionModels.whereLike({
|
|
||||||
nmProvinsiKel: addrData.state_text,
|
|
||||||
nmKotamadyaKel: addrData.city_text,
|
|
||||||
nmKecamatanKel: addrData.district_text,
|
|
||||||
nmKelurahan: addrData.village_text,
|
|
||||||
});
|
|
||||||
if (byAll.length > 1) {
|
|
||||||
addrData.state_id = byAll[0].kodeProv;
|
|
||||||
addrData.city_id = byAll[0].kodeKab;
|
|
||||||
addrData.district_id = byAll[0].kodeKec;
|
|
||||||
addrData.village_id = byAll[0].kodeKel;
|
|
||||||
}
|
|
||||||
|
|
||||||
let byKel = await RegionModels.whereLike({
|
|
||||||
nmKelurahan: addrData.village_text,
|
|
||||||
});
|
|
||||||
if (byAll.length < 1 && byKel.length > 0) {
|
|
||||||
addrData.state_id = byKel[0].kodeProv;
|
|
||||||
addrData.city_id = byKel[0].kodeKab;
|
|
||||||
addrData.district_id = byKel[0].kodeKec;
|
|
||||||
addrData.village_id = byKel[0].kodeKel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addrData.state_id === null) {
|
|
||||||
let byPr = await RegionModels.whereLike({ nmProvinsiKel: addrData.state_text });
|
|
||||||
if (byPr.length > 0) {
|
|
||||||
addrData.state_id = byPr[0].kodeProv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addrData.state_id !== null && addrData.city_id === null) {
|
|
||||||
let byKt = await RegionModels.whereLike({ nmKotamadyaKel: addrData.city_text });
|
|
||||||
if (byKt.length > 0) {
|
|
||||||
addrData.city_id = byKt[0].kodeKab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addrData.state_id !== null && addrData.city_id !== null && addrData.district_id === null) {
|
|
||||||
let byKc = await RegionModels.whereLike({ nmKecamatanKel: addrData.district_text });
|
|
||||||
if (byKc.length > 0) {
|
|
||||||
addrData.district_id = byKc[0].kodeKec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addrData.state_id !== null && addrData.city_id !== null && addrData.district_id !== null && addrData.village_id === null) {
|
|
||||||
let byKl = await RegionModels.whereLike({ nmKelurahan: addrData.village_text });
|
|
||||||
if (byKl.length > 0) {
|
|
||||||
addrData.village_id = byKl[0].kodeKel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GpsTracksModels.create2Address(addrData).catch((e) => {
|
|
||||||
Logger.log("error", `${schedulerName} running_error: ${JSON.stringify(e, Object.getOwnPropertyNames(e))}`);
|
|
||||||
});
|
|
||||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC;
|
|
||||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
GpsTracksModels.create2Address({
|
GpsTracksModels.create2Address({
|
||||||
device_id: tracks[i].device_id,
|
device_id: track.device_id,
|
||||||
master_id: tracks[i].id,
|
master_id: track.id,
|
||||||
lat: tracks[i].latitude,
|
lat: track.latitude,
|
||||||
lng: tracks[i].longitude,
|
lng: track.longitude,
|
||||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||||
log_reverse_geo: JSON.stringify(respData),
|
// log_reverse_geo: JSON.stringify(respData.data),
|
||||||
|
log_reverse_geo: stringify(respData.data),
|
||||||
crt: now,
|
crt: now,
|
||||||
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
});
|
})
|
||||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER;
|
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER
|
||||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
await GpsTracksModels.update2(track.id, updtData)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
})()
|
||||||
let respData = {};
|
|
||||||
if (respReverseGeo) {
|
|
||||||
if (respReverseGeo.status != 200) {
|
|
||||||
respData.data = respReverseGeo.data;
|
|
||||||
} else {
|
|
||||||
respData.msg = e.message;
|
|
||||||
}
|
|
||||||
} else if (typeof e.response != "undefined") {
|
|
||||||
respData.data = e.response;
|
|
||||||
} else {
|
|
||||||
respData.msg = e.message;
|
|
||||||
}
|
|
||||||
GpsTracksModels.create2Address({
|
|
||||||
device_id: tracks[i].device_id,
|
|
||||||
master_id: tracks[i].id,
|
|
||||||
lat: tracks[i].latitude,
|
|
||||||
lng: tracks[i].longitude,
|
|
||||||
stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
|
||||||
// log_reverse_geo: JSON.stringify(respData.data),
|
|
||||||
log_reverse_geo: stringify(respData.data),
|
|
||||||
crt: now,
|
|
||||||
crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
});
|
|
||||||
updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER;
|
|
||||||
await GpsTracksModels.update2(tracks[i].id, updtData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.allSettled(tracks.map(processTrack))
|
||||||
|
|
||||||
|
// for (let i = 0; i < tracks.length; i++) {
|
||||||
|
// const track = tracks[i]
|
||||||
|
// console.log("tracks[i] :", track.id, track.device_id, track.latitude, track.longitude)
|
||||||
|
// let now = moment().unix()
|
||||||
|
// let updtData = {}
|
||||||
|
// let respReverseGeo = null
|
||||||
|
// try {
|
||||||
|
// const sameAddr = await GpsTracksModels.select2Address(track.latitude, track.longitude)
|
||||||
|
|
||||||
|
// if (sameAddr.length > 0) {
|
||||||
|
// let addrData = {
|
||||||
|
// device_id: track.device_id,
|
||||||
|
// master_id: track.id,
|
||||||
|
// type: sameAddr[0].type,
|
||||||
|
// lat: track.latitude,
|
||||||
|
// lng: track.longitude,
|
||||||
|
// country_id: sameAddr[0].country_id,
|
||||||
|
// country_code: sameAddr[0].country_code,
|
||||||
|
// country_text: sameAddr[0].country_text,
|
||||||
|
// state_id: sameAddr[0].state_id,
|
||||||
|
// state_text: sameAddr[0].state_text,
|
||||||
|
// city_id: sameAddr[0].city_id,
|
||||||
|
// city_text: sameAddr[0].city_text,
|
||||||
|
// district_id: sameAddr[0].district_id,
|
||||||
|
// district_text: sameAddr[0].district_text,
|
||||||
|
// village_id: sameAddr[0].village_id,
|
||||||
|
// village_text: sameAddr[0].village_text,
|
||||||
|
// postcode: sameAddr[0].postcode,
|
||||||
|
// streets: sameAddr[0].streets,
|
||||||
|
// fulladdress: encodeURIComponent(decodeURIComponent(sameAddr[0].fulladdress)),
|
||||||
|
// type_reverse_geo: sameAddr[0].type_reverse_geo,
|
||||||
|
// stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||||
|
// log_reverse_geo: sameAddr[0].log_reverse_geo,
|
||||||
|
// crt: now,
|
||||||
|
// crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
// }
|
||||||
|
// GpsTracksModels.create2Address(addrData)
|
||||||
|
// updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC
|
||||||
|
// await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let params = new url.URLSearchParams({
|
||||||
|
// lat: track.latitude,
|
||||||
|
// lon: track.longitude,
|
||||||
|
// format: "geojson",
|
||||||
|
// })
|
||||||
|
// //const axInstance = axios.create()
|
||||||
|
// const axInstance = axios.create({
|
||||||
|
// proxy: {
|
||||||
|
// host: process.env.PROXY_URL,
|
||||||
|
// port: process.env.PROXY_PORT,
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// axios.defaults.timeout = 10000
|
||||||
|
// axios.defaults.crossDomain = true
|
||||||
|
// // respReverseGeo = await axios({
|
||||||
|
// // url: request.osm_reverse_geo.urlFull,
|
||||||
|
// // method: request.osm_reverse_geo.method,
|
||||||
|
// // params: params,
|
||||||
|
// // responseType: 'json',
|
||||||
|
// // });
|
||||||
|
// // respReverseGeo = await axInstance.get(request.osm_reverse_geo.urlFull + "?" + params.toString(), {
|
||||||
|
// // timeout: 10000,
|
||||||
|
// // });
|
||||||
|
// respReverseGeo = await axInstance.get(
|
||||||
|
// request.osm_reverse_geo.urlFull + "?" + params.toString(),
|
||||||
|
// {
|
||||||
|
// timeout: 10000,
|
||||||
|
// headers: {
|
||||||
|
// "User-Agent": "movana-fleet-management/1.0 (emirsyafmun@gmail.com)",
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// let respData = respReverseGeo.data || {}
|
||||||
|
// if (respReverseGeo.status == 200) {
|
||||||
|
// console.log("respReverseGeo: ", respData || "null")
|
||||||
|
// if (respData.features.length < 1) {
|
||||||
|
// GpsTracksModels.create2Address({
|
||||||
|
// device_id: track.device_id,
|
||||||
|
// master_id: track.id,
|
||||||
|
// lat: track.latitude,
|
||||||
|
// lng: track.longitude,
|
||||||
|
// stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_LOST,
|
||||||
|
// log_reverse_geo: JSON.stringify(respData),
|
||||||
|
// crt: now,
|
||||||
|
// crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
// })
|
||||||
|
// updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_LOST
|
||||||
|
// await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
// } else {
|
||||||
|
// let respAddr = respData.features[0].properties.address
|
||||||
|
// let addrData = {
|
||||||
|
// device_id: track.device_id,
|
||||||
|
// master_id: track.id,
|
||||||
|
// lat: track.latitude,
|
||||||
|
// lng: track.longitude,
|
||||||
|
// country_id: GpsTracksModels.DEFAULT_COUNTRY_ID,
|
||||||
|
// country_code: respAddr.country_code,
|
||||||
|
// country_text: respAddr.country
|
||||||
|
// ? respAddr.country.toUpperCase()
|
||||||
|
// : respAddr.country || null,
|
||||||
|
// state_id: null,
|
||||||
|
// city_id: null,
|
||||||
|
// district_id: null,
|
||||||
|
// village_id: null,
|
||||||
|
// postcode: respAddr.postcode,
|
||||||
|
// fulladdress: encodeURIComponent(respData.features[0].properties.display_name),
|
||||||
|
// stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_SC,
|
||||||
|
// log_reverse_geo: respData.features[0].properties
|
||||||
|
// ? JSON.stringify(respData.features[0].properties)
|
||||||
|
// : null,
|
||||||
|
// crt: now,
|
||||||
|
// crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
// }
|
||||||
|
// if (respAddr.state || respAddr.city) {
|
||||||
|
// addrData.state_text =
|
||||||
|
// respAddr.region ||
|
||||||
|
// respAddr.state ||
|
||||||
|
// respAddr.state_district ||
|
||||||
|
// respAddr.county ||
|
||||||
|
// respAddr.city ||
|
||||||
|
// ""
|
||||||
|
// addrData.state_text = addrData.state_text
|
||||||
|
// ? addrData.state_text.toUpperCase()
|
||||||
|
// : addrData.state_text || null
|
||||||
|
// addrData.state_text = addrData.state_text || null
|
||||||
|
// }
|
||||||
|
// if (respAddr.city_district || respAddr.city) {
|
||||||
|
// addrData.city_text = respAddr.city_district || respAddr.city || ""
|
||||||
|
// addrData.city_text = addrData.city_text
|
||||||
|
// ? addrData.city_text.toUpperCase()
|
||||||
|
// : addrData.city_text || null
|
||||||
|
// addrData.city_text = addrData.city_text || null
|
||||||
|
// }
|
||||||
|
// if (respAddr.suburb || respAddr.subdistrict) {
|
||||||
|
// addrData.district_text =
|
||||||
|
// respAddr.suburb || respAddr.subdistrict || respAddr.subdivision || ""
|
||||||
|
// addrData.district_text = addrData.district_text
|
||||||
|
// ? addrData.district_text.toUpperCase()
|
||||||
|
// : addrData.district_text || null
|
||||||
|
// addrData.district_text = addrData.district_text || null
|
||||||
|
// }
|
||||||
|
// if (respAddr.village) {
|
||||||
|
// addrData.village_text = respAddr.village || respAddr.neighbourhood || ""
|
||||||
|
// addrData.village_text = addrData.village_text
|
||||||
|
// ? addrData.village_text.toUpperCase()
|
||||||
|
// : addrData.village_text || null
|
||||||
|
// addrData.village_text = addrData.village_text || null
|
||||||
|
// }
|
||||||
|
// if (respAddr.amenity || respAddr.road || respAddr.city_block) {
|
||||||
|
// addrData.streets = ""
|
||||||
|
// addrData.streets += respAddr.amenity ? respAddr.amenity + ", " : ""
|
||||||
|
// addrData.streets += respAddr.road ? respAddr.road + ", " : ""
|
||||||
|
// addrData.streets += respAddr.house_number ? respAddr.house_number + ", " : ""
|
||||||
|
// addrData.streets += respAddr.house_name ? respAddr.house_name + ", " : ""
|
||||||
|
// addrData.streets += respAddr.city_block ? respAddr.city_block + ", " : ""
|
||||||
|
// addrData.streets += addrData.streets || null
|
||||||
|
// if (addrData.streets) {
|
||||||
|
// addrData.streets = encodeURIComponent(addrData.streets.slice(0, -2))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let byAll = await RegionModels.whereLike({
|
||||||
|
// nmProvinsiKel: addrData.state_text,
|
||||||
|
// nmKotamadyaKel: addrData.city_text,
|
||||||
|
// nmKecamatanKel: addrData.district_text,
|
||||||
|
// nmKelurahan: addrData.village_text,
|
||||||
|
// })
|
||||||
|
// if (byAll.length > 1) {
|
||||||
|
// addrData.state_id = byAll[0].kodeProv
|
||||||
|
// addrData.city_id = byAll[0].kodeKab
|
||||||
|
// addrData.district_id = byAll[0].kodeKec
|
||||||
|
// addrData.village_id = byAll[0].kodeKel
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let byKel = await RegionModels.whereLike({
|
||||||
|
// nmKelurahan: addrData.village_text,
|
||||||
|
// })
|
||||||
|
// if (byAll.length < 1 && byKel.length > 0) {
|
||||||
|
// addrData.state_id = byKel[0].kodeProv
|
||||||
|
// addrData.city_id = byKel[0].kodeKab
|
||||||
|
// addrData.district_id = byKel[0].kodeKec
|
||||||
|
// addrData.village_id = byKel[0].kodeKel
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (addrData.state_id === null) {
|
||||||
|
// let byPr = await RegionModels.whereLike({ nmProvinsiKel: addrData.state_text })
|
||||||
|
// if (byPr.length > 0) {
|
||||||
|
// addrData.state_id = byPr[0].kodeProv
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (addrData.state_id !== null && addrData.city_id === null) {
|
||||||
|
// let byKt = await RegionModels.whereLike({ nmKotamadyaKel: addrData.city_text })
|
||||||
|
// if (byKt.length > 0) {
|
||||||
|
// addrData.city_id = byKt[0].kodeKab
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// addrData.state_id !== null &&
|
||||||
|
// addrData.city_id !== null &&
|
||||||
|
// addrData.district_id === null
|
||||||
|
// ) {
|
||||||
|
// let byKc = await RegionModels.whereLike({ nmKecamatanKel: addrData.district_text })
|
||||||
|
// if (byKc.length > 0) {
|
||||||
|
// addrData.district_id = byKc[0].kodeKec
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// addrData.state_id !== null &&
|
||||||
|
// addrData.city_id !== null &&
|
||||||
|
// addrData.district_id !== null &&
|
||||||
|
// addrData.village_id === null
|
||||||
|
// ) {
|
||||||
|
// let byKl = await RegionModels.whereLike({ nmKelurahan: addrData.village_text })
|
||||||
|
// if (byKl.length > 0) {
|
||||||
|
// addrData.village_id = byKl[0].kodeKel
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GpsTracksModels.create2Address(addrData).catch((e) => {
|
||||||
|
// Logger.log(
|
||||||
|
// "error",
|
||||||
|
// `${schedulerName} running_error: ${JSON.stringify(
|
||||||
|
// e,
|
||||||
|
// Object.getOwnPropertyNames(e)
|
||||||
|
// )}`
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_SC
|
||||||
|
// await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log("FAILED respReverseGeo: ", respReverseGeo)
|
||||||
|
// GpsTracksModels.create2Address({
|
||||||
|
// device_id: track.device_id,
|
||||||
|
// master_id: track.id,
|
||||||
|
// lat: track.latitude,
|
||||||
|
// lng: track.longitude,
|
||||||
|
// stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||||
|
// log_reverse_geo: JSON.stringify(respData),
|
||||||
|
// crt: now,
|
||||||
|
// crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
// })
|
||||||
|
// updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER
|
||||||
|
// await GpsTracksModels.update2(track.id, updtData)
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// let respData = {}
|
||||||
|
// if (respReverseGeo) {
|
||||||
|
// if (respReverseGeo.status != 200) {
|
||||||
|
// respData.data = respReverseGeo.data
|
||||||
|
// } else {
|
||||||
|
// respData.msg = e.message
|
||||||
|
// }
|
||||||
|
// } else if (typeof e.response != "undefined") {
|
||||||
|
// respData.data = e.response
|
||||||
|
// } else {
|
||||||
|
// respData.msg = e.message
|
||||||
|
// }
|
||||||
|
// GpsTracksModels.create2Address({
|
||||||
|
// device_id: tracks[i].device_id,
|
||||||
|
// master_id: tracks[i].id,
|
||||||
|
// lat: tracks[i].latitude,
|
||||||
|
// lng: tracks[i].longitude,
|
||||||
|
// stts_reverse_geo: GpsTracksModels.STTS_REVERSE_GEO_ER,
|
||||||
|
// // log_reverse_geo: JSON.stringify(respData.data),
|
||||||
|
// log_reverse_geo: stringify(respData.data),
|
||||||
|
// crt: now,
|
||||||
|
// crt_format: moment.unix(now).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
// })
|
||||||
|
// updtData.stts_reverse_geo = GpsTracksModels.STTS_REVERSE_GEO_ER
|
||||||
|
// await GpsTracksModels.update2(tracks[i].id, updtData)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e)
|
||||||
Logger.log("error", `${schedulerName} error: ${JSON.stringify(e)}`);
|
Logger.log("error", `${schedulerName} error: ${JSON.stringify(e)}`)
|
||||||
}
|
}
|
||||||
// })();
|
// })();
|
||||||
|
|
||||||
Logger.log("info", `${schedulerName} success do reverse geocoding ${moment().format("YYYY-MM-DD HH:mm:ss")}`);
|
Logger.log("info", `${schedulerName} success do reverse geocoding ${moment().format("YYYY-MM-DD HH:mm:ss")}`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.log("error", `${schedulerName} error: ${JSON.stringify(e)}`);
|
Logger.log("error", `${schedulerName} error: ${JSON.stringify(e)}`)
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
};
|
}
|
||||||
|
|
||||||
const index = async () => {
|
const index = async () => {
|
||||||
while (1 == 1) {
|
while (1 == 1) {
|
||||||
await go();
|
await go()
|
||||||
await new Promise((r) => setTimeout(r, 1000));
|
await new Promise((r) => setTimeout(r, 1000))
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
index();
|
index()
|
||||||
|
|||||||
274
cron/TripsWorker.js
Normal file
274
cron/TripsWorker.js
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
const path = require("path")
|
||||||
|
require("dotenv").config({ path: path.resolve(__dirname, "../.env") })
|
||||||
|
|
||||||
|
const cron = require("node-cron")
|
||||||
|
const db = require("../config/dbConnCron")
|
||||||
|
const moment = require("moment")
|
||||||
|
const TIMEFIX = 25200
|
||||||
|
|
||||||
|
cron.schedule("0 0 * * * *", job)
|
||||||
|
cron.schedule("*/5 * * * *", tripGrouping)
|
||||||
|
// job()
|
||||||
|
// tripGrouping()
|
||||||
|
|
||||||
|
async function job() {
|
||||||
|
console.log("Monthly table job executed:", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||||
|
const currentDate = moment()
|
||||||
|
const lasYearDate = currentDate.clone().subtract(1, "years")
|
||||||
|
const databaseName = process.env.DATABASE
|
||||||
|
|
||||||
|
for (let i = 0; i <= 14; i++) {
|
||||||
|
const targetMonth = lasYearDate.clone().add(i, "months")
|
||||||
|
const yy = targetMonth.format("YY") // Two-digit year
|
||||||
|
const mm = targetMonth.format("MM") // Two-digit month
|
||||||
|
const tableName = `tracks_${yy}${mm}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if table exists
|
||||||
|
console.log(`Checking existence of table '${tableName}'...`)
|
||||||
|
const checkQuery = `
|
||||||
|
SELECT TABLE_NAME
|
||||||
|
FROM information_schema.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
|
||||||
|
`
|
||||||
|
const checkParams = [databaseName, tableName]
|
||||||
|
const existenceResult = await db.query(checkQuery, checkParams)
|
||||||
|
|
||||||
|
if (existenceResult.length === 0) {
|
||||||
|
// Table does not exist; create it
|
||||||
|
const createQuery = `
|
||||||
|
CREATE TABLE ${tableName} (
|
||||||
|
id bigint NOT NULL AUTO_INCREMENT,
|
||||||
|
original_hex text,
|
||||||
|
protocol enum('gt06','tk119','smartphone') DEFAULT NULL,
|
||||||
|
action enum('login','heartbeat','location','alarm','other') DEFAULT NULL,
|
||||||
|
device_id varchar(16) DEFAULT NULL,
|
||||||
|
latitude double DEFAULT NULL,
|
||||||
|
longitude double DEFAULT NULL,
|
||||||
|
speed int DEFAULT NULL COMMENT 'km/h',
|
||||||
|
orientation int NOT NULL DEFAULT '0' COMMENT 'in 360 degrees',
|
||||||
|
ignition int NOT NULL DEFAULT '0' COMMENT 'pengapian. 1=>on, 2=>off, 3=>acc_low, 4=>acc_high',
|
||||||
|
stts_engine int NOT NULL DEFAULT '0' COMMENT '1=>idling, 2=>moving, 3=>stopping',
|
||||||
|
stts_gps int NOT NULL DEFAULT '0' COMMENT '1=>on, 2=>off',
|
||||||
|
length_gps int NOT NULL DEFAULT '0' COMMENT 'length of GPS information,',
|
||||||
|
pos_stlt_gps int NOT NULL DEFAULT '0' COMMENT 'quantity of positioning satellites',
|
||||||
|
pos_type_gps int NOT NULL DEFAULT '0' COMMENT 'GPS real-time/differential positioning. 1=>diff_positioning,2=>realtime_positioning',
|
||||||
|
is_pos_gps int NOT NULL DEFAULT '0' COMMENT 'GPS having been positioning or not. 1=>not,2=>positioning',
|
||||||
|
stts_gsm int NOT NULL DEFAULT '0' COMMENT '1=>no signal, 2=>extremely weak signal 3=>very weak signal, 4=>good signal, 5=>strong signal',
|
||||||
|
stts_oil_electricity int NOT NULL DEFAULT '0' COMMENT '1=>on, 2=>off',
|
||||||
|
stts_alarm int NOT NULL DEFAULT '0' COMMENT '1=>normal,2=>shock,3=>power_cut,4=>low_battery,5=>sos',
|
||||||
|
stts_charge int NOT NULL DEFAULT '0' COMMENT '1=>off,2=>on',
|
||||||
|
stts_acc int NOT NULL DEFAULT '0' COMMENT '1=>low,2=>high',
|
||||||
|
stts_volt int NOT NULL DEFAULT '0' COMMENT '1=>shutdown,2=>extreme_low_battery,3=>very_low_batter,4=>low_battery,5=>medium,6=>high,7=>very_high',
|
||||||
|
stts_switch int NOT NULL DEFAULT '0' COMMENT '1=>off, 2=>on',
|
||||||
|
stts_reverse_geo int NOT NULL DEFAULT '0' COMMENT '1=>success, 2=>not, 3=>error, 4=>lost',
|
||||||
|
pre_milleage double NOT NULL DEFAULT '0' COMMENT 'in km. distance from prev to now',
|
||||||
|
sum_milleage double NOT NULL DEFAULT '0' COMMENT 'in km. summary device milleage. calculated based on this device',
|
||||||
|
vhc_milleage double NOT NULL DEFAULT '0' COMMENT 'in km. summary vhc milleage. calculated based on vhc, every change vhc this will get last milleage on that vhc',
|
||||||
|
drv_milleage double NOT NULL DEFAULT '0' COMMENT 'in km. summary drv milleage. calculated based on drv, every change drv this will get last milleage on that drv',
|
||||||
|
vhc_id int NOT NULL DEFAULT '0',
|
||||||
|
drv_id int NOT NULL DEFAULT '0',
|
||||||
|
source int NOT NULL DEFAULT '1' COMMENT '1=>gps_tracker, 2=>smartphone',
|
||||||
|
crt int NOT NULL,
|
||||||
|
crt_format datetime NOT NULL,
|
||||||
|
crt_d int NOT NULL DEFAULT '0' COMMENT 'from device/terminal',
|
||||||
|
crt_d_format datetime DEFAULT NULL,
|
||||||
|
crt_s int NOT NULL DEFAULT '0' COMMENT 'from server (receive time)',
|
||||||
|
crt_s_format datetime DEFAULT NULL,
|
||||||
|
crt_device_raw bigint DEFAULT '0' COMMENT 'device raw time',
|
||||||
|
daily_trip_id int unsigned DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
KEY tracks_device_id (device_id),
|
||||||
|
KEY tracks_vhc_id (vhc_id),
|
||||||
|
KEY tracks_drv_id (drv_id),
|
||||||
|
KEY idx_crt_d (crt_d),
|
||||||
|
KEY idx_vhc_crt_d (vhc_id,crt_d),
|
||||||
|
KEY idx_vhc_id_engine (vhc_id,stts_engine),
|
||||||
|
KEY idx_vhc_lat_long_crt (vhc_id,latitude,longitude,crt),
|
||||||
|
KEY idx_geo_stts_id (stts_reverse_geo,latitude,longitude,id),
|
||||||
|
KEY idx_gps_valid_geo (latitude,longitude,stts_reverse_geo),
|
||||||
|
KEY idx_gps_order (id),
|
||||||
|
KEY t_gps_tracks_latitude_IDX (latitude,longitude,vhc_id,crt_d,action) USING BTREE,
|
||||||
|
KEY t_gps_tracks_crt_s_IDX (crt_s,action) USING BTREE,
|
||||||
|
KEY t_gps_tracks_stts_reverse_geo_IDX (stts_reverse_geo,action,id,latitude,longitude) USING BTREE
|
||||||
|
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
|
||||||
|
`
|
||||||
|
const createParams = [] // No parameters for this CREATE statement
|
||||||
|
await db.query(createQuery, createParams)
|
||||||
|
console.log(`Table '${tableName}' created successfully.`)
|
||||||
|
} else {
|
||||||
|
console.log(`Table '${tableName}' already exists.`)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing table '${tableName}':`, error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// drop tables older than 12 months
|
||||||
|
const dropMonth = currentDate.clone().subtract(13, "months")
|
||||||
|
const dropYy = dropMonth.format("YY")
|
||||||
|
const dropMm = dropMonth.format("MM")
|
||||||
|
const dropTableName = `tracks_${dropYy}${dropMm}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dropQuery = `DROP TABLE IF EXISTS ${dropTableName}`
|
||||||
|
await db.query(dropQuery, [])
|
||||||
|
console.log(`Table '${dropTableName}' dropped successfully (if it existed).`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error dropping table '${dropTableName}':`, error.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert prev data
|
||||||
|
for (let i = 0; i <= 12; i++) {
|
||||||
|
const histMonth = lasYearDate.clone().add(i, "months")
|
||||||
|
const histYy = histMonth.format("YY")
|
||||||
|
const histMm = histMonth.format("MM")
|
||||||
|
const histTableName = `tracks_${histYy}${histMm}`
|
||||||
|
console.log(`Processing history insertion for table '${histTableName}'...`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
// const q1 = `SELECT count(*) jmlData FROM ${histTableName}`
|
||||||
|
// const r1 = await db.query(q1)
|
||||||
|
// const jmlData = r1[0].jmlData
|
||||||
|
// if (jmlData == 0) {
|
||||||
|
const startOfMonth = histMonth.clone().startOf("month").unix() - TIMEFIX
|
||||||
|
const endOfMonth = histMonth.clone().endOf("month").unix() - TIMEFIX
|
||||||
|
console.log(
|
||||||
|
`Inserting data into history table '${histTableName}' for records from ${startOfMonth} to ${endOfMonth}`
|
||||||
|
)
|
||||||
|
|
||||||
|
const q2 = `
|
||||||
|
INSERT INTO ${histTableName}
|
||||||
|
SELECT *, null FROM t_gps_tracks a
|
||||||
|
WHERE
|
||||||
|
crt_d < ? AND crt_d >= ?
|
||||||
|
and action = 'location'
|
||||||
|
and not exists (
|
||||||
|
select 1 from ${histTableName} b
|
||||||
|
where b.id = a.id
|
||||||
|
)
|
||||||
|
`
|
||||||
|
const d2 = [endOfMonth, startOfMonth]
|
||||||
|
const r2 = await db.query(q2, d2)
|
||||||
|
console.log(`Inserted ${r2.affectedRows} rows into '${histTableName}'`)
|
||||||
|
// } else {
|
||||||
|
// console.log(`Table '${histTableName}' already has data (${jmlData} rows). Skipping insertion.`)
|
||||||
|
// }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error inserting data into history table '${histTableName}':`, error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Monthly table job completed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tripGrouping() {
|
||||||
|
console.log("Trip grouping job executed:", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||||
|
for (let i = 0; i <= 1; i++) {
|
||||||
|
const lastMonth = moment().subtract(1, "months")
|
||||||
|
const histMonth = lastMonth.clone().add(i, "months")
|
||||||
|
const histYy = histMonth.format("YY")
|
||||||
|
const histMm = histMonth.format("MM")
|
||||||
|
const histTableName = `tracks_${histYy}${histMm}`
|
||||||
|
console.log(`Processing history insertion for table '${histTableName}'...`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.time(`Trip grouping for ${histTableName}`)
|
||||||
|
const startOfMonth = histMonth.clone().startOf("month").unix() - TIMEFIX
|
||||||
|
const endOfMonth = histMonth.clone().endOf("month").unix() - TIMEFIX
|
||||||
|
|
||||||
|
const q2 = `
|
||||||
|
insert into trips
|
||||||
|
(id,name,nopol1,vhc_id,mileage,start,finish,startMileage,finishMileage,startLoc,finishLoc,pool_code,dc_code,row_count)
|
||||||
|
WITH
|
||||||
|
gaps AS (
|
||||||
|
SELECT
|
||||||
|
-- previous gap since previous row > 1 hour (3600s)
|
||||||
|
CASE
|
||||||
|
WHEN (crt_d - LAG(crt_d, 1, NULL) OVER (PARTITION BY vhc_id ORDER BY crt_d)) > 3600
|
||||||
|
THEN 1 ELSE 0
|
||||||
|
END AS isStop,
|
||||||
|
t.*
|
||||||
|
FROM ${histTableName} t
|
||||||
|
WHERE
|
||||||
|
t.latitude IS NOT NULL
|
||||||
|
AND t.longitude IS NOT NULL
|
||||||
|
AND t.action = 'location'
|
||||||
|
AND t.crt_d BETWEEN ? AND ?
|
||||||
|
)
|
||||||
|
, trips AS (
|
||||||
|
SELECT
|
||||||
|
-- mark the start of a trip when ignition=4 and previous ignition <> 4
|
||||||
|
CASE
|
||||||
|
WHEN ignition = 4
|
||||||
|
AND LAG(ignition, 1, 0) OVER (PARTITION BY vhc_id ORDER BY crt_d) <> 4
|
||||||
|
or LAG(isStop, 1, 0) over (PARTITION BY vhc_id ORDER BY crt_d) = 1
|
||||||
|
THEN 1 ELSE 0
|
||||||
|
END AS trip_start,
|
||||||
|
g.*
|
||||||
|
FROM gaps g
|
||||||
|
)
|
||||||
|
, numbered AS (
|
||||||
|
SELECT
|
||||||
|
*,
|
||||||
|
-- assign a trip_id by cumulative sum of trip_start
|
||||||
|
SUM(trip_start) OVER (PARTITION BY vhc_id ORDER BY crt_d) AS trip_id
|
||||||
|
FROM trips
|
||||||
|
where
|
||||||
|
ignition = 4
|
||||||
|
and isStop = 0
|
||||||
|
),
|
||||||
|
agg AS (
|
||||||
|
SELECT
|
||||||
|
v.id,
|
||||||
|
v.name,
|
||||||
|
v.nopol1,
|
||||||
|
vhc_id,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY v.id ORDER BY MIN(a.crt_d)) AS trip_id,
|
||||||
|
SUM(pre_milleage) AS mileage,
|
||||||
|
MIN(a.crt_d) AS start,
|
||||||
|
MAX(a.crt_d) AS finish,
|
||||||
|
MIN(a.vhc_milleage) AS startMileage,
|
||||||
|
MAX(a.vhc_milleage) AS finishMileage,
|
||||||
|
(SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MIN(a.id) LIMIT 1) AS startLoc,
|
||||||
|
(SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MAX(a.id) LIMIT 1) AS finishLoc,
|
||||||
|
COUNT(*) AS row_count
|
||||||
|
FROM t_vehicles v
|
||||||
|
LEFT JOIN numbered a ON a.vhc_id = v.id
|
||||||
|
WHERE
|
||||||
|
v.dlt is null and trip_id != 0
|
||||||
|
GROUP BY v.id, a.trip_id
|
||||||
|
HAVING COUNT(*) > 1
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
agg.id,name,nopol1,vhc_id,mileage,start,finish,startMileage,finishMileage,startLoc,finishLoc,
|
||||||
|
tvd.pool_code, tvd.dc_code,
|
||||||
|
row_count
|
||||||
|
FROM agg agg
|
||||||
|
join t_vehicles_detail tvd on tvd.vid = agg.id
|
||||||
|
ORDER BY agg.id, trip_id
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
mileage = values(mileage),
|
||||||
|
start = values(start),
|
||||||
|
finish = values(finish),
|
||||||
|
startMileage = values(startMileage),
|
||||||
|
finishMileage = values(finishMileage),
|
||||||
|
startLoc = values(startLoc),
|
||||||
|
finishLoc = values(finishLoc),
|
||||||
|
row_count = values(row_count)
|
||||||
|
`
|
||||||
|
const d2 = [startOfMonth, endOfMonth]
|
||||||
|
const r2 = await db.query(q2, d2)
|
||||||
|
console.log(`Inserted ${r2.affectedRows} rows into 'trips' table from '${histTableName}'`)
|
||||||
|
console.timeEnd(`Trip grouping for ${histTableName}`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error inserting data into history table '${histTableName}':`, error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Trip grouping job completed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the process running
|
||||||
|
// console.log("Cron scheduler ")
|
||||||
|
process.on("SIGINT", () => {
|
||||||
|
console.log("Stopping cron scheduler...")
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,9 @@
|
|||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
|
"mysql2": "^3.15.1",
|
||||||
"nanoid": "^3.3.1",
|
"nanoid": "^3.3.1",
|
||||||
|
"node-cron": "^4.2.1",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"udp-packet": "^2.0.0",
|
"udp-packet": "^2.0.0",
|
||||||
|
|||||||
4163
pnpm-lock.yaml
generated
Normal file
4163
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user