-
Notifications
You must be signed in to change notification settings - Fork 10
/
MostlyHarmlessTooSkill.cs
207 lines (180 loc) · 7.27 KB
/
MostlyHarmlessTooSkill.cs
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
using System;
using System.Collections.Generic;
using System.Threading;
using MistyRobotics.Common.Data;
using MistyRobotics.SDK;
using MistyRobotics.SDK.Messengers;
namespace SkillLibrary
{
/**********************************************************************
Copyright 2020 Misty Robotics
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**WARRANTY DISCLAIMER.**
* General. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MISTY
ROBOTICS PROVIDES THIS SAMPLE SOFTWARE "AS-IS" AND DISCLAIMS ALL
WARRANTIES AND CONDITIONS, WHETHER EXPRESS, IMPLIED, OR STATUTORY,
INCLUDING THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, TITLE, QUIET ENJOYMENT, ACCURACY, AND NON-INFRINGEMENT OF
THIRD-PARTY RIGHTS. MISTY ROBOTICS DOES NOT GUARANTEE ANY SPECIFIC
RESULTS FROM THE USE OF THIS SAMPLE SOFTWARE. MISTY ROBOTICS MAKES NO
WARRANTY THAT THIS SAMPLE SOFTWARE WILL BE UNINTERRUPTED, FREE OF VIRUSES
OR OTHER HARMFUL CODE, TIMELY, SECURE, OR ERROR-FREE.
* Use at Your Own Risk. YOU USE THIS SAMPLE SOFTWARE AND THE PRODUCT AT
YOUR OWN DISCRETION AND RISK. YOU WILL BE SOLELY RESPONSIBLE FOR (AND MISTY
ROBOTICS DISCLAIMS) ANY AND ALL LOSS, LIABILITY, OR DAMAGES, INCLUDING TO
ANY HOME, PERSONAL ITEMS, PRODUCT, OTHER PERIPHERALS CONNECTED TO THE PRODUCT,
COMPUTER, AND MOBILE DEVICE, RESULTING FROM YOUR USE OF THIS SAMPLE SOFTWARE
OR PRODUCT.
Please refer to the Misty Robotics End User License Agreement for further
information and full details:
https://www.mistyrobotics.com/legal/end-user-license-agreement/
**********************************************************************/
/// <summary>
/// Another Mostly Empty Skill
/// Upon OnStart event, starts a timed callback to randomly change the LED until the skill is cancelled or times out
/// </summary>
public class MostlyHarmlessTooSkill : IMistySkill
{
/// <summary>
/// Robot reference
/// </summary>
private IRobotMessenger _misty;
/// <summary>
/// Flag indicating class was disposed
/// </summary>
private bool _disposed = false;
/// <summary>
/// Timer object to perform callbacks at a regular interval
/// </summary>
private Timer _heartbeatTimer;
#region Required Skill Methods, Event Handlers & Accessors
/// <summary>
/// Skill details for the robot
/// Currently you need a guid to distinguish your skill from others on the robot, get one at this link and paste it in
/// https://www.guidgenerator.com/online-guid-generator.aspx
///
/// There are other parameters you can set if you want:
/// Description - a description of your skill
/// TimeoutInSeconds - timeout of skill in seconds
/// StartupRules - a list of options to indicate if a skill should start immediately upon startup
/// BroadcastMode - different modes can be set to share different levels of information from the robot using the 'SkillData' websocket
/// AllowedCleanupTimeInMs - How long to wait after calling OnCancel before denying messages from the skill and performing final cleanup
/// </summary>
public INativeRobotSkill Skill { get; private set; } = new NativeRobotSkill("MostlyHarmlessTooSkill", "82d7e714-b2b8-432a-a467-d5dfcff3d534");
/// <summary>
/// Random number generator
/// </summary>
private Random _randomGenerator = new Random();
/// <summary>
/// This method is called by the wrapper to set your robot interface
/// You need to save this off in the local variable commented on above as you are going use it to call the robot
/// </summary>
/// <param name="robotInterface"></param>
public void LoadRobotConnection(IRobotMessenger robotInterface)
{
_misty = robotInterface;
}
/// <summary>
/// Called when the robot wants to start this skill
/// </summary>
/// <param name="parameters"></param>
public void OnStart(object sender, IDictionary<string, object> parameters)
{
_misty.SkillLogger.LogVerbose($"MostlyHarmlessTooSkill : OnStart called => Start a callack to change the LED every 250 ms");
//Start a timer Heartbeat callback -Periodicity Example, waits a second before starting, then changes every 250 ms
//Will run until skill times out or is cancelled
_heartbeatTimer = new Timer(HeartbeatCallback, null, 1000, 250);
}
/// <summary>
/// Called when a user or the robot calls cancel on this skill
/// </summary>
public void OnCancel(object sender, IDictionary<string, object> parameters)
{
_misty.SkillLogger.LogVerbose($"MostlyHarmlessTooSkill : OnCancel called => Change LED to Red");
_misty.ChangeLED(255, 0, 0, null);
}
/// <summary>
/// Called when the skill times out
/// </summary>
public void OnTimeout(object sender, IDictionary<string, object> parameters)
{
_misty.SkillLogger.LogVerbose($"MostlyHarmlessTooSkill : OnTimeout called => Change LED to Purple");
_misty.ChangeLED(148, 0, 211, null);
}
/// <summary>
/// OnPause simply calls OnCancel in this example
/// </summary>
/// <param name="parameters"></param>
public void OnPause(object sender, IDictionary<string, object> parameters)
{
//In this example, Pause is not implemented by default and it simply calls OnCancel
_misty.SkillLogger.LogVerbose($"MostlyHarmlessTooSkill : OnPause called");
OnCancel(sender, parameters);
}
/// <summary>
/// OnResume simply calls OnStart in this example
/// </summary>
/// <param name="parameters"></param>
public void OnResume(object sender, IDictionary<string, object> parameters)
{
//In this example, Resume is not implemented by default and it simply calls OnStart
_misty.SkillLogger.LogVerbose($"MostlyHarmlessTooSkill : OnResume called");
OnStart(sender, parameters);
}
/// <summary>
/// Dispose method must be implemented by the class
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Protected Dispose implementation
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Free any other managed objects here.
_heartbeatTimer?.Dispose();
}
// Free any unmanaged objects here.
_disposed = true;
}
/// <summary>
/// Skill Finalizer/Destructor
/// </summary>
~MostlyHarmlessTooSkill()
{
Dispose(false);
}
#endregion
#region User Created Helper Methods
/// <summary>
/// Callback method for the heartbeat timer event
/// </summary>
/// <param name="data"></param>
private void HeartbeatCallback(object data)
{
//Ignore callbacks if we are cancelling...
if(!_misty.Wait(0)) { return; }
_misty.ChangeLED((uint)_randomGenerator.Next(0, 256), (uint)_randomGenerator.Next(0, 256), (uint)_randomGenerator.Next(0, 256), null);
_misty.SkillLogger.LogVerbose($"Change LED called after heartbeat callback");
}
#endregion
}
}