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

OctoPrint plugin for OctoDash config #921

Closed
TheSin- opened this issue Aug 19, 2020 · 24 comments
Closed

OctoPrint plugin for OctoDash config #921

TheSin- opened this issue Aug 19, 2020 · 24 comments
Labels
enhancement New feature or request

Comments

@TheSin-
Copy link
Contributor

TheSin- commented Aug 19, 2020

Just wanted a separate entry for creating an octoprint plugin for config handling on octodash to avoid using a keyboard.

More info to come on this but it could also be using to gather info that might not be in the API, like and API extension in the future.

@TheSin- TheSin- added the enhancement New feature or request label Aug 19, 2020
@UnchartedBull
Copy link
Owner

An actual plugin would be super useful. I don't know whether this is possible (I mean it is definitely possible, but whether it is allowed as a plugin) is to bootstrap the OctoPrint Installation to the plugin installation, that would also make the setup a lot easier :)

@UnchartedBull
Copy link
Owner

UnchartedBull commented Aug 19, 2020

Ok maybe another thing from the top of my head. One of the biggest changes planned for v3 is the switch to OctoPrints socket interface (https://docs.octoprint.org/en/master/api/push.html), which should marginally reduce load, but finally would make DLP optional as well (since Z-Height is available there). The problem is that you need to create a session once (the user needs to login for that). What I just thought about is something like a handshake process - The user would start OctoDash and would click an authenticate button or something like that, this would then result in a popup from the plugin which asks the currently logged in user to grant permission to OctoDash thus creating a token for OctoDash. Manual input should still be available though, but if that works out there is no real need for installation wizard anymore (or only a really small one with only checkboxes and maybe number inputs), since most of the other data can be retrieved from the Printer Profile. That would be super nice. Let me know if you want to investigate this further, or whether I should check if that's possible.

Edit: Seems to be possible for API Keys already: https://docs.octoprint.org/en/master/bundledplugins/appkeys.html 🎉

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

I do remember ready you comment on an other ticket about switching to push. Are you far along on that? Should make an octoprint api service that other services can access this would keep all eh calls to the api together and clean? Making it easier to switch the calls later to push since we would just use function calls internally? My current Angular project that is what I'm doing since the API isn't complete and I figure it'll be easier to change since I can control the input and output in the function no matter what changes.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

hmm that's a good plan honestly. I was kinda thinking the same, if octodash started up with an ip only on the display. Then in octoprint plugin you enter the ip to initiate the setup, that could exchange the initial data we require. the next thing on the script could be a 6 digit key just like bluetooth that would just confirm the right devices on the same network. Incase there is more then one, between the ip and the key I'm sure we could trust it for the setup.

I do agree that manual needs to be retained just in case, but I like the brain storming here.

And I for sure think this is possible and a very good user experience as it uses things that users are currently used to for iOT devices.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

right now I'm just going over all the code to get familiar, since I have a brand new printer I'm building and I have everything for the filament box, weight sensors, heater, fans, Arduino, etc etc I'm planing a mock setup. I'm currently trying to figure out where the blocker is on the main display when it can't find the printer cause that makes it hard to get back into config or use the PSU button to power it up which I'd like to do, the card is blocking, I'd like to add a different banner that isn't blocking and then pause other api calls/loops till the printer is found cause it just keeps cycling like mad. That will help me debug even locally a bit more

Should be easy to just have a isConnected boolean then stops all other calls and just returns till isConnected is true. And have isConnected loop keep trying but never redo the card so that it doesn't keep flashing and stacking just check if it's visible and don't and return, wait for the next check. Again this would work really well with an api service that has all the calls.

@UnchartedBull
Copy link
Owner

I probably wouldn't invest the time in switching everything over to a single service. The APIs are wrapped quiet cleanly, so switching them out shouldn't be a huge thing, probably just changing a few function names and file names.

The pin would also be an option yeah. I'm currently just browsing the docs and stumbled upon this: https://docs.octoprint.org/en/master/bundledplugins/discovery.html. I mean we're currently getting quite ahead of ourselfs but that would allow OctoDash to discover any OctoPrint instance on the network, which would then mean we wouldn't need the 6 digit code and can rely on the popup window in OctoPrint (if that all works out). I guess I'll send Gina an e-mail shortly to quickly check whether that popup-authentication thing also works for the push updates. Or whether we can request such a token via the API.

If that all works this would make the setup tremendously easier and open up OctoDash to more people. Really liking this!

Regarding the card stacking: The notification service does have a function you can call to suppress all notifications: https://github.com/UnchartedBull/OctoDash/blob/master/src/app/notification/notification.service.ts#L29. But the whole sleep mode thing is still kind of funky since it is fairly hard to completely shut of the API calls. That should all be easier with the push updates though.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

oh I didn't know they have a discovery service, does it use mdns? cause that would be amazing, that being said we would have to make sure to list them all and make them selectable since there might be more then one instance on a network again I know I currently run 3. But in the list we could have other to still allow manual incase. But that would be very touch screen friendly. I might make a quick demo trying it out.

For the sleep mode you just need an app wide constant. that wait the catch isn't called do the notice isn't called. Once isConnected is true then eveything works as it should.

if (app.isConnected === true)
call
else
Do what you would do if the call failed or just silently return?

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

Looks like discovery is mdns so something like

https://www.npmjs.com/package/bonjour#var-browser--bonjourfindoptions-onup

should be able to find them all into a list so we can display them!

Man I'm getting excited for this.. this will make it so easy for ppl.

@UnchartedBull
Copy link
Owner

I thought about that as well, but I didn't manage to get it working. Most of the API calls are capsulated in Observables which need to return the API result or reject (throw an error). So returning nothing isn't really an option though. Shortly after I failed at the first attempt the push updates were mentioned somewhere, so I never bothered to try again, since most of the issues would fix themself automatically.

Yeah that would be so neat. Also for switching around OctoDash between instances, I think there is an issue for that already.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 19, 2020

okay well we have lots of GREAT ideas here lets start with one, I have to run out but I think I'm going to try to tackle the mDNS thing later one and see how it work san dhow I can make it look. just get a list and make it selectable in the no-config wizard.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 20, 2020

only bonjour is a bust so far, that nom module I posted is node only I didn't notice it at first cause it's the multicast-dns module that it installs, trying to find an alternative.

@UnchartedBull
Copy link
Owner

UnchartedBull commented Aug 20, 2020

You can access CLI tools / the whole node library through the electron app. It is a little more work to get the data back and forth (ipc) but nothing to crazy. The whole update thing does it that way, so that's maybe a good starting point if you want to investigate this :)

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 20, 2020

again just my inexperience with angular, I'll have a look at that.

That being said "npm install bonjour" and doing nothing else cause all instances of setTimeout or setInterval to break. reading about it, it has something to do with nodejs types and you need to use timers, timer.setTimeout.

Again being green I wasn't sure I wanted to go down this route, it's not even bonjour that does it be bonjour depends on multicast-dns and that module is what causes it. It seems easy enough to add the timer call but I really don't know what other issues that might cause so I wasn't sure I wanted to push that envelop ;)

