<phyphox version="1.12">
    <title>Heart Rate with GPS</title>
    <icon>💓🛰</icon>
    <category>Bluetooth</category>
    <description>Read generic heart rate services and log GPS location.</description>
    <data-containers>
        <container size="0">tble</container>
        <container size="0">bpm</container>
        <container size="0">flags</container>
        <container size="0">bpm1</container>
        <container size="0">bpm2</container>

        <container size="0">lat</container>
        <container size="0">lon</container>
        <container size="0">z</container>
        <container size="0">zwgs84</container>
        <container size="0">v</container>
        <container size="0">dir</container>
        <container size="0">accuracy</container>
        <container size="0">zAccuracy</container>
        <container size="0">t</container>
        <container size="1">status</container>
        <container size="0">satellites</container>
        <container size="1" init="0">countT</container>
        <container size="0">d</container>
        <container size="0">dist</container>
        <container size="0">dnew</container>
        <container size="1" init="0">countUpdated</container>
        <container size="1" init="1">countUpdated+1</container>
        <container size="0">subLat</container>
        <container size="0">subLon</container>
        <container size="0">dLat</container>
        <container size="0">dLon</container>
        <container size="1">startLat</container>
        <container size="1">startLon</container>
        <container size="1">diststart</container>
    </data-containers>
    <input>
        <bluetooth uuid="0000180d-0000-1000-8000-00805f9b34fb" mode="notification">
            <output char="00002A37-0000-1000-8000-00805F9B34FB" offset="0" length="1" conversion="singleByte">flags</output>
            <output char="00002A37-0000-1000-8000-00805F9B34FB" offset="1" length="1" conversion="singleByte">bpm1</output>
            <output char="00002A37-0000-1000-8000-00805F9B34FB" offset="2" length="2" conversion="uInt16LittleEndian">bpm2</output>
            <output char="00002A37-0000-1000-8000-00805F9B34FB" extra="time">tble</output>
        </bluetooth>
        <location>
          <output component="lat">lat</output>
          <output component="lon">lon</output>
          <output component="z">z</output>
          <output component="zwgs84">zwgs84</output>
          <output component="v">v</output>
          <output component="dir">dir</output>
          <output component="accuracy">accuracy</output>
          <output component="zAccuracy">zAccuracy</output>
          <output component="t">t</output>
          <output component="satellites">satellites</output>
          <output component="status">status</output>
        </location>
    </input>
    <views>
        <view label="Raw Data">
            <graph label="Heart Rate" timeOnX="true" labelX="t" unitX="s" labelY="Heart Rate" unitY="bpm" partialUpdate="true">
                <input axis="y">bpm</input>
                <input axis="x">tble</input>
            </graph>
        </view>
        <view label="Position">
      <value label="Status">
        <input>status</input>
        <map max="-1">GPS disabled</map>
        <map min="0">GPS active</map>
      </value>
      <separator height="1"/>
      <graph label="Latitude" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="[[quantity_short_latitude]]" unitY="[[unit_short_degree]]" partialUpdate="true">
        <input axis="x">t</input>
        <input axis="y">lat</input>
      </graph>
      <graph label="Longitude" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="[[quantity_short_longitude]]" unitY="[[unit_short_degree]]" partialUpdate="true">
        <input axis="x">t</input>
        <input axis="y">lon</input>
      </graph>
      <graph label="Altitude" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="[[quantity_short_altitude]]" unitY="[[unit_short_meter]]" partialUpdate="true">
        <input axis="x">t</input>
        <input axis="y">z</input>
      </graph>
    </view>
    <view label="Movement">
      <value label="Status">
        <input>status</input>
        <map max="-1">GPS disabled</map>
        <map min="0">GPS active</map>
      </value>
      <separator height="1"/>
      <graph label="Speed" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="[[quantity_short_velocity]]" unitY="[[unit_short_meter_per_second]]" unitYperX="[[unit_short_meter_per_square_second]]" partialUpdate="true">
        <input axis="x">t</input>
        <input axis="y">v</input>
      </graph>
      <graph label="Direction" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="Direction" unitY="[[unit_short_degree]]" partialUpdate="true" style="dots">
        <input axis="x">t</input>
        <input axis="y">dir</input>
      </graph>
      <graph label="Distance travelled" timeOnX="true" labelX="[[quantity_short_time]]" unitX="[[unit_short_second]]" labelY="[[quantity_short_distance]]" unitY="[[unit_short_kilo_meter]]" partialUpdate="true">
        <input axis="x">t</input>
        <input axis="y">dist</input>
      </graph>
    </view>
    <view label="Simple">
      <value label="Status">
        <input>status</input>
        <map max="-1">GPS disabled</map>
        <map min="0">GPS active</map>
      </value>
      <separator height="1"/>
      <value label="Latitude" size="1" precision="6" unit="[[unit_short_degree]]">
        <input>lat</input>
      </value>
      <value label="Longitude" size="1" precision="6" unit="[[unit_short_degree]]">
        <input>lon</input>
      </value>
      <value label="Altitude" size="1" precision="1" unit="[[unit_short_meter]]">
        <input>z</input>
      </value>
      <value label="Altitude" size="1" precision="1" unit="m (WGS84)">
        <input>zwgs84</input>
      </value>
      <separator height="1"/>
      <value label="Speed" size="1" precision="1" unit="[[unit_short_meter_per_second]]">
        <input>v</input>
      </value>
      <value label="Speed" size="1" precision="1" factor="3.6" unit="[[unit_short_kilo_meter_per_hour]]">
        <input>v</input>
      </value>
      <separator height="1"/>
      <value label="Direction" size="1" precision="1" unit="[[unit_short_degree]]">
        <input>dir</input>
      </value>
      <value label="Compass" size="1">
        <input>dir</input>
        <map max="-157.5">[[direction_short_south]]</map>
        <map max="-112.5">[[direction_short_south_west]]</map>
        <map max="-67.5">[[direction_short_west]]</map>
        <map max="-22.5">[[direction_short_north_west]]</map>
        <map max="22.5">[[direction_short_north]]</map>
        <map max="67.5">[[direction_short_north_east]]</map>
        <map max="112.5">[[direction_short_east]]</map>
        <map max="157.5">[[direction_short_south_east]]</map>
        <map max="202.5">[[direction_short_south]]</map>
        <map max="247.5">[[direction_short_south_west]]</map>
        <map max="292.5">[[direction_short_west]]</map>
        <map max="337.5">[[direction_short_north_west]]</map>
        <map>[[direction_short_north]]</map>
      </value>
      <separator height="1"/>
      <value label="Distance travelled" size="1" precision="3" unit="[[unit_short_kilo_meter]]">
        <input>dist</input>
      </value>
      <value label="Distance from start" size="1" precision="3" unit="[[unit_short_kilo_meter]]">
        <input>diststart</input>
      </value>
      <separator height="1"/>
      <value label="Horizontal Accuracy" size="1" precision="1" unit="[[unit_short_meter]]">
        <input>accuracy</input>
      </value>
      <value label="Vertical Accuracy" size="1" precision="1" unit="[[unit_short_meter]]">
        <input>zAccuracy</input>
      </value>
      <value label="Satellites" size="1" precision="0">
        <input>satellites</input>
        <map max="-1">unknown</map>
      </value>
      <separator height="1"/>
      <info label="Note, that some devices do not have a GPS sensor, but provide location data through mobile or WIFI connections. These data sources produce data with bad accuracy."/>
      <separator height="1"/>
      <info label="Also make sure that your system's location setting is not set to &quot;Power saving&quot; because this usually turns off the precise GPS source."/>
      <separator height="1"/>
      <info label="The horizontal accuracy is the uncertainty of your location, while the vertical accuracy is the (usually worse) uncertainty of your altitude. If the accuracy is zero, this information is not available."/>
    </view>
    <view label="Coordinates">
      <value label="Status">
        <input>status</input>
        <map max="-1">GPS disabled</map>
        <map min="0">GPS active</map>
      </value>
      <separator height="2"/>
      <value format="float" label="Latitude" size="1" precision="6" unit="[[unit_short_degree]]">
        <input>lat</input>
      </value>
      <value format="float" label="Longitude" size="1" precision="6" unit="[[unit_short_degree]]">
        <input>lon</input>
      </value>
      <separator height="2"/>
      <value format="degree-minutes" label="Latitude" size="1" precision="4" positiveUnit="[[direction_short_north]]" negativeUnit="[[direction_short_south]]">
        <input>lat</input>
      </value>
      <value format="degree-minutes" label="Longitude" size="1" precision="4" positiveUnit="[[direction_short_east]]" negativeUnit="[[direction_short_west]]">
        <input>lon</input>
      </value>
      <separator height="2"/>
      <value format="degree-minutes-seconds" label="Latitude" size="1" precision="2" positiveUnit="[[direction_short_north]]" negativeUnit="[[direction_short_south]]">
        <input>lat</input>
      </value>
      <value format="degree-minutes-seconds" label="Longitude" size="1" precision="2" positiveUnit="[[direction_short_east]]" negativeUnit="[[direction_short_west]]">
        <input>lon</input>
      </value>
    </view>
    </views>
    <analysis sleep="0.1">
        <if greater="true">
            <input>flags</input>
            <input type="value">127</input>
            <input>bpm2</input>
            <input>bpm1</input>
            <output clear="false">bpm</output>
        </if>

        <count>
          <input clear="false">t</input>
          <output clear="false">countT</output>
        </count>
        <count>
          <input clear="false">d</input>
          <output>countUpdated</output>
        </count>
        <add>
          <input clear="false">countUpdated</input>
          <input type="value">1</input>
          <output>countUpdated+1</output>
        </add>
        <subrange>
          <input clear="false" as="from">countUpdated</input>
          <input clear="false" as="in">lat</input>
          <output>subLat</output>
        </subrange>
        <subrange>
          <input clear="false" as="from">countUpdated</input>
          <input clear="false" as="in">lon</input>
          <output>subLon</output>
        </subrange>
        <differentiate>
          <input clear="false">subLat</input>
          <output>dLat</output>
        </differentiate>
        <differentiate>
          <input clear="false">subLon</input>
          <output>dLon</output>
        </differentiate>
        <formula formula="0.01745329252*sqrt((cos(0.01745329252*[1_])*[3_])^2+[2_]*[2_])*6371">
          <input clear="false">subLat</input>
          <input>dLat</input>
          <input>dLon</input>
          <output>dnew</output>
        </formula>
        <if greater="true">
          <input clear="false">countT</input>
          <input clear="false">countUpdated+1</input>
          <input clear="false">dnew</input>
          <output clear="false">d</output>
        </if>
        <integrate>
          <input clear="false">d</input>
          <output>dist</output>
        </integrate>
        <first>
          <input clear="false">lon</input>
          <output>startLon</output>
        </first>
        <first>
          <input clear="false">lat</input>
          <output>startLat</output>
        </first>
        <formula formula="6371*acos(sin(0.01745329252*[1])*sin(0.01745329252*[3])+cos(0.01745329252*[1])*cos(0.01745329252*[3])*cos(0.01745329252*([2]-[4])))">
          <input>startLat</input>
          <input>startLon</input>
          <input clear="false">lat</input>
          <input clear="false">lon</input>
          <output>diststart</output>
        </formula>
    </analysis>
    <export>
        <set name="Heart Rate">
            <data name="Time (s)">tble</data>
            <data name="Heart Rate (bpm)">bpm</data>
        </set>
        <set name="GPS">
          <data name="Time (s)">t</data>
          <data name="Latitude (°)">lat</data>
          <data name="Longitude (°)">lon</data>
          <data name="Altitude (m)">z</data>
          <data name="Altitude WGS84 (m)">zwgs84</data>
          <data name="Speed (m/s)">v</data>
          <data name="Direction (°)">dir</data>
          <data name="Distance (km)">dist</data>
          <data name="Horizontal Accuracy (m)">accuracy</data>
          <data name="Vertical Accuracy (m)">zAccuracy</data>
          <data name="Satellites">satellites</data>
        </set>
    </export>
</phyphox>
