Plugin development Tutorial Problem

Hi everyone,
this is my first post on this forum, but I've some problems whit the begin of this tutorial. I follow step by step the guide but can't reach the same result.
I wanna develop a plugin directly on my raspberry Pi3B+, so i skip first instructions:

cd ~/devel
git clone https://github.com/foosel/OctoPrint
[...]
cd OctoPrint
virtualenv venv
[...]
source venv/bin/activate
(venv) pip install -e .[develop,plugins]
[...]
(venv) octoprint --help
Usage: octoprint [OPTIONS] COMMAND [ARGS]...
[...]

So i skip to this part:

source ~/oprint/bin/activate
(oprint) octoprint --help
Usage: octoprint [OPTIONS] COMMAND [ARGS]...
[...]

but when i try to write the first example helloworld.py and then command "octoprint serve", octoprint go to safe mode and the command return me this message, that is a little bit different from the one in the example:

2019-10-24 21:54:28,660 - octoprint.startup - INFO - ******************************************************************************
2019-10-24 21:54:28,662 - octoprint.startup - INFO - Starting OctoPrint 1.3.12
2019-10-24 21:54:28,663 - octoprint.startup - INFO - ******************************************************************************
2019-10-24 21:54:28,808 - octoprint.util.connectivity_checker - INFO - Connectivity changed from offline to online
2019-10-24 21:54:29,208 - octoprint.startup - INFO - Blacklist processing done, adding 1 blacklisted plugin versions: roomtemp (any)
2019-10-24 21:54:29,252 - octoprint.plugin.core - INFO - Loading plugins from /home/pi/oprint/lib/python2.7/site-packages/octoprint/plugins, /home/pi/.octoprint/plugins and installed plugin packages...
2019-10-24 21:54:30,995 - octoprint.plugin.core - INFO - Found 16 plugin(s) providing 15 mixin implementations, 23 hook handlers
2019-10-24 21:54:31,297 - octoprint.server.heartbeat - INFO - Starting server heartbeat, 900.0s interval
2019-10-24 21:54:31,322 - octoprint.cli.server - ERROR - Uncaught exception
Traceback (most recent call last):
File "/home/pi/oprint/bin/octoprint", line 11, in
load_entry_point('OctoPrint', 'console_scripts', 'octoprint')()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/init.py", line 609, in main
octo(args=args, prog_name="octoprint", auto_envvar_prefix="OCTOPRINT")
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/core.py", line 764, in call
return self.main(*args, **kwargs)
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/pi/oprint/local/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/cli/server.py", line 206, in serve_command
ignore_blacklist)
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/cli/server.py", line 118, in run_server
octoprint_server.run()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/init.py", line 281, in run
self._start_intermediary_server()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/init.py", line 1751, in _start_intermediary_server
self._intermediary_server.server_bind()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 108, in server_bind
SocketServer.TCPServer.server_bind(self)
File "/usr/lib/python2.7/SocketServer.py", line 431, in server_bind
self.socket.bind(self.server_address)
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 98] Address already in use

I'm running:

OctoPrint version : 1.3.12
OctoPi version : 0.16.0

Sorry for my bad english, but i've no idea how i can make it work, am I make a mistake?

Thanks Giovanni.

The error is because when you are trying to run the command octoprint serve it's already running as a daemon (service in windows terms). You would need to run the command sudo service octoprint stop prior to running the octoprint serve command.

2 Likes

ok, thanks, it worked, but how can I restart octoprint in order to view the plugin in my browser? I tried octoprint daemon start and "sudo service octoprint start"

So it depends on how you are developing and where. I always develop in a separate working folder and then zip up the files and install via the plugin manager.

I'm a beginer so i think that's better for me to develope directly on raspberry and see my result on OctoPrint. Well i'm following that guide, my question is: can i see the plugin in action without reboot my system every time or no? When I do octoprint serve I have to do sudo reboot to se the plugin or I can do it another way?

I've never tried it, but I think if your file is stored in the ~/.octoprint/plugins/ folder then running the command sudo service octoprint restart would basically restart the octoprint service and should load the plugin. Or after you've modified the file you can use the web interface (if it loads) and use the restart octoprint option.

Robo 3D tried to make everyone do that (since the Software Development Manager by his own admission has never developed software). It's not really a good idea to develop directly on the Raspberry Pi itself.

