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 } }) }, }, })