diff --git a/chandelier/bt_device.py b/chandelier/bt_device.py index d1bb1e4..e79a320 100644 --- a/chandelier/bt_device.py +++ b/chandelier/bt_device.py @@ -4,10 +4,23 @@ from time import sleep import sys +import re import pexpect from retry import retry from .utilities import errprint, stdprint +def reset_config(): + try: + hci_name = re.search('hc..', pexpect.spawn('hcitool dev').read().decode("utf-8")).group(0) + hci = pexpect.spawn("sudo hciconfig "+ hci_name +" reset") + if hci.expect(pexpect.EOF) == 0: + return True + else: + return False + except pexpect.ExceptionPexpect as exception: + errprint(exception) + return False + class BluetoothDevice: """ Class for generic bluetooth. Can be connected, checked if connected and is disconnecting when object remove.""" @@ -17,7 +30,7 @@ class BluetoothError(Exception): class DeviceNotFound(Exception): """Raised when given device can't be found""" - def check_if_connected(self): + def is_connected(self): try: hci = pexpect.spawn("hcitool con") if hci.expect([self.addr, pexpect.EOF]) == 0: @@ -29,33 +42,45 @@ def check_if_connected(self): return False def __end_connection__(self): - self.__interface__.sendline("\ndisconnect") - self.__interface__.expect("diconnected", timeout=5) + if not hasattr(self, '__interface__'): + self.__interface__ = self.__open_interface__() + self.__prepare_bluetooth__(self.__agent__) + print("Disconnecting!") + self.__interface__.sendline("\ndisconnect " + self.addr) + self.__interface__.expect("Successful disconnected", timeout=5) + self.__interface__.sendline("\nremove " + self.addr) + self.__interface__.expect("Device has been removed", timeout=5) + self.__interface__.close(force=True) + sleep(5) - @retry(pexpect.exceptions.TIMEOUT, tries=20) - def __check_if_device_is_visible__(self): + @retry(pexpect.exceptions.TIMEOUT, tries=3, delay=1) + def __is_device_visible__(self): try: self.__interface__.sendline("\ndevices") - self.__interface__.expect(self.addr) + self.__interface__.expect(self.addr, timeout=5) except self.DeviceNotFound as exception: raise exception - @retry(pexpect.exceptions.TIMEOUT, tries=120) + @retry(pexpect.exceptions.TIMEOUT, tries=3, delay=2) def __connect_to_device__(self): - if not self.check_if_connected: - self.__end_connection__() - sleep(3) self.__interface__.sendline("\nconnect "+self.addr) self.__interface__.expect("Connection successful", timeout=5) + sleep(2) + if not self.is_connected(): + raise pexpect.exceptions.TIMEOUT + + def __trust__(self): + self.__interface__.sendline("\ntrust " + self.addr) + self.__interface__.expect("trust succeeded", timeout=5) def __pair__(self): try: self.__interface__.sendline("\npaired-devices") try: - self.__interface__.expect(self.addr) + self.__interface__.expect(self.addr, timeout=5) except pexpect.exceptions.TIMEOUT: self.__interface__.sendline("\npair " + self.addr) - self.__interface__.expect("Pairing successful") + self.__interface__.expect("Pairing successful", timeout=5) except: raise self.BluetoothError @@ -66,6 +91,7 @@ def __open_interface__(self): # enable debuging to stdout if self.__debug_on__: bluetoothctl.logfile = sys.stdout.buffer + sleep(3) return bluetoothctl except Exception as exception: errprint(exception) @@ -77,13 +103,13 @@ def __prepare_bluetooth__(self, __agent__): self.__interface__.sendline("\nagent off") self.__interface__.sendline("\nagent " + __agent__) self.__interface__.sendline("\ndefault-agent") - self.__interface__.expect("successful") + self.__interface__.expect("successful", timeout=5) self.__interface__.sendline("\npower on") - self.__interface__.expect("succeeded") + self.__interface__.expect("succeeded", timeout=5) self.__interface__.sendline("\npairable on") - self.__interface__.expect("succeeded") + self.__interface__.expect("succeeded", timeout=5) self.__interface__.sendline("\nscan on") - self.__interface__.expect("started") + self.__interface__.expect("started", timeout=5) except Exception as exception: errprint(exception) errprint("Raspberry have problem with prepare bluetooth.") @@ -91,12 +117,16 @@ def __prepare_bluetooth__(self, __agent__): def __connect__(self): try: - self.__check_if_device_is_visible__() + self.__is_device_visible__() stdprint("Device " + self.addr + " is visible") + sleep(1) + self.__trust__() self.__pair__() + sleep(1) stdprint("Device " + self.addr + " is paired") self.__connect_to_device__() - stdprint("Connection to " + self.addr + " are estabilished") + sleep(1) + stdprint("Connection to " + self.addr + " is estabilished") except self.DeviceNotFound as exception: errprint(exception) errprint("Rasberry couldn't find device or connect.") @@ -106,28 +136,38 @@ def __connect__(self): errprint("Rasberry couldn't pair to the device.") raise exception - def __init__(self, addr, debug=False, agent="NoInputNoOutput"): + def __init__(self, addr, disconnect=True, debug=False, agent="NoInputNoOutput"): try: + self.disconnect_on_failure = disconnect self.addr = addr self.__debug_on__ = debug self.__agent__ = agent - if self.check_if_connected(): + if self.is_connected(): stdprint("Device already connected.") return None self.__interface__ = self.__open_interface__() self.__prepare_bluetooth__(self.__agent__) self.__connect__() - self.__interface__.kill(15) + self.__interface__.close(force=True) + print("Interface is killed") except Exception as exception: + global shit_happens print(exception) - self.__interface__ = self.__open_interface__() - #self.__end_connection__() + if self.disconnect_on_failure: + reset_config() + self.__interface__ = self.__open_interface__() + self.__end_connection__() + self.__interface__.close(force=True) + shit_happens = True + print("Interface is killed") raise exception #def __del__(self): - # self.__interface__ = self.__open_interface__() - # try: - # #self.__end_connection__() - # except: - # pass - # stdprint("Device " + self.addr + " is disconnected!") + # if self.__debug_on__: + # print("disconnect") + # self.__interface__ = self.__open_interface__() + # try: + # self.__end_connection__() + # except: + # pass + # stdprint("Device " + self.addr + " is disconnected!") diff --git a/chandelier/bt_devices.py b/chandelier/bt_devices.py index fe8fece..4b421cd 100644 --- a/chandelier/bt_devices.py +++ b/chandelier/bt_devices.py @@ -7,36 +7,44 @@ class BluetoothSpeaker(bt_device.BluetoothDevice): - @retry(Exception, tries=5, delay=3) + @retry(Exception, tries=3, delay=1) def __get_pulse_audio_sink__(self): with pulsectl.Pulse('list-sinks') as pulse: for sink in pulse.sink_list(): if sink.proplist.get('device.string') == self.addr: return sink.index, sink.name - def __init__(self, addr, debug=False, agent="NoInputNoOutput"): - super().__init__(addr, debug, agent) + def __init__(self, addr, disconnect=False, debug=False, agent="NoInputNoOutput"): + super().__init__(addr, disconnect=False, debug=debug, agent=agent) sleep(3) try: self.pa_index, self.paname = self.__get_pulse_audio_sink__() except TypeError: + global shit_happens + shit_happens = True utilities.errprint("Device " + self.addr + " is not recongized as bluetooth speaker.") raise self.BluetoothError class BluetoothRemote(bt_device.BluetoothDevice): + __loop = "" remote_inputs = [] output = "" - @retry(Exception, tries=5, delay=3) + + @retry(Exception, tries=3, delay=1) def __remote_devices__(self, addr): - remote_address = addr devices = [evdev.InputDevice(path) for path in evdev.list_devices()] for device in devices: - if device.phys not in remote_address: + if device.phys == '': devices.remove(device) + if len(devices) < 2: + raise Exception return devices + def stop_waiting_on_output(self): + self.__loop.stop() + def wait_and_get_output(self): @asyncio.coroutine async def print_events(device): @@ -46,27 +54,29 @@ async def print_events(device): asyncio.get_running_loop().stop() return cat_event - loop = asyncio.new_event_loop() + self.__loop = asyncio.new_event_loop() tasks = [] for device in self.remote_inputs: - tasks.append(loop.create_task(print_events(device))) + tasks.append(self.__loop.create_task(print_events(device))) - loop.run_forever() + self.__loop.run_forever() for task in tasks: - if task.done(): - return task.result() - - #devs_tasks = [] - #for device in inputs: - # task = asyncio.ensure_future(print_events(device)) - # devs_tasks.append(task) + try: + if task.done(): + return task.result() + except: + return None def __init__(self, addr, debug=False, agent="NoInputNoOutput"): try: - super().__init__(addr, debug, agent) + super().__init__(addr, disconnect=False, debug=debug, agent=agent) self.remote_inputs = self.__remote_devices__(addr) except Exception as exception: + global shit_happens + shit_happens = True + bt_device.reset_config() utilities.errprint(exception) + self.__end_connection__() raise exception diff --git a/chandelier/chandelier.py b/chandelier/chandelier.py index 9cef163..521df5f 100644 --- a/chandelier/chandelier.py +++ b/chandelier/chandelier.py @@ -1,113 +1,307 @@ -import sys from time import sleep -from chandelier import bt_devices, led, movement_sensor, pulseaudio -from .utilities import errprint +import time import threading +from sys import exit +from retry import retry +import gc +from chandelier import bt_devices, led, movement_sensor, pulseaudio +global shit_happens +shit_happens = False class Chandelier: standby_on = True + playing_voices = False + waiting = False + press_duration = "" + leds = False + + @retry(Exception, tries=3, delay=1) + def connect_to_remote(self): + self.remote = bt_devices.BluetoothRemote(self.remote_addr) + def __init__(self, sensors_pins, led_pins, speaker_addr, remote_addr): - self.blt_speaker = bt_devices.BluetoothSpeaker(speaker_addr, debug=False) - self.remote = bt_devices.BluetoothRemote(remote_addr) + self.remote_addr = remote_addr + self.connect_to_remote() + self.blt_speaker = bt_devices.BluetoothSpeaker(speaker_addr, disconnect=False) + self.pa = pulseaudio.OutputControl([0, self.blt_speaker.pa_index]) self.sensors = movement_sensor.MovementSensors(sensors_pins) self.led = led.Led(led_pins[0], led_pins[1], led_pins[2]) + global shit_happens + if shit_happens: + print("Shit happened when trying to connect to bluetooth device!") + exit("14") def play_ringtone(self, volume): self.ringtone = pulseaudio.Play( - [(self.blt_speaker.pa_index, volume)], "../ringtone.mp3") + [(self.blt_speaker.pa_index, volume)], "../ringtone.mp3", self.pa) def stop_playing_ringtone(self): self.ringtone.stop_playing() + self.ringtone = None - def play_voices(self, volume): - self.svoices = pulseaudio.Play([(self.blt_speaker.pa_index, volume)], "../ambient1.wav") + def play_voices(self, volume=3): + self.voices_player = pulseaudio.Play( + [(0, volume)], "/home/pi/NAGRANIE_FINAL_BASIC.wav", self.pa, repeat=False) + + def play_failed(self, volume=2): + self.fail_player = pulseaudio.Play( + [(self.blt_speaker.pa_index, volume)], "./lose.wav", self.pa, repeat=False) + while not self.fail_player.is_playing(): + sleep(0.1) + while self.fail_player.is_playing(): + sleep(0.5) + self.fail_player.stop_playing() + self.fail_player = None + + def play_successed(self, volume=2): + self.success_player = pulseaudio.Play( + [(self.blt_speaker.pa_index, volume)], "./win.wav", self.pa, repeat=False) + while not self.success_player.is_playing(): + sleep(0.1) + while self.success_player.is_playing(): + sleep(0.5) + self.success_player.stop_playing() + self.success_player = None def stop_playing_voices(self): - self.svoices.stop_playing() + self.voices_player.stop_playing() + self.voices_player = None + + def stop_led(self): + self.led.set_r_intensity(0) + self.led.set_g_intensity(0) def led_white(self): - self.led.set_r_intensity(100) - self.led.set_g_intensity(100) + while self.leds: + for i in range(140, 186, 1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(pow(1.025, i)) + if self.leds: + return True + sleep(0.03) + + sleep(0.03) + + for i in range(186, 140, -1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(pow(1.025, i)) + if self.leds: + return True + sleep(0.03) + def led_red(self): - self.led.set_r_intensity(100) - self.led.set_g_intensity(0) + while self.leds: + for i in range(140, 186, 1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(0) + if self.leds: + return True + sleep(0.03) + + sleep(0.03) + + for i in range(186, 140, -1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(0) + if self.leds: + return True + sleep(0.03) def __led_pulsing_white(self): - while self.standby_on == True: - for i in range(1, 155, 1): - self.led.set_r_intensity(pow(1.03, i)) - self.led.set_g_intensity(pow(1.03, i)) - if self.standby_on == False: + while self.standby_on: + for i in range(1, 35, 1): + self.led.set_r_intensity(pow(1.035, i)) + self.led.set_g_intensity(pow(1.035, i)) + if not self.standby_on: return True sleep(0.03) + for i in range(35, 186, 1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(pow(1.025, i)) + if not self.standby_on: + return True + sleep(0.03) + + sleep(0.03) - for i in range(155, 1, -1): - self.led.set_r_intensity(pow(1.03, i)) - self.led.set_g_intensity(pow(1.03, i)) - if self.standby_on == False: + for i in range(186, 35, -1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(pow(1.025, i)) + if not self.standby_on: + return True + sleep(0.03) + for i in range(35, 1, -1): + self.led.set_r_intensity(pow(1.035, i)) + self.led.set_g_intensity(pow(1.035, i)) + if not self.standby_on: return True sleep(0.03) - def __led_pulsing_red(self): - self.led.set_g_intensity(0) - while self.standby_on == True: - for i in range(1, 155, 1): - self.led.set_r_intensity(pow(1.03, i)) - if self.standby_on == False: + def led_pulsing_red(self): + while self.playing_voices: + for i in range(1, 35, 1): + self.led.set_r_intensity(pow(1.035, i)) + self.led.set_g_intensity(0) + if not self.playing_voices: return True sleep(0.03) + for i in range(35, 186, 1): + self.led.set_r_intensity(pow(1.025, i)) + self.led.set_g_intensity(0) + if not self.playing_voices: + return True + sleep(0.03) + + sleep(0.03) - for i in range(155, 1, -1): - self.led.set_r_intensity(pow(1.03, i)) - if self.standby_on == False: + for i in range(186, 35, -1): + self.led.set_r_intensity(pow(1.025, i)) + if not self.playing_voices: return True sleep(0.03) + for i in range(35, 1, -1): + self.led.set_r_intensity(pow(1.035, i)) + if not self.playing_voices: + return True + sleep(0.03) + def ambient_play(self): + self.ambient_player = pulseaudio.Play([(self.blt_speaker.pa_index, 2)], "/home/pi/ambient1.wav", self.pa) + + def ambient_stop_play(self): + self.ambient_player.stop_playing() + self.ambient_player = None + def wait_between_seq(self): + self.waiting = True + led_thread = threading.Thread(target=self.__led_pulsing_white, daemon=True) + self.ambient_play() + button_thread = threading.Thread(target=self.wait_for_pick_up) + button_thread.start() + led_thread.start() + button_thread.join(999) + self.stop_led() + sleep(0.3) + self.leds=True + self.led_white() + sleep(0.3) + self.leds=False + self.stop_led() + sleep(0.3) + self.leds=True + self.led_white() + sleep(0.3) + self.leds=False + self.stop_led() + sleep(0.3) + self.leds=True + self.led_white() + sleep(0.3) + self.leds=False + self.ambient_stop_play() def wait_for_beggining(self): + self.ambient_play() led_thread = threading.Thread(target=self.__led_pulsing_white) - sensors_thread = threading.Thread(target=self.sensors.wait_for_movement) + sensors_thread = threading.Thread( + target=self.sensors.wait_for_movement) sensors_thread.start() led_thread.start() + sleep(10) sensors_thread.join() self.standby_on = False - + self.ambient_stop_play() + def voices(self): - led_thread = threading.Thread(target=self.__led_pulsing_red) - self.play_voices(5) + self.press_duration = "" + self.playing_voices = True + led_thread = threading.Thread(target=self.led_pulsing_red) + button_thread = threading.Thread(target=self.wait_for_pick_up) led_thread.start() - result = self.wait_for_pick_up() + sleep(1) + self.play_voices() + while not self.voices_player.is_playing(): + sleep(0.1) + button_thread.start() + while (self.press_duration == "" or self.press_duration == "short") and self.voices_player.is_playing(): + sleep(0.25) self.stop_playing_voices() - return result - - def wait_for_pick_up(self): - butt_down = self.remote.wait_and_get_output() - print(butt_down) - while True: - if butt_down.keystate == 1: - while True: - butt_up = self.remote.wait_and_get_output() - if butt_up.keystate == 0: - if butt_up.event.sec - butt_down.event.sec >= 3: - return "long" - else: - return "short" + if self.press_duration == "": + self.remote.stop_waiting_on_output() + self.playing_voices = False + return self.press_duration + def fail(self): + self.leds = True + threading.Thread(target=self.led_red, daemon=True) + self.play_failed() + self.leds = False + def success(self): + self.leds = True + threading.Thread(target=self.led_white, daemon=True) + self.play_successed() + self.leds = False -def main(): + def wait_for_pick_up(self): + print("imin") + start = time.time() + time.clock() + elapsed = 0 + while True: + elapsed = time.time() - start + if elapsed and self.waiting > 10: + threading.Thread(target=self.connect_to_remote, daemon=True).start() + butt_down = self.remote.wait_and_get_output() + if type(butt_down) == None: + self.press_duration = "" + return False + elif butt_down.keystate == 1: + butt_up = self.remote.wait_and_get_output() + if butt_up.keystate == 0: + if butt_up.event.sec - butt_down.event.sec >= 3: + print("long") + self.press_duration = "long" + return self.press_duration + else: + self.press_duration = "short" + print("short") + if not self.waiting and not self.playing_voices: + return self.press_duration - chandelier = Chandelier([16, 26], [20, 21, 21], - "30:21:A0:29:85:28", "2A:07:98:10:34:2C") #sensors, leds, speaker, remote +def sequence(): + chandelier = Chandelier([26, 19, 16], [20, 21, 21], + "0C:A6:94:62:67:40", "2A:07:98:10:32:05") # sensors, leds, speaker, remote chandelier.wait_for_beggining() - chandelier.led_white() - sleep(3) + chandelier.leds = True + threading.Thread(target=chandelier.led_white, daemon=True) chandelier.play_ringtone(1) - print("dupa") chandelier.wait_for_pick_up() + chandelier.leds = False chandelier.stop_playing_ringtone() - if chandelier.voices() == "short": - print("you did it <3") - \ No newline at end of file + press_duration = chandelier.voices() + if press_duration == "long": + chandelier.fail() + else: + chandelier.success() + +def waiting(): + chandelier = Chandelier([26, 19, 16], [20, 21, 21], + "0C:A6:94:62:67:40", "2A:07:98:10:32:05") # sensors, leds, speaker, remote + chandelier.wait_between_seq() + +#2A:07:98:10:34:2C ribbon remote +#2A:07:98:10:32:05 with sticker remote + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Seq or waiting') + parser.add_argument('--wait', action='store_true', help='Execute waiting sequence') + args = parser.parse_args() + + if args.wait: + waiting() + else: + sequence() + diff --git a/chandelier/led.py b/chandelier/led.py index d66f3a4..cf6d171 100644 --- a/chandelier/led.py +++ b/chandelier/led.py @@ -9,7 +9,7 @@ def __init__(self, pin): self.pin = pin class Led: - def __init__(self, R, G, B, freq=50): + def __init__(self, R, G, B, freq=100): self._red = LedColor(R) self._green = LedColor(G) self._blue = LedColor(B) diff --git a/chandelier/pulseaudio.py b/chandelier/pulseaudio.py index 1f653db..68a9c2b 100644 --- a/chandelier/pulseaudio.py +++ b/chandelier/pulseaudio.py @@ -1,59 +1,76 @@ import pulsectl import vlc -from time import sleep class OutputControl(): def SetVolumeSink(self, Sink): - temp_vol = Sink[0]().volume - temp_vol.value_flat = Sink[1] - self.__interface__.sink_volume_set(Sink[0]().index, temp_vol) + for sink in self.sinks_list: + if sink().index == Sink[0]: + temp_vol = sink().volume + temp_vol.value_flat = Sink[1] + self.__interface__.sink_volume_set(sink().index, temp_vol) + return None - def __CreateCombinedSink__(self, sinks_list): - sinks_names = ','.join(Sink[0]().name for Sink in sinks_list) + + def CreateCombinedSink(self, sinks_list): + sinks_names = ','.join(Sink().name for Sink in sinks_list) print(sinks_names) args = "sink_name=HubertPierdoliGlupoty slaves=\"" + \ sinks_names + "\" sink_properties=\"\"" sink_module = self.__interface__.module_load("module-combine-sink", args) for Sink in self.__interface__.sink_list(): if Sink.owner_module == sink_module: - return (lambda: self.__interface__.sink_info(Sink.index), 1.0) + sinks_list.append(lambda: self.__interface__.sink_info(Sink.index)) - def __SetDefaultOutput__(self, Sink): - self.__interface__.sink_default_set(Sink[0]()) + def SetDefaultOutput(self, Sink): + for sink in self.sinks_list: + if sink().index == Sink: + self.__interface__.sink_default_set(sink()) + return None - def __init__(self, sinks_index_and_volume): + def __init__(self, sinks_indexes): self.__interface__ = pulsectl.Pulse('interface') self.sinks_list = [] - for Sink in sinks_index_and_volume: + for Sink in sinks_indexes: def sink_pulseaudio(index): return lambda: self.__interface__.sink_info(index) - self.sinks_list.append((sink_pulseaudio(Sink[0]), float(Sink[1]))) + self.sinks_list.append(sink_pulseaudio(Sink)) - if len(self.sinks_list) > 1: - self.sinks_list.insert(0, self.__CreateCombinedSink__(self.sinks_list)) - self.__SetDefaultOutput__(self.sinks_list[0]) - for Sink in self.sinks_list: - self.SetVolumeSink(Sink) - else: - self.__SetDefaultOutput__(self.sinks_list[0]) - self.SetVolumeSink(self.sinks_list[0]) + def __del__(self): + self.__interface__.disconnect() + self.__interface__.close() -class Play(OutputControl): +class Play(): def play(self): self.player.play() def stop_playing(self): self.player.stop() + + def is_playing(self): + return self.player.is_playing() def __del__(self): self.player.stop() self.player.release() + print("player is released!") - def __init__(self, sinks, file): + def __init__(self, sinks, file, pa, repeat=True): self.file = file - self.player = vlc.MediaPlayer(vlc.Instance('--input-repeat=999999'), file) - super().__init__(sinks) + if len(sinks) > 1: + pa.__CreateCombinedSink__([item[0] for item in sinks]) + pa.SetDefaultOutput(pa.sinks_list[-1]) + else: + pa.SetDefaultOutput(sinks[0][0]) + + for sink in sinks: + pa.SetVolumeSink(sink) + + if repeat: + self.player = vlc.MediaPlayer(vlc.Instance('--input-repeat=999999'), file) + else: + self.player = vlc.MediaPlayer(vlc.Instance(), file) self.play() + diff --git a/lose.wav b/lose.wav new file mode 100644 index 0000000..f8d5b5d Binary files /dev/null and b/lose.wav differ diff --git a/script.sh b/script.sh old mode 100644 new mode 100755 index 23fb3c9..ff2d9f5 --- a/script.sh +++ b/script.sh @@ -1,4 +1,52 @@ -check if user is in lp groups -start and enable bluetoothctl, pulseaudio , sshd -automaticly connect to wifi with static ip (from env) -reboot if exit with error code 10 \ No newline at end of file +#!/bin/bash + +# /etc/init.d/script.sh +### BEGIN INIT INFO +# Provides: script.sh +# Required-Start: $all +# Required-Stop: $all +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start daemon at boot time +# Description: Enable service provided by daemon. +### END INIT INFO + +#check if user is in lp groups +#start and enable bluetoothctl, pulseaudio , sshd +#automaticly connect to wifi with static ip (from env) +#reboot if exit with error code 10 +# +RC=0 +SH=0 +TSH=0 +pushd /home/pi/Chandelier + +date +while [[ ${RC} == '0' ]]; do + echo "Starting" + python3 -m chandelier + RC=$? + echo $RC + if [[ ${RC} == '14' ]]; then + SH==$(($SH + 1)) + RC=0 + elif [[ ${RC} == '0' ]]; then + echo "Waiting" + python3 -m chandelier --wait + else + echo "Smth happened" + TSH==$(($SH + 1)) + sleep 2 + fi + + if [[ $SH == '3' ]]; then + echo "Shit happened 3 times in a row, rebooting" + sudo reboot -f + fi + if [[ $TSH == '10' ]]; then + echo "Total shit happened 10 times in a row, rebooting" + sudo reboot -f + fi + +done +echo "Done $RC" diff --git a/win.wav b/win.wav new file mode 100644 index 0000000..8aaea3e Binary files /dev/null and b/win.wav differ