Created
July 24, 2021 12:19
-
-
Save purpl3F0x/deb68863a7195eb842afa3b0017202fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Copyright 2015-2021 by Garmin Ltd. or its subsidiaries. | |
// Subject to Garmin SDK License Agreement and Wearables | |
// Application Developer Agreement. | |
// | |
import Toybox.Ant; | |
import Toybox.Lang; | |
import Toybox.Time; | |
const PAGE_NUMBER = 1; | |
class MySensor extends Ant.GenericChannel { | |
private const DEVICE_NUM = 0; // probably not a constnant | |
private const DEVICE_TYPE = 3; | |
private const TRANS_TYPE = 1; | |
private const PERIOD = 8192; | |
private var _chanAssign as ChannelAssignment; | |
private var _deviceCfg as DeviceConfig; | |
private var _pastEventCount as Number?; | |
private var isClosed as Boolean; | |
private var isPaired as Boolean; | |
// Message indexes | |
private const MESSAGE_ID_INDEX = 0; | |
private const MESSAGE_CODE_INDEX = 1; | |
private var deleteThis as Float; | |
//! Constructor | |
public function initialize() { | |
// Get the channel | |
_chanAssign = new Ant.ChannelAssignment( | |
Ant.CHANNEL_TYPE_RX_ONLY, | |
Ant.NETWORK_PUBLIC); | |
GenericChannel.initialize(method(:onMessage), _chanAssign); | |
// Set the configuration | |
_deviceCfg = new Ant.DeviceConfig({ | |
:deviceNumber => 0, // Wildcard our search | |
:deviceType => 2, | |
:transmissionType => 0x05, | |
:messagePeriod => 8192, | |
:radioFrequency => 66, // Ant Frequency (2400 + 66Mhz) | |
:searchTimeoutLowPriority => 2, // Timeout in 5s, | |
:searchThreshold => 0}); // Pair to all transmitting sensors | |
GenericChannel.setDeviceConfig(_deviceCfg); | |
// _data = new MO2Data(); | |
isPaired = false; | |
isClosed = true; | |
} | |
//! Open an ANT channel | |
//! @return true if channel opened successfully, false otherwise | |
public function open() as Boolean { | |
isClosed = false; | |
// Open the channel | |
var open = GenericChannel.open(); | |
// _data = new MO2Data(); | |
_pastEventCount = 0; | |
return open; | |
} | |
//! Close the ANT sensor and save the session | |
public function closeSensor() as Void { | |
GenericChannel.close(); | |
} | |
//! Set the current time | |
public function setTime() as Void { | |
// if (!_searching && _data.isUtcTimeSet()) { | |
// // Create and populate the data payload | |
// var payload = new Array<Number>[8]; | |
// payload[0] = 0x10; // Command data page | |
// payload[1] = 0x00; // Set time command | |
// payload[2] = 0xFF; // Reserved | |
// payload[3] = 0; // Signed 2's complement value indicating local time offset in 15m intervals | |
// | |
// // Set the current time | |
// var moment = Time.now(); | |
// for (var i = 0; i < 4; i++) { | |
// payload[i + 4] = ((moment.value() >> i) & 0x000000FF); | |
// } | |
// | |
// // Form and send the message | |
// var message = new Ant.Message(); | |
// message.setPayload(payload); | |
// GenericChannel.sendAcknowledge(message); | |
// } | |
} | |
//! Update when a message is received | |
//! @param msg The ANT message | |
public function onMessage(msg as Message) as Void { | |
// Parse the payload | |
var payload = msg.getPayload(); | |
System.println(payload); | |
if ( Ant.MSG_ID_CHANNEL_RESPONSE_EVENT == msg.messageId ) { | |
if ( Ant.MSG_ID_RF_EVENT == payload[MESSAGE_ID_INDEX] ) { | |
// React to changes in the ANT channel state | |
switch(payload[MESSAGE_CODE_INDEX]) { | |
// Drop to search occurs after 2s elapse or 8 RX_FAIL events, whichever comes first | |
case Ant.MSG_CODE_EVENT_RX_FAIL_GO_TO_SEARCH: | |
// Reset HR data after missing over 2s of messages | |
break; | |
// Search timeout occurs after SEARCH_TIMEOUT duration passes without pairing | |
case Ant.MSG_CODE_EVENT_RX_SEARCH_TIMEOUT: | |
System.println("RX timeout!"); | |
break; | |
// Close event occurs after a search timeout or if it was requested | |
case Ant.MSG_CODE_EVENT_CHANNEL_CLOSED: | |
// Reset HR data after the channel closes | |
System.println("Channel Closed!"); | |
// If ANT closed the channel, re-open it to continue pairing | |
if(!isClosed) { | |
open(); | |
} | |
break; | |
} | |
} | |
} else if ( Ant.MSG_ID_BROADCAST_DATA == msg.messageId ) { | |
// data.parse( payload ); // Parse payload into data | |
deleteThis = payload[7]; | |
System.print("Got Data: "); | |
System.println(payload); | |
if ( !isPaired ) { | |
isPaired = true; // Only fire paired event once | |
// deviceNumber = msg.deviceNumber; | |
// transmissionType = msg.transmissionType; | |
} | |
} | |
} | |
//! Get the data for this sensor | |
//! @return Data object | |
// public function getData() as MO2Data { | |
// return _data; | |
// } | |
public function getData() as Float or String or Null{ | |
return deleteThis; | |
} | |
//! Get whether the channel is searching | |
//! @return true if searching, false otherwise | |
public function isSearching() as Boolean { | |
return ! isPaired; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Toybox.Application; | |
import Toybox.Lang; | |
import Toybox.WatchUi; | |
using Toybox.Ant; | |
class testdatafieldApp extends Application.AppBase { | |
private var _sensor as MO2Sensor?; | |
function initialize() { | |
AppBase.initialize(); | |
} | |
function onMessage(msg as Message) { | |
// Parse the payload | |
var payload = msg.getPayload(); | |
print("Got message!!"); | |
} | |
// onStart() is called on application start up | |
function onStart(state as Dictionary?) as Void { | |
try { | |
// Create the sensor object and open it | |
_sensor = new MySensor(); | |
(_sensor as MySensor).open(); | |
} catch (e instanceof Ant.UnableToAcquireChannelException) { | |
System.println(e.getErrorMessage()); | |
_sensor = null; | |
} | |
} | |
// onStop() is called when your application is exiting | |
function onStop(state as Dictionary?) as Void { | |
if (_sensor != null) { | |
_sensor.closeSensor(); | |
} | |
} | |
// Return the initial view of your application here | |
function getInitialView() as Array<Views or InputDelegates>? { | |
return [ new testdatafieldView(_sensor) ] as Array<Views or InputDelegates>; | |
} | |
} | |
function getApp() as testdatafieldApp { | |
return Application.getApp() as testdatafieldApp; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Toybox.Activity; | |
import Toybox.Lang; | |
import Toybox.WatchUi; | |
class testdatafieldView extends WatchUi.SimpleDataField { | |
private var _sensor as MySensor?; | |
// Set the label of the data field here. | |
function initialize(sensor as MySensor?) { | |
SimpleDataField.initialize(); | |
_sensor = sensor; | |
label = "Body Temperature"; | |
} | |
// The given info object contains all the current workout | |
// information. Calculate a value and return it in this method. | |
// Note that compute() and onUpdate() are asynchronous, and there is no | |
// guarantee that compute() will be called before onUpdate(). | |
function compute(info as Activity.Info) as Float or String or Null { | |
// See Activity.Info in the documentation for available information. | |
return _sensor.getData(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment