This is an old revision of the document!
Lakka is an emulation environment designed to run console and arcade emulators in a kiosk-style setup. The underlying operating system for Lakka is a Linux distribution named LibreELEC that uses read-only access to the filesystem via squashfs. The following is a quick and possibly reliable method to add IoT capabilities via python and subscrbing to an MQTT topic.
pip
can be installed with:
wget -c https://bootstrap.pypa.io/get-pip.py
and then by executing:
python get-pip.py
which will perform a local install of pip.
Next, the default PATH
must be adjusted to take the local pyton binaries into account. This is done by editing .profile
and adding:
#!/usr/bin/sh export PATH=~/.local/bin:/usr/bin:/usr/sbin
and then saving the file.
A re-log is necessary to take the new path into account.
After logging in, install paho MQTT with:
pip install paho-mqtt
which will create a local install of paho MQTT.
The file from the code section (mqttSwitch.py
) should be placed at /storage/system/mqttSwitch/mqttSwitch.py
after which the file should be made executable, for instance, by issuing chmod +x /storage/system/mqttSwitch/mqttSwitch.py
. The file /storage/.config/autostart.sh
should either be created or edited in order to add the following line for mqttSwitch.py
:
/usr/bin/python /storage/system/mqttSwitch/mqttSwitch.py --daemon
#!/usr/bin/env python ########################################################################### ## Copyright (C) Wizardry and Steamworks 2019 - License: GNU GPLv3 ## ########################################################################### import yaml, subprocess, os, argparse, signal, sys import paho.mqtt.client as mqtt from os import path from daemonize import Daemonize with open(os.path.join(os.path.dirname(sys.argv[0]), 'config.yml'), 'r') as ymlfile: cfg = yaml.load(ymlfile, Loader=yaml.FullLoader) # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): print 'Connected with result code: ', str(rc) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. #client.subscribe("$SYS/#") client.subscribe('arcade-engine/#') # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): if str(msg.payload) == 'shutdown': os.system('systemctl poweroff') def main(): client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect(cfg['mqtt']['host'], cfg['mqtt']['port'], 60) # Blocking call that processes network traffic, dispatches callbacks and # handles reconnecting. # Other loop*() functions are available that give a threaded interface and a # manual interface. client.loop_forever() def daemon(): try: if path.exists(cfg['pid']): with open(cfg['pid'], 'r') as pid_file: pid = pid_file.read() os.kill(int(pid), signal.SIGHUP) os.remove(cfg['pid']) except Exception, e: print 'Unable to kill previous process: ', str(e) return daemon = Daemonize(app='mqttSwitch', pid=cfg['pid'], action=main) daemon.start() parser = argparse.ArgumentParser() parser.add_argument('--daemon', action='store_true', help='run as a daemon') parser.add_argument('--foreground', action='store_true', help='run as a daemon') args = parser.parse_args() if(args.daemon): daemon() elif(args.foreground): main() parser.print_help()