Browse Source

moved controllers from pin.py to controller.py, worked in ButtonController and created file errmsg.py for error messages

digital 7 years ago
parent
commit
d20f67037d
3 changed files with 238 additions and 123 deletions
  1. 159 3
      src/digilib/gpio/controller.py
  2. 77 0
      src/digilib/gpio/errmsg.py
  3. 2 120
      src/digilib/gpio/pin.py

+ 159 - 3
src/digilib/gpio/controller.py

@@ -19,6 +19,8 @@ import logging
 log = logging.getLogger(__name__+"")
 lctrl = logging.getLogger(__name__+".ctrl")
 
+import time
+
 import curio
 import digilib.network
 import digilib.misc
@@ -86,12 +88,25 @@ class ButtonController(object):
     ----------
     pin_num: int
         the number of the pin wich is connected to the button and to logical HIGH through an appropriate resistor.
+    time_short_press: int
+        the maximum time the button needs to be pressed to be registered as a short press.
+    time_long_press: int
+        the maximum time the button needs to be pressed to be registered as a long press. if ``time_short_press`` is greater the long press feature is disabled.
+
+    Attributes
+    ----------
+    STATE_PRESSED: int
+        the value returned from gpio.read if the button is pressed
+    STATE_RELEASED: int
+        the value returned from gpio.read if the button is released
     """
-    def __init__(self,pin_num):
+    def __init__(self,pin_num,time_short_press,time_long_press,):
         """
         """
         super().__init__()
         self.pin_num = pin_num
+        self.time_short_press = time_short_press
+        self.time_long_press = time_long_press
         digilib.gpio.wrapper.setup(self.pin_num,digilib.gpio.wrapper.OUT)
 
     async def read_button_state(self):
@@ -112,8 +127,44 @@ class ButtonController(object):
 
     async def main_loop(self):
         """
-        This is the main loop of the Controller class.
-        """
+        The main loop executes registered callbacks if the button state was changed, was pressed for ``self.time_short_press`` or ``self.time_long_press``.
+
+        Attributes
+        ----------
+        prev_state: int
+            the state of the button during the last loop.
+        time_pressed: int
+            the time when the button was pressed, taken from time.time()
+        time_released: int
+            the time when the button was released, taken from time.time()
+        """
+        prev_state = None
+        time_pressed = 0
+        time_released = 0
+        try:
+            while True:
+                state = self.read_button_state()
+                if state != prev_state:
+                    if state = self.STATE_PRESSED:
+                        # the button was pressed just now
+                        time_pressed = time.time()
+                        # TODO execute registered methods
+                    else:
+                        # the button was released just now
+                        time_released = time.time()
+                        # TODO execute registered methods
+                        if ( time_released - time_pressed
+                                >= self.time_short_press ):
+                            # the button was pressed for a short time.
+                            # TODO execute registered methods
+                            pass
+                        elif ( time_released - time_pressed
+                                >= self.time_long_press ):
+                            # the button was pressed for a short time.
+                            # TODO execute registered methods
+                            pass
+                prev_state = state
+                await curio.sleep(0.1)
 
     async def minutely(self):
         """
@@ -131,9 +182,114 @@ class ButtonController(object):
         This method is called by the core when it shuts down.
         """
 
+class LED(ControllerBase):
+    """
+    Controllerbase controlls a normal LED.
 
+    Parameters
+    ----------
+    pin_num: int
+        number of the led's pin
 
+    Attributes
+    ----------
+    lock: threading.Lock
+        The lock used to protect gpio operations.
+    """
+    lock = None
 