A better approach might be:

  1. Create a folder on your own workstation as well as one on the Pi
  2. Code there on your workstation using a good IDE-based editor
  3. Each development cycle, push the code sideways over to the Pi
  4. From a remote session to the Pi:
    a. stop the currently-running OctoPrint
    b. in the folder, verify that you're still activated in the virtual environment
    c. from that folder run python setup.py develop to apply your updates to OctoPrint
    d. start OctoPrint
    e. run tail -f ~/.octoprint/logs/octoprint.log to see how it's doing

Of course, I automate all this using bash scripts and aliases so it's just a few keystrokes each cycle. For me, since I've created these:

  • begin # activates the virtual environment and cd's to the folder
  • cycle # script which runs that setup.py command, restarts the OctoPrint service and tail's the log

From my workstation, I have a macro setup to run the bash script to use rsync to move everything over sideways to the Pi (but only the changes).

The benefits are that I'm using a faster machine with an excellent editor to code things. I can then use git features to do code versioning. I trust my MacBook's hard drive more than the microSD card on the Pi. I can more easily work with other coders like this. I don't have to worry so much that the microSD needs to be fsck'd. I never misplace recent code on the wrong microSD card ("where is that code!?")

Or, if you don't need to access hardware exclusive to the pi, just install OctoPrint on your development machine and develop completely locally. That's how I do it since I don't have time for lengthy deployment cycles if I'm supposed to stay on top of everything :sweat_smile:

1 Like

Thank you all, so, to recap, I'm a mac user and I'm using the Terminal for ssh connection,Cyberduck to transfer files and Brackets to edit all files. Is it good enough?
So I can edit all files on my Mac, then i transfer the plugin directory on Pi and use octoprint dev plugin:install to test the plugin.

You should be good to go with that toolset but I would suggest using scp instead of Cyberduck since it will allow you to automate things a bit more. That said, There are many ways to do this and it is really up to you how you want to tackle it.

I actually do my development and dev testing on a dedicated RPi over ssh. I have set up a reverse ssh tunnel to the dev host from my computer so I can edit remote files using a local editor (link below). I then do further testing on a second RPi and on an Ubuntu LXC container. The main reason for that is that I actually do a bunch of things related to the hardware (sensors and stuff) but I find it convenient for other reasons too.

My method using a bare-bones octopi install:

  • ssh as user pi to the host: ssh pi@octopidev
  • activate the virtual environment: source ~/oprint/bin/activate
  • change to the plugins directory: cd ~/.octoprint/plugins/
  • Either create a new plugin using the cookiecutter described in the tutorial first (octoprint dev plugin:new helloworld) or simply change into an existing plugin folder ex: cd OctoPrint-Dashboard/
  • Init git if it is a new plugin: git init
  • Modify files and/or add/remove files. For this I use rsub on the remote host together with Sublime Text on the Mac: rsub __init__.py
  • install the plugin from the root dir of the plugin (only needed once for a new plugin): octoprint dev plugin:install
  • Testing the change now simply involves restarting octoprint via the web UI or command line with: sudo service octoprint restart. For JS/template changes, it is usually enough to simply reload the web ui in a browser.
  • To commit the change (assuming that you have set up a remote repo on github), do the usual git dance: git add, git commit, git push.

To test on another instance, I can either use the plugin manager via the web ui to fetch from GitHub via a direct URL or simply do a git pull and install it command-line when necessary.

This works pretty well for me. I don't need to transfer files between hosts all the time and backups are managed via the remote repository whenever I push the dev branch. The only real downsides is that restarting OctoPrint takes slightly longer on the RPi compared to on the Mac and that it requires a second RPi.

If you need to synchronize entire folder structures over to the Pi, I would suggest the rsync command which does this quite nicely. And it knows if anything has changed so it's efficient.

Is there any way to do it automaticaly? So if i change a file on my mac it automaticaly change on the Pi?

rsync works by pushing changed files over. It doesn't recognize if you've changed the name of something. So if you needed to do this, you'd have to:

  1. delete the contents of the receiving folder
  2. rsync it over

That said, the standard way is how I develop on my MacBook and push to the Pi. Every few weeks I'll go to the receiving folder and do a git status after each git cycle. If I see anything that isn't tracked then it means that I've recently renamed something and it needs to be manually removed on the Pi. It's less work than the method above which I've described in this post.