Files
mozc-devices/mozc-nazoru/src/nazoru/led.py
Makoto Shimazu 0a438843ee Add a LED in chassis (#18)
LED was equipped in the chassis. This patch turns it on.
SlowLED changes the brightness gradually. wiringpi is used for it to leverage the hardware PWA equipped by Raspberry Pi.
2018-08-04 07:54:37 +09:00

146 lines
3.8 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
#
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class LEDBase(object):
def __init__(self, pin):
self._pin = pin
def on(self):
pass
def off(self):
pass
def blink(self, interval):
pass
def set_brightness(self, brightness):
pass
try:
import RPi.GPIO as GPIO
import threading
GPIO.setmode(GPIO.BOARD)
class LED(LEDBase):
ON = 'ON'
OFF = 'OFF'
def __init__(self, pin):
self._pin = pin
self._lock = threading.Lock()
self._timer = None
GPIO.setup(pin, GPIO.OUT)
self.off()
def on(self):
with self._lock:
self._state = self.ON
GPIO.output(self._pin, False)
self._ensure_stop_timer()
def off(self):
with self._lock:
self._state = self.OFF
GPIO.output(self._pin, True)
self._ensure_stop_timer()
def blink(self, interval):
self._ensure_stop_timer()
def toggle():
self._timer = None
if self._state == self.ON:
self.off()
else:
self.on()
self._timer = threading.Timer(interval, toggle)
self._timer.daemon = True
self._timer.start()
toggle()
def _ensure_stop_timer(self):
if self._timer is not None:
self._timer.cancel()
self._timer = None
import wiringpi
wiringpi.wiringPiSetupPhys()
class SlowLED(LEDBase):
DUTY_MAX = 1024
INTERVAL_MS = 10
def __init__(self, pin, delay_ms):
self._pin = pin
self._delay_ms = delay_ms
wiringpi.pinMode(pin, wiringpi.GPIO.PWM_OUTPUT)
self._target_duty = 0
self._current_duty = 0
self._remaining_cycles = 0
self._lock = threading.Lock()
self._timer = None
self.off()
# Called every 10ms
def _update(self):
with self._lock:
diff = (self._target_duty - self._current_duty) // \
self._remaining_cycles
self._current_duty += diff
self._remaining_cycles -= 1
self._set_duty_immediate(self._current_duty)
if self._remaining_cycles == 0:
self._timer.cancel()
self._timer = None
return
self._timer = threading.Timer(self.INTERVAL_MS * 0.001, self._update)
self._timer.daemon = True
self._timer.start()
# |duty|: 0 - 100
def _set_duty_immediate(self, duty):
wiringpi.pwmWrite(self._pin, int(self.DUTY_MAX * duty // 100))
def _set_duty_slow(self, duty, time_ms):
with self._lock:
self._target_duty = duty
self._remaining_cycles = time_ms // self.INTERVAL_MS
if self._timer is None:
self._timer = threading.Timer(self.INTERVAL_MS * 0.001, self._update)
self._timer.daemon = True
self._timer.start()
def on(self):
self._set_duty_slow(100, self._delay_ms)
def off(self):
self._set_duty_slow(0, self._delay_ms)
# |brightness|: 0 - 100
def set_brightness(self, brightness):
self._set_duty_slow(brightness, self._delay_ms)
except ImportError as e:
import sys
class LED(LEDBase):
pass
class SlowLED(LEDBase):
def __init__(self, pin, delay_ms):
super(SlowLED, self).__init__(pin)
LED_BLUE = LED(38)
LED_RED = LED(40)
LED_CHASSIS = SlowLED(32, 500)