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__+"")
 log = logging.getLogger(__name__+"")
 lctrl = logging.getLogger(__name__+".ctrl")
 lctrl = logging.getLogger(__name__+".ctrl")
 
 
+import time
+
 import curio
 import curio
 import digilib.network
 import digilib.network
 import digilib.misc
 import digilib.misc
@@ -86,12 +88,25 @@ class ButtonController(object):
     ----------
     ----------
     pin_num: int
     pin_num: int
         the number of the pin wich is connected to the button and to logical HIGH through an appropriate resistor.
         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__()
         super().__init__()
         self.pin_num = pin_num
         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)
         digilib.gpio.wrapper.setup(self.pin_num,digilib.gpio.wrapper.OUT)
 
 
     async def read_button_state(self):
     async def read_button_state(self):
@@ -112,8 +127,44 @@ class ButtonController(object):
 
 
     async def main_loop(self):
     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):
     async def minutely(self):
         """
         """
@@ -131,9 +182,114 @@ class ButtonController(object):
         This method is called by the core when it shuts down.
         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.network
 import digilib.misc
 import digilib.misc
 
 
+import .errmsg
 log = logging.getLogger(__name__+"")
 log = logging.getLogger(__name__+"")
 lgpio = logging.getLogger(__name__+".gpio")
 lgpio = logging.getLogger(__name__+".gpio")
 
 
 # Error messages
 # Error messages
-ERROR_TAKES_ARGUMENTS = "{} takes {} {} argument(s): {}"
+# ERROR_TAKES_ARGUMENTS = "{} takes {} {} argument(s): {}"
 # respond(ERROR_TAKES_ARGUMENTS.format(
 # respond(ERROR_TAKES_ARGUMENTS.format(
 #         command, "one", "positional", "<name>"))
 #         command, "one", "positional", "<name>"))
 
 
-_pins_for_cleanup = set()
-_gpio = None
 
 
 class PinBase(object):
 class PinBase(object):
     """
     """
@@ -70,123 +69,6 @@ class AnalogPin(PinBase):
     def __init__(self,pin_number):
     def __init__(self,pin_number):
         super(AnalogPin,self).__init__(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__":
 if __name__ == "__main__":
     pass
     pass