Run Jupyter Notebooks as a Service on macOS

I was looking for a way to run jupyer notebook without using a constantly open terminal or a screen session. On macOS there is a way to create services using a .plist file and the launchctl command.

Because I use different environments for all Python related stuff, it wasn’t immediately clear to me how to do this when I’ve installed Jupyter only in a pyenv. After some fiddling around, I finally solved it. The key was to set the working directory parameter to the directory in which the environment is loaded. In my case this is ~/notebooks where I automatically load the env by using a .python-version file.

Below you find the .plist file, that enables you to start/stop the notebook server using launchctl <start|stop> local.jupyter.notebook.

It assumes that you have a Python environenment in /Users/USERNAME/notebooks. So simply change it to your needs. Put the file into /Users/USERNAME/Library/LaunchAgents and call launchctl load PATH_TO_FILE once to load it. After this you can start/stop the service as described above.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>local.jupyter.notebook</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/USERNAME/.pyenv/shims/jupyter</string>
        <string>notebook</string>
        <string>--notebook-dir</string>
        <string>/Users/USERNAME/notebooks</string>
        <string>--no-browser</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/Users/USERNAME/Library/LaunchAgents/jupyter-notebook.stderr</string>
    <key>StandardOutPath</key>
    <string>/Users/USERNAME/Library/LaunchAgents/jupyter-notebook.stdout</string>
    <key>WorkingDirectory</key>
    <string>/Users/USERNAME/notebooks</string>
</dict>
</plist>

 

Show Download and Upload speed on your LaMetric Time

Following a request at the LaMetric forum I wrote a small Python script for displaying your current download and upload speed  on a LaMetric Time. The script can run on your own laptop or server (preferred).

Basically you need to do two things:

  • Create an app for the LaMetric Time
  • run the script that performs the speed test and push the results to the device

1. Create an indicator app

This is quite an easy thing to do. You need an account for the LaMetric developer area (it’s free, so don’t worry). In the developer area you can create a new app – in this case select indicator application.

On the new page, you can create the layout of the app. You need two text frames, one for the download speed and one for the upload speed. Also choose an icon for each frame, I decided to use a green down and green up arrow. It’s important that you select “Push” so that you can send your information to the LaMetric Time.

My design looks like this, but I later decided to drop the “Mbit/s”. It made the text too long, which is ok, the text will scroll on the display, but it means you have to wait for the scrolling to end, before the next frame is displayed. Plus I know that it’s Mbit/s. I’m also thinking about dropping the “UL” and “DL” prefix, since the arrows give me enough information.

Next you need to enter some information about the app, that is displayed in the store. You nee an App name and a short description, also make sure to check the “Private app” field.

Click “Save” and the app is ready to be published. On the next page you will see the URLs and the access token that is needed to send data to the app. Copy the “Local Push URL” and “Access token”. You could also use the “Push URL” instead of the local one, but I prefer it that way. I find it unnecessary  to send the data from my server at home to the LaMetric servers from where it comes back to my LaMetric Time which stands 5m away from my server.

Hit “Publish” and after a few minutes you should get a mail telling you that your app is ready.

Now you can install the app on your LaMetric Time. The following four screenshots describe how to do this:

Now your LaMetric Time is ready to receive data.

2. Run the script periodically on your server to update the values

The script can be found on GitHub: lm_connection_speed – if you don’t know how to clone a repository, you can also directly download the files: Download

I recommend Python 3, but it should work (no guarantee) with Python 2. It has three dependencies (requests, json and speedtest-cli). Please make sure install those before running the script.

Open the connection_speed.py in an text editor and look for lines 21/22 and insert the access token and push url from above. Save the file and you are good to go.

If you remember I said that I don’t want to see the “Mbit/s” – if you want to see it, you need to change two more lines in the file:

dl_rate = "DL {:.2f}".format(DL / 1000 / 1000)
dl_icon = "i402"
ul_rate = "UL {:.2f}".format(UL / 1000 / 1000)
ul_icon = "i120"

needs to be:

dl_rate = "DL {:.2f} Mbit/s".format(DL / 1000 / 1000)
dl_icon = "i402"
ul_rate = "UL {:.2f} Mbit/s".format(UL / 1000 / 1000)
ul_icon = "i120"

Now you can run the script

python3 connection_speed.py

Have a look the remarks in the README and for running the script periodically please consult your preferred search engine.

LaMetric Firmware 1.7.5

A new firmware for the LaMetric Time is out – version 1.7.5 has some nice things to offer for those of us who would like to use the device in home automation (sadly the documentation is not yet updated). While this has been announced in the change log for 1.7.4, there have been some bugs and there are still one or two things that needs fixing, but that’s just minor stuff.

So, lets dive right in: You can control the LaMetric time nearly completely via the REST-API. You can

  • switch between apps (previous or next, just like hitting the buttons on the device)
  • switch directly to a specific app
  • control the radio (on, off, switch channel – but not add or edit channels)
  • set alarms and enable or disable them
  • start/stop/reset the stopwatch
  • start/stop/reset/set the countdown

This is all on top off the already existing features (accessing device information about WiFi, Bluetooth, volume, display etc.)

This means nearly everything that had to be done using the iOS/Android app before, can now be done using any programming language you want.

I explained in my previous articles how to sent notifications – and it’s basically the same with the new controls. I’ve used PHP in the articles, because it’s what most people in the forum requested, but personally I use Python.

Until now I had written some scripts, without a specific library,  just a bunch of requests in a file which did the things I wanted. But when I discovered the new features I chose to clean my code and maybe make a Python package out of it –  at least a simple class for interacting with the device.

As any programmer should do, I did a search on GitHub to see if there are already some libraries. And of course I found one – lmnotify was relatively up to date and so I forked it and added some new code. Today I sent my pull request and it was already merged. This package is also available via PIP and it  supports all the features that I mentioned above.

Feel free to use this package, sent bugs, feature requests, pull requests.

 

Next I’ll be working on adding support for the LaMetric Time to Home Assistant – a platform for home automation that I’ve been using for a while and I think I already saw something LaMetric related, but without the features from the new firmware it’s useless for me.