Since I'm pro at cli I might give it an other go ;)

@msteele999
Copy link

Just wanted a separate entry for creating an octoprint plugin for config handling on octodash to avoid using a keyboard.

More info to come on this but it could also be using to gather info that might not be in the API, like and API extension in the future.

I also vote for a plugin.

I run OctoPrint on a Windows Intel stick on Python3 - I don't really have the environment to run the install.sh and have it execute.

Mark

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 22, 2020

Do not get confused between setup and config.

This plugin will just remove some of the initial questions, like name of printer, and length from extruder, number of extruders. Or anything else that might need a keyboard during the onboarding or usage.

This will in no way replace the install.sh which is setup and makes sure the required softwares and system startup is created. If you want to try to run it off the beaten path you will need to figure out some things on your own, trying to set it up to run on windows will be on you not the plugin.

@UnchartedBull
Copy link
Owner

@TheSin- I guess using the CLI for the scan is the better path here. It is also a one-time operation for most users, so shipping another plugin for that might create unnecessary overhead.

@msteele999 You need to build the program for Windows (which is possible with electron-builder). More info on how to build everything is here: https://github.com/UnchartedBull/OctoDash/blob/master/CONTRIBUTING.md plus in the electron-builder docs.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 25, 2020

Got it working using a node module.

Screen Shot 2020-08-24 at 8 12 11 PM

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 25, 2020

