Homepage GitHub

Yukon UI & Rest API


(Theodoros Ntakouris) #81

Does being able to POST new configuration and restart yukon backend sound like a new idea?

I’d much prefer to have some database of a kind and add the ability to export data as log files or over json on demand, but let’s postpone that part till the other parts are in a more complete state.

What’s the purpose of the file server on the old gui_tool? guiserv

I think the rest api interface is close to it’s final state: swagger link


(Pavel Kirienko) #82

Sure, but we don’t need to restart the whole backend. We just need to instantiate a new pyuavcan.Node and destroy the old one. We may even keep the interfaces running, but I am not sure (I’m yet to get to that part).

We need the file server for firmware updates:

Which reminds me that if the server is running on a different machine, the user should be able to somehow upload the file to the server via the GUI.

The file server may be useful by itself irrespective of the firmware update feature.


Side note:

We don’t say “dynamic allocation” anymore. We say “plug-and-play” instead, because it reflects the semantics better.


(Theodoros Ntakouris) #83

Changed references to /plugandplay instead.

Another question: Type info caching during development of new types. If someone is going to use Yukon while developing new uavcan types at the same time, caching should be done on the browser’s cache that can be easily cleaned-on-refresh (example, on chrome: ctrl+shift+r / hard reload)?

Instead, we can always schedule type updates in the background, using types that exist in the cache and re-pulling everything from the server. That sounds like a bad idea and does not add much to the UX. Perhaps we can add some Cache-Control headers on the server-side with a variable ttl for each type: Practically infinite for UAVCAN public regulated ones, no caching for ones that are under some special dev folder (or if the folder contains a .nocache file?), a month or a day for other private unregulated ones.

Both parts of Yukon are probably going to run in the same machine while doing development, it should be pretty easy to just directory junction the paths that the backend is going to look at for the type info.


(Pavel Kirienko) #84

I don’t know what would be the best strategy. I think we can safely rely on the browser’s cache as you described in the beginning of your post, it seems sensible.

I don’t think it’s a sensible idea to require specific directory names or files, because due to the nature of DSDL it is expected that stable types will be sharing directories with unstable ones. You can always determine whether a data type is stable (i.e., safe to cache) by looking at its major version number: zero means unstable (don’t cache or use a low expiration timeout), anything >0 means stable (safe to cache forever or (better) until restart).


(Pavel Kirienko) #85

@Zarkopafilis I couldn’t run the changes from your pull request locally because the module @/Router is missing:

 ERROR  Failed to compile with 2 errors

This dependency was not found:

* @/Router in ./src/main.js, ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue

To install it, you can run: npm install --save @/Router
^C
✘-INT ~/uavcan/Yukon/frontend [:4d5c7aa|✚ 2] 
21:54 $ npm install --save @/Router
npm ERR! code ENOLOCAL
npm ERR! Could not install from "@/Router" as it does not contain a package.json file.

This thread is not the right place for this post, but I couldn’t comment on the pull request because GitHub is malfunctioning (it’s weird, I click the “Comment” button and my text just disappears, come on Microsoft!).


(Theodoros Ntakouris) #86

I replied over at github, it should be fine with npm run dev , the python backend does not do much stuff at the moment.


(Theodoros Ntakouris) #87

@pavel.kirienko The idea for the streaming approach is as follows:

Now that vuex is inside the project, we have enabled a state management system that is accessible from outside of the component hierarchy scope, for all of the app’s lifetime. This enables us to initiate a websocket connection on the background, which update’s the state, with that being decoupled from each component.

This kind of websocket connectivity should be fire-and-forget on the backend side.
For example, on the homescreen part, when the app is firstly loaded, each component does a get request in order to load information about the server, the pnp table and the node list.

Using websockets, these can then be updated on the background even when the user is on a different tab. Support for each and every component is not required. For example, we can only implement this functionality for stuff like the node list and the plug and play.

I’m investigating possible architectures and writing tests.

On the python side of parts, you just add connections on to a set and then, on each event, you broadcast updates to each and every connection.

On the js side of parts, you just use an EventSource


(Luis Diego García) #88

Hi, I am interested in helping out with Yukon.

I currently have experience with React Native, React, Redux, and Sagas. I see that you decided to use Vue and Vuex. I can invest some time learning about Vue in order to help out.

I’m curious to know if you considered using GraphQL instead of REST for the API?


(Scott Dixon) #89

Oh neat. New ideas! Please educate us on why GraphQL would be better for this use case? I love learning new things.


(Theodoros Ntakouris) #90

Hello. It’s very nice to see new people coming abroad. We evaluated React for the project and ended up using vue over it, due to licensing and slightly better developer experience.

Personally I have evaluated GraphQL as a solution for the project. The problems it’s designed to solve are:

  • Consuming data from multiple sources
  • Avoid the need of reconstructing (mapping) objects in the frontend
    … through an extra layer of abstraction.

Any webapp of medium size is going to have some kind of relation projected over REST endpoints. That aside, you can tell by just looking specific components that ql is not going to provide significant advantage (look at the Global Register View for example – the mappings and computed properties are huge).

Same thing with the “simpler” components: The 4 ones that make up the homescreen, for example. Yes we could debate over doing 1 call over 4 ones (1 for each sub-component). The 2 ones are really a couple of bytes and merging the other 2 would not make such difference. It would also make it a bit harder to separate concerns between components, require the logic of “splitting” the response inside the vuex/actions in order to update the correct module’s state parts.

I’m still open to using it if you find a proper use case: But for now, I see no valid one.


(Theodoros Ntakouris) #91

I finally found some time to finish work on GRV.

Here are some notes from the devcall:

Soft deadline for async pyuavcan: End of june
Hard: End of july-mid august

Next up to work on: Global Register View, file upload modal/popup thing

  • Merged Homescreen PR

(Theodoros Ntakouris) #92

@pavel.kirienko Sneak peek on how I am validating type edit form values:

I unsure of what float format you are using. Do you have some spec or a formula that I can swiftly calculate min and max number for floats? (JS has only got a ‘number’ data type, per IEEE 754.


(Pavel Kirienko) #93

You seem to be missing a minus-one in the uint case. The upper boundary (assuming that it is inclusive) should be 2 ^ ret.bits - 1. In the int case, the lower boundary should be negated.

For floats we use three formats defined in IEEE 754: binary16, binary32, and binary64. Their maximum values are defined as follows:

where frac constructs a rational number for exact computation; if you don’t require exactness, feel free to omit it.

The minimum values can be found by negating the maximums.

I am wondering though, would it not be easier to just obtain type information from PyDSDL instead of computing everything in JS? Just asking.