bdqh-course-platform/src/render/stores/nmea.ts

128 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import EventEmitter from 'events'
import { defineStore } from 'pinia'
import { parse, Helpers } from 'nmea'
export class NMEADataSource extends EventEmitter {}
const verify = (value: String) => {
if (!value) {
return false
}
const dollar_index = value.indexOf('$')
const star_index = value.indexOf('*')
if (value.indexOf('$') !== 0 || star_index <= dollar_index) {
return false
}
const [sentence, checksum, ] = value.split('*')
return Helpers.verifyChecksum(sentence, checksum)
}
export const useNMEAStore = defineStore('nmea', {
state: () => ({
GGA: null,
GLL: null,
GSA: {},
GSV: {},
RMC: null,
VTG: null,
ZDA: null,
TXT: null,
// ANT: null,
// DHV: null,
// LPS: null,
// UTC: null,
// GST: null,
// INS: null,
// TIM: null,
handled: false,
}),
getters: {
dateTime () {
if (!this.RMC || !this.RMC.date || !this.RMC.timestamp) return
return Helpers.parseDateTime(this.RMC.date, this.RMC.timestamp)
},
longitude () {
if (!this.RMC || !this.RMC.lon || !this.RMC.lonPole) return
return Helpers.parseLongitude(this.RMC.lon, this.RMC.lonPole)
},
latitude () {
if (!this.RMC || !this.RMC.lat || !this.RMC.latPole) return
return Helpers.parseLatitude(this.RMC.lat, this.RMC.latPole)
},
altitude () {
if (!this.GGA || !this.GGA.alt || !this.GGA.altUnit) return
return Helpers.parseAltitude(this.GGA.alt, this.GGA.altUnit)
},
satellites () {
return (talker_id) => {
const gsa = this.GSA[talker_id]
const gsvs = this.GSV[talker_id]
if (!gsa || !gsvs ) return
const satelliteArr = []
const active_satellites = gsa.satellites
gsvs.forEach(({ satellites }) => {
satellites.forEach(satellite => {
if (active_satellites.indexOf(parseInt(satellite.id)) < 0) {
satellite.active = false
} else {
satellite.active = true
}
satelliteArr.push(satellite)
})
})
return satelliteArr
}
},
},
actions: {
bindDataSource(source: NMEADataSource) {
source.on('open', () => this.$reset())
let result;
source.on('data', (data: String) => {
if (!verify(data)) return
result = parse(data)
if (!result) return
// 监控第一条语句并重置所有state
if (result.sentence === 'GGA') this.$reset()
switch (result.sentence) {
case 'GSA':
this.GSA[result.talker_id] = result
break;
case 'GSV':
if (!this.GSV[result.talker_id]) {
this.GSV[result.talker_id] = []
}
this.GSV[result.talker_id].push(result)
break;
default:
this.$state[result.sentence] = result
break;
}
// 监听最后一条语句并设置handled为true
if (result.sentence === 'TXT') {
this.handled = true
}
})
},
},
})