Browse Source

added FakeGPIO and made some design improvements

digital 8 years ago
parent
commit
129b091175
1 changed files with 119 additions and 11 deletions
  1. 119 11
      pin/__init__.py

+ 119 - 11
pin/__init__.py

@@ -18,10 +18,31 @@
 
 # Python modules
 import logging
+import threading
+import traceback
 # Third party modules
 import curio
 import digilib.network
 
+class FakeGPIO(object):
+    pin_values = {}
+    def output(self,pins,value):
+        lpin.debug("setting pin(s) {} to value {}".format(
+            pins, value
+        ))
+        if type(pins) == int:
+            pins = [pins]
+        for p in pins:
+            self.pin_values[p] = value
+    def read(self,pin):
+        return self.pin_values[pin]
+
+try:
+    import RPi.GPIO as gpio
+except:
+    print(traceback.format_exc())
+    gpio = FakeGPIO()
+
 log = logging.getLogger(__name__+"")
 lpin = logging.getLogger(__name__+".pin")
 
@@ -56,14 +77,16 @@ class PinBase(object):
             )
         )
         self.value = value
+        gpio.output(self.pin_number,value)
     def read(self):
+        value = gpio.output(self.pin_number,value)
         lpin.debug(
             "pin {} has value {}".format(
                 str(self.pin_number),
-                str(self.value)
+                str(value)
             )
         )
-        return self.value
+        return value
 
 class DigitalPin(PinBase):
     value_high = True
@@ -79,8 +102,8 @@ class AnalogPin(PinBase):
 
 class PinControllerBase(object):
     """docstring for PinControllerBase.
-    PinControllerBase is the base class for all classes controlling a physical
-    device connected to multiple pins
+    PinControllerBase is the base class for all classes controlling one or more physical devices connected to a gpio header
+
     """
     pins = []
     def __init__(self):
@@ -89,6 +112,24 @@ class PinControllerBase(object):
         return DigitalPin(*args)
     def make_analog_pin(self,*args):
         return AnalogPin(*args)
+    # def get_text_to_func(self):
+    #     """
+    #     ***description***
+    #     this function returns a dict {string:function,}. It is good practice that string is "<__module__><__name__><name of the api function>". This prevents duplicate names. The purpose of this dict is to provide access to the object's api methods.
+    #
+    #     ***object.api_func vs text_to_func["api_func"]***
+    #     if a class or a function translates text commands to function calls, it is easier to use `text_to_func["api_func"]()`. However, if a class or function calls the api functions, it is better to use `api_object.api_function()`.
+    #     """
+    #     return {}
+
+class PinAPIBase(object):
+    """docstring for PinAPI.
+    PinAPIBase is the base class for all classes providing an api to multiple
+    PinController.
+    """
+    controllers = []
+    def __init__(self):
+        super(PinAPIBase, self).__init__()
 
 class PCEngine(PinControllerBase):
     """Test Class"""
@@ -102,6 +143,11 @@ class PCEngine(PinControllerBase):
         self.pin_analog = self.make_digital_pin(pin_analog)
         self.pins.append(self.pin_on_off)
         self.pins.append(self.pin_analog)
+    def get_text_to_func(self,speed):
+        text_to_func = {
+            "turn": self.turn
+        }
+        return text_to_func
     def set_speed(self,speed):
         self.pin_analog.output(speed)
         self.speed = speed
@@ -112,15 +158,77 @@ class PCEngine(PinControllerBase):
         # self.set_speed(speed)
         self.pin_on_off.output(1)
         self.is_on = state
+    # async def turn(self,direction,*args,respond_method):
+    #     lpin.debug(args)
+    #     lpin.debug(threading.current_thread())
+    #     # with self ad
+    #     lpin.info("turning {}".format(direction))
+    #     right_state = self.engine_right.is_on
+    #     right_speed = self.engine_right.speed
+    #     left_state = self.engine_left.is_on
+    #     left_speed = self.engine_left.speed
+    #     if direction == "right":
+    #         self.engine_right.set_state(False)
+    #         self.engine_left.set_state(True)
+    #         self.engine_left.set_speed(1)
+    #     elif direction == "left":
+    #         self.engine_right.set_state(True)
+    #         self.engine_right.set_speed(1)
+    #         self.engine_left.set_state(False)
+    #     await curio.sleep(2)
+    #     # time.sleep(2)
+    #     self.engine_right.set_state(right_state)
+    #     self.engine_right.set_speed(right_speed)
+    #     self.engine_left.set_state(left_state)
+    #     self.engine_left.set_speed(left_speed)
+    #     lpin.info("done turning {}".format(direction))
+    #     # set engines to previous values
 
+class EnginesController(PinAPIBase):
+    engine_left = None
+    engine_right = None
+    action_in_process = False
+    def __init__(self,left,right):
+        super(EnginesController,self).__init__()
+        self.engine_right = self.make_engine(*right)
+        self.engine_left = self.make_engine(*left)
+    def __enter__(self):
+        if self.action_in_process:
+            lpin.debug("action already in process, not entering")
+            return False
+    def get_text_to_func(self,speed):
+        text_to_func = {
+            "turn": self.turn
+        }
+        return text_to_func
+    def make_engine(self,*args):
+        return digilib.pin.PCEngine(*args)
+    async def turn(self,direction,*args,respond_method):
+        lpin.debug(args)
+        lpin.debug(threading.current_thread())
+        # with self ad
+        lpin.info("turning {}".format(direction))
+        right_state = self.engine_right.is_on
+        right_speed = self.engine_right.speed
+        left_state = self.engine_left.is_on
+        left_speed = self.engine_left.speed
+        if direction == "right":
+            self.engine_right.set_state(False)
+            self.engine_left.set_state(True)
+            self.engine_left.set_speed(1)
+        elif direction == "left":
+            self.engine_right.set_state(True)
+            self.engine_right.set_speed(1)
+            self.engine_left.set_state(False)
+        await curio.sleep(2)
+        # time.sleep(2)
+        self.engine_right.set_state(right_state)
+        self.engine_right.set_speed(right_speed)
+        self.engine_left.set_state(left_state)
+        self.engine_left.set_speed(left_speed)
+        lpin.info("done turning {}".format(direction))
+        # set engines to previous values
 
-class PinAPIBase(object):
-    """docstring for PinAPI.
-    PinAPIBase is the base class for all classes providing an api to multiple
-    PinController.
-    """
-    def __init__(self):
-        super(PinAPIBase, self).__init__()
 
 class LED(DigitalPin):
     def __init__(self,pin_number):