Linux Companion App (LNXlink)

LNXlink

Custom Size – 1
This is a new tool that I created for controlling and monitoring a Linux OS. I’ve been using IOT Link on Windows and I wanted to have one for Linux, but I couldn’t find any alternatives. I’ve tested it on Ubuntu 20.04, but most likely it will work on most distributions.
Check my repo on github.

I’ve added most features of IOT Link, with an addition of a new feature for controlling and monitoring the media. I used this tool to create a media player on home assistant.

If you have any feature requests or want to report a bug, create it here.

Hope you like it!

10 Likes

Awesome! Will try it out. I was using something I wrote as well. Just mqtt with a status and cmnd topic.

I use it to suspend my PC all the time. So it’s listening to dbus events, once it going to shutdown and sleep. It lets the broker know.

1 Like

I didn’t think of checking the dbus events for shutdown and sleep.

The way I programmed mine is to consider the PC on when the app is running and sends off just before it’s stopped.
When the PC shuts down, it stops all running services gracefully, so my app will send the off command, though I haven’t tried it for sleep because I don’t use it.

I will give a try on your app, thanks for sharing!

Hi. I installed the app and it sends messages to my mqtt broker. However Home Assistant does not autodiscover it. Autodiscover is turned on and works perfect for IOT Link on my Windows pc. Any ideas?

I haven’t implemented Autodiscover yet on LNXLink.
You will have to add it manually through configuration.yaml.
I am planning to add this feature in the future.

Oohh. I see. I will do a manual configuration i HA then. Any ETA on autodiscovery?

I’ll try to add autodiscovery features it in the next weeks. I’ll let you know when I do.

1 Like

I’ve updated LNX Link to support MQTT AutoDiscovery.
Follow the installation instructions on github to update to the newest version.

2 Likes

This is awesome and I like idea very much, but how can I get currently played media info from any player?
As for now, I installed LNXLink on Archlinux machine and Ubuntu machine.

Archlinux: This is my main home server (media server, home assistant, cloud, mqtt, etc.) and this is also machine connected to main TV, where from we are watching movies from Stremio and VLC. This Achlinux machine is running with KDE.

  1. Only if I play some local media file in native KDE media player, i.e. Dragon Player, I have title, artist, status, playing info in LNXLink.

  1. If I play any media in any other player, I have no info in LNXLink (except for volume):

image

My main goal is to use LNXLink on this Archlinux machine for Stremio and VLC.
I know it is possible to obtain info from mentioned players (of course), cause KDE Connect app is displaying currently played media info, no matter what player is running.

Ubuntu: I installed LNXLink on some spare Ubuntu laptop just to check, cause I know that Archlinux knows to be troublesome for lot of things, but unfortunately, I don’t getting media info in LNXLink no matter what player is running. I tried everything I currently have installed on Ubuntu - Stremio, VLC, MPV and native Videos app.

image

Any help appreciated :slight_smile:

1 Like

Thanks for getting in touch with me for this issue and for providing so much information.
I have some tips that might help you:

  1. My app supports multiple players, but find the 1st one to show information. I’ve made the assumption that that’s the that is playing. Try closing all other players, like chrome, vlc, etc… and just play with one at a time.
  2. Run my app manually to check for any error logs that might occur, but don’t forget to stop the service before doing so. This can be done like so: /usr/bin/python3 /opt/lnxlink/run.py
  3. I am using Ubuntu Linux 20.04, so try running my app on that distribution to check if the problem still exists.
  4. To get the players, I am using a 3rd party library called mpris2. I have the link to the documentation. If you are not familiar with programming languages, let me know to create a simple script that we can get all the players to fix the problem.

Let me know if you could fix the problem or need more assistance.

@bkbilly : Thanks for reply!
I will be on some trip next few days starting from today, so will not be able to experimenting, but I will so as soon as I’m back home and will follow up.

