Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making RedMap usable beyond NodeRed #279

Open
mhaberler opened this issue Jul 24, 2024 · 6 comments
Open

Making RedMap usable beyond NodeRed #279

mhaberler opened this issue Jul 24, 2024 · 6 comments

Comments

@mhaberler
Copy link

@dceejay here is a whacky idea

I like RedMap a lot, have used it in the past and find the idea of a mesage-driven map very compelling - it was super productive for my purpose and really left no urgent feature wishes for me

It would be wonderful to reuse RedMap in a non-NodeRed context, for instance in a PWA done with React, Vue or Svelte

why? because that wouldnt assume a Linux carriership is available - for instance an isolated application where sensor values come say via MQTT from embedded device and net connectivity cannot be assumed

I think the changes would be relativily minor to enable reuse of the RedMap - basically splitting out the SockJS connector into a separate file, and wrapping the core into some non-NodeRed examples which acquire the message context accordingly to the framework

I could imagine going for this work but I do not want to long-term fork RedMap for that

would you be willing to adopt such a split eventually, and occasionally give advice on the effort ?

of course assuming it doesnt bring down the house ;)

best regards
Michael

ps: here's a use case example

@dceejay
Copy link
Owner

dceejay commented Jul 25, 2024

Hi,
I'd like to understand some more how you think it would work. How could it be implemented without breaking the default Node-RED install ? What sort of devices are you thinking of serving it from ? There is quite a lot to host and serve (especially if you need to include maps). Given Node-RED runs on pretty small Linux devices like a PI zero and can also handle the data transformation part of your requirement there may not be much benefit... but I'm willing to be convinced.

@mhaberler
Copy link
Author

what I am thinking of is a "map interpreter as an npm package" (lets call it RedMap Interpreter or RMI) which reacts to messages passed via a generic message IO channel. RMI would attach to an existing Leaflet instance passed at init time, or create its own if told.

the RedMap NodeRed extension would:

  • import the RMI package
  • init Leaflet and pass it as parameter
  • provide the messaging hooks to/from the RMI via SockWS.

Other than the code base splitup there would be no semantic change to behavior. However now you can import the RMI package into an arbitrary web application and tie it to an arbitrary message context - since it's just about passing JSON back and forth

To explain how I arrived at that idea: I build a Node-Red/Redmap based flight display for hot air ballooning. Here it is:

image

The carrier ship: a mini PC runing Linux+NodeRED:
image

It does all sorts of advanced stuff - read BLE sensors, receive and display ADS-B messages via RTL-SDR, vertical and ground speed, heading, sector range rings with dead reckoning to predict where you are going. It turned out to be super useful, for instance sector range rings with dead reckoning to predict where you are going.

And it was by any measure the clunkiest flight instrument I ever had - mostly because running NodeRed on Android doesnt hunt and lots of baggage is needed.

Applying 80/20, I can do most of the functionality with a Vue, React or Svelte PWA. And for that I'd want to keep RedMap - without the server entourage; no point in re-inventing that wheel. If I want to go further, I could move the PWA to React Native and use say the phone's BLE API. But for the standard case the location API as available in the browser is good enough. So here the "message context" is just updates from the browser AP's to location, barometer etc.

let me give another example:

https://windy.com is a popular weather app and based on Leaflet. Part of its appeal comes from its plugin capability (https://docs.windy-plugins.com/) which fostered enormous user creativity - among them all sorts of race trackers, like for yachting, planes etc. The scheme is identical: the plugin connects to some message source, and acts upon updates received - typically secure Websockets, MQTT-over-wss or Server Events.

Here's one of them - a boat tracker extension:

image

For every such plugin, folks have reinvented the wheel: adding icons, orienting and styling them, tracks etc - at which point I recommended to split the problem into a generic mapping part and a message adaptation layer - the latter could just be an edit field with an arrow function to transform whatever comes down the messaging channel at hand into something RedMap understands (for a related example see myhelloiot - the visual is created by editng a JSX fragment and includes the message transform)

third example: you have an event source which talks WSS or MQTT-WSS - but it's an embedded controller, not a linux box. A PWA does the job, and there's no point for a Linux box. I have good experience with PicoMQTT and work is underway to make that work over WSS.

I hope this gets the idea across: separate Leaflet handling from message context, thus making the map component reusable

I will try to do a PoC with a React Leaflet app using the sensor/location API in the browser, and butcher worldmap.js into place without regard for reusability, just to see if the idea flies.

@dceejay
Copy link
Owner

dceejay commented Jul 29, 2024

Hi, very cool application.

I sort of get it - but still struggling to see where you actually want the split to be - as I have many Leaflet plugins already included - are you trying to get below that so you can add other plugins - Ie just exposing the Leaflet layer as you say - or do you mean right at the top at the web socket level ? in which case just take the whole worldmap/worldmap directory as that is all the client side code, and you just need to replicate the server side parts to convert whatever into worldmap json objects over the socket.

Or is it to add something somewhere in between so that the client side has access to local sensors etc ? eg the current tracking button
image that uses the location api

@mhaberler
Copy link
Author

My assumption so far was:

  • I can cut at the Websockets level
  • message "above the cut" can now be obtained through arbitrary methods: wss, MQTT, Server Events..
  • those messages typically will go through a transformation function which translates incoming objects to something RedMap understands
  • if the code is run in the context of an existing Leaflet application, it would take the Leaflet instance as another parameter to decorate that (the windy plugin scenario)
  • if as-is (Leaflet instance parameter is null) it would create its own Leaflet instance like now (existing Node-Red scenario or application from scratch)

but maybe this is a step to far ahead

probably a more immediate question is: can you envisage running RedMap referring to an existing Leaflet instance instead of creating its own?

@dceejay
Copy link
Owner

dceejay commented Jul 29, 2024

So you want both ? as at the top you want "arbitrary methods" and yet want an existing underlying instance of Leaflet.

All the plugins I add would also have to extend that instance ? What version of Leaflet would that be etc - I note Windy use a "slightly patched" version 1.4 - whereas I'm using 1.9 currently - so would all the plugins I use play nice ? Also in the general case how can we ensure compatibility ?

I guess you could check for the existence of the L. object and if it doesn't already exist then optionally load the leaflet library - but not sure how to do that as it's currently just a script include in the index.html - but happy to let you try.

@mhaberler
Copy link
Author

with "arbitrary methods" I meant - messages directed to RedMap are not limited to the current SockWS code; they'd be passed to via a method from using code regardeless of ingress

yes, the plugin idea assumes an existing leaflet instance; good point about the versioning/compatibility issues

yes, the idea was to check at runtime if possible

I think the best bet is to attempt the butchering port and asess the fallout

too early to decide on feasibility

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants