2

I am trying to run a Python script on startup.

I followed this guide from Instructibles on setting up a cron job.

It returns the following error in the logs:

File "IoTTest.py", line 58, in <module>
client.connect("Axxxxxxxxxx.iot.eu-west-1.amazonaws.com", xxxx, xx)
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 612, in connect
return self.reconnect()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 734, in reconnect
sock = socket.create_connection((self._host, self._port), source_address=(self._bind_address, 0))
File "/usr/lib/python2.7/socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno -2] Name or service not known

Basically, I want to send a message to AWS IoT using Python:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
  if rc == 0 :
    print("CONNECTED TO AWS IoT")
    client.subscribe("$aws/things/XXXXX/shadow/update/accepted")
     ....
    return True

  else :
    client.disconnect() 
    return False

def on_message(client, userdata, msg):
  ....

client = mqtt.Client(client_id="Test")
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(ca_certs='./certs/root-CA.crt', certfile='./certs/xxxx-certificate.pem.crt', keyfile='./certs/xxxx-private.pem.key', tls_version=ssl.PROTOCOL_SSLv23)
client.tls_insecure_set(True)
client.connect("Axxxxxxxxxx.iot.eu-west-1.amazonaws.com", xxxx, xx)  ===> log showed error here !
client.loop_forever()

Note: I can run this python script successfully with direct command:

python IoTTest.py

Any suggestion is appreciated.

1

My guess is that your code is running before the network is actually ready, so when trying to resolve the URL, things go horribly wrong and your script crashes.

Cron provides no real promises about when @reboot scripts run:

Please note that startup, as far as @reboot is concerned, is the time when the cron(8) daemon startup. In particular, it may be before some system daemons, or other facilities, were startup. This is due to the boot order sequence of the machine.

If you are using a Raspbian version after or including Jessie (i.e. Jessie or Stretch as of 2017), you can take advantage of systemd, which gives you much more control.

Let's create a new service file at /etc/systemd/system/iottest.service:

[Unit]
Description=Start IoTTest
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/python /home/yourusername/IoTTest.py

[Install]
WantedBy=multi-user.target

You'll probably need to create that file with root privileges. Once done, save that, disable your cron job and run:

systemctl enable iottest.service

Then, reboot, and you're done!

However, Debian Jessie apparently has some issues with network-online.target; it may be necessary to work around this as described in the link.

  • Hi Aurora0001, your suggestion is very interesting, however it seems not working. I followed your step, ran: sudo systemctl enable iottest.service. It returns: Created symlink from /etc/systemd/system/multi-user.target.wants/iottest.service to /etc/systemd/system/iottest.service. After rebooting the RPi, it doesn't send any msg to AWS ioT – franco phong Sep 9 '17 at 14:58
  • @francophong Any interesting output from journalctl -u iottest.service that might give us a clue what's happening? – Aurora0001 Sep 9 '17 at 15:15
  • @ Aurora0001, I tried, it returns: No journal files were found. Does it mean the service didn't start or something wrong ? – franco phong Sep 9 '17 at 15:20
  • @francophong Did you run that as root (sudo journalctl -u iottest.service)? I forgot to mention that, sorry. – Aurora0001 Sep 9 '17 at 15:22
  • yes, it did return some errors: [/etc/systemd/system/iottest.service:8] Executable path is not absolute, ignoring: python /home/pi/Test/IoTTest.py iottest.service lacks both ExecStart= and ExecStop= setting. Refusing. – franco phong Sep 9 '17 at 15:28
0

I found an answer for this error: as Aurora0001 mentioned, script ran before network is ready. Although his solution is not working, but I found an workaround for it.

In launcher.sh, I added a delay about 10 secs(you need check it depend on RPi) . That's it, and it works fine.

sleep 10s
cd /
cd home/pi
sudo python IoTTest.py
cd /

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.