-
Notifications
You must be signed in to change notification settings - Fork 3
/
testki.html
132 lines (120 loc) · 6.89 KB
/
testki.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<!DOCTYPE html>
<html lang="en">
<head><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/png" href="favicon.png" /><title>Kiox2 display</title>
<meta name="Description" content="3rd party HR access must be enabled (and Gadgetbridge must be connected)">
<!-- <link rel="manifest" href="manifest_ki.json"> -->
<style>
body {font-family:Helvetica; background:#535353; color: white; height: 100vh; overflow:hidden}
h3 {color:#00baf2}
h1, h3 {text-align: center}
h4 {text-align: right}
#unit {float:right;font-weight: bold}
.light {background:white; color:#535353}
meter::-webkit-meter-bar {background: linear-gradient(to right, #ddd 49%, black 50%, #ddd 51%)}
h4>a {text-decoration:none; color:white}
#hr {user-select: none}
</style></head>
<body >
<a target="map" aria-label="map"><meter></meter></a><span id="unit"></span>
<a download='mytrack.gpx'><h1 id="speed">25</h1></a>
<h3 id="shot">Speed</h3>
<hr>
<h4><a href="https://github.com/dj0001/miband3-selfie" target="map">bpm</a></h4>
<h1 id="scanBtnn">ᛒ</h1>
<h3 id='hr'></h3>
<script>
var imp=true, speedo=true, col=true, hrmeter=true //edit here
var time1,time0,speed0, dst=0, mx=0, avg, ls=location.search, alt0, hrmx=0
function _(i18,lang) { lang=lang||navigator.language.split('-')[0]
var locales={en:['Heartrate','Speed','Distance'], es:['ritmo cardiaco','velocidad','distancia']}; locales.de=["Herzrate","Geschwindigkeit","Distanz"];
return locales[lang]?locales[lang][locales.en.indexOf(i18)]:i18 }
hr.textContent=_('Heartrate')
var gpx = '<?xml version="1.0" encoding="UTF-8"?>%0D%0A<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd" creator="dj" version="1.1"><trk><name>test</name><trkseg>%0D%0A'
if(col) document.querySelector('meter').low=0.51
unit.onclick=function(){imp=!imp; unit.textContent=(imp?'km':'mi')+(speedo?'/h':'')}
shot.onclick=function(){speedo=!speedo; this.textContent=speedo?_('Speed'):_('Distance'); imp=!imp;unit.click()}; speedo=!speedo;shot.click() //device search
speed.onclick=function(){this.textContent='\u2205 '+avg.toFixed(1)}
speed.oncontextmenu=function(){document.querySelector("a[download]").href="data:application/gpx+xml,"+gpx.replace('test',dst.toFixed(1)+'km')+"</trkseg></trk></gpx>"; document.querySelector("a[download]").download='mytrack'+new Date().toJSON().slice(0,-5)+'.gpx'}
if(ls=='?bright') document.body.classList.toggle("light") //?bright theme
navigator.geolocation.watchPosition(function(pos) {
var hr=1*scanBtnn.textContent||''; if(hr) hr='<gpxtpx:TrackPointExtension><gpxtpx:hr>'+hr+'</gpxtpx:hr></gpxtpx:TrackPointExtension>'
if(pos.coords.speed || speed0) gpx += '<trkpt lat="' + pos.coords.latitude + '" lon="' + pos.coords.longitude + '">'+'<time>'+new Date().toJSON()+'</time>'+hr+'</trkpt>%0D%0A'
document.querySelector('a[target=map]').href='https://www.openstreetmap.org/?mlat='+pos.coords.latitude+'&mlon='+pos.coords.longitude //+'&layers=C'
if(time0) dst+=speed0*(pos.timestamp-time0)/1000/1000
time0=pos.timestamp; speed0=pos.coords.speed; time1=time1||time0
var tmp=(pos.coords.speed*(imp?3.6:2.237)).toFixed(1).split('.'); speed.innerHTML=speedo? tmp[0]+'.<small>'+tmp[1]+'</small>' : (dst*(imp?1:0.621)).toFixed(1)
if(ls=='?alt') unit.textContent=(pos.coords.altitude>alt0?'\u2191 ':'')+pos.coords.altitude.toFixed()+' m'; alt0=pos.coords.altitude //?alt
if(ls=='?head') {unit.textContent='\u2191';unit.style.transform='rotate('+-pos.coords.heading+'deg)'} //?head compass
if(ls=='?trip') unit.textContent=new Date(time0-time1).toJSON().slice(11,16) //?trip time
avg=dst/(time0-time1)*1000*1000; if(!hrmeter||isNaN(scanBtnn.textContent)) document.querySelector('meter').value=pos.coords.speed/(2*avg)||0 //speed in comparision with average speed (middle)
if(col && (!hrmeter||isNaN(scanBtnn.textContent))) document.querySelector('meter').high=mx/(2*avg)||1; mx=Math.max(mx,speed0)
}, function(err) {console.warn(err.message)}, {enableHighAccuracy:true, timeout:50000, maximumAge:0})
if(ls=='?ambi') { const sensor = new AmbientLightSensor();
sensor.onreading = () => {if (sensor.illuminance>10) document.body.classList.add("light"); else document.body.classList.remove("light")}
sensor.start() } //flag
hr.onclick=function(){scanBtnn.textContent='≤ '+hrmx} //
</script>
<!-- <script src="webapp.bundle.js"></script> -->
<script>
//const bluetooth = navigator.bluetooth;
document.querySelector('#scanBtnn').addEventListener('click', scann);
const connect = async props => {
console.clear()
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: [0xFEE0] }, { services: ['heart_rate'] }],
acceptAllDevices: false,
})
console.log(`%c\n👩🏼⚕️`, 'font-size: 82px;', 'Starting HR...\n\n')
scanBtnn.textContent='...'
//await device.gatt.disconnect(); //?
const server = await device.gatt.connect(),
service = await server.getPrimaryService('heart_rate'),
char = await service.getCharacteristic('heart_rate_measurement')
char.oncharacteristicvaluechanged = props.onChange
char.startNotifications()
return char
}
function scann() {
//const data = []
var hrtime0, hrtime1, hrval, hrb=0 //
hr.oncontextmenu=function(){scanBtnn.textContent='∅ '+(hrb/(hrtime0-hrtime1)*1000*60).toFixed(1); return false} //
connect({
onChange: e => {
const val = e.target.value.getInt8(1)
/* data.push(val / 2)
let arr = data.slice(-200)
if (arr.length < 200) {
const fill = []
let n = 200 - arr.length
while (n--) fill.push(arr[0])
arr = fill.concat(arr)
} */
console.clear()
//console.graph(arr)
console.log(val) //console.log(`%c\n💚 ${val}`, 'font-size: 24px;')
scanBtnn.textContent=val
hrmx=Math.max(hrmx,val) //
if(hrtime0) hrb+=hrval*(Date.now()-hrtime0)/1000/60; else hrtime1=Date.now()
document.querySelector('h4>a').textContent='bpm'; if(hrval && val!=hrval) document.querySelector('h4>a').textContent += val>hrval? '↗':'↘' //
if(hrmeter) {document.querySelector('meter').value=val/180; document.querySelector('meter').high=.85} //
hrval=val; hrtime0=Date.now()
document.querySelector('h4>a').href+=(hrtime0/1000).toFixed()+';'+val+',' //
},
}).catch(e => console.warn(Error(e)))
navigator.wakeLock.request('screen') //
document.querySelector('h4>a').href='csvtocanvas2.htm?'
}
/* if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw_ki.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
} */
</script>
</body>
</html>