Skip to content

Commit 9800e37

Browse files
committed
Refactor plugin input and output classes.
1 parent 9bd0436 commit 9800e37

File tree

4 files changed

+63
-141
lines changed

4 files changed

+63
-141
lines changed

myDevices/devices/analog/__init__.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,9 @@ def analogReadAllVolt(self):
9191
values[i] = float("%.2f" % self.analogReadVolt(i))
9292
return values
9393

94-
def read(self, channel, data_type=None, diff=False):
95-
read_functions = {'float': self.analogReadFloat, 'f': self.analogReadFloat,
96-
'volt': self.analogReadVolt, 'v': self.analogReadVolt}
97-
read_function = read_functions.get(data_type, self.analogRead)
94+
def read(self, channel, value_type=None, diff=False):
95+
read_functions = {'float': self.analogReadFloat, 'volt': self.analogReadVolt}
96+
read_function = read_functions.get(value_type, self.analogRead)
9897
return read_function(channel, diff)
9998

10099
def readFloat(self, channel, diff=False):
@@ -131,8 +130,10 @@ def analogWriteVolt(self, channel, value):
131130
self.analogWriteFloat(channel, value /self._analogRef)
132131
return self.analogReadVolt(channel)
133132

134-
def write(self, channel, value):
135-
return self.analogWrite(channel, value)
133+
def write(self, channel, value, value_type=None):
134+
write_functions = {'float': self.analogWriteFloat, 'volt': self.analogWriteVolt}
135+
write_function = write_functions.get(value_type, self.analogWrite)
136+
return write_function(channel, value)
136137

137138
def writeFloat(self, channel, value):
138139
return self.analogWriteFloat(channel, value)
@@ -206,17 +207,17 @@ def pwmWriteFloat(self, channel, value):
206207
self.pwmWrite(channel, int(value * self._pwmMax))
207208
return self.pwmReadFloat(channel)
208209

209-
def read(self, channel, data_type=None):
210+
def read(self, channel, value_type=None):
210211
read_functions = {'float': self.pwmReadFloat, 'angle': self.pwmReadAngle}
211-
read_function = read_functions.get(data_type, self.pwmRead)
212+
read_function = read_functions.get(value_type, self.pwmRead)
212213
return read_function(channel)
213214

214215
def readFloat(self, channel):
215216
return self.pwmReadFloat(channel)
216217

217-
def write(self, channel, value, data_type=None):
218+
def write(self, channel, value, value_type=None):
218219
write_functions = {'float': self.pwmWriteFloat, 'angle': self.pwmWriteAngle}
219-
write_function = write_functions.get(data_type, self.pwmWrite)
220+
write_function = write_functions.get(value_type, self.pwmWrite)
220221
return write_function(channel, value)
221222

222223
def writeFloat(self, channel, value):
@@ -291,5 +292,4 @@ def writeAngle(self, channel, value):
291292
DRIVERS["mcp4725"] = ["MCP4725"]
292293
DRIVERS["mcp48XX"] = ["MCP4802", "MCP4812", "MCP4822"]
293294
DRIVERS["mcp492X"] = ["MCP4921", "MCP4922"]
294-
DRIVERS["pca9685"] = ["PCA9685"]
295295
DRIVERS["pcf8591"] = ["PCF8591"]

myDevices/plugins/analog.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def __init__(self, plugin_id):
1414
Arguments:
1515
plugin_id: Plugin ID in the format 'plugin_name:section', e.g. 'cayenne-pca9685:PCA9685'
1616
"""
17-
InputOutput.__init__(self, plugin_id, 'analog', 'in')
17+
InputOutput.__init__(self, plugin_id, 'in', 'analog_sensor')
1818

1919
def read_float(self, channel):
2020
"""Read the float value on the specified channel."""
@@ -29,18 +29,17 @@ def read_angle(self, channel):
2929
return self.read_value(channel, 'angle')
3030

3131

32-
class AnalogIO(AnalogInput):
32+
class AnalogOutput(AnalogInput):
3333
"""Reads/writes data from an analog or PWM plugin input/output."""
3434

35-
def __init__(self, plugin_id, function):
35+
def __init__(self, plugin_id):
3636
"""Initializes the plugin input/output.
3737
3838
Arguments:
3939
plugin_id: Plugin ID in the format 'plugin_name:section', e.g. 'cayenne-pca9685:PCA9685'
40-
function: The pin function, 'in' if the pin is an input, 'out' if it is an output
41-
"""
42-
InputOutput.__init__(self, plugin_id, 'analog', function)
43-
40+
"""
41+
InputOutput.__init__(self, plugin_id, 'out', 'analog_actuator')
42+
4443
def write_float(self, value, channel):
4544
"""Write the float value on the specified channel."""
4645
return self.write_value(value, channel, 'float')
@@ -51,17 +50,4 @@ def write_volt(self, value, channel):
5150