I do not want to go to far in this cause this is my first time using angular with electron and nodejs. This is what I had to do to make it work, please verify (this is just to get console.log it's not doing anything yet but I can easily make a list from it)

diff --git a/package.json b/package.json
index eddf827..a8332e1 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,8 @@
     "electron-store": "^6.0.0",
     "got": "^11.5.2",
     "lodash": "^4.17.20",
+    "mdns": "^2.5.1",
+    "ngx-electron": "^2.2.0",
     "ngx-spinner": "^10.0.1",
     "progress-stream": "^2.0.0",
     "rxjs": "~6.6.2",
@@ -95,12 +97,13 @@
     "@angular/language-service": "~10.0.11",
     "@types/ajv": "^1.0.0",
     "@types/lodash": "^4.14.159",
-    "@types/node": "^14.6.0",
+    "@types/node": "~12.12.54",
     "@typescript-eslint/eslint-plugin": "^3.9.1",
     "@typescript-eslint/parser": "^3.9.1",
     "codelyzer": "^6.0.0",
     "electron": "^9.2.1",
     "electron-builder": "^22.8.0",
+    "electron-rebuild": "^2.0.0",
     "electron-reload": "^1.5.0",
     "eslint": "7.7.0",
     "eslint-plugin-import": "^2.22.0",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index cd8c126..32ec391 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -8,6 +8,7 @@ import { FaIconLibrary, FontAwesomeModule } from "@fortawesome/angular-fontaweso
 import { fas } from "@fortawesome/free-solid-svg-icons";
 import { RoundProgressModule } from "angular-svg-round-progressbar";
 import { NgxSpinnerModule } from "ngx-spinner";
+import { NgxElectronModule } from 'ngx-electron';
 
 import { AppComponent } from "./app.component";
 import { AppRoutingModule } from "./app.routing.module";
@@ -65,6 +66,7 @@ import { URLSafePipe } from "./url.pipe";
     FormsModule,
     FontAwesomeModule,
     NgxSpinnerModule,
+    NgxElectronModule,
     BrowserAnimationsModule,
     MatRippleModule,
   ],
diff --git a/src/app/config/no-config/no-config.component.ts b/src/app/config/no-config/no-config.component.ts
index 840b5ec..17c00d7 100644
--- a/src/app/config/no-config/no-config.component.ts
+++ b/src/app/config/no-config/no-config.component.ts
@@ -2,6 +2,8 @@ import { HttpClient, HttpErrorResponse, HttpHeaders } from "@angular/common/http
 import { Component, OnInit } from "@angular/core";
 import { Router } from "@angular/router";
 
