From e75063a0f3cd0e3f64edb0305c792c837b2b2e11 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 5 Jul 2021 10:50:11 +0200 Subject: [PATCH] Initial commit --- amp_controller.pdf | Bin 0 -> 33989 bytes amp_controller.py | 133 ++++++++++++++++ amp_controller.sch | 378 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 511 insertions(+) create mode 100644 amp_controller.pdf create mode 100644 amp_controller.py create mode 100644 amp_controller.sch diff --git a/amp_controller.pdf b/amp_controller.pdf new file mode 100644 index 0000000000000000000000000000000000000000..618ecce1dd97ace445baa1446ede93278efd5dd8 GIT binary patch literal 33989 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 ntBbgm*_c8B?AIgX=Jw^_XlU None: + """Set all GPIO pins to output.""" + for pin in self.GPIO_PINS.values(): + gpio.setup(pin, gpio.OUT) + + def set_channel(self, channel_name) -> None: + """Set the channel on the amplifier.""" + pin = self.GPIO_PINS[channel_name] + gpio.output(pin, True) + time.sleep(0.5) + gpio.output(pin, False) + + def power(self, state) -> None: + """Turn the amplifier on or off via the GPIO pins.""" + if state == "on": + gpio.output(self.GPIO_PINS["Relay"], True) + time.sleep(0.5) + self.powered = True + else: + gpio.output(self.GPIO_PINS["Relay"], False) + self.powered = False + + def pulse_playing(self) -> bool: + """Return True if there is something playing on the specified Pulseaudio card. + Return False in every other case. + """ + output = subprocess.check_output( + "cat " + self.PULSE_CARD_PATH, shell=True, universal_newlines=True + ) + + state = output.split("\n")[0] + + if "RUNNING" in state: + logging.debug("Pulseaudio connected") + return True + + return False + + def mpd_client_connected(self) -> bool: + """Return True if an mpd client is connected and False if not. + Requires 'log_level="secure"' or "debug" to be set in mpd.conf. + """ + output = subprocess.check_output( + ["tail", "-1", self.MPD_LOG_FILE], universal_newlines=True + ) + + if output != self.last_mpd_output: + self.last_mpd_output = output + if re.match(".* opened from .*", output): + logging.debug("mpd client connected") + return True + + return False + + +if __name__ == "__main__": + ac = amp_controller() + ac.setup_pins() + ac.power("on") + ac.set_channel("CD") + + timer = ac.SHUTOFF_TIMER_DURATION + while True: + # Check for changes every second. + time.sleep(ac.CHECK_FREQUENCY) + + # Only connected, nothing playing. + if ac.mpd_client_connected(): + if not ac.powered: + ac.power("on") + ac.set_channel("CD") + + # (Re)set the timer to the short duration if a client connects. Don't + # overwrite a running timer currently greater than the short duration one. + if timer > 0 and timer <= ac.SHORT_TIMER_DURATION: + timer = ac.SHORT_TIMER_DURATION + elif timer < 0: + timer = ac.SHORT_TIMER_DURATION + + logging.debug("Timer set to {}".format(timer)) + + if timer == 0: + logging.debug("Timer ran out") + ac.power("off") + + if ac.pulse_playing() and not ac.powered: + ac.power("on") + ac.set_channel("CD") + + # Reset the timer. + timer = ac.SHUTOFF_TIMER_DURATION + + # Start the counter if nothing is currently playing. + if not ac.pulse_playing(): + timer -= ac.CHECK_FREQUENCY + logging.debug("Nothing playing.") + logging.debug("Timer: " + str(timer)) + continue + + if timer < -1000: # Just to be safe and avoid weird overflows. + timer = -1 + + # If there is something playing (no ifs matched) just reset the counter. + timer = ac.SHUTOFF_TIMER_DURATION + logging.debug("Something is playing.") + logging.debug("Timer: " + str(timer)) diff --git a/amp_controller.sch b/amp_controller.sch new file mode 100644 index 0000000..1db8e8c --- /dev/null +++ b/amp_controller.sch @@ -0,0 +1,378 @@ +EESchema Schematic File Version 4 +EELAYER 30 0 +EELAYER END +$Descr A4 11693 8268 +encoding utf-8 +Sheet 1 1 +Title "Automating an old HiFi receiver" +Date "2021-03-10" +Rev "" +Comp "" +Comment1 "" +Comment2 "" +Comment3 "" +Comment4 "" +$EndDescr +$Comp +L Connector:Raspberry_Pi_2_3 J1 +U 1 1 60DDC401 +P 5450 3800 +F 0 "J1" H 6000 5200 50 0000 C CNN +F 1 "Raspberry_Pi_3" H 6000 5100 50 0000 C CNN +F 2 "" H 5450 3800 50 0001 C CNN +F 3 "https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf" H 5450 3800 50 0001 C CNN + 1 5450 3800 + 1 0 0 -1 +$EndComp +$Comp +L Isolator:LTV-847 U1 +U 3 1 60DE520A +P 7200 4300 +F 0 "U1" H 7200 4100 50 0000 C CNN +F 1 "LTV-847" H 7200 4000 50 0000 C CNN +F 2 "Package_DIP:DIP-16_W7.62mm" H 7000 4100 50 0001 L CIN +F 3 "http://optoelectronics.liteon.com/upload/download/DS-70-96-0016/LTV-8X7%20series.PDF" H 7200 4300 50 0001 L CNN + 3 7200 4300 + 1 0 0 -1 +$EndComp +$Comp +L Isolator:LTV-847 U1 +U 2 1 60DE73C5 +P 4050 3600 +F 0 "U1" H 4050 3925 50 0000 C CNN +F 1 "LTV-847" H 4050 3834 50 0000 C CNN +F 2 "Package_DIP:DIP-16_W7.62mm" H 3850 3400 50 0001 L CIN +F 3 "http://optoelectronics.liteon.com/upload/download/DS-70-96-0016/LTV-8X7%20series.PDF" H 4050 3600 50 0001 L CNN + 2 4050 3600 + 1 0 0 -1 +$EndComp +$Comp +L power:GND #PWR07 +U 1 1 60DEB291 +P 6800 4400 +F 0 "#PWR07" H 6800 4150 50 0001 C CNN +F 1 "GND" H 6805 4227 50 0000 C CNN +F 2 "" H 6800 4400 50 0001 C CNN +F 3 "" H 6800 4400 50 0001 C CNN + 1 6800 4400 + 1 0 0 -1 +$EndComp +$Comp +L power:GND1 #PWR09 +U 1 1 60DEC006 +P 7600 4400 +F 0 "#PWR09" H 7600 4150 50 0001 C CNN +F 1 "GND1" H 7605 4227 50 0000 C CNN +F 2 "" H 7600 4400 50 0001 C CNN +F 3 "" H 7600 4400 50 0001 C CNN + 1 7600 4400 + 1 0 0 -1 +$EndComp +Wire Wire Line + 7600 4400 7500 4400 +Wire Wire Line + 6900 4400 6800 4400 +$Comp +L Device:R_Small R3 +U 1 1 60DEFEFD +P 6700 4200 +F 0 "R3" V 6504 4200 50 0000 C CNN +F 1 "330R" V 6595 4200 50 0000 C CNN +F 2 "" H 6700 4200 50 0001 C CNN +F 3 "~" H 6700 4200 50 0001 C CNN + 1 6700 4200 + 0 1 1 0 +$EndComp +Text GLabel 3200 3500 2 50 UnSpc ~ 0 +Tuner +Text GLabel 7600 4200 2 50 UnSpc ~ 0 +Phono +Text GLabel 4400 3500 2 50 UnSpc ~ 0 +CD +$Comp +L power:GND #PWR05 +U 1 1 60DF21B1 +P 5750 5150 +F 0 "#PWR05" H 5750 4900 50 0001 C CNN +F 1 "GND" H 5755 4977 50 0000 C CNN +F 2 "" H 5750 5150 50 0001 C CNN +F 3 "" H 5750 5150 50 0001 C CNN + 1 5750 5150 + 1 0 0 -1 +$EndComp +Wire Wire Line + 5050 5100 5150 5100 +Connection ~ 5150 5100 +Wire Wire Line + 5150 5100 5250 5100 +Connection ~ 5250 5100 +Wire Wire Line + 5250 5100 5350 5100 +Connection ~ 5350 5100 +Wire Wire Line + 5350 5100 5450 5100 +Connection ~ 5450 5100 +Wire Wire Line + 5450 5100 5550 5100 +Connection ~ 5550 5100 +Wire Wire Line + 5550 5100 5650 5100 +Connection ~ 5650 5100 +Wire Wire Line + 5650 5100 5750 5100 +$Comp +L Device:Q_NPN_BCE Q1 +U 1 1 60E00D90 +P 7150 2800 +F 0 "Q1" H 7341 2846 50 0000 L CNN +F 1 "Q_NPN_BCE" H 7341 2755 50 0000 L CNN +F 2 "" H 7350 2900 50 0001 C CNN +F 3 "~" H 7150 2800 50 0001 C CNN + 1 7150 2800 + 1 0 0 -1 +$EndComp +$Comp +L Device:R_Small R4 +U 1 1 60E03B10 +P 6700 2800 +F 0 "R4" V 6504 2800 50 0000 C CNN +F 1 "1k" V 6595 2800 50 0000 C CNN +F 2 "" H 6700 2800 50 0001 C CNN +F 3 "~" H 6700 2800 50 0001 C CNN + 1 6700 2800 + 0 1 1 0 +$EndComp +Wire Wire Line + 7500 4200 7600 4200 +Wire Wire Line + 6800 4200 6900 4200 +$Comp +L Isolator:LTV-847 U1 +U 1 1 60DE5F9F +P 2850 3600 +F 0 "U1" H 2850 3925 50 0000 C CNN +F 1 "LTV-847" H 2850 3834 50 0000 C CNN +F 2 "Package_DIP:DIP-16_W7.62mm" H 2650 3400 50 0001 L CIN +F 3 "http://optoelectronics.liteon.com/upload/download/DS-70-96-0016/LTV-8X7%20series.PDF" H 2850 3600 50 0001 L CNN + 1 2850 3600 + 1 0 0 -1 +$EndComp +$Comp +L power:GND1 #PWR02 +U 1 1 60E260A0 +P 3250 3700 +F 0 "#PWR02" H 3250 3450 50 0001 C CNN +F 1 "GND1" H 3255 3527 50 0000 C CNN +F 2 "" H 3250 3700 50 0001 C CNN +F 3 "" H 3250 3700 50 0001 C CNN + 1 3250 3700 + 1 0 0 -1 +$EndComp +$Comp +L power:GND1 #PWR04 +U 1 1 60E262E7 +P 4450 3700 +F 0 "#PWR04" H 4450 3450 50 0001 C CNN +F 1 "GND1" H 4455 3527 50 0000 C CNN +F 2 "" H 4450 3700 50 0001 C CNN +F 3 "" H 4450 3700 50 0001 C CNN + 1 4450 3700 + 1 0 0 -1 +$EndComp +Wire Wire Line + 4350 3700 4450 3700 +Wire Wire Line + 3150 3700 3250 3700 +$Comp +L power:GND #PWR01 +U 1 1 60E27552 +P 2450 3700 +F 0 "#PWR01" H 2450 3450 50 0001 C CNN +F 1 "GND" H 2455 3527 50 0000 C CNN +F 2 "" H 2450 3700 50 0001 C CNN +F 3 "" H 2450 3700 50 0001 C CNN + 1 2450 3700 + 1 0 0 -1 +$EndComp +$Comp +L power:GND #PWR03 +U 1 1 60E27847 +P 3650 3700 +F 0 "#PWR03" H 3650 3450 50 0001 C CNN +F 1 "GND" H 3655 3527 50 0000 C CNN +F 2 "" H 3650 3700 50 0001 C CNN +F 3 "" H 3650 3700 50 0001 C CNN + 1 3650 3700 + 1 0 0 -1 +$EndComp +Wire Wire Line + 2450 3700 2550 3700 +Wire Wire Line + 3650 3700 3750 3700 +Wire Wire Line + 2450 3500 2550 3500 +Wire Wire Line + 4650 3000 3650 3000 +Wire Wire Line + 3650 3500 3750 3500 +Wire Wire Line + 3150 3500 3200 3500 +Wire Wire Line + 4350 3500 4400 3500 +$Comp +L Device:R_Small R1 +U 1 1 60E39D0E +P 2450 3200 +F 0 "R1" V 2254 3200 50 0000 C CNN +F 1 "330R" V 2345 3200 50 0000 C CNN +F 2 "" H 2450 3200 50 0001 C CNN +F 3 "~" H 2450 3200 50 0001 C CNN + 1 2450 3200 + 1 0 0 -1 +$EndComp +$Comp +L Device:R_Small R2 +U 1 1 60E3A62A +P 3650 3200 +F 0 "R2" V 3454 3200 50 0000 C CNN +F 1 "330R" V 3545 3200 50 0000 C CNN +F 2 "" H 3650 3200 50 0001 C CNN +F 3 "~" H 3650 3200 50 0001 C CNN + 1 3650 3200 + 1 0 0 -1 +$EndComp +Wire Wire Line + 2450 2900 2450 3100 +Wire Wire Line + 3650 3000 3650 3100 +Wire Wire Line + 3650 3300 3650 3500 +Wire Wire Line + 2450 3300 2450 3500 +Wire Wire Line + 6800 2800 6950 2800 +Wire Wire Line + 6250 3300 6400 3300 +$Comp +L power:GND #PWR08 +U 1 1 60E02F01 +P 7250 3050 +F 0 "#PWR08" H 7250 2800 50 0001 C CNN +F 1 "GND" H 7255 2877 50 0000 C CNN +F 2 "" H 7250 3050 50 0001 C CNN +F 3 "" H 7250 3050 50 0001 C CNN + 1 7250 3050 + 1 0 0 -1 +$EndComp +Wire Wire Line + 7250 3000 7250 3050 +Connection ~ 8900 2250 +Wire Wire Line + 8900 2550 8900 2250 +Wire Wire Line + 8850 2550 8900 2550 +Wire Wire Line + 8650 2250 8900 2250 +$Comp +L power:+5V #PWR010 +U 1 1 60DFDF95 +P 8900 2250 +F 0 "#PWR010" H 8900 2100 50 0001 C CNN +F 1 "+5V" H 8915 2423 50 0000 C CNN +F 2 "" H 8900 2250 50 0001 C CNN +F 3 "" H 8900 2250 50 0001 C CNN + 1 8900 2250 + 1 0 0 -1 +$EndComp +$Comp +L Device:D_Small D1 +U 1 1 60DF89B5 +P 8550 2250 +F 0 "D1" H 8550 2150 50 0000 C CNN +F 1 "D_Small" H 8550 2134 50 0001 C CNN +F 2 "" V 8550 2250 50 0001 C CNN +F 3 "~" V 8550 2250 50 0001 C CNN + 1 8550 2250 + -1 0 0 1 +$EndComp +$Comp +L Relay:DIPxx-1Cxx-51x RL1 +U 1 1 60DF6245 +P 8550 2750 +F 0 "RL1" V 9000 2750 50 0000 C CNN +F 1 "AZ8-1CH-50A" V 9100 2750 50 0000 C CNN +F 2 "Relay_THT:Relay_StandexMeder_DIP_LowProfile" H 9000 2700 50 0001 L CNN +F 3 "https://standexelectronics.com/wp-content/uploads/datasheet_reed_relay_DIP.pdf" H 8550 2750 50 0001 C CNN + 1 8550 2750 + 0 1 1 0 +$EndComp +Wire Wire Line + 7250 2550 7250 2600 +Wire Wire Line + 2450 2900 4650 2900 +Wire Wire Line + 6600 2800 6400 2800 +Wire Wire Line + 6400 2800 6400 3200 +Wire Wire Line + 6400 3200 6250 3200 +Connection ~ 5750 5100 +Wire Wire Line + 7250 2550 8200 2550 +Wire Wire Line + 8200 2250 8200 2550 +Wire Wire Line + 5250 2500 5350 2500 +Wire Wire Line + 5250 2450 5250 2500 +Connection ~ 5250 2500 +$Comp +L power:+5V #PWR06 +U 1 1 60DF360B +P 5250 2450 +F 0 "#PWR06" H 5250 2300 50 0001 C CNN +F 1 "+5V" H 5265 2623 50 0000 C CNN +F 2 "" H 5250 2450 50 0001 C CNN +F 3 "" H 5250 2450 50 0001 C CNN + 1 5250 2450 + 1 0 0 -1 +$EndComp +Wire Wire Line + 5750 5100 5750 5150 +$Comp +L Switch:SW_SPST SW1 +U 1 1 60E85113 +P 8550 3650 +F 0 "SW1" H 8550 3550 50 0000 C CNN +F 1 "SW_SPST" H 8550 3794 50 0001 C CNN +F 2 "" H 8550 3650 50 0001 C CNN +F 3 "~" H 8550 3650 50 0001 C CNN + 1 8550 3650 + 1 0 0 -1 +$EndComp +Wire Wire Line + 6400 4200 6600 4200 +Wire Wire Line + 6400 3300 6400 4200 +Wire Wire Line + 8750 3650 8950 3650 +Wire Wire Line + 8950 3650 8950 3050 +Wire Wire Line + 8950 3050 8850 3050 +Wire Wire Line + 8200 2250 8450 2250 +Wire Wire Line + 8200 2550 8250 2550 +Connection ~ 8200 2550 +Wire Wire Line + 8150 2950 8150 3650 +Wire Wire Line + 8150 3650 8350 3650 +Wire Wire Line + 8150 2950 8250 2950 +Text GLabel 8150 3350 0 50 Input ~ 0 +AMP_Power +Text GLabel 8950 3350 2 50 Output ~ 0 +AMP_Power +$EndSCHEMATC