diff --git a/Ejectable/App.tsx b/Ejectable/App.tsx index d06e8d88..da127ffe 100644 --- a/Ejectable/App.tsx +++ b/Ejectable/App.tsx @@ -9,11 +9,9 @@ import useCachedResources from './hooks/useCachedResources'; import useColorScheme from './hooks/useColorScheme'; import Navigation from './navigation'; import { Trips } from './GT2'; -import * as fs from 'fs'; - -export var debug:boolean = false; - var expoGeoState:any; + var debug:boolean = false; + var expoGeoState:any = null; export default function App() { const isLoadingComplete = useCachedResources(); @@ -29,12 +27,11 @@ export default function App() { if (status !== 'granted') { setErrorMsg('Permission to access location was denied'); return; - } + } else Trips.setLocEnabled(true); let location = await Location.getCurrentPositionAsync({}); setLocation(location); - if (!errorMsg && location) - Trips.deltaLoc(JSON.stringify(location)); + Trips.deltaLoc(location); })(); }, []); diff --git a/Ejectable/Coordinate.tsx b/Ejectable/Coordinate.tsx index 8becb22b..563be6a7 100644 --- a/Ejectable/Coordinate.tsx +++ b/Ejectable/Coordinate.tsx @@ -3,13 +3,13 @@ public mLatitude:number = 0.0; public mLongitude:number = 0.0; - mResults:any = [0, 0]; - PI_OVER_180:number = 0.017453292519943295769236907684886; - EARTH_RADIUS:number = 6371009; + mResults:any = [0, 0]; + PI_OVER_180:number = 0.017453292519943295769236907684886; + EARTH_RADIUS:number = 6371009; constructor (longitude:number, latitude:number) { this.mLongitude = longitude; - this.mLatitude = latitude; + this.mLatitude = latitude; } getLongitude() { return this.mLongitude; } setLongitude(longitude:number) { this.mLongitude = longitude; } diff --git a/Ejectable/GT2.tsx b/Ejectable/GT2.tsx index 53d7dfbc..85e9d2f9 100644 --- a/Ejectable/GT2.tsx +++ b/Ejectable/GT2.tsx @@ -1,8 +1,19 @@ -import * as React from 'react'; +import React, { useState, useEffect } from 'react'; +import * as Location from 'expo-location'; import { Coordinate } from "./Coordinate"; import { Text, View } from './components/Themed'; -import { Alert, StyleSheet } from 'react-native'; -import { useState, useEffect } from 'react'; +import { Button, StyleSheet } from 'react-native'; + + var debug:boolean = false; +export var endPending:boolean = false; + var expoGeoState:any = null; +export var locEnabled:boolean = false; + + const heartbeat:number = 500; + const displayBeat:number = 3; + +export function getEndPending() { return(endPending) } +export function toggleEndPending() { endPending = !endPending;} const styles = StyleSheet.create({ tripText: { @@ -14,68 +25,154 @@ const styles = StyleSheet.create({ fontWeight: 'bold', }}); -var lastLoc:any = null; -const heartbeat:number = 500; -const displayBeat:number = 3; -class Chronometer { +function Monitor() { - public display:string = "00.00.00"; - clock:number = 0; - intervalID:any = null; + const [location, setLocation] = useState(Object); + const [errorMsg, setErrorMsg] = useState(""); + + useEffect(() => { + (async () => { + let { status } = await Location.requestBackgroundPermissionsAsync(); + if (status !== 'granted') { + setErrorMsg('Permission to monitor location was denied'); + return; + } else Trips.setLocEnabled(true); + + let location = await Location.getCurrentPositionAsync({}); + setLocation(location); + Trips.deltaLoc(location); + })(); + }, []); + + expoGeoState = 'Waiting..'; + if (errorMsg) { + expoGeoState = errorMsg; + } else if (location) { + expoGeoState = JSON.stringify(location); + } + + + } + + +class Trip { + + public elapsed:string = "00.00.00"; + ticks:number = 0; + interval:any; + segments:number = 1; + distance:number = 0; + ds:number = 0; + CO2:number = 0.0; + loc:Coordinate = new Coordinate(0.0,0.0); + startPoint:Coordinate = new Coordinate(0.0,0.0) + tick() {let hours:number = 0, minutes:number = 0, seconds:number = 0; - this.clock++; - hours = this.clock < 3600 ? 0 : (this.clock / 3600); - minutes = this.clock < 60 ? 0 : (this.clock - (hours * 3600)) / 60; - seconds = this.clock % 60; - this.display = hours + ":" + minutes + ":" + seconds; + this.ticks++; + hours = this.ticks < 3600 ? 0 : (this.ticks / 3600); + minutes = this.ticks < 60 ? 0 : (this.ticks - (hours * 3600)) / 60; + seconds = this.ticks % 60; + this.elapsed = hours.toFixed(0) + ":" + minutes.toFixed(0) + ":" + seconds.toFixed(0); } - public start() { this.clock = 0; - this.intervalID = setInterval(this.tick, heartbeat); - } - public resume() { this.intervalID = setInterval(this.tick, heartbeat); } - public stop() { clearInterval(this.intervalID); } + public start() { this.interval = setInterval(() => this.tick(), heartbeat); } + public resume() { this.startPoint = new Coordinate(0.0,0.0) + this.loc = new Coordinate(0.0, 0.0); + this.segments++; + this.interval = setInterval(() => this.tick(), heartbeat); } + public stop() { this.ds = this.loc.distanceTo(this.startPoint); + this.distance += this.ds; + clearInterval(this.interval); + + } } - +interface expoGeoObj { + coords: [ + altitude:number, + altitudeAccuracy:number, + latitude:number, + accuracy:number, + longitude:number, + heading:number, + speed:number, + timestamp:number + ] +} + export class GT2 { - loc:Coordinate = new Coordinate(0,0); - clock:Chronometer = new Chronometer(); - startPoint:Coordinate = new Coordinate(0,0); + trip:Trip = new Trip(); + endPoint:Coordinate = new Coordinate(0.0,0.0); + startPoint:Coordinate = new Coordinate(0.0,0.0); displayInterval:number = displayBeat * heartbeat; public distance:number = 0.0; - co2Rate:number = 0.0; - currTime:number = 0; - lastTime:number = 0; + co2Rate:number = 250.0; z:number = 0.0; - public v:number = 0.0; + public v:number = 0.0; public inProgress:boolean = false; public paused:boolean = false; public elapsed:number = 0.0; - segments:number = 0; elevation:number = 0.0; + public units:string = "km"; + public CO2Effect:string = "carbon burden"; + nTrips:number = 0; - parseGeoExpo(key:string, value:any) {} + n:number = 0.0; + m:number = 0.0; + public deltaLoc(lastFix:any) { + lastFix = JSON.stringify(lastFix); + let expoFix:expoGeoObj = JSON.parse(lastFix); + this.trip.loc.setLongitude(expoFix.coords['longitude']); + this.trip.loc.setLatitude(expoFix.coords['latitude']); + + if (this.trip.startPoint.mLatitude == 0.0) { + this.trip.startPoint.mLatitude = this.trip.loc.mLatitude; + this.trip.startPoint.mLongitude = this.trip.loc.mLongitude; + } + + this.trip.ds = this.trip.loc.distanceTo(this.trip.startPoint); + + } + + public end() { + + this.trip.stop(); + this.inProgress = false; + this.nTrips++; + toggleEndPending(); + + } + + public setLocEnabled(value:boolean) { locEnabled = value} + + public pause() { + + if (!this.paused) { + this.trip.stop(); + this.paused = true; + } else { + this.trip.resume(); + this.paused = false; + } + } public reset() { - this.startPoint = new Coordinate(0,0); this.distance = 0.0; - this.co2Rate = 0.0; - this.currTime = 0; - this.lastTime = 0; - this.loc = new Coordinate(0,0); + this.co2Rate = 0.0; + this.endPoint = new Coordinate(0,0); + this.startPoint = new Coordinate(0,0); this.v = 0; this.inProgress = false; this.paused = false; @@ -83,42 +180,40 @@ export class GT2 { } - public end() { - - this.clock.stop(); - this.inProgress = false; - this.nTrips++; - - } - - public pause() { - - if (!this.paused) { - this.clock.stop(); - this.paused = true; - } else { - this.clock.start(); - this.paused = false; - } - - } - public start() { this.reset(); - this.clock.start(); + this.trip = new Trip(); + this.trip.start(); this.inProgress = true; + } - + + lt:number = 0.0; + + public getTripSummary() : string { + + return ( + 'Elapsed - ' + this.trip.elapsed + '\n' + + 'Origin: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) + + ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' + + 'Destination: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) + + ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' + + 'CO2: ' + this.trip.CO2 + ' grams ' + this.CO2Effect ); + + } + public getTripPanel() : string { - if (this.inProgress) - return ( - 'Elapsed - ' + this.clock.display + '\n' + - 'Geo: ' + 'lat: ' + this.loc.mLatitude + ' long: ' + this.loc.mLatitude + '\n' + - 'Vector: ' + 'distance: ' + this.distance + ' velocity: ' + this.v + '\n' + + if (this.inProgress) { + return ( + 'Elapsed - ' + this.trip.elapsed + '\n' + + 'Geo: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) + + ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' + + 'Vector: ' + 'distance: ' + this.trip.ds + ' velocity: ' + this.v + '\n' + 'Altitude: ' + this.elevation + '\n'); - else return("No trip in progress. " + this.nTrips + " trip(s) completed"); + } + else return("No trip in progress. " + this.nTrips + " trip(s) completed."); } @@ -149,14 +244,44 @@ export class TripDisplay extends React.Component { render() { - return( - + if (!debug) + return( + {Trips.getTripPanel() } - ); + ); + else; + return( + + + {Trips.getTripPanel() } + + {expoGeoState} + ); + } } - + +export class TripSummary extends React.Component { + + constructor(props:any) { + super(props); + this.state = { slug: null }; + } + + render() { + + return( + + + {Trips.getTripSummary() } + + ); + + } + +} + export var Trips:GT2 = new GT2(); diff --git a/Ejectable/navigation/index.tsx b/Ejectable/navigation/index.tsx index b591fdfa..7364d4d3 100644 --- a/Ejectable/navigation/index.tsx +++ b/Ejectable/navigation/index.tsx @@ -42,6 +42,7 @@ function RootNavigator() { + ); @@ -51,7 +52,7 @@ function RootNavigator() { * A bottom tab navigator displays tab buttons on the bottom of the display to switch screens. * https://reactnavigation.org/docs/bottom-tab-navigator */ -const BottomTab = createBottomTabNavigator(); +export const BottomTab = createBottomTabNavigator(); function BottomTabNavigator() { const colorScheme = useColorScheme(); diff --git a/Ejectable/screens/HomeScreen.tsx b/Ejectable/screens/HomeScreen.tsx index 90c5662f..90a74e2c 100644 --- a/Ejectable/screens/HomeScreen.tsx +++ b/Ejectable/screens/HomeScreen.tsx @@ -5,7 +5,10 @@ import { ScreenInfo3 } from '../components/ScreenInfo'; const image = { uri: "https://meansofproduction.biz/images/GREENT.jpg" }; -export default function HomeScreen() { +export var nav:any = null; + +export default function HomeScreen(navigation:any) { + nav = navigation; return ( diff --git a/Ejectable/screens/SettingsScreen.tsx b/Ejectable/screens/SettingsScreen.tsx index 2b8d4854..3c427e56 100644 --- a/Ejectable/screens/SettingsScreen.tsx +++ b/Ejectable/screens/SettingsScreen.tsx @@ -4,6 +4,7 @@ import { Text, View } from '../components/Themed'; import { useState } from 'react'; import ScreenInfo from '../components/ScreenInfo'; import { SafeAreaView } from 'react-native-safe-area-context'; +import { Trips } from '../GT2'; export default function SettingsScreen() { const [number, onChangeNumber] = React.useState(""); @@ -26,15 +27,27 @@ export default function SettingsScreen() {