Open reszelaz opened 6 years ago
Hi Zibi! I'd absolutely accept this PR. Yet, I have a task to add support for all GPIO pins. Maybe I can have it done within two weeks, I'll let you know.
Best, /J
Do you think that the pin numbers are fine? If we agree on these we could already prepare the cabling in our setup.
Hi Zibi! Yes, those numbers will work and are in the correct order. I will push by the end of today. Best, Jens
Hi Zibi! In new commit: added support for 10 pins (3,5,7,8,10,11,12,13,15,16) removed socket timeout from tcp server removed hardcoded attribute polling for now, removed change event subscription and pushing
I have not had time to look at the tcp server causing the ~50ms overhead yet. I did the changes quickly so please review the code before using. :) All the best,/J
Hi,
Maybe you can consider setting the available pins through a tango property and then create pin attribute dynamically.
Dynamic attributes are created through initialize_dynamic_attributes
function. This function is call after the init_device
method.
Here a small example (not tested):
pins = device_property(dtype=(int,))
def initialize_dynamic_attributes(self):
for pin_number in self.pins:
# Create attribute name
voltage_attrname = "pin{}_voltage".format(pin_number)
output_attrname = "pin{}_output".format(pin_number)
# Get tango type
tango_type = tango.CmdArgType.DevBoolean
# Create attributes
voltage_attr = tango.Attr(voltage_attrname,
tango_type, tango.READ_WRITE)
output_attr = tango.Attr(output_attrname,
tango_type, tango.READ_WRITE)
# Add attribute and setup read/write/allowed method
self.add_attribute(
voltage_attr,
r_meth=self.read_pin_voltage,
w_meth=self.write_pin_voltage,
is_allo_meth=self.is_voltage_allowed)
self.add_attribute(
output_attr,
r_meth=self.read_pin_output,
w_meth=self.write_pin_output,
is_allo_meth=self.is_output_allowed)
# If event needed, setup change event
self.set_change_event(voltage_attrname, True, True)
self.set_change_event(output_attrname, True, True)
# Voltage
@catch_connection_error
def read_pin_voltage(self, attr):
attr_name = attr.get_name()
pin_number = int(filter(str.isdigit, attr_name))
value = self.raspberry.readvoltage(pin_number)
setattr(self, "__pin{}_voltage".format(pin_number), value)
attr.set_value(value)
@catch_connection_error
def write_pin_voltage(self, attr):
w_value = attr.get_write_value()
attr_name = attr.get_name()
pin_number = int(filter(str.isdigit, attr_name))
python_attr = "__pin_{}_voltage".format(pin_number)
self.set_voltage(w_value, pin_number, getattr(self, python_attr))
setattr(self, "_{}".format(attr_name), w_value)
# Ouptut
@catch_connection_error
def read_pin_output(self, attr):
attr_name = attr.get_name()
pin_number = int(filter(str.isdigit, attr_name))
value = self.raspberry.readoutput(pin_number)
setattr(self, "__pin{}_output".format(pin_number), value)
attr.set_value(value)
@catch_connection_error
def write_pin_output(self, attr):
w_value = attr.get_write_value()
attr_name = attr.get_name()
pin_number = int(filter(str.isdigit, attr_name))
self.raspberry.setoutput(pin_number, w_value)
You can notice that the write methods are slightly different. As attributes are created dynamically, you can not profit of the PyTango hight level API wrapping and you have to set yourself the attribute value (same to get the write value).
Cheers, /Antoine
Sounds good to me! For the moment we will try the recently added pins attributes which fulfills with our requirements. So do not rush with this refactoring just for us. Thanks a lot guys!
Thanks Antoine! The dynamic pin attributes is a great idea. I also realized that I can refactor the TCP IP server, adding an argument with argparse to flag wheter to start the HTTP server for the camera frame or not. In this case you’ll only add camera support to the server when needed.
First of all many thanks for sharing this project! It will be very usefull for our needs (timed control of the pneumatic valves).
I was going to implement 5 more I/O pins. I was thinking about pins: 11, 12, 13, 15 and 16. Would you accept such PR?