+    def __init__(self,pin_num):
+        super().__init__()
+        self.pin = pin.DigitalPin(pin_num,_gpio.OUT)
+        self.lock = threading.Lock()
+        self.on()
+
+    async def on(self,args=[],command=None,respond=None):
+        if self.lock.locked():
+            response("This LED is already in use")
+            return
+        with self.lock:
+            self.write(True)
+
+    async def off(self,args=[],command=None,respond=None):
+        if self.lock.locked():
+            respond("This LED is already in use")
+            return
+        with self.lock:
+            self.write(False)
+
+    async def set(self,args=[],command=None,respond=None):
+        if len(args) != 1:
+            respond("one missing argument: state")
+            return
+        [state] = args
+        if self.lock.locked():
+            response("This LED is already in use")
+            return
+        with self.lock:
+            self.write(state)
+
+
+class StatusLED(PinControllerBase):
+
+    def __init__(self,pin_red,pin_green):
+        super(StatusLED,self).__init__([pin_red,pin_green])
+        self.pin_red = DigitalPin(pin_red,_gpio.OUT)
+        self.pin_green = DigitalPin(pin_green,_gpio.OUT)
+        self.green()
+
+    def red(self,args=[],command=None,respond=None):
+        if len(args) > 1:
+            respond(errmsg.args(command,"one","optional","<state>"))
+            return
+        elif len(args) == 1:
+            state = digilib.misc.parse_to_int_list(*args)
+        else:
+            state = 1
+        self.pin_red.write(state)
+        self.pin_green.write(int(not state))
+
+    def green(self,args=[],command=None,respond=None):
+        if len(args) > 1:
+            respond(ERROR_TAKES_ARGUMENTS.format(
+                command,"one","optional","<state>"))
+            return
+        elif len(args) == 1:
+            state = int(*args)
+        else:
+            state = 1
+        self.pin_green.write(state)
+        self.pin_red.write(int(not state))
+
+class DebugPinController(PinControllerBase):
+
+    def write(self,args=[],command=None,respond=None):
+        if len(args) != 2:
+            respond(ERROR_TAKES_ARGUMENTS.format(
+                    command, "two", "positional", "<name>"))
+            return False
+        pins = digilib.misc.parse_to_int_list(args[0])
+        [state] = digilib.misc.parse_to_int_list(args[1])
+        _gpio.write(pins,state)
+
+    def read(self,args=[],command=None,respond=None):
+        if len(args) != 2:
+            respond(ERROR_TAKES_ARGUMENTS.format(
+                    command, "two", "positional", "<name>"))
+            return False
+        pins = digilib.misc.parse_to_int_list(args[0])
+        [state] = digilib.misc.parse_to_int_list(args[1])
+        rv = _gpio.read(pins,state)
+        lgpio.debug(rv)
+        respond(str(rv))
+
+    def raise_exc(self,args=[],command=None,respond=None):
+        raise Exception("Test Exception")
+
+    async def araise_exc(self,args=[],command=None,respond=None):
+        state = digilib.misc.parse_to_int_list("1,2,3,4")
+        a = 1+2
+        raise Exception("Test Async Exception")
 
 
 

+ 77 - 0
src/digilib/gpio/errmsg.py

@@ -0,0 +1,77 @@
+# Copyright 2017 Digital
+#
+# This file is part of DigiLib.
+#
+# DigiLib is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DigiLib is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with DigiLib.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Error messages
+--------------
+Some error messages often used in gpio. They should be used with ``.format()``.
+"""
+
+
+
+def args(command=None,amount=None,optional=None,syntax=None):
+    retmsg = ""
+    if command:
+        retmsg += "'{}' ".format(command)
+    retmsg += "takes "
+    if amount:
+        retmsg += "{} ".format(amount)
+    if optional:
+        retmsg += "{} ".format(optional)
+    retmsg += "argument(s): "
+    if syntax:
+        retmsg += "{} ".format(syntax)
+    return retmsg
+
+ERROR_TAKES_ARGUMENTS = "{} takes {} {} argument(s): {}"
+
+
+if __name__ == "__main__":
+    print(args("cmd","one","optional","<state>"))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#

+ 2 - 120
src/digilib/gpio/pin.py

@@ -26,16 +26,15 @@ import curio
 import digilib.network
 import digilib.misc
 
+import .errmsg
 log = logging.getLogger(__name__+"")
 lgpio = logging.getLogger(__name__+".gpio")
 
 # Error messages
-ERROR_TAKES_ARGUMENTS = "{} takes {} {} argument(s): {}"
+# ERROR_TAKES_ARGUMENTS = "{} takes {} {} argument(s): {}"
 # respond(ERROR_TAKES_ARGUMENTS.format(
 #         command, "one", "positional", "<name>"))
 
-_pins_for_cleanup = set()
-_gpio = None
 
 class PinBase(object):
     """
