Yet Another WebIOPi+
 All Classes Namespaces Files Functions Variables Macros Pages
__init__.py
Go to the documentation of this file.
1 # Copyright 2012-2013 Eric Ptak - trouch.com
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from webiopi.decorators.rest import request, response
16 from webiopi.utils.types import M_JSON
17 
18 class ADC():
19  def __init__(self, channelCount, resolution, vref):
20  self._analogCount = channelCount
21  self._analogResolution = resolution
22  self._analogMax = 2**resolution - 1
23  self._analogRef = vref
24 
25  def __family__(self):
26  return "ADC"
27 
28  def checkAnalogChannel(self, channel):
29  if not 0 <= channel < self._analogCount:
30  raise ValueError("Channel %d out of range [%d..%d]" % (channel, 0, self._analogCount-1))
31 
32  def checkAnalogValue(self, value):
33  if not 0 <= value <= self._analogMax:
34  raise ValueError("Value %d out of range [%d..%d]" % (value, 0, self._analogMax))
35 
36  @request("GET", "analog/count")
37  @response("%d")
38  def analogCount(self):
39  return self._analogCount
40 
41  @request("GET", "analog/resolution")
42  @response("%d")
43  def analogResolution(self):
44  return self._analogResolution
45 
46  @request("GET", "analog/max")
47  @response("%d")
48  def analogMaximum(self):
49  return int(self._analogMax)
50 
51  @request("GET", "analog/vref")
52  @response("%.2f")
53  def analogReference(self):
54  return self._analogRef
55 
56  def __analogRead__(self, channel, diff):
57  raise NotImplementedError
58 
59  @request("GET", "analog/%(channel)d/integer")
60  @response("%d")
61  def analogRead(self, channel, diff=False):
62  self.checkAnalogChannel(channel)
63  return self.__analogRead__(channel, diff)
64 
65  @request("GET", "analog/%(channel)d/float")
66  @response("%.2f")
67  def analogReadFloat(self, channel, diff=False):
68  return self.analogRead(channel, diff) / float(self._analogMax)
69 
70  @request("GET", "analog/%(channel)d/volt")
71  @response("%.2f")
72  def analogReadVolt(self, channel, diff=False):
73  if self._analogRef == 0:
74  raise NotImplementedError
75  return self.analogReadFloat(channel, diff) * self._analogRef
76 
77  @request("GET", "analog/*/integer")
78  @response(contentType=M_JSON)
79  def analogReadAll(self):
80  values = {}
81  for i in range(self._analogCount):
82  values[i] = self.analogRead(i)
83  return values
84 
85  @request("GET", "analog/*/float")
86  @response(contentType=M_JSON)
87  def analogReadAllFloat(self):
88  values = {}
89  for i in range(self._analogCount):
90  values[i] = float("%.2f" % self.analogReadFloat(i))
91  return values
92 
93  @request("GET", "analog/*/volt")
94  @response(contentType=M_JSON)
95  def analogReadAllVolt(self):
96  values = {}
97  for i in range(self._analogCount):
98  values[i] = float("%.2f" % self.analogReadVolt(i))
99  return values
100 
101 class DAC(ADC):
102  def __init__(self, channelCount, resolution, vref):
103  ADC.__init__(self, channelCount, resolution, vref)
104 
105  def __family__(self):
106  return "DAC"
107 
108  def __analogWrite__(self, channel, value):
109  raise NotImplementedError
110 
111  @request("POST", "analog/%(channel)d/integer/%(value)d")
112  @response("%d")
113  def analogWrite(self, channel, value):
114  self.checkAnalogChannel(channel)
115  self.checkAnalogValue(value)
116  self.__analogWrite__(channel, value)
117  return self.analogRead(channel)
118 
119  @request("POST", "analog/%(channel)d/float/%(value)f")
120  @response("%.2f")
121  def analogWriteFloat(self, channel, value):
122  self.analogWrite(channel, int(value * self._analogMax))
123  return self.analogReadFloat(channel)
124 
125  @request("POST", "analog/%(channel)d/volt/%(value)f")
126  @response("%.2f")
127  def analogWriteVolt(self, channel, value):
128  self.analogWriteFloat(channel, value /self._analogRef)
129  return self.analogReadVolt(channel)
130 
131 
132 class PWM():
133  def __init__(self, channelCount, resolution, frequency):
134  self._pwmCount = channelCount
135  self._pwmResolution = resolution
136  self._pwmMax = 2**resolution - 1
137  self.frequency = frequency
138  self.period = 1.0/frequency
139 
140  # Futaba servos standard
141  self.servo_neutral = 0.00152
142  self.servo_travel_time = 0.0004
143  self.servo_travel_angle = 45.0
144 
145  self.reverse = [False for i in range(channelCount)]
146 
147  def __family__(self):
148  return "PWM"
149 
150  def checkPWMChannel(self, channel):
151  if not 0 <= channel < self._pwmCount:
152  raise ValueError("Channel %d out of range [%d..%d]" % (channel, 0, self._pwmCount-1))
153 
154  def checkPWMValue(self, value):
155  if not 0 <= value <= self._pwmMax:
156  raise ValueError("Value %d out of range [%d..%d]" % (value, 0, self._pwmMax))
157 
158  def __pwmRead__(self, channel):
159  raise NotImplementedError
160 
161  def __pwmWrite__(self, channel, value):
162  raise NotImplementedError
163 
164  @request("GET", "pwm/count")
165  @response("%d")
166  def pwmCount(self):
167  return self._pwmCount
168 
169  @request("GET", "pwm/resolution")
170  @response("%d")
171  def pwmResolution(self):
172  return self._pwmResolution
173 
174  @request("GET", "pwm/max")
175  @response("%d")
176  def pwmMaximum(self):
177  return int(self._pwmMax)
178 
179  @request("GET", "pwm/%(channel)d/integer")
180  @response("%d")
181  def pwmRead(self, channel):
182  self.checkPWMChannel(channel)
183  return self.__pwmRead__(channel)
184 
185  @request("GET", "pwm/%(channel)d/float")
186  @response("%.2f")
187  def pwmReadFloat(self, channel):
188  return self.pwmRead(channel) / float(self._pwmMax)
189 
190  @request("POST", "pwm/%(channel)d/integer/%(value)d")
191  @response("%d")
192  def pwmWrite(self, channel, value):
193  self.checkPWMChannel(channel)
194  self.checkPWMValue(value)
195  self.__pwmWrite__(channel, value)
196  return self.pwmRead(channel)
197 
198  @request("POST", "pwm/%(channel)d/float/%(value)f")
199  @response("%.2f")
200  def pwmWriteFloat(self, channel, value):
201  self.pwmWrite(channel, int(value * self._pwmMax))
202  return self.pwmReadFloat(channel)
203 
204  def getReverse(self, channel):
205  self.checkChannel(channel)
206  return self.reverse[channel]
207 
208  def setReverse(self, channel, value):
209  self.checkChannel(channel)
210  self.reverse[channel] = value
211  return value
212 
213  def RatioToAngle(self, value):
214  f = value
215  f *= self.period
216  f -= self.servo_neutral
217  f *= self.servo_travel_angle
218  f /= self.servo_travel_time
219  return f
220 
221  def AngleToRatio(self, value):
222  f = value
223  f *= self.servo_travel_time
224  f /= self.servo_travel_angle
225  f += self.servo_neutral
226  f /= self.period
227  return f
228 
229  @request("GET", "pwm/%(channel)d/angle")
230  @response("%.2f")
231  def pwmReadAngle(self, channel):
232  f = self.pwmReadFloat(channel)
233  f = self.RatioToAngle(f)
234  if self.reverse[channel]:
235  f = -f
236  else:
237  f = f
238  return f
239 
240  @request("POST", "pwm/%(channel)d/angle/%(value)f")
241  @response("%.2f")
242  def pwmWriteAngle(self, channel, value):
243  if self.reverse[channel]:
244  f = -value
245  else:
246  f = value
247  f = self.AngleToRatio(f)
248  self.pwmWriteFloat(channel, f)
249  return self.pwmReadAngle(channel)
250 
251  @request("GET", "pwm/*")
252  @response(contentType=M_JSON)
253  def pwmWildcard(self):
254  values = {}
255  for i in range(self._pwmCount):
256  val = self.pwmReadFloat(i)
257  values[i] = {}
258  values[i]["float"] = float("%.2f" % val)
259  values[i]["angle"] = float("%.2f" % self.RatioToAngle(val))
260  return values
261 
262 DRIVERS = {}
263 DRIVERS["ads1x1x"] = ["ADS1014", "ADS1015", "ADS1114", "ADS1115"]
264 DRIVERS["mcp3x0x"] = ["MCP3002", "MCP3004", "MCP3008", "MCP3204", "MCP3208"]
265 DRIVERS["mcp4725"] = ["MCP4725"]
266 DRIVERS["mcp48XX"] = ["MCP4802", "MCP4812", "MCP4822"]
267 DRIVERS["mcp492X"] = ["MCP4921", "MCP4922"]
268 DRIVERS["pca9685"] = ["PCA9685"]
269 DRIVERS["pcf8591"] = ["PCF8591"]
270 DRIVERS["mcp3424"] = ["MCP3424"]
271 DRIVERS["advri2c"] = ["AD5161I", "AD5241", "AD5242", "AD5243", "AD5245", "AD5246", "AD5247", "AD5248", "AD5263I", "AD5280", "AD5282"]
272 DRIVERS["advrspi"] = ["AD5160", "AD5161S", "AD5162", "AD5165", "AD5200", "AD5201", "AD5204", "AD5206", "AD5263S", "AD5290", "AD8400", "AD8402", "AD8403"]
273 DRIVERS["advrspidc"] = ["AD5161DC", "AD5204DC", "AD5263DC", "AD5290DC", "AD8403DC"]
tuple response
Definition: coap-client.py:9