This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Convert this .NET SPA site into SignalK plugin
#1
Hello everyone,

First a bit of context: I wanted a "something" (external app, signalk plugin, whatever) that would record my boat performance over time, so I could get and "optimized polar". I know there's a polar recorder in OpenCPN, but I never managed to make it work. Also, I don't use OpenCPN. I tried the existing SignalK plugin, but it doesn't suite my need either. So I decided to write it myself, using the language I'm confortable with, which is C#, in the shape of a Blazor server application. When developing, I realized i could be interesting to have both the "cumulated" or "optimal" polar side by side with the current session's polar,  to be able to compare how well I'm sailing compared to what the boat can achieve in it's optimal triming conditions. Also, my girlfriend is just getting started in regattas, so she asked me if I could add a tool to analyse each training or competition, so as a developer, of course I couldn't resist.

Until now I got this far (note data is fake, as I develop at home using the delta simulator):

View of the optimized polar (cumulated over sessions):
   

View of the current session's polar:
   

View of the list of past sessions's polar:
   

View of the current training session:
   

View of the past training sessions (by clicking on each you get detailed info, including performance value base on a percentage of the optimal polar):
   

I won't ask to translate this into a react signalk-webapp, I'm already on it and I doubt anyone is interested Big Grin .
But since I've never worked with react until now, I would appreciate some advise, more specifically on how to communicate a plugin (which is runing constantly and a webapp which runs only when displayed).

Any insight will be appreciated!
Reply
#2
First: SK Web applications need not be React applications. WebApps are just static web applications: a bunch of html, css and js files in public directory of the WebApp.

I have no experience with Blazor. Can it produce a static web application? But it looks like your application has also a server side component to it, at least the snapshots look like they are stored on the server.

Have you considered using the existing plugins to write all of your data to InfluxDB / InfluxDB2 ? Then you could retrieve performance related data for any point in time at will, not just the snapshots. You could store the data in InfluxDb on the boat and then export the data to take with you and import to a db at home /in the cloud to be analysed.

If you have not looked into InfluxDb / Grafana combo that's what I would definitely start with.

Then if you need something more custom you could write your webapp with the tool you know, Blazor, and access the data in the db directly from C# with InfluxDb API.
Reply
#3
Thanks tkurki, I didn't think about using the already present storage wich is Influx. I was obvious and yet I went ahead and stored everything in a SQLite db. However, a time series db might not be the best option for some data. 

On the other side, Blazor is definetly not a static web site. It's a server process that streams html content to client using SignalR. Currently everything is computed/stored in the server side and updates are sent to client. Runs fine on the RPi and I can embed each page in KIP separately, but it cannot be integrated in SignalK.

So, after reading your advises, what comes to mind is this:

A SignalK plugin that
  • Handles the configuration
  • Expose 2 endpoints to Start/Stop recording session.
  • Expose 1 endpoint to fetch the list of sessions.
  • Save to SQLite (or file) the start/end times of each session

A SignalK webapp (react, since I already started) that has 3 pages
  • Display the optimal polar
  • Session recorder with start/stop button and the current data (polar, chart, etc)
  • Analysis page. Basically same as the sesion recorder, but without the button to start/stop recording, and with a list of recorded sessions.


Since all data is stored in InfluxDB, polar and other data can be fetched/computed on the fly when needed.

Does this sound like a valid architecture?
Reply
#4
Yes, I think it is.

Some details:
- i agree that timeseries db is not for everything
- your data structure is pretty close to a logbook. have you seen https://www.npmjs.com/package/@meri-impe...lk-logbook ? you could use it to record race related events, crew members etc. And sooner or later you'll need sail inventory and sail changes, that are already there. signalk-logbook also documents the api that it uses in OpenApi and the author is here and in Signal K Slack
- there is no very convenient way to enable/disable InfluxDb loggin. you can use the http api that the plugin configuration UI uses, but you need to send the whole configuration, not just flip enable/disable
- how do you plan to enter the optimal polar and serve it to your application? Signal K specification does include data structure for polars, see https://github.com/SignalK/specification...-data.json but it's been a while so I can't remember off the top of my head the details
- have you checked https://github.com/SignalK/polars-plugin ? As you can see from the commits not like it is under active development...but I would like to have a basic, no-backend-needed polar plugin

PS. Interestingly enough Blazor can produce browser only apps, under WebAssembly https://blog.logrocket.com/why-you-shoul...rameworks/
Reply
#5
Thanks again.

- I know the @meri-imperiumi/signalk-logbook plugin, and not I have it installed, but also is the code I'm using as a template to learn how to code this Tongue

- I've been doing a few tests today, and so far i think I'll have to replicate the settings (url, token, org and bucket) in my plugin's configuration.

- I never planned on loading an existing polar (the original idea was that the "optimal polar" is computed from al the sailing sessions). However it's something I've been thinking a lot today. If I don't have my "own storage" as I do on the .NET's app, I will have to recreate the polars at runtime which is not efficient, but also it wouldnt allow to modify them, and even less create/import one manually. For modern boats there are polar files available in csv format, so some people might be interested in this.
That being said, I think a bit more about it, but i guess the best approach is to decouple the recorded data in influx and the computed polar itself. That way, a polar can be created from a time range in influx, from a file, or entering it manually. No matter how, it will be stored in the SQLite db.

- Yes I tried the polars-plugin, but aside from the display itself, i didn't find it of any use really :/

About Blazor WebAssembly, it's true that the page is a .dll that 100% runs on the client, but both the .dll and other static assets need to be hosted somewhere, and I never tried with a non .Net server, but this definetly worth some investigation. (Note, my current project uses Blazor Server approach, but is quite easy to migrate).
Reply
#6
Well, I investigated a bit and I certainly can host Blazor WASM in nodeJs (never tried other than asp.net for that), which opens a new world of possiblities for me!! Big Grin
The plugin will handle configuration, expose a few APIs and host the wasm app, which will do the rest. Once I'm done, i will translate it to React anywayy, since I want to learn.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)