/// <summary> /// invoked when the user is attempting to tell us something about the course /// </summary> /// <param name="response"></param> private void ProcessMarkCommand(AppMessagePacket response) { var mark = (MarkType)((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 1)).Value; var bearingTuple = response.Values.SingleOrDefault(x => x.Key == 2); if (bearingTuple != null) { //bearing int pebbleBearing = ((AppMessageInt32)bearingTuple).Value; //convert to double double bearingToNorth = ((double)pebbleBearing / 65536.0) * 360.0; //pebble reports bearing to NORTH, we need to figure out what we're pointed at double bearingToMark = 360 - bearingToNorth; _queueCommand((s, r) => r.SetMarkBearing(mark, bearingToMark, true)); } else { //location _queueCommand((s, r) => r.SetMarkLocation(mark)); } }
/// <summary> /// update the the pebble with data from the current race/boat state /// </summary> /// <param name="state"></param> public void Update(State state) { //don't send anything until the last send has completed or errored if (_lastSend == null || _lastSend.IsCanceled || _lastSend.IsCompleted || _lastSend.IsFaulted //or if it has exceeded the send timeout || !_lastSendAt.HasValue || state.SystemTime - _lastSendAt.Value > _sendTimeout) { if (!_pebble.IsAlive) { //begin a reconnect thread out of process only if there isn't already one in progress if ((!_lastReconnectAttempt.HasValue || state.SystemTime - _lastReconnectAttempt > new TimeSpan(0, 0, 10)) && (_reconnect == null || _reconnect.IsFaulted || _reconnect.IsCanceled || _reconnect.IsCompleted)) { _reconnect = BeginReconnect(state.SystemTime); } } else { _transactionId--; AppMessagePacket message = new AppMessagePacket(); message.ApplicationId = _uuid; message.TransactionId = _transactionId; message.Command = (byte)Command.Push; string captions = ""; for (int i = 0; i < _lineCount; i++) { LineStateMap map = null; lock (_lineValueIndexes) { map = _lineStateMaps [_lineValueIndexes [i]]; } message.Values.Add(new AppMessageString() { Key = (uint)message.Values.Count, Value = map.Caption }); captions = captions + map.Caption + ","; message.Values.Add(new AppMessageString() { Key = (uint)message.Values.Count, Value = map.Get(state) }); } if (state.Message != null) { message.Values.Add(new AppMessageString() { Key = (uint)message.Values.Count, Value = state.Message.Text }); } _lastSend = _pebble.SendApplicationMessage(message); _lastSendAt = state.SystemTime; _logger.Debug("Sent state to pebble " + _pebble.PebbleID + " (" + captions + ")"); } } }
//self._pebble.send_packet(AppRunState(data=AppRunStateStart(uuid=app_uuid))) public async Task LaunchApp(UUID uuid) { var data = new AppMessagePacket(); data.ApplicationId = uuid; data.Command = (byte)Command.Push; data.TransactionId = 1; data.Values.Add(new AppMessageUInt8() { Key = 1, Value = 1 }); //this one is key 0, doesn't actually do anything await SendMessageNoResponseAsync(Endpoint.Launcher, data.GetBytes()); }
/// <summary> /// invoked when the user wants to change out a line on the dashboard /// </summary> /// <param name="response"></param> private void ProcessDashCommand(AppMessagePacket response) { //which line are we changing? var line = ((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 1)).Value; //change it to which map? var map = ((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 2)).Value; _logger.Info("Pebble " + _pebble.PebbleID + " Has requested Dashboard Row " + line + " to show " + _lineStateMaps[map].Caption); lock (_lineValueIndexes) { _lineValueIndexes[(int)line] = (int)map; } }
private static void SendAppMessage(Pebble pebble) { string uuidAppPath = SelectApp(); if (!string.IsNullOrEmpty(uuidAppPath) && File.Exists(uuidAppPath)) { using (var stream = new FileStream(uuidAppPath, FileMode.Open)) { using (var zip = new Zip()) { zip.Open(stream); var bundle = new AppBundle(); stream.Position = 0; bundle.Load(zip, pebble.Firmware.HardwarePlatform.GetSoftwarePlatform()); System.Console.Write("Enter Message:"); var messageText = System.Console.ReadLine(); //format a message var rand = new Random().Next(); AppMessagePacket message = new AppMessagePacket(); message.Command = (byte)Command.Push; message.Values.Add(new AppMessageUInt32() { Key = 0, Value = (uint)rand }); message.Values.Add(new AppMessageString() { Key = 1, Value = messageText }); message.ApplicationId = bundle.AppMetadata.UUID; message.TransactionId = 255; //send it Console.WriteLine("Sending Status " + rand + " to " + bundle.AppMetadata.UUID.ToString()); var task = pebble.SendApplicationMessage(message); task.Wait(); Console.WriteLine("Response received"); } } } else { Console.WriteLine("No .pbw"); } }
/// <summary> /// received when a button is pushed on the pebble dashboard /// </summary> /// <param name="response"></param> private void ProcessButtonCommand(AppMessagePacket response) { var lineTuple = response.Values.SingleOrDefault(x => x.Key == 1); if (lineTuple != null && lineTuple is AppMessageUInt8) { var line = ((AppMessageUInt8)lineTuple).Value; var action = _lineStateMaps[_lineValueIndexes[line]].Action; if (action != null) { _logger.Info("Received button press for line " + line + ", executing action for " + _lineStateMaps[_lineValueIndexes[line]].Caption); action(); } else { _logger.Info("Received button press for line " + line + ", but there is no action defined for " + _lineStateMaps[_lineValueIndexes[line]].Caption); } } }
/// <summary> /// invoked when data is received by the pebble /// </summary> /// <param name="response"></param> private void Receive(AppMessagePacket response) { if (response.Values != null) { var commandTuple = response.Values.SingleOrDefault(x => x.Key == 0); if (commandTuple != null && commandTuple is AppMessageUInt8) { UICommand command = (UICommand)((AppMessageUInt8)commandTuple).Value; if (_commandMaps.ContainsKey(command)) { _commandMaps[command](response); } else { _logger.Info("Received Command " + command.ToString() + " from pebble " + _pebble.PebbleID + ", but there is no map specified"); } } } }
private static void ReceiveAppMessage(AppMessagePacket response) { System.Console.WriteLine("Recieved App Message"); }
private void OnApplicationMessageReceived(AppMessagePacket response) { SendMessageNoResponseAsync(Endpoint.ApplicationMessage, new byte[] { 0xFF, response.Values != null ? response.TransactionId :(byte)0 }); }
public async Task <AppMessagePacket> SendApplicationMessage(AppMessagePacket data) { //DebugMessage(data.GetBytes()); return(await SendMessageAsync <AppMessagePacket>(Endpoint.ApplicationMessage, data.GetBytes())); }
private static async Task ShowPebbleMenu(Pebble pebble) { //string uuid = "22a27b9a-0b07-47af-ad87-b2c29305bab6"; var menu = new Menu( "Disconnect", "Get Time", "Set Current Time", "Get Firmware Info", "Send Ping", "Media Commands", "Install App", "Send App Message", "Reset", "Send Notification"); while (true) { switch (menu.ShowMenu()) { case 0: pebble.Disconnect(); return; case 1: var timeResult = await pebble.GetTimeAsync(); DisplayResult(timeResult, x => string.Format("Pebble Time: " + x.Time.ToString("G"))); break; case 2: await pebble.SetTimeAsync(DateTime.Now); goto case 1; case 3: var firmwareResult = await pebble.GetFirmwareVersionAsync(); DisplayResult(firmwareResult, x => string.Join(Environment.NewLine, "Firmware", x.Firmware.ToString(), "Recovery Firmware", x.RecoveryFirmware.ToString())); break; case 4: var pingResult = await pebble.PingAsync(); DisplayResult(pingResult, x => "Received Ping Response"); break; case 5: ShowMediaCommands(pebble); break; case 6: var progress = new Progress <ProgressValue>( pv => Console.WriteLine(pv.ProgressPercentage + " " + pv.Message)); string appPath = SelectApp(); if (!string.IsNullOrEmpty(appPath) && File.Exists(appPath)) { using (var stream = new FileStream(appPath, FileMode.Open)) { using (var zip = new Zip()) { zip.Open(stream); var bundle = new AppBundle(); stream.Position = 0; bundle.Load(zip, pebble.Firmware.HardwarePlatform.GetPlatform()); var task = pebble.InstallClient.InstallAppAsync(bundle, progress); await task; if (task.IsFaulted) { Console.WriteLine("Failed to install"); } //for firmware v3, launch is done as part of the install //Console.WriteLine("App Installed, launching..."); //var uuid=new UUID(bundle.AppInfo.UUID); //pebble.LaunchApp(uuid); //Console.WriteLine ("Launched"); } } } else { Console.WriteLine("No .pbw"); } break; case 7: //read the uuid from the pbw string uuidAppPath = SelectApp(); if (!string.IsNullOrEmpty(uuidAppPath) && File.Exists(uuidAppPath)) { using (var stream = new FileStream(uuidAppPath, FileMode.Open)) { using (var zip = new Zip()) { zip.Open(stream); var bundle = new AppBundle(); stream.Position = 0; bundle.Load(zip, pebble.Firmware.HardwarePlatform.GetPlatform()); //format a message var rand = new Random().Next(); AppMessagePacket message = new AppMessagePacket(); message.Values.Add(new AppMessageUInt32() { Value = (uint)rand }); message.Values.Add(new AppMessageString() { Value = "Hello from .net" }); message.ApplicationId = bundle.AppMetadata.UUID; message.TransactionId = 255; //send it Console.WriteLine("Sending Status " + rand + " to " + bundle.AppMetadata.UUID.ToString()); var t = pebble.SendApplicationMessage(message); await t; Console.WriteLine("Response received"); } } } else { Console.WriteLine("No .pbw"); } break; case 8: pebble.Reset(ResetCommand.Reset); break; case 9: TestNotification(pebble); break; } } }
/// <summary> /// update the the pebble with data from the current race/boat state /// </summary> /// <param name="state"></param> public void Update(State state) { //don't send anything until the last send has completed or errored if (_lastSend == null || _lastSend.IsCanceled || _lastSend.IsCompleted || _lastSend.IsFaulted //or if it has exceeded the send timeout || !_lastSendAt.HasValue || state.SystemTime - _lastSendAt.Value > _sendTimeout) { if (!_pebble.IsAlive) { //begin a reconnect thread out of process only if there isn't already one in progress if ((!_lastReconnectAttempt.HasValue || state.SystemTime -_lastReconnectAttempt > new TimeSpan(0,0,10)) && (_reconnect == null || _reconnect.IsFaulted || _reconnect.IsCanceled || _reconnect.IsCompleted)) { _reconnect = BeginReconnect (state.SystemTime); } } else { _transactionId--; AppMessagePacket message = new AppMessagePacket (); message.ApplicationId = _uuid; message.TransactionId = _transactionId; message.Command = (byte)Command.Push; string captions = ""; for (int i = 0; i < _lineCount; i++) { LineStateMap map = null; lock (_lineValueIndexes) { map = _lineStateMaps [_lineValueIndexes [i]]; } message.Values.Add (new AppMessageString () { Key = (uint)message.Values.Count, Value = map.Caption }); captions = captions + map.Caption + ","; message.Values.Add (new AppMessageString () { Key = (uint)message.Values.Count, Value = map.Get (state) }); } if (state.Message != null) { message.Values.Add (new AppMessageString () { Key = (uint)message.Values.Count, Value = state.Message.Text }); } _lastSend = _pebble.SendApplicationMessage (message); _lastSendAt = state.SystemTime; _logger.Debug ("Sent state to pebble " + _pebble.PebbleID + " (" + captions + ")"); } } }
/// <summary> /// invoked when the user is attempting to tell us something about the course /// </summary> /// <param name="response"></param> private void ProcessMarkCommand(AppMessagePacket response) { var mark = (MarkType)((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 1)).Value; var bearingTuple = response.Values.SingleOrDefault(x=>x.Key==2); if (bearingTuple!=null) { //bearing int pebbleBearing = ((AppMessageInt32)bearingTuple).Value; //convert to double double bearingToNorth = ((double)pebbleBearing/65536.0)*360.0; //pebble reports bearing to NORTH, we need to figure out what we're pointed at double bearingToMark = 360 - bearingToNorth; _queueCommand((s, r) => r.SetMarkBearing(mark, bearingToMark, true)); } else { //location _queueCommand((s, r) => r.SetMarkLocation(mark)); } }
/// <summary> /// invoked when the user wants to change out a line on the dashboard /// </summary> /// <param name="response"></param> private void ProcessDashCommand(AppMessagePacket response) { //which line are we changing? var line = ((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 1)).Value; //change it to which map? var map = ((AppMessageUInt8)response.Values.SingleOrDefault(x => x.Key == 2)).Value; _logger.Info("Pebble "+_pebble.PebbleID+" Has requested Dashboard Row "+line+" to show "+_lineStateMaps[map].Caption); lock (_lineValueIndexes) { _lineValueIndexes[(int) line] = (int) map; } }
/// <summary> /// received when a button is pushed on the pebble dashboard /// </summary> /// <param name="response"></param> private void ProcessButtonCommand(AppMessagePacket response) { var lineTuple = response.Values.SingleOrDefault(x=>x.Key==1); if(lineTuple!=null && lineTuple is AppMessageUInt8) { var line = ((AppMessageUInt8)lineTuple).Value; var action = _lineStateMaps[_lineValueIndexes[line]].Action; if(action!=null) { _logger.Info("Received button press for line " + line + ", executing action for " + _lineStateMaps[_lineValueIndexes[line]].Caption); action(); } else { _logger.Info("Received button press for line " + line+", but there is no action defined for "+_lineStateMaps[_lineValueIndexes[line]].Caption); } } }
/// <summary> /// invoked when data is received by the pebble /// </summary> /// <param name="response"></param> private void Receive(AppMessagePacket response) { if (response.Values != null) { var commandTuple = response.Values.SingleOrDefault(x => x.Key == 0); if(commandTuple!=null && commandTuple is AppMessageUInt8) { UICommand command = (UICommand)((AppMessageUInt8)commandTuple).Value; if(_commandMaps.ContainsKey(command)) { _commandMaps[command](response); } else { _logger.Info("Received Command " + command.ToString() + " from pebble " + _pebble.PebbleID+", but there is no map specified"); } } } }