5251
def write_angle(self, value, channel):
5352
"""Write the angle on the specified channel."""
54-
return self.write_value(value, channel, 'angle')
55-
56-
57-
class AnalogOutput(AnalogIO):
58-
"""Reads/writes data from an analog or PWM plugin input/output."""
59-
60-
def __init__(self, plugin_id):
61-
"""Initializes the plugin input/output.
62-
63-
Arguments:
64-
plugin_id: Plugin ID in the format 'plugin_name:section', e.g. 'cayenne-pca9685:PCA9685'
65-
"""
66-
AnalogIO.__init__(self, plugin_id, 'out')
67-
53+
return self.write_value(value, channel, 'angle')

myDevices/plugins/digital.py

Lines changed: 20 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,33 @@
11
"""
22
This module provides classes for interfacing with digital plugins.
33
"""
4-
from myDevices.plugins.manager import PluginManager
4+
from myDevices.plugins.io import InputOutput
55
from myDevices.utils.logger import info, debug, exception
66

77

8-
class DigitalIO():
9-
"""Reads data from an digital input/output."""
8+
class DigitalInput(InputOutput):
9+
"""Reads data from an digital input."""
1010

11-
def __init__(self, gpio, function):
12-
"""Initializes the digital input/output.
11+
def __init__(self, plugin_id):
12+
"""Initializes the plugin input.
1313
1414
Arguments:
15-
gpio: The GPIO plugin ID in the format 'plugin_name:section', e.g. 'cayenne-mcp23xxx:MCP'
16-
function: The pin function, 'in' if the pin is an input, 'out' if it is an output
17-
"""
18-
self.gpio_name = gpio
19-
self.gpio = None
20-
self.function = function.lower()
21-
self.current_functions = {}
22-
self.read_args = {}
23-
self.write_args = {}
24-
self.plugin_manager = PluginManager()
25-
self.set_gpio()
26-
27-
def set_gpio(self):
28-
"""Sets the GPIO plugin."""
29-
if not self.gpio:
30-
self.gpio = self.plugin_manager.get_plugin_by_id(self.gpio_name)
31-
self.read_args = self.plugin_manager.get_args(self.gpio, 'read_args')
32-
self.write_args = self.plugin_manager.get_args(self.gpio, 'write_args')
33-
34-
def set_function(self, channel):
35-
"""Sets the GPIO function."""
36-
if self.gpio and (channel not in self.current_functions or self.function != self.current_functions[channel]):
37-
function = getattr(self.gpio['instance'], self.gpio['set_function'])(channel, self.function).lower()
38-
self.current_functions[channel] = function
39-
if function == 'in':
40-
try:
41-
debug('Register callback for channel {}'.format(channel))
42-
getattr(self.gpio['instance'], self.gpio['register_callback'])(channel, self.data_changed, data=channel)
43-
except:
44-
debug('Unable to register callback for channel {}'.format(channel))
45-
pass
46-
47-
def to_tuple(self, value):
48-
"""Converts value to tuple with the appropriate data type."""
49-
data_type = 'digital_sensor'
50-
if (self.function == 'out'):
51-
data_type = 'digital_actuator'
52-
return (value, data_type)
53-
54-
def read_value(self, channel):
55-
"""Read the data value on the specified channel."""
56-
self.set_gpio()
57-
self.set_function(channel)
58-
try:
59-
value = getattr(self.gpio['instance'], self.gpio['read'])(channel, **self.read_args)
60-
value = int(value)
61-
except ValueError as e:
62-
debug(e)
63-
value = None
64-
return value
65-
66-
def read(self, channel):
67-
"""Gets the digital value for the channel as a tuple with the type."""
68-
return self.to_tuple(self.read_value(channel))
15+
plugin_id: Plugin ID in the format 'plugin_name:section', e.g. 'cayenne-pca9685:PCA9685'
16+
"""
17+
InputOutput.__init__(self, plugin_id, 'in', 'digital_sensor')
6918

70-
def write_value(self, value, channel):
71-
"""Write the data value on the specified channel."""
72-
self.set_gpio()
73-
self.set_function(channel)
74-
try:
75-
value = getattr(self.gpio['instance'], self.gpio['write'])(channel, int(value), **self.write_args)
76-
except ValueError as e:
77-
debug(e)
78-
value = None
79-
return value
19+
def value_to_tuple(self, value):
20+
"""Converts value to tuple with the appropriate Cayenne data type."""
21+
return (int(value), self.data_type)
8022

81-
def write(self, value, channel):
82-
"""Write the digital value for the channel."""
83-
return self.write_value(value, channel)
8423

85-
def register_callback(self, callback):
86-
"""Register a callback for data changes."""
87-
info('Registering callback: {}'.format(callback))
88-
self.callback = callback
24+
class DigitalOutput(DigitalInput):
25+
"""Reads and writes data from a digital output."""
8926