@@ -70,123 +69,6 @@ class AnalogPin(PinBase):
     def __init__(self,pin_number):
         super(AnalogPin,self).__init__(pin_number)
 
-class ControllerBase(object):
-    """
-    PinControllerBase is the base class for all classes controlling one or more physical devices connected to a gpio header or other controllers
-    """
-
-    def __init__(self):
-        super().__init__()
-
-
-class LED(DigitalPin):
-    """
-    Controlls a LED
-
-    Parameters
-    ----------
-    pin: int
-        number of the led's pin
-
-    Attributes
-    ----------
-    lock: threading.Lock
-        The lock used to protect gpio operations.
-    """
-    lock = None
-
-    def __init__(self,pin):
-        super(DigitalPin,self).__init__(pin,_gpio.OUT)
-        self.lock = threading.Lock()
-        self.on()
-
-    async def on(self,args=[],command=None,respond=None):
-        if self.lock.locked():
-            response("This LED is already in use")
-            return
-        with self.lock:
-            self.write(True)
-
-    async def off(self,args=[],command=None,respond=None):
-        if self.lock.locked():
-            respond("This LED is already in use")
-            return
-        with self.lock:
-            self.write(False)
-
-    async def set(self,args=[],command=None,respond=None):
-        if len(args) != 1:
-            respond("one missing argument: state")
-            return
-        [state] = args
-        if self.lock.locked():
-            response("This LED is already in use")
-            return
-        with self.lock:
-            self.write(state)
-
-
-class StatusLED(PinControllerBase):
-
-    def __init__(self,pin_red,pin_green):
-        super(StatusLED,self).__init__([pin_red,pin_green])
-        self.pin_red = DigitalPin(pin_red,_gpio.OUT)
-        self.pin_green = DigitalPin(pin_green,_gpio.OUT)
-        self.green()
-
-    def red(self,args=[],command=None,respond=None):
-        if len(args) > 1:
-            respond(ERROR_TAKES_ARGUMENTS.format(
-                command,"one","optional","<state>"))
-            return
-        elif len(args) == 1:
-            state = digilib.misc.parse_to_int_list(*args)
-        else:
-            state = 1
-        self.pin_red.write(state)
-        self.pin_green.write(int(not state))
-
-    def green(self,args=[],command=None,respond=None):
-        if len(args) > 1:
-            respond(ERROR_TAKES_ARGUMENTS.format(
-                command,"one","optional","<state>"))
-            return
-        elif len(args) == 1:
-            state = int(*args)
-        else:
-            state = 1
-        self.pin_green.write(state)
-        self.pin_red.write(int(not state))
-
-class DebugPinController(PinControllerBase):
-
-    def write(self,args=[],command=None,respond=None):
-        if len(args) != 2:
-            respond(ERROR_TAKES_ARGUMENTS.format(
-                    command, "two", "positional", "<name>"))
-            return False
-        pins = digilib.misc.parse_to_int_list(args[0])
-        [state] = digilib.misc.parse_to_int_list(args[1])
-        _gpio.write(pins,state)
-
-    def read(self,args=[],command=None,respond=None):
-        if len(args) != 2:
-            respond(ERROR_TAKES_ARGUMENTS.format(
-                    command, "two", "positional", "<name>"))
-            return False
-        pins = digilib.misc.parse_to_int_list(args[0])
-        [state] = digilib.misc.parse_to_int_list(args[1])
-        rv = _gpio.read(pins,state)
-        lgpio.debug(rv)
-        respond(str(rv))
-
-    def raise_exc(self,args=[],command=None,respond=None):
-        raise Exception("Test Exception")
-
-    async def araise_exc(self,args=[],command=None,respond=None):
-        state = digilib.misc.parse_to_int_list("1,2,3,4")
-        a = 1+2
-        raise Exception("Test Async Exception")
 
 if __name__ == "__main__":
     pass