Some comments for now:

  1. Will try, but on Ubuntu, this was already tried after fresh installation of LNXLink and right after fresh system boot up, but will see what logs have to tell (running app manually).
  2. Of course, this is always best idea. Running manually helped me to make it working as it is working now on Archlinux, cause Arch is totally different and didn’t worked at all out of box :slight_smile:
  3. I am also with 20.04 on mentioned Ubuntu laptop.
  4. I am usually able to make slight changes in code and fit it to my needs, but will ask for help if needed, thanks.

Hi. Unfortunately, I have no enough knowledge to fight with this :frowning:

Absolutely everything is apply the same for my Ubuntu and Archlinux. The only difference is that on Archlinux I have native KDE video player, called Dragon Player which is detected by LNXLink, but I’m not using it at all because it’s sucks :slight_smile:

Let’s first say: My deepest apologize for wrong data provided: my laptop isn’t on Ubuntu 20.04, but on 21.10 instead, sorry.

Second: In mean time, I noticed that media from web browser is detected successfully on both machines - Ubuntu 21.10 and Archlinux. E.g. no matter if I’m playing youtube or some other web video or music (soundcloud, etc.), media info is displayed on HA lovelace and this part with web borwsers is fully functional. Tested with Firefox, Chrome, Chromium, Konqueror and Tor (Ok, Tor is not giving media info, but LNXLink is giving info “Tor browser is playing media”)
(archmedia is Archlinux and DESKTOP-PC is Ubuntu):

I noticed that service starting very often has an errors. This is totally random and I’m restarting service until I get the start without errors. E.g. when I run systemctl --user start lnxlink , right after that I’m always running systemctl --user status lnxlink to check are there any errors. If there are errors, I’m doing systemctl --user restart lnxlink until I get clear status without errors (5-6 times sometimes).
Screenshot for better overview:

Error log for copy/paste:

