OSMC Systemd Service startup WITHOUT network connection

Hello,

this is my first post here and I’m about to get crazy. I developed a Car-PC system with an Arduino to get CAN-Bus messages (e.g. Steering Wheel Controls). Now, when OSMC has booted, it should start my script, which gets connected to Kodi to interpret the arduino CAN-Bus messages.
It works fine, as long as OSMC boots with network connection (tested it with an mobile hotspot). But If there is no network connection, it wont start my script.
My Service: /lib/systemd/system/control.service

[Unit]
Description = Catch controls
After = remote-fs.target
[Service]
Type = forking
RemainAfterExit=yes
ExecStart = /path/to/script
[Install]
WantedBy = multi-user.target

Any suggestions?

Try to replace:

After = remote-fs.target

After = mediacenter.service

Do you mean it won’t start the script or the script doesn’t run/do what it’s supposed to do? I think we would need to see your script to comment properly.

The script doesn’t start, it does what it should do.

What I think is, that OSMC / Kodi waits for a network connection to sychronize the time(?)
And when this fails, then it doesn’t trigger the service /script.

Could that be? Is there a possibility to disable time synchronization on boot ?

Thank you, I’ll try it tomorrow when I continue working on my car after work. :+1:

First off, if you need Kodi to be up and running before your script runs, I’d use these two lines instead:

[Unit]
After=default.target

[Install]
WantedBy=default.target

(graphical.target will also work). This is the equivalent of saying wait until runlevel 5 has been reached before kicking off the process.

Well, you have the line After = remote-fs.target so that makes sense if, due to a lack of network, remote-fs.target can’t start. Are you therefore sure you need this dependency?

1 Like

Thanks for your reply.

Unfortunately it doesn’t work… same behavior, but know, even if there is network connection it does not work. If I start the service by my own: ‘sudo systemctl start control.service’ everything works fine…

Is there a way to stop searching for network and timeserver? That even affects the boot time :frowning:

More information:

The service starts the following script:

> #!/bin/bash
> sleep 10
> sudo python /home/osmc/scripts/control.py &

which is:

> # -*- coding: utf-8 -*-
> import serial
> import time
> from kodipydent import Kodi
> import os
> kodi = Kodi('localhost', username='********', password='*******')
> connecting = True
> print "start!"

> def connectCAN():
>         global s
>         global connecting
>         while connecting:
>                 try:
>                         s = serial.Serial('/dev/ttyUSB0', 9600) # Namen ggf. anpassen
>                         time.sleep(6) # der Arduino resettet nach einer Seriellen Verbindung, daher muss kurz gewartet werden
>                         connecting = False
>                 except:
>                         print "Serial Connection failed!"
>                 time.sleep(5)

> connectCAN()
> print "connected!"


> while 1:
>         try:
>                 input = s.readline()
>                 if "up" in input:
>                         if "iup" not in input:
>                                 print "next!"
>                                 os.system("kodi-send --action='PlayerControl(Next)'")
>                                 time.sleep(0.2)
>                 if "down" in input:
>                         if "idown" not in input:
>                                 print "prev!"
>                                 os.system("kodi-send --action='PlayerControl(Previous)'")
>                                 time.sleep(0.2)
>                 if "iback" in input:
>                         print "left, back!"
>                         kodi.Input.Back()
>                         time.sleep(0.3)
>                 if "imenu" in input:
>                         print "menu!"
>                         kodi.GUI.ActivateWindow(window="home")
>                         time.sleep(0.4)
> # [...]
>             s.flushInput()
>         except KeyboardInterrupt:
>                 exit(0)
>         except:
>                 s.close()
>                 connectCAN()

Please specify what doesn’t work. For example, did you remove the line

After = remote-fs.target

from the control.service file? You haven’t explained why it’s there.

So please show us your latest control.service file and also show the output from sytemctl status control.service.

1 Like

I’ve tested a lot of parameters and the last I tried was

After = remote-fs.target

Service now looks like this:

