Skip to content

Instantly share code, notes, and snippets.

@purpl3F0x
Created July 24, 2021 12:19
Show Gist options
  • Save purpl3F0x/deb68863a7195eb842afa3b0017202fe to your computer and use it in GitHub Desktop.
Save purpl3F0x/deb68863a7195eb842afa3b0017202fe to your computer and use it in GitHub Desktop.
//
// 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;
}
}
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;
}
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