Jan 11 16:33:34 archmedia python3[92666]: rc = self._packet_handle()
Jan 11 16:33:34 archmedia python3[92666]: File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 3039, in _packet_handle
Jan 11 16:33:34 archmedia python3[92666]: return self._handle_connack()
Jan 11 16:33:34 archmedia python3[92666]: File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 3138, in _handle_connack
Jan 11 16:33:34 archmedia python3[92666]: on_connect(
Jan 11 16:33:34 archmedia python3[92666]: File “/opt/lnxlink/run.py”, line 85, in on_connect
Jan 11 16:33:34 archmedia python3[92666]: self.setup_discovery()
Jan 11 16:33:34 archmedia python3[92666]: File “/opt/lnxlink/run.py”, line 135, in setup_discovery
Jan 11 16:33:34 archmedia python3[92666]: addon = self.Addons[service]
Jan 11 16:33:34 archmedia python3[92666]: KeyError: ‘network’

I also tried to add Environment=DISPLAY=:0 to lnxlink.service file, cause it was complain that cannot find display specified, result is the same with or without - no media info from VLC and Stremio.

If I stop service and run program manually with cd /opt/lnxlink && /usr/bin/pyhton3 /opt/lnxlink/run.py , sometimes I got following on Archlinux:

[stiw47@archmedia bin]$ cd /opt/lnxlink/
[stiw47@archmedia lnxlink]$ /usr/bin/python3 /opt/lnxlink/run.py
Connected with result code 0
cpu sensor
memory sensor
Exception in thread Thread-1 (_thread_main):
Traceback (most recent call last):
File “/usr/lib/python3.10/threading.py”, line 1009, in _bootstrap_inner
self.run()
File “/usr/lib/python3.10/threading.py”, line 946, in run
self._target(*self._args, **self._kwargs)
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 3591, in _thread_main
self.loop_forever(retry_first_connection=True)
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 1756, in loop_forever
rc = self._loop(timeout)
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 1164, in _loop
rc = self.loop_read()
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 1556, in loop_read
rc = self._packet_read()
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 2439, in _packet_read
rc = self._packet_handle()
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 3039, in _packet_handle
return self._handle_connack()
File “/usr/lib/python3.10/site-packages/paho/mqtt/client.py”, line 3138, in _handle_connack
on_connect(
File “/opt/lnxlink/run.py”, line 85, in on_connect
self.setup_discovery()
File “/opt/lnxlink/run.py”, line 135, in setup_discovery
addon = self.Addons[service]
KeyError: ‘network’

And some other time, everything is ok:

[stiw47@archmedia ~]$ cd /opt/lnxlink/
[stiw47@archmedia lnxlink]$ /usr/bin/python3 /opt/lnxlink/run.py
Connected with result code 0
cpu sensor
memory sensor
network sensor
media sensor

Same apply if I’m running /usr/bin/python3 /opt/lnxlink/run.py or DISPLAY=:0 /usr/bin/python3 /opt/lnxlink/run.py

Unfortunately, I don’t know to debug it further. I checked MPRIS2 page, but only thing my knowledge letting me do is to check running players from python console. It’s detecting VLC, but I have no VLC media info in HA.

image

Regarding Stremio, it is not related with your app. It seems that Stremio cannot be detected via mpris2:

image

I believe this post is confusing, sorry for that.

Addition, just discovered, what a heck: If I’m playing corrupted media file in VLC, the one which will never start and VLC player would become stuck with orange line sliding left-right in VLC progress bar, then info is there in lovelace, LOL.

image

These are some left overs after my last HDD crashing, it seems I still didn’t cleaned up all garbage. Sorry, with any other media file, correct and working media file, there is no info from VLC :frowning:

Really strange, just keep an eye on archmedia lovelace card :slight_smile:
Big Hero 6 is corrupted media file, and TMNT is valid media file.

I also can see that if I load .mp3 files to VLC, I’m getting proper media info in home assistant. Was I maybe on wrong track from beginning and is this way possible to get an info only from audio media files and not from video :slight_smile: ?

One more edit: Anyway, getting info in home assistant when playing .mp3 file, but there is also no info when playing .m4a audio file in VLC :frowning: Firstly I meant it could be some problem with metadata inside media file container, but don’t think so cause “playing” is also not changing from false to true with .m4a and video files (.mkv, .mp4) and it’s changing with .mp3

I am not sure what is the problem with the KeyError ‘network’ that you get, but I will keep that in mind.
Could you check that the file /opt/lnxlink/modules/network.py and that the network option on config.yaml exists like the template?

As for your original question you should try running this small app and send me the output.
It will check all running players and try to get their status and the metadata.
The player that the LNX-Link app is using is the 1st one. If it’s any other, then you can help me look for a way to find which status should I check to get the results.

@bkbilly
Ok, so, I found where is the problem.

All my previous posts in this thread should be ignored. I’d rather strike-through all of them, but it’s probably stupid.

It seems this thing is heavy relying on metadata from media file. If there is no metadata on main media container, then will not be media info from player. Even “playing” will be “false” and “status” will be “idle”.

image

As said post before, I noticed that some of my .mp3 files are giving media info in Home Assistant, so I analyzed them with FFMpeg. It gives me below output:

Opposite to my video files, which weren’t giving info in Home Assistant:

After I added metadata on main container with:

ffmpeg -i Brave.2012.1080p.BRrip.x264.stiw47.Dual.mkv -c copy -metadata title="Brave" -metadata language="Serbian // English" -metadata artist="Pixar" -metadata album="Brave" Brave.New.Metadata.mp4

I got following:

And media info in Home Assistant finally appeared:

image

And FYI, just one metadata parameter, e.g. title, would be enough for get info. I will see is there any GUI software which can quickly set metadata on bulk of files according file name or something similar, or will give up of this, cause I have around 1k media files :slight_smile:
Also will check could maybe some VLC settings be tweaked, cause as said before, Dragon Player is giving proper info in Home Assistant with same media files, ones without metadata.

Thank you for your answer.

I have file: /opt/lnxlink/modules/network.py , below is file content:

[stiw47@archmedia ~]$ cat /opt/lnxlink/modules/network.py
import psutil
from datetime import datetime

class Addon():
    service = 'network'
    name = 'Network'
    icon = 'mdi:access-point-network'
    unit = 'Mbit/s'

    def __init__(self):
        self.timeOld = datetime.now()
        self.sentOld = psutil.net_io_counters().bytes_sent
        self.recvOld = psutil.net_io_counters().bytes_recv

    def getInfo(self):
        """ Returns Mbps"""
        timeNew = datetime.now()
        sentNew = psutil.net_io_counters().bytes_sent
        recvNew = psutil.net_io_counters().bytes_recv


        timeDiff = (timeNew - self.timeOld).total_seconds()
        sentDiff = sentNew - self.sentOld
        recvDiff = recvNew - self.recvOld

        self.timeOld = timeNew
        self.sentOld = sentNew
        self.recvOld = recvNew

        sentsSpeed = round(sentDiff * 8 / timeDiff / 1024 / 1024, 2)
        recvSpeed = round(recvDiff * 8 / timeDiff / 1024 / 1024, 2)

        return {'download': recvSpeed, 'upload': sentsSpeed}
[stiw47@archmedia ~]$

I’m not sure how to work with templates yet (and what is the template in this case :slight_smile: ), but below is content of config.yaml

[stiw47@archmedia ~]$ cat /opt/lnxlink/config.yaml
mqtt:
  prefix: iotlink/archmedia
  clientId: archmedia
  statsPrefix: archmedia-monitor/stats
  server: 192.168.0.21
  port: 1883
  auth:
    user:
    pass:
  discovery:
    enabled: true
  lwt:
    enabled: true
    qos: 1
    retain: true
    connectMsg: 'ON'
    disconnectMsg: 'OFF'
control:
- shutdown
- send-keys
- run
- notify
- media
monitoring:
- cpu
- memory
- network
- media
[stiw47@archmedia ~]$

I tried this small app, below is output. Currently, only VLC is playing, my kids are watching cartoon, one without metadata :slight_smile:

[stiw47@archmedia ~]$ python /opt/lnxlink/media_check.py
1) st=Playing, title=None, artist=None, album=None
[stiw47@archmedia ~]$

I can see that media_check.py is giving proper info, cause status is really playing and this file have no metadata, but “status” in Home Assistant card is “idle” and “playing” is “false” as said before :frowning:

Certain case for VLC, maybe this could be hint:

If I’m playing .mkv file with barely metadata within, title=“tmnt test”, output from media_check.py would be:

[stiw47@archmedia ~]$ python /opt/lnxlink/media_check.py
1) st=Playing, title=tmnt test, artist=None, album=None
[stiw47@archmedia ~]$

It will be shown in HA, all together with “status”: “playing” and “playing”: “true”:

image

And I would be able to see same that “tmnt test” in VLC player as title:

From other side, if I’m playing same that video file, but this time without metadata at all, media_check.py would be:

[stiw47@archmedia ~]$ python /opt/lnxlink/media_check.py
1) st=Playing, title=None, artist=None, album=None
[stiw47@archmedia ~]$

It will not be shown in HA, “status” and “playing” will be wrong:

image

But, in VLC player, file name will be shown as title, in lack of real metadata title:

Maybe you could use this somehow.

Please don’t take me wrong, my intention is not to pushing. I just noticed this and would like to let you know. Everything here is based on free will and only if you have a time and if you want to take a look.

I am really happy that you took an interest to find the bugs on my app, so I don’t feel pushed.

The problem with getting the current media that it’s playing is that I am heavily relying on the mpris2 library so that I can have it as global as possible. I’ve noticed some problems if there are more than one players at the same time. This needs some fine tuning, but I don’t think that this is what is wrong in your case. I will push an update once I get the chance.

I am not sure how to use the vlc player metadata as an alternative, so I am not sure that I could help you with that…

I will push an update in the next days for the bug with the multiple players which might help you.

Hi just learned about this app, looks great, thanks for putting it together, will be so much better than using SSH. I installed it onto a proxmox host hoping to get some details into HA. The problem is that after entering in all the details im not seeing any attempts to connect on the MQTT broker. Is there any troubleshooting steps you could recommend or any logs i can see from the app?
EDIT:
looking at previous issues i found the below command and the output from it (if you would prefer issues in the github please me know)