[Unit]
Description = Catch controls
After=graphical.target
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/home/osmc/scripts/control.sh
[Install]
WantedBy=multi-user.target

Status says:

osmc@BMW:~$ sudo systemctl status control.service

  • control.service - Catch controls
    Loaded: loaded (/lib/systemd/system/control.service; enabled)
    Active: inactive (dead)

When I start it manually:

osmc@BMW:~$ sudo systemctl status control.service -l

  • control.service - Catch controls
    Loaded: loaded (/lib/systemd/system/control.service; enabled)
    Active: active (running) since Mon 2017-07-24 22:54:29 CEST; 17s ago
    Process: 919 ExecStart=/home/osmc/scripts/control.sh (code=exited, status=0/SUCCESS)
    Main PID: 924 (sudo)
    CGroup: /system.slice/control.service
    |-924 sudo python /home/osmc/scripts/control.py
    `-925 python /home/osmc/scripts/control.py

Jul 24 22:54:29 BMW-EC systemd[1]: Started Catch controls.
Jul 24 22:54:29 BMW-EC sudo[924]: root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/bin/python /home/osmc/scripts/control.py
Jul 24 22:54:29 BMW-EC sudo[924]: pam_unix(sudo:session): session opened for user root by (uid=0)

I’d still recommend that you change the last line to:

WantedBy=graphical.target

Add the following line immediately after the #!/bin/bash line of /home/osmc/scripts/control.sh (ie make it the 2nd line):

/usr/bin/logger Starting control.sh...

then restart the machine, then run grab-logs -J and provide the URL.

BTW, the sleep 10 in the shell script it will have no effect on systemd’s operation. And the script runs as root anyway, so no need for sudo.

1 Like

Don’t be confused, control.sh; control.py and control.service is actually named controls.sh; controls.py and controls.service

was just a typo in my first post and I continued writing ‘control’ instead of ‘controls’. Just fyi

Link: https://paste.osmc.tv/uvuhujerij

EDIT:
controls.sh now looks like this (changed before reboot):

> #!/bin/bash
> /usr/bin/logger Starting control.sh...
> python /home/osmc/scripts/controls.py &

EDIT 2:

osmc@BMW-EC:~/scripts$ sudo systemctl status controls.service
* controls.service - Catch controls
   Loaded: loaded (/lib/systemd/system/controls.service; enabled)
   Active: inactive (dead)
osmc@BMW-EC:~/scripts$

after starting the service manually:

osmc@BMW-EC:~/scripts$ sudo systemctl status controls.service
* controls.service - Catch controls
   Loaded: loaded (/lib/systemd/system/controls.service; enabled)
   Active: active (running) since Mon 2017-07-24 23:47:24 CEST; 3s ago
  Process: 803 ExecStart=/home/osmc/scripts/controls.sh (code=exited, status=0/SUCCESS)
 Main PID: 806 (python)
   CGroup: /system.slice/controls.service
           `-806 python /home/osmc/scripts/controls.py
Jul 24 23:47:24 BMW-EC logger[805]: Starting control.sh...
Jul 24 23:47:24 BMW-EC systemd[1]: Started Catch controls.

controls.service:

[Unit]
Description = Catch controls
After=graphical.target
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/home/osmc/scripts/controls.sh
[Install]
WantedBy=graphical.target

The log shows it’s an ordering issue:

Jul 24 23:37:34 BMW-EC systemd[1]: Found ordering cycle on graphical.target/start
Jul 24 23:37:34 BMW-EC systemd[1]: Found dependency on multi-user.target/start
Jul 24 23:37:34 BMW-EC systemd[1]: Found dependency on controls.service/start
Jul 24 23:37:34 BMW-EC systemd[1]: Found dependency on graphical.target/start
Jul 24 23:37:34 BMW-EC systemd[1]: Breaking ordering cycle by deleting job controls.service/start
Jul 24 23:37:34 BMW-EC systemd[1]: Job controls.service/start deleted to break ordering cycle starting with graphical.target/start

causing the service to be deleted from the startup order.

