Source code for wpilib.solenoid

# validated: 2017-12-12 EN f9bece2ffbf7 edu/wpi/first/wpilibj/Solenoid.java
#----------------------------------------------------------------------------
# Copyright (c) FIRST 2008-2012. All Rights Reserved.
# Open Source Software - may be modified and shared by FRC teams. The code
# must be accompanied by the FIRST BSD license file in the root directory of
# the project.
#----------------------------------------------------------------------------

import hal
import weakref
import warnings

from .livewindow import LiveWindow
from .resource import Resource
from .sensorbase import SensorBase
from .solenoidbase import SolenoidBase

__all__ = ["Solenoid"]

def _freeSolenoid(solenoidHandle):
    hal.freeSolenoidPort(solenoidHandle)

[docs]class Solenoid(SolenoidBase): """Solenoid class for running high voltage Digital Output. The Solenoid class is typically used for pneumatic solenoids, but could be used for any device within the current spec of the PCM. .. not_implemented: initSolenoid """ def __init__(self, *args, **kwargs): """Constructor. Arguments can be supplied as positional or keyword. Acceptable positional argument combinations are: - channel - moduleNumber, channel Alternatively, the above names can be used as keyword arguments. :param moduleNumber: The CAN ID of the PCM the solenoid is attached to :type moduleNumber: int :param channel: The channel on the PCM to control (0..7) :type channel: int """ # keyword arguments channel = kwargs.pop("channel", None) moduleNumber = kwargs.pop("moduleNumber", None) if kwargs: warnings.warn("unknown keyword arguments: %s" % kwargs.keys(), RuntimeWarning) # positional arguments if len(args) == 1: channel = args[0] elif len(args) == 2: moduleNumber, channel = args elif len(args) != 0: raise ValueError("don't know how to handle %d positional arguments" % len(args)) if moduleNumber is None: moduleNumber = SensorBase.getDefaultSolenoidModule() if channel is None: raise ValueError("must specify channel") super().__init__(moduleNumber) self.channel = channel SensorBase.checkSolenoidModule(moduleNumber) SensorBase.checkSolenoidChannel(channel) portHandle = hal.getPortWithModule(moduleNumber, channel) self._solenoidHandle = hal.initializeSolenoidPort(portHandle) hal.report(hal.UsageReporting.kResourceType_Solenoid, channel, moduleNumber) self.setName("Solenoid", self.moduleNumber, self.channel) self.__finalizer = weakref.finalize(self, _freeSolenoid, self._solenoidHandle) # Need this to free on unit test wpilib reset Resource._add_global_resource(self) @property def solenoidHandle(self): if not self.__finalizer.alive: raise ValueError("Cannot use channel after free() has been called") return self._solenoidHandle
[docs] def free(self): """Mark the solenoid as freed.""" super().free() self.__finalizer() self._solenoidHandle = None
[docs] def set(self, on): """Set the value of a solenoid. :param on: True will turn the solenoid output on. False will turn the solenoid output off. :type on: bool """ hal.setSolenoid(self.solenoidHandle, on)
[docs] def get(self): """Read the current value of the solenoid. :returns: True if the solenoid output is on or false if the solenoid output is off. :rtype: bool """ return hal.getSolenoid(self.solenoidHandle)
[docs] def isBlackListed(self): """ Check if the solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and disabled until power cycle, or until faults are cleared. See :meth:`.SolenoidBase.clearAllPCMStickyFaults` :returns: If solenoid is disabled due to short. """ value = self.getPCMSolenoidBlackList() & (1 << self.channel) return value != 0
[docs] def setPulseDuration(self, durationSeconds): """ Set the pulse duration in the PCM. This is used in conjunction with the startPulse method to allow the PCM to control the timing of a pulse. The timing can be controlled in 0.01 second increments. see :meth:`startPulse` :param durationSeconds: The duration of the pulse, from 0.01 to 2.55 seconds. """ duration_ms = int(durationSeconds * 1000) hal.setOneShotDuration(self.solenoidHandle, duration_ms)
[docs] def startPulse(self): """ Trigger the PCM to generate a pulse of the duration set in setPulseDuration. see :meth:`setPulseDuration` """ hal.fireOneShot(self.solenoidHandle)
[docs] def initSendable(self, builder): builder.setSmartDashboardType("Solenoid") builder.setSafeState(lambda: self.set(False)) builder.addBooleanProperty("Value", self.get, self.set)