+import { ElectronService } from 'ngx-electron';
+
 import { Config, ConfigService } from "../config.service";
 
 @Component({
@@ -22,7 +24,7 @@ export class NoConfigComponent implements OnInit {
   public octoprintConnection: boolean;
   public octoprintConnectionError: string;
 
-  public constructor(private configService: ConfigService, private http: HttpClient, private router: Router) {
+  public constructor(private configService: ConfigService, private http: HttpClient, private router: Router, private _electronService: ElectronService) {
     this.configUpdate = this.configService.isUpdate();
     console.log(this.configUpdate);
     if (this.configUpdate) {
@@ -137,6 +139,22 @@ export class NoConfigComponent implements OnInit {
 
   public ngOnInit(): void {
     this.changeProgress();
+
+    const mdns = this._electronService.remote.require('mdns');
+    const browser = mdns.createBrowser(mdns.tcp('octoprint'));
+    browser.on('serviceUp', service => {
+      var host = service.host.replace(/\.$/, '');
+      var port = service.port
+      var path = service.txtRecord.path.replace(/\/$/, '');
+      var name = service.name.match(/"([^"]+)"/)[1];
+      var version = service.txtRecord.version
+      console.log("service up: ", name + " (" + version +") @", host + ":" + port + path + "/api");
+      console.log("service up: ", service);
+    });
+    browser.on('serviceDown', service => {
+      console.log("service down: ", service);
+    });
+    browser.start();
   }
 
   public testOctoprintAPI(): boolean {
diff --git a/src/app/filament/filament.component.ts b/src/app/filament/filament.component.ts
index 4f336d0..f5915c4 100644
--- a/src/app/filament/filament.component.ts
+++ b/src/app/filament/filament.component.ts
@@ -16,8 +16,8 @@ export class FilamentComponent implements OnInit {
   private totalPages = 5;
 
   public page: number;
-  private timeout: number;
-  private timeout2: number;
+  private timeout: NodeJS.Timer;
+  private timeout2: NodeJS.Timer;
 
   public filamentSpools: FilamentSpoolList;
   public isLoadingSpools = true;
diff --git a/src/app/files.service.ts b/src/app/files.service.ts
index a032dca..cc66905 100644
--- a/src/app/files.service.ts
+++ b/src/app/files.service.ts
@@ -13,7 +13,7 @@ import { OctoprintFilesAPI, OctoprintFolderAPI, OctoprintFolderContentAPI } from
 })
 export class FilesService {
   private httpGETRequest: Subscription;
-  private httpGETRequestTimeout: number;
+  private httpGETRequestTimeout: NodeJS.Timer;
   private httpPOSTRequest: Subscription;
   private httpDELETERequest: Subscription;
 
diff --git a/src/app/standby/standby.component.ts b/src/app/standby/standby.component.ts
index cc16329..6b03daf 100644
--- a/src/app/standby/standby.component.ts
+++ b/src/app/standby/standby.component.ts
@@ -17,7 +17,7 @@ export class StandbyComponent implements OnInit {
   public connecting = false;
   public error = "";
   private connectionRetries = 3;
-  private displaySleepTimeout: number;
+  private displaySleepTimeout: NodeJS.Timer;
 
   public constructor(
     private configService: ConfigService,
diff --git a/src/app/update/update.component.ts b/src/app/update/update.component.ts
index 50bf316..7a7e090 100644
--- a/src/app/update/update.component.ts
+++ b/src/app/update/update.component.ts
@@ -14,7 +14,7 @@ export class UpdateComponent implements OnInit {
 
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   private ipc: any;
-  private installationAnimationInterval: number;
+  private installationAnimationInterval: NodeJS.Timer;
   public updateProgress: UpdateDownloadProgress = {
     percentage: 0,
     transferred: 0,

run

npm install
./node_modules/.bin/electron-rebuild
npm start

you need to rebuild electron cause the version of nodejs needs to match, this is what took me the longest to learn and figure out. That and the timer issue that NodeJS adds, though the solution is very simple for that one.

Obviously the browser.on blocks would call a list generator that would redraw the selection on the script if a service was found or removed. Since I can get version we can also make sure the OctoPrint has a minimum version if we wanted to.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 26, 2020

Screen Shot 2020-08-25 at 8 53 28 PM

local is fake hence the version, it's also disabled but it needs some styling cause it's not obvious. But it's working.

@UnchartedBull
Copy link
Owner

Damn, that is super nice! Even with version information, great work 👍 . Feel free to open a PR for that :)

If you don't want to take over the styling I can do that, or you do it, just whats fitting you :)

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 26, 2020

Just a few more tweaks and I'll submit one, I want to reorganize the onboarding now that we have touch for the selection of the API, I can re populate the printer name and such. I also still need a plan for manual entry just incase (backup for mdns failure). But it's coming along, so far.

@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 28, 2020

Very happy with the changes I made, I'm just working on pre populating the printer info via API then I'll make a PR for this. I want to do it in stages so I'm not removing anything from the onboarding just pre populating the values and asking for the API first so I can do that. I'm hoping to finish that tonight or this weekend depending on time.

TheSin- added a commit to TheSin-/OctoDash that referenced this issue Aug 29, 2020
- Add electron-rebuild to dev depends so that electron can be rebuilt with the installed node
- Fix setTimeout and setInstance to with with Node modules (required for mdns)
- Reduce the version on node as electron needs to be on the same version for this to work
- Change order in on boarding wizard to select API first
- Use mdns to detect and list octoprint instances (WIP need to figure out min version required)
- Auto set Printer name if a detected install if found.

I'm trying to reduce input and the need for a keyboard during onboarding.  Obviously this is just the first step as the API key still needs to be inputed.  But it's still a start.

Follow Issue UnchartedBull#921 for more info on the changes.
@TheSin-
Copy link
Contributor Author

TheSin- commented Aug 29, 2020

Shoot I waited to long and have conflicts now. I'm going to try to fix them today to get the first PR in.

UnchartedBull added a commit that referenced this issue Sep 16, 2020
* - Add mdns and ngx-electron plugin
- Add electron-rebuild to dev depends so that electron can be rebuilt with the installed node
- Fix setTimeout and setInstance to with with Node modules (required for mdns)
- Reduce the version on node as electron needs to be on the same version for this to work
- Change order in on boarding wizard to select API first
- Use mdns to detect and list octoprint instances (WIP need to figure out min version required)
- Auto set Printer name if a detected install if found.

I'm trying to reduce input and the need for a keyboard during onboarding.  Obviously this is just the first step as the API key still needs to be inputed.  But it's still a start.

Follow Issue #921 for more info on the changes.

* Add postinstall so it auto rebuilds electron against node

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Return Boolean

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Resolve a few issues with VSCode and more consistent var naming

* Add version compare to disable older Nodes

* Switch back to 5000 as the default and add a note about port 80

* test

* Revert "test"

This reverts commit 8564d39.

* Attempt to fix CI

* restructure main.js

* With the new changes newer node is working again

* Use proper indentation

* Forgot to update package-lock with node update

* electron stuff finished

* Fix lint errors and warnings

* finalise workflow

* small bugfix

* prevent the same instance showing multiple times

* remove node from angular app

* Manually trigger change detection

* Also trigger change detection for Page changes to fix bug

* intial setup to load op script

* Fix ngZone issue

* Remove ngx-electron from package-lock

* Remove electron-rebuild, postinstall script and test if the travis changes are still needed since we are no longer rebuilding

* Tested and no longer required, was a rebuild only issue

* fix OctoPrint var

* finally get that freakin jQuery working

not pretty, but it works

* cleanup + reset URL if manual input is opened.

* Check OctoPrint connection and load client library

* Update package-lock, fix a few navigation bugs

* Make sure pages can't go below 0 or above totalPages

* refactor navigation controller + show next button after page 1 again

* login with request working

* use printer name from printerprofile

* fix setup (all working)

* Convert to range slider to numeric input is not required

* I think 150 would be fast enough to load

* value selector for numbers

* fix layout issue

* Fix alignemnt on large and small views

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>
@UnchartedBull
Copy link
Owner

https://github.com/jneilliii/OctoPrint-OctoDashCompanion closing due to the awesome plugin by @jneilliii :)

kantlivelong pushed a commit to kantlivelong/OctoDash that referenced this issue May 5, 2021
* - Add mdns and ngx-electron plugin
- Add electron-rebuild to dev depends so that electron can be rebuilt with the installed node
- Fix setTimeout and setInstance to with with Node modules (required for mdns)
- Reduce the version on node as electron needs to be on the same version for this to work
- Change order in on boarding wizard to select API first
- Use mdns to detect and list octoprint instances (WIP need to figure out min version required)
- Auto set Printer name if a detected install if found.

I'm trying to reduce input and the need for a keyboard during onboarding.  Obviously this is just the first step as the API key still needs to be inputed.  But it's still a start.

Follow Issue UnchartedBull#921 for more info on the changes.

* Add postinstall so it auto rebuilds electron against node

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Return Boolean

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Resolve a few issues with VSCode and more consistent var naming

* Add version compare to disable older Nodes

* Switch back to 5000 as the default and add a note about port 80

* test

* Revert "test"

This reverts commit 8564d39.

* Attempt to fix CI

* restructure main.js

* With the new changes newer node is working again

* Use proper indentation

* Forgot to update package-lock with node update

* electron stuff finished

* Fix lint errors and warnings

* finalise workflow

* small bugfix

* prevent the same instance showing multiple times

* remove node from angular app

* Manually trigger change detection

* Also trigger change detection for Page changes to fix bug

* intial setup to load op script

* Fix ngZone issue

* Remove ngx-electron from package-lock

* Remove electron-rebuild, postinstall script and test if the travis changes are still needed since we are no longer rebuilding

* Tested and no longer required, was a rebuild only issue

* fix OctoPrint var

* finally get that freakin jQuery working

not pretty, but it works

* cleanup + reset URL if manual input is opened.

* Check OctoPrint connection and load client library

* Update package-lock, fix a few navigation bugs

* Make sure pages can't go below 0 or above totalPages

* refactor navigation controller + show next button after page 1 again

* login with request working

* use printer name from printerprofile

* fix setup (all working)

* Convert to range slider to numeric input is not required

* I think 150 would be fast enough to load

* value selector for numbers

* fix layout issue

* Fix alignemnt on large and small views

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants