Introducing FRC Web Components

FRC Web Components is a set of web components you can use to build custom HTML dashboards for your robot.

FRC Web Components works with pynetworktables2js to communicate with your robot over NetworkTables. To use, run pynetworktables2js where you’re serving your HTML files, include the frc-web-components.js file as a script in your HTML page, and wrap your HTML in a frc-dashboard tag, and you’re ready to go!

<html>
  <head>
    <title>My Robot Dashboard!</title>
  </head>
  <body>
    <frc-dashboard>
      <nt-string key="/robotName" value="Dozer"></nt-string>
      <nt-number key="/angle" value="135"></nt-number>
      <h1>
        My robot's name is <frc-label source-key="/robotName"></frc-label>
      </h1>
      <frc-differential-drivebase
        source-key="/LiveWindow/Ungrouped/DifferentialDrive[1]"
      ></frc-differential-drivebase>
      <frc-gyro source-key="/angle" precision="2"></frc-gyro>
    </frc-dashboard>
    <script src="./frc-web-components.js"></script>
  </body>
</html>

Installing is easy:

  • Install pynetworktables2js
  • Download the frc-web-components.js file from the releases page and include it in your HTML dashboard.

Usage examples can be found here.

Additional documentation can be found on the github page’s readme: https://github.com/frc-web-components/frc-web-components

FRC Web Components is meant to extensible, meaning you can create your own components if the list of available ones don’t fit your needs!

Any feedback or contributions would be greatly welcomed! This is a new project so there are sure to be some issues. Please let me know if you want to test or need help getting started.

30 Likes

Looks interesting. I’m not a programmer but I will forward this to our programming team.

1 Like

Just wanted to share an example of a custom dashboard you can build using FRC Web Components:

It’s a touchscreen interface the students I mentor built that we were planning on using for this year’s competition. The 5 buttons on the left are the different modes the robot can be in. You can manually press these buttons to change the robot’s controls (except for when the match transitions to teleop or auto, then the change is automatic).

You can aim and shoot manually, or choose auto aiming, which will take the robot through 4 states: Backup, aim, stop, and shoot. This is visually represented by the “Shooter Pizza Tracker”, inspired by domino’s pizza tracker.

We have a ball counter for our intake which automatically shows how many balls there are, and an input field below for debugging if it miscounts.

There’s an interactive control panel, which spins to what the color sensor sees. You can also press on the different colors to go to that specific color, or press the rotate buttons to rotate the control panel a specific number of times.

There’s radio buttons to select between high and low gear.

And finally a control to transition through our different stages of climbing.

17 Likes

Interesting idea. Have you considered designing this for a modern web framework (e.g. React)?

2 Likes

lit-element and lit-html are about as modern as they come. They make use of new web standards which allow you to create native elements. I chose them for a few reasons:

  1. LitElement is more lightweight than angular/react/vue since it’s just a class that extends the brower’s HTMLElement class.
  2. It can be used without any tools, there’s no need for webpack, babel, or any transpilers. This makes it much more approachable compared to other frameworks that require a lot of time setting up and use of tools that require a lot of time to learn. It allowed me to create a script that you can include on a page that lets you build a dashboard with just a few HTML elements and CSS. No need for any javascript unless you want to build your own components.
  3. It’s simpler and easier to learn compared to frameworks like React and Angular which have pretty steep learning curves. I wanted to make something as easy and approachable as possible without losing any of the power other frameworks have. I chose this approach since many programmers in FIRST do not have a lot of experience with web technologies, so lowering the barrier as much as possible to creating a custom dashboard was a must.
  4. LitElement is here to stay. That’s not to say React/Angular/Vue aren’t, but LitElement is based on APIs supported natively by the browser, so as long as support for them will be around there will be support for LitElement or something like it.
  5. The elements created by LitElement are framework agnostic since they are native to the browser and can be included in a project that uses React/Angular/Vue/etc. This makes the approach less opinionated and allows you to use the tools you want to use. You could for example include the web components inside a dashboard created using the FRCDashboard project, which uses react uses electron (correction, it doesn’t use react. But my point still stands, you can use this with react or another framework if you wished to).
10 Likes

@AmoryG I have to give a huge shout out and thank you for this. It is beautiful, simple, and effective. We just purchased an external touchscreen for our driver station, and had the realization that shuffleboard does not support multiple displays so we were going to use an html solution, but had no idea where to start. This is perfect.

2 Likes

Just wanted to mention a few updates:

  • Added a power distribution panel and NetworkTable tree components
  • Added new form components
  • Fixed a bunch of bugs
  • Improved examples

Here is a video of me interacting with the new components with NetworkTables:

https://www.youtube.com/watch?v=CaRYY8_vcrQ

Examples for these components and all others can be found here: https://frc-web-components.github.io/examples/vanilla/index.html

As always, any feedback is welcome. I’d love to hear if anyone wants any particular components added. A lot of the components here are based off of Shuffleboard widgets, so anything you’d like to see in Shuffleboard/Smartdashboard can be suggested here too.

2 Likes

I under stand how to add the web components but how would I get for example our encoder data and place into the web components and would I add the code for this in the src folder of my FRC Robots code or would I have to do it in a completely separate folder. Im a bit confused and would love to add this to our programming…

I have no idea if im doing this right
image

this is what happens when I open pynetworktables2js.exe

The dashboard is actually intended to be run on your driverstation, so it should be separate from your robot code. You’ll have to create an html file that includes the frc-web-components.js script, which you’ll probably want to put in folder on your driverstation desktop or something. The pynetworktables2js exe file should also be run on the driverstation and separate from your robot specific code as well. Here’s a couple of examples that use npm and webpack you could copy: GitHub - frc-web-components/examples

Although it’s still in development, I would say the easiest way to use FRC Web Components is with the dashboard: https://frc-web-components.github.io/dashboard/

It’s similar to shuffleboard in that it has a drag/drop like interface you can use to add elements to and connect them with NetworkTables. Documentation on how to install the dashboard and use it can be found here: FRC Web Components — frc-web-components documentation (documentation is also a work in progress)

When you are happy with the dashboard you’ve built you can download it as an html file and push it to a github repo or whatever. You can also edit the html manually and upload it in the dashboard app if you want to do that instead of building it in the app. Either way, it’s a lot easier to get FRC Web Components working if you use the dashboard app.

1 Like

I don’t suppose there is a way to get robot enable/disable selectable on the webpage and passed to the driverstation?

How about displaying camera views from the cameraserver streams?

The dashboard has an FMS component exactly like what’s in shuffleboard which displays the enable/disable state. There’s also simulation components that requires the halsim websocket extension to run. You can set the robot’s state to disabled/auto/teleop/test with the robot state component. Tbh most of these sim components I created a few months ago back when the halsim websocket extension was first created, so some of these components might not work great for 2021. There’s a good chance they work, but there might be some bugs. I’ll focus again on the sim components soon, just have been pretty occupied with other things lately. There’s also a camera component which handles cameraserver streams. You can’t really see it in the dashboard right now since it’s not currently streaming to my dashboard, but it’s the selected component (the one with the green dashed border with a bunch of properties you can set similar to the ones in shuffleboard, like crosshair color, compression, width, height, etc.

Is there an easy way to truncate the # of decimal points for values? I’m just using the frc-label class to print doubles… I’m hoping this can be done on the webbrowser so I don’t have to burden the roborio with that math.

You can currently set the precision property which sets the # of decimal points for the number bar component:

What you probably want is a precision property for the number field component:

It doesn’t currently exist, but I can add it later today if this solution works for you.

Can it be added to the frc-label component? It’s nice to have key:value for a big column of data.

Thanks!

Could I see a screenshot of what you’re trying to do? I’m not completely sure I understand what you mean. Are you trying to display a table of data?

No values filled in since I’m not connected to the robot, but:

Just using frc-label component - but the values have like 20 decimal points, would be nice to be able to truncate them…

<div class="col-sm-3">
  <h4>Limelight</h4>
  <p>Limelight X: <frc-label source-key="/limelight/tx"></frc-label></p>
  <p>Limelight Y: <frc-label source-key="/limelight/ty"></frc-label></p>
  <p>Limelight Area: <frc-label source-key="/limelight/ta"></frc-label></p>
  <p>Limelight Valid: <frc-label source-key="/limelight/tv"></frc-label></p>
  <p>Limelight LEDs: <frc-label source-key="/limelight/ledMode"></frc-label></p>
</div>

I see. Maybe I can add an frc-number-label component that takes in a number value and allows you to set how many decimal places it has? Perhaps I can also add a table component that looks like this: HTML Examples | Grid | Components | Vaadin

Also, are you using the dashboard app from here or are you creating the dashboard by adding the frc web components script using npm/the script from the releases page? I’m asking because if you’re using the script then I’ll have to create a new release for you to get the updated change.

If you’re importing the script, could you try adding this code to the end of the body tag and tell me if it works?

<script>

      class NumberLabel extends webbit.Webbit {

        static get styles() {
          return webbit.css`
            :host {
              display: inline;
              font-size: inherit;
              font-family: inherit;
              font-weight: inherit;
              text-align: inherit;
              box-sizing: border-box;
              color: inherit;
            }
          `;
        }

        static get properties() {
          return {
            value: { type: Number, primary: true },
            precision: { type: Number }
          };
        }

        constructor() {
          super();
          this.value = 0;
          this.precision = 2;
        }

        render() {
          return webbit.html`${this.value.toFixed(this.precision)}`;
        }
      }

      webbitRegistry.define('frc-number-label', NumberLabel);

    </script>

Just replace your frc-label elements with frc-number-label and it should work. It’s a temporary solution you can use while you’re waiting for me to create a release.

I think it works - will need to test it with the robot to get actual #s to see it working. Doesn’t work great with sim mode.

I’m not using the dashboard app, just creating HTML directly.

I like the look of the grid component, I would definitely use that!