1+ // Copyright (c) 2023-2025 Gold87 and other Elastic contributors
2+ // This software can be modified and/or shared under the terms
3+ // defined by the Elastic license:
4+ // https://github.com/Gold872/elastic-dashboard/blob/main/LICENSE
5+
6+ // From: https://frc-elastic.gitbook.io/docs/additional-features-and-references/robot-notifications-with-elasticlib and https://github.com/Gold872/elastic-dashboard/blob/main/elasticlib/Elastic.java
7+
8+ package org .carlmontrobotics .lib199 .vendorLibs ;
9+
10+ import com .fasterxml .jackson .annotation .JsonProperty ;
11+ import com .fasterxml .jackson .core .JsonProcessingException ;
12+ import com .fasterxml .jackson .databind .ObjectMapper ;
13+ import edu .wpi .first .networktables .NetworkTableInstance ;
14+ import edu .wpi .first .networktables .PubSubOption ;
15+ import edu .wpi .first .networktables .StringPublisher ;
16+ import edu .wpi .first .networktables .StringTopic ;
17+ /**
18+ * A class that provides methods for interacting with the Elastic dashboard, including sending
19+ * notifications and selecting tabs. This taken straight from the official Elastic documentation
20+ * (see https://frc-elastic.gitbook.io/docs/additional-features-and-references/robot-notifications-with-elasticlib for documentation
21+ * and for original code https://github.com/Gold872/elastic-dashboard/blob/main/elasticlib/Elastic.java)
22+ */
23+
24+ public final class Elastic {
25+ private static final StringTopic notificationTopic =
26+ NetworkTableInstance .getDefault ().getStringTopic ("/Elastic/RobotNotifications" );
27+ private static final StringPublisher notificationPublisher =
28+ notificationTopic .publish (PubSubOption .sendAll (true ), PubSubOption .keepDuplicates (true ));
29+ private static final StringTopic selectedTabTopic =
30+ NetworkTableInstance .getDefault ().getStringTopic ("/Elastic/SelectedTab" );
31+ private static final StringPublisher selectedTabPublisher =
32+ selectedTabTopic .publish (PubSubOption .keepDuplicates (true ));
33+ private static final ObjectMapper objectMapper = new ObjectMapper ();
34+
35+ /**
36+ * Represents the possible levels of notifications for the Elastic dashboard. These levels are
37+ * used to indicate the severity or type of notification.
38+ */
39+ public enum NotificationLevel {
40+ /** Informational Message */
41+ INFO ,
42+ /** Warning message */
43+ WARNING ,
44+ /** Error message */
45+ ERROR
46+ }
47+
48+ /**
49+ * Sends an notification to the Elastic dashboard. The notification is serialized as a JSON string
50+ * before being published.
51+ *
52+ * @param notification the {@link Notification} object containing notification details
53+ */
54+ public static void sendNotification (Notification notification ) {
55+ try {
56+ notificationPublisher .set (objectMapper .writeValueAsString (notification ));
57+ } catch (JsonProcessingException e ) {
58+ e .printStackTrace ();
59+ }
60+ }
61+
62+ /**
63+ * Selects the tab of the dashboard with the given name. If no tab matches the name, this will
64+ * have no effect on the widgets or tabs in view.
65+ *
66+ * <p>If the given name is a number, Elastic will select the tab whose index equals the number
67+ * provided.
68+ *
69+ * @param tabName the name of the tab to select
70+ */
71+ public static void selectTab (String tabName ) {
72+ selectedTabPublisher .set (tabName );
73+ }
74+
75+ /**
76+ * Selects the tab of the dashboard at the given index. If this index is greater than or equal to
77+ * the number of tabs, this will have no effect.
78+ *
79+ * @param tabIndex the index of the tab to select.
80+ */
81+ public static void selectTab (int tabIndex ) {
82+ selectTab (Integer .toString (tabIndex ));
83+ }
84+
85+ /**
86+ * Represents an notification object to be sent to the Elastic dashboard. This object holds
87+ * properties such as level, title, description, display time, and dimensions to control how the
88+ * notification is displayed on the dashboard.
89+ */
90+ public static class Notification {
91+ @ JsonProperty ("level" )
92+ private NotificationLevel level ;
93+
94+ @ JsonProperty ("title" )
95+ private String title ;
96+
97+ @ JsonProperty ("description" )
98+ private String description ;
99+
100+ @ JsonProperty ("displayTime" )
101+ private int displayTimeMillis ;
102+
103+ @ JsonProperty ("width" )
104+ private double width ;
105+
106+ @ JsonProperty ("height" )
107+ private double height ;
108+
109+ /**
110+ * Creates a new Notification with all default parameters. This constructor is intended to be
111+ * used with the chainable decorator methods
112+ *
113+ * <p>Title and description fields are empty.
114+ */
115+ public Notification () {
116+ this (NotificationLevel .INFO , "" , "" );
117+ }
118+
119+ /**
120+ * Creates a new Notification with all properties specified.
121+ *
122+ * @param level the level of the notification (e.g., INFO, WARNING, ERROR)
123+ * @param title the title text of the notification
124+ * @param description the descriptive text of the notification
125+ * @param displayTimeMillis the time in milliseconds for which the notification is displayed
126+ * @param width the width of the notification display area
127+ * @param height the height of the notification display area, inferred if below zero
128+ */
129+ public Notification (
130+ NotificationLevel level ,
131+ String title ,
132+ String description ,
133+ int displayTimeMillis ,
134+ double width ,
135+ double height ) {
136+ this .level = level ;
137+ this .title = title ;
138+ this .displayTimeMillis = displayTimeMillis ;
139+ this .description = description ;
140+ this .height = height ;
141+ this .width = width ;
142+ }
143+
144+ /**
145+ * Creates a new Notification with default display time and dimensions.
146+ *
147+ * @param level the level of the notification
148+ * @param title the title text of the notification
149+ * @param description the descriptive text of the notification
150+ */
151+ public Notification (NotificationLevel level , String title , String description ) {
152+ this (level , title , description , 3000 , 350 , -1 );
153+ }
154+
155+ /**
156+ * Creates a new Notification with a specified display time and default dimensions.
157+ *
158+ * @param level the level of the notification
159+ * @param title the title text of the notification
160+ * @param description the descriptive text of the notification
161+ * @param displayTimeMillis the display time in milliseconds
162+ */
163+ public Notification (
164+ NotificationLevel level , String title , String description , int displayTimeMillis ) {
165+ this (level , title , description , displayTimeMillis , 350 , -1 );
166+ }
167+
168+ /**
169+ * Creates a new Notification with specified dimensions and default display time. If the height
170+ * is below zero, it is automatically inferred based on screen size.
171+ *
172+ * @param level the level of the notification
173+ * @param title the title text of the notification
174+ * @param description the descriptive text of the notification
175+ * @param width the width of the notification display area
176+ * @param height the height of the notification display area, inferred if below zero
177+ */
178+ public Notification (
179+ NotificationLevel level , String title , String description , double width , double height ) {
180+ this (level , title , description , 3000 , width , height );
181+ }
182+
183+ /**
184+ * Updates the level of this notification
185+ *
186+ * @param level the level to set the notification to
187+ */
188+ public void setLevel (NotificationLevel level ) {
189+ this .level = level ;
190+ }
191+
192+ /**
193+ * @return the level of this notification
194+ */
195+ public NotificationLevel getLevel () {
196+ return level ;
197+ }
198+
199+ /**
200+ * Updates the title of this notification
201+ *
202+ * @param title the title to set the notification to
203+ */
204+ public void setTitle (String title ) {
205+ this .title = title ;
206+ }
207+
208+ /**
209+ * Gets the title of this notification
210+ *
211+ * @return the title of this notification
212+ */
213+ public String getTitle () {
214+ return title ;
215+ }
216+
217+ /**
218+ * Updates the description of this notification
219+ *
220+ * @param description the description to set the notification to
221+ */
222+ public void setDescription (String description ) {
223+ this .description = description ;
224+ }
225+
226+ public String getDescription () {
227+ return description ;
228+ }
229+
230+ /**
231+ * Updates the display time of the notification
232+ *
233+ * @param seconds the number of seconds to display the notification for
234+ */
235+ public void setDisplayTimeSeconds (double seconds ) {
236+ setDisplayTimeMillis ((int ) Math .round (seconds * 1000 ));
237+ }
238+
239+ /**
240+ * Updates the display time of the notification in milliseconds
241+ *
242+ * @param displayTimeMillis the number of milliseconds to display the notification for
243+ */
244+ public void setDisplayTimeMillis (int displayTimeMillis ) {
245+ this .displayTimeMillis = displayTimeMillis ;
246+ }
247+
248+ /**
249+ * Gets the display time of the notification in milliseconds
250+ *
251+ * @return the number of milliseconds the notification is displayed for
252+ */
253+ public int getDisplayTimeMillis () {
254+ return displayTimeMillis ;
255+ }
256+
257+ /**
258+ * Updates the width of the notification
259+ *
260+ * @param width the width to set the notification to
261+ */
262+ public void setWidth (double width ) {
263+ this .width = width ;
264+ }
265+
266+ /**
267+ * Gets the width of the notification
268+ *
269+ * @return the width of the notification
270+ */
271+ public double getWidth () {
272+ return width ;
273+ }
274+
275+ /**
276+ * Updates the height of the notification
277+ *
278+ * <p>If the height is set to -1, the height will be determined automatically by the dashboard
279+ *
280+ * @param height the height to set the notification to
281+ */
282+ public void setHeight (double height ) {
283+ this .height = height ;
284+ }
285+
286+ /**
287+ * Gets the height of the notification
288+ *
289+ * @return the height of the notification
290+ */
291+ public double getHeight () {
292+ return height ;
293+ }
294+
295+ /**
296+ * Modifies the notification's level and returns itself to allow for method chaining
297+ *
298+ * @param level the level to set the notification to
299+ * @return the current notification
300+ */
301+ public Notification withLevel (NotificationLevel level ) {
302+ this .level = level ;
303+ return this ;
304+ }
305+
306+ /**
307+ * Modifies the notification's title and returns itself to allow for method chaining
308+ *
309+ * @param title the title to set the notification to
310+ * @return the current notification
311+ */
312+ public Notification withTitle (String title ) {
313+ setTitle (title );
314+ return this ;
315+ }
316+
317+ /**
318+ * Modifies the notification's description and returns itself to allow for method chaining
319+ *
320+ * @param description the description to set the notification to
321+ * @return the current notification
322+ */
323+ public Notification withDescription (String description ) {
324+ setDescription (description );
325+ return this ;
326+ }
327+
328+ /**
329+ * Modifies the notification's display time and returns itself to allow for method chaining
330+ *
331+ * @param seconds the number of seconds to display the notification for
332+ * @return the current notification
333+ */
334+ public Notification withDisplaySeconds (double seconds ) {
335+ return withDisplayMilliseconds ((int ) Math .round (seconds * 1000 ));
336+ }
337+
338+ /**
339+ * Modifies the notification's display time and returns itself to allow for method chaining
340+ *
341+ * @param displayTimeMillis the number of milliseconds to display the notification for
342+ * @return the current notification
343+ */
344+ public Notification withDisplayMilliseconds (int displayTimeMillis ) {
345+ setDisplayTimeMillis (displayTimeMillis );
346+ return this ;
347+ }
348+
349+ /**
350+ * Modifies the notification's width and returns itself to allow for method chaining
351+ *
352+ * @param width the width to set the notification to
353+ * @return the current notification
354+ */
355+ public Notification withWidth (double width ) {
356+ setWidth (width );
357+ return this ;
358+ }
359+
360+ /**
361+ * Modifies the notification's height and returns itself to allow for method chaining
362+ *
363+ * @param height the height to set the notification to
364+ * @return the current notification
365+ */
366+ public Notification withHeight (double height ) {
367+ setHeight (height );
368+ return this ;
369+ }
370+
371+ /**
372+ * Modifies the notification's height and returns itself to allow for method chaining
373+ *
374+ * <p>This will set the height to -1 to have it automatically determined by the dashboard
375+ *
376+ * @return the current notification
377+ */
378+ public Notification withAutomaticHeight () {
379+ setHeight (-1 );
380+ return this ;
381+ }
382+
383+ /**
384+ * Modifies the notification to disable the auto dismiss behavior
385+ *
386+ * <p>This sets the display time to 0 milliseconds
387+ *
388+ * <p>The auto dismiss behavior can be re-enabled by setting the display time to a number
389+ * greater than 0
390+ *
391+ * @return the current notification
392+ */
393+ public Notification withNoAutoDismiss () {
394+ setDisplayTimeMillis (0 );
395+ return this ;
396+ }
397+ }
398+ }
0 commit comments