Since it seems that you don’t need network connectivity, perhaps revert to @joakim_s’s suggestion [quote=“joakim_s, post:2, topic:37838, full:true”]
Try to replace:

After = remote-fs.target

After = mediacenter.service
[/quote]

together with WantedBy=multi-user.target.

1 Like

changed both to mediacenter.service. Getting this output now:

osmc@BMW-EC:~$ sudo systemctl status controls.service -l

  • controls.service - Catch controls
    Loaded: loaded (/lib/systemd/system/controls.service; enabled)
    Active: active (exited) (Result: exit-code) since Tue 2017-07-25 00:26:02 CEST; 2min 43s ago
    Process: 243 ExecStart=/home/osmc/scripts/controls.sh (code=exited, status=0/SUCCESS)
    Main PID: 267 (code=exited, status=1/FAILURE)
    CGroup: /system.slice/controls.service

Jul 25 00:26:06 BMW-EC controls.sh[243]: File “/usr/lib/python2.7/urllib2.py”, line 449, in _open
Jul 25 00:26:06 BMW-EC controls.sh[243]: ‘_open’, req)
Jul 25 00:26:06 BMW-EC controls.sh[243]: File “/usr/lib/python2.7/urllib2.py”, line 409, in _call_chain
Jul 25 00:26:06 BMW-EC controls.sh[243]: result = func(*args)
Jul 25 00:26:06 BMW-EC controls.sh[243]: File “/usr/lib/python2.7/urllib2.py”, line 1227, in http_open
Jul 25 00:26:06 BMW-EC controls.sh[243]: return self.do_open(httplib.HTTPConnection, req)
Jul 25 00:26:06 BMW-EC controls.sh[243]: File “/usr/lib/python2.7/urllib2.py”, line 1197, in do_open
Jul 25 00:26:06 BMW-EC controls.sh[243]: raise URLError(err)
Jul 25 00:26:06 BMW-EC controls.sh[243]: urllib2.URLError: <urlopen error [Errno 111] Connection refused>
Jul 25 00:26:06 BMW-EC systemd[1]: controls.service: main process exited, code=exited, status=1/FAILURE

That’s a strange decision.

The error is being thrown at line 1197 in /usr/lib/python2.7/urllib2.py. The file is readable text so you can view it yourself. At what point does the process now try to start? I also notice that you removed the sleep 10 from the shell script, so you’ve lost the delay before running the python script. It might be worth adding it again or placing a line in controls.service ExecStartPre=/bin/sleep 10 .

(Just as an aside, you can run /home/osmc/scripts/control.py just like a shell script by having #!/usr/bin/python on the first line and making the file executable.)

Some questions:

  1. What is the reason for including RemainAfterExit=yes?
  2. Why did you choose Type=forking, rather than Type=simple?
1 Like

Oh sorry, it was late and I misunderstood this.
I will correct it to:

WantedBy=multi-user.target.


I understood this as a piece of advice to remove it. I try adding the delay again.


First, I try to get it work like this so I can exclude Black Linux/Kodi/OSMC magic that makes my code fail. Then I can try to minimize it like this, thank you.


I had Problems keeping the service up while Kodi is running, I now don’t really know if it was a fault of the service or in my code because I couldn’t work on that project for a quite long time now and I forgot some things.

The service has to run all the time because it interprets the control of my steering wheel and iDrive (BMW).

Same reason here, I just tried let it run continuously next to the system.

I really searched for a documentation that explains all these parameters. All I found were just a few examples where I read “forking” and thought that would be a good idea.

Same thing with “remote-fs.target”. Just saw that in a example and tried it.

Thank you for your support, I really appreciate it.

If you mean that the process kept finishing, you can get systemd to restart it automaticaly by including the line

Restart=always

in the [Service] section of controls.service. I’d suggest you remove RemainAfterExit=yes.

1 Like

Oh, thank you that sounds good! I’ll try it.

I also need to try the delay to get this working, maybe kodi isn’t ready at that time yet.


How about this? Should I keep it forking ?

Leave it as it is for now. Better not to change too many things at once.