90-
def unregister_callback(self):
91-
"""Register a callback for data changes."""
92-
self.callback = None
93-
94-
def data_changed(self, channel, value):
95-
"""Callback that is called when data has changed."""
96-
if self.callback:
97-
self.callback(self.to_tuple(value))
27+
def __init__(self, plugin_id):
28+
"""Initializes the digital input/output.
29+
30+
Arguments:
31+
plugin_id: Plugin ID in the format 'plugin_name:section', e.g. 'cayenne-mcp23xxx:MCP'
32+
"""
33+
InputOutput.__init__(self, plugin_id, 'out', 'digital_actuator')

myDevices/plugins/io.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@
66

77

88
class InputOutput():
9-
"""Reads/writes data from a digital, analog or PWM input/output plugin."""
10-
DATA_TYPES = {'digital': {'in': 'digital_sensor', 'out':'digital_actuator'},
11-
'analog': {'in': 'analog_sensor', 'out': 'analog_actuator'}}
9+
"""Reads data from and writes data to an input/output plugin."""
1210

13-
def __init__(self, plugin_id, io_type, function):
14-
"""Initializes the analog input/output.
11+
def __init__(self, plugin_id, function, data_type):
12+
"""Initializes the input/output.
1513
1614
Arguments:
1715
plugin_id: Extension plugin ID in the format 'plugin_name:section', e.g. 'cayenne-pca9685:PCA9685'
18-
io_type: The type of IO, 'analog' or 'digital'
19-
function: The pin function, 'in' if the pin is an input, 'out' if it is an output
16+
function: The IO function, 'in' or 'out'
17+
data_type: The Cayenne data type, e.g. 'digital_sensor'
2018
"""
2119
self.plugin_id = plugin_id
2220
self.plugin = None
23-
self.io_type = io_type.lower()
21+
self.data_type = data_type.lower()
2422
self.function = function.lower()
2523
self.current_functions = {}
2624
self.read_args = {}
@@ -54,40 +52,42 @@ def set_function(self, channel):
5452
except:
5553
debug('Error setting function')
5654

57-
def to_tuple(self, value):
58-
"""Converts value to tuple with the appropriate data type."""
59-
try:
60-
return (value, InputOutput.DATA_TYPES[self.io_type][self.function])
61-
except:
62-
return value
55+
def value_to_tuple(self, value):
56+
"""Converts value to tuple with the appropriate Cayenne data type."""
57+
return (value, self.data_type)
6358

64-
def read(self, channel, data_type=None):
59+
def read(self, channel, value_type=None):
6560
"""Gets the data value for the channel as a tuple with the type."""
66-
return self.to_tuple(self.read_value(channel, data_type))
61+
return self.value_to_tuple(self.read_value(channel, value_type))
6762

68-
def read_value(self, channel, data_type=None):
63+
def read_value(self, channel, value_type=None):
6964
"""Read the data value on the specified channel."""
7065
self.set_plugin()
7166
self.set_function(channel)
7267
result = None
7368
try:
74-
result = getattr(self.plugin['instance'], self.plugin['read'])(channel, data_type=data_type, **self.read_args)
69+
read_args = self.read_args
70+
if value_type:
71+
read_args['value_type'] = value_type
72+
result = getattr(self.plugin['instance'], self.plugin['read'])(channel, **read_args)
7573
except:
76-
info('Error reading value from plugin {}, channel {}, {}'.format(self.plugin_id, channel, self.plugin))
74+
exception('Error reading value from plugin {}, channel {}, {}'.format(self.plugin_id, channel, self.plugin))
7775
return result
7876

79-
def write(self, value, channel, data_type=None):
77+
def write(self, value, channel, value_type=None):
8078
"""Write the digital value for the channel."""
81-
info('IO write, value {}, channel {}'.format(value, channel))
82-
return self.write_value(value, channel, data_type)
79+
return self.write_value(value, channel, value_type)
8380

84-
def write_value(self, value, channel, data_type=None):
81+
def write_value(self, value, channel, value_type=None):
8582
"""Write the data value on the specified channel."""
8683
self.set_plugin()
8784
self.set_function(channel)
8885
result = None
8986
try:
90-
result = getattr(self.plugin['instance'], self.plugin['write'])(channel, value, data_type=data_type, **self.write_args)
87+
write_args = self.write_args
88+
if value_type:
89+
write_args['value_type'] = value_type
90+
result = getattr(self.plugin['instance'], self.plugin['write'])(channel, value, **write_args)
9191
except ValueError as e:
9292
debug(e)
9393
return result
@@ -104,4 +104,4 @@ def unregister_callback(self):
104104
def data_changed(self, channel, value):
105105
"""Callback that is called when data has changed."""
106106
if self.callback:
107-
self.callback(self.to_tuple(value))
107+
self.callback(self.value_to_tuple(value))

0 commit comments

Comments
 (0)