new device communication & analysis
- switched to websockets - analysis as pure function with internal hidden cache - new redux reducers
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as msgpack from 'msgpack-lite';
|
||||
|
||||
class DeviceHttpDataSource extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.data = [];
|
||||
this.dataUrl = this.props.deviceUrl + "/api/session/data";
|
||||
|
||||
// msgpack setup
|
||||
this.msgpackCodec = msgpack.createCodec();
|
||||
this.msgpackCodec.addExtUnpacker(205, function (byteArr) {
|
||||
const buffer = byteArr.buffer.slice(byteArr.byteOffset, byteArr.byteLength + byteArr.byteOffset);
|
||||
const result = new Int16Array(buffer);
|
||||
return result;
|
||||
});
|
||||
|
||||
this.fetchDataHttp = this.fetchDataHttp.bind(this);
|
||||
}
|
||||
|
||||
|
||||
getUrl(url) {
|
||||
return new Promise((accept, reject) => {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", url, true);
|
||||
req.responseType = "arraybuffer";
|
||||
|
||||
req.onload = function (event) {
|
||||
var resp = req.response;
|
||||
if (resp) {
|
||||
accept(resp);
|
||||
}
|
||||
};
|
||||
req.send(null);
|
||||
});
|
||||
//todo reject on error
|
||||
}
|
||||
|
||||
async fetchDataHttp() {
|
||||
try {
|
||||
const url = this.dataUrl + "?startIdx=" + this.data.length;
|
||||
const arrayBuffer = await this.getUrl(url);
|
||||
const decoded = msgpack.decode(new Uint8Array(arrayBuffer), { codec: this.msgpackCodec });
|
||||
|
||||
const typedValueArr = decoded['values'];
|
||||
const newDataStart = this.data.length;
|
||||
for (let i = 0; i < typedValueArr.length; ++i) {
|
||||
this.data.push(typedValueArr[i]);
|
||||
}
|
||||
this.props.onNewData(this.data, newDataStart);
|
||||
} catch (err) {
|
||||
//console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.timer = setInterval(this.fetchDataHttp, this.props.pollInterval);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeviceHttpDataSource.propTypes = {
|
||||
deviceUrl: PropTypes.string.isRequired,
|
||||
onNewData: PropTypes.func.isRequired,
|
||||
pollInterval: PropTypes.number // poll interval in ms
|
||||
};
|
||||
|
||||
DeviceHttpDataSource.defaultProps = {
|
||||
pollInterval: 20000
|
||||
};
|
||||
|
||||
export default DeviceHttpDataSource;
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Content, Card, CardItem, Body, Text, Button } from 'native-base';
|
||||
import { Image, ScrollView } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { startSession} from '../state/ActionCreators';
|
||||
import { ConnState, startSession } from '../state/DeviceReduxCoupling';
|
||||
|
||||
function HomeView(props) {
|
||||
const buttonText = props.running ? "View Swim Session" : "Start swimming";
|
||||
@@ -50,7 +50,7 @@ function HomeView(props) {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return { running: state.session.running };
|
||||
return { running: state.deviceState.connState == ConnState.CONNECTED_STARTING };
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(HomeView);
|
||||
|
||||
@@ -5,13 +5,11 @@ import { LinearGradient } from 'expo-linear-gradient';
|
||||
import IconCard from './IconCard';
|
||||
import Graph from './Graph';
|
||||
import { connect } from 'react-redux';
|
||||
import { stopSession } from '../state/ActionCreators';
|
||||
import backgroundColors from './Themes';
|
||||
import { useKeepAwake } from 'expo-keep-awake';
|
||||
import { stopSession } from '../state/DeviceReduxCoupling';
|
||||
|
||||
|
||||
function LiveTrainingView(props)
|
||||
{
|
||||
function LiveTrainingView(props) {
|
||||
const analysis = props.session.analysis;
|
||||
const onStopClick = () => {
|
||||
props.dispatch(stopSession());
|
||||
@@ -21,7 +19,7 @@ function LiveTrainingView(props)
|
||||
const totalMomentum = Math.trunc(analysis.totalMomentum / 10000);
|
||||
|
||||
useKeepAwake();
|
||||
|
||||
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={backgroundColors[props.theme]}
|
||||
@@ -68,11 +66,10 @@ const styles = StyleSheet.create({
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
session: state.session,
|
||||
peaksPerLap: state.settings.peaksPerLap,
|
||||
theme: state.settings.theme,
|
||||
session: state.deviceState,
|
||||
peaksPerLap: state.settings.analysis.peaksPerLap,
|
||||
theme: state.settings.theme,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(LiveTrainingView);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user