root@proxmox:~# systemctl --user status lnxlink
● lnxlink.service - LNXLink
     Loaded: loaded (/root/.config/systemd/user/lnxlink.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-01-31 15:29:55 AEDT; 13s ago
   Main PID: 96503 (python3)
      Tasks: 1 (limit: 38084)
     Memory: 16.9M
        CPU: 109ms
     CGroup: /user.slice/user-0.slice/[email protected]/app.slice/lnxlink.service
             └─96503 /usr/bin/python3 /opt/lnxlink/run.py

Jan 31 15:30:07 proxmox python3[96503]:     return _bootstrap._gcd_import(name[level:], package, level)
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap>", line 986, in _find_and_load>
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap_external>", line 790, in exec_>
Jan 31 15:30:07 proxmox python3[96503]:   File "<frozen importlib._bootstrap>", line 228, in _call_with_fra>
Jan 31 15:30:07 proxmox python3[96503]:   File "/opt/lnxlink/modules/media.py", line 1, in <module>
Jan 31 15:30:07 proxmox python3[96503]:     from dbus.mainloop.glib import DBusGMainLoop
Jan 31 15:30:07 proxmox python3[96503]: ModuleNotFoundError: No module named 'dbus'
...skipping...

also dbus is installed
root@proxmox:~# sudo apt-get install dbus
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
dbus is already the newest version (1.12.20-2).

root@proxmox:~# pip3 install pydbus
Requirement already satisfied: pydbus in /usr/local/lib/python3.9/dist-packages (0.6.0)

tried installing sudo apt install python3-dbus

but then i get this error

● lnxlink.service - LNXLink
     Loaded: loaded (/root/.config/systemd/user/lnxlink.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-01-31 20:32:09 AEDT; 50s ago
   Main PID: 149058 (python3)
      Tasks: 1 (limit: 38084)
     Memory: 20.1M
        CPU: 136ms
     CGroup: /user.slice/user-0.slice/[email protected]/app.slice/lnxlink.service
             └─149058 /usr/bin/python3 /opt/lnxlink/run.py

Jan 31 20:33:00 proxmox python3[149058]:     from pynput import keyboard
Jan 31 20:33:00 proxmox python3[149058]:   File "/usr/local/lib/python3.9/dist-packages/pynput/__init__.py", line 40, in <module>
Jan 31 20:33:00 proxmox python3[149058]:     from . import keyboard
Jan 31 20:33:00 proxmox python3[149058]:   File "/usr/local/lib/python3.9/dist-packages/pynput/keyboard/__init__.py", line 31, in <module>
Jan 31 20:33:00 proxmox python3[149058]:     backend = backend(__name__)
Jan 31 20:33:00 proxmox python3[149058]:   File "/usr/local/lib/python3.9/dist-packages/pynput/_util/__init__.py", line 76, in backend
Jan 31 20:33:00 proxmox python3[149058]:     raise ImportError('this platform is not supported: {}'.format(
Jan 31 20:33:00 proxmox python3[149058]: ImportError: this platform is not supported: ('failed to acquire X connection: Bad display name ""', DisplayNameError(''))
Jan 31 20:33:00 proxmox python3[149058]: Try one of the following resolutions:
Jan 31 20:33:00 proxmox python3[149058]:  * Please make sure that you have an X server running, and that the DISPLAY environment variable is set correctly

From searching around it looks like this error is because my linux is only running in cmd line not a GUI, could this be correct?