def __init__(self): self.setPinMapping() GPIOPort.__init__(self, max(self.pins) + 1) self.post_value = True self.post_function = True self.gpio_setup = [] self.gpio_reset = [] self.gpio_map = None self.pinFunctionSet = set() self.valueFile = {pin:None for pin in self.pins} self.functionFile = {pin:None for pin in self.pins} self.callbacks = {} self.edge_poll = select.epoll() thread = Thread(target=self.pollEdges, daemon=True) thread.start() for pin in self.pins: # Export the pins here to prevent a delay when accessing the values for the # first time while waiting for the file group to be set self.__checkFilesystemExport__(pin) if gpio_library: gpio_library.setmode(gpio_library.ASUS) elif not Hardware().isRaspberryPi3(): # On the Pi 3 the memory mapped /dev/gpiomem file seems to give strange, inconsistent readings, like duplicated # 4 byte sequences and "oipg" ASCII values. This might be some issue with the way Python mmap works since it didn't # seem to happen with the wiringPi C library using uint32_t pointers. For now we just avoid using /dev/gpiomem on Pi 3. try: with open('/dev/gpiomem', 'rb') as gpiomem: self.gpio_map = mmap.mmap(gpiomem.fileno(), BLOCK_SIZE, prot=mmap.PROT_READ) except FileNotFoundError: pass except OSError as err: error(err)
def getMessageBody(self, inviteCode): body = {'id': inviteCode} hardware = Hardware() if hardware.Serial and hardware.isRaspberryPi(): body['type'] = 'rpi' body['hardware_id'] = hardware.Serial else: hardware_id = hardware.getMac() if hardware_id: body['type'] = 'mac' body['hardware_id'] = hardware_id try: system_data = [] cayennemqtt.DataChannel.add(system_data, cayennemqtt.SYS_HARDWARE_MAKE, value=hardware.getManufacturer(), type='string', unit='utf8') cayennemqtt.DataChannel.add(system_data, cayennemqtt.SYS_HARDWARE_MODEL, value=hardware.getModel(), type='string', unit='utf8') system_info = SystemInfo() capacity_data = system_info.getMemoryInfo((cayennemqtt.CAPACITY, )) capacity_data += system_info.getDiskInfo((cayennemqtt.CAPACITY, )) for item in capacity_data: system_data.append(item) body['properties'] = {} body['properties']['pinmap'] = NativeGPIO().MAPPING if system_data: body['properties']['sysinfo'] = system_data except: exception('Error getting system info') return json.dumps(body)
def __init__(self, chip=0, mode=0, bits=8, speed=0, init=True): bus = 0 hardware = Hardware() if hardware.isTinkerBoard(): bus = 2 elif hardware.isBeagleBone(): bus = 1 Bus.__init__(self, "SPI", "/dev/spidev%d.%d" % (bus, chip)) self.chip = chip val8 = array.array('B', [0]) val8[0] = mode if fcntl.ioctl(self.fd, SPI_IOC_WR_MODE, val8): raise Exception("Cannot write SPI Mode") if fcntl.ioctl(self.fd, SPI_IOC_RD_MODE, val8): raise Exception("Cannot read SPI Mode") self.mode = struct.unpack('B', val8)[0] assert (self.mode == mode) val8[0] = bits if fcntl.ioctl(self.fd, SPI_IOC_WR_BITS_PER_WORD, val8): raise Exception("Cannot write SPI Bits per word") if fcntl.ioctl(self.fd, SPI_IOC_RD_BITS_PER_WORD, val8): raise Exception("Cannot read SPI Bits per word") self.bits = struct.unpack('B', val8)[0] assert (self.bits == bits) val32 = array.array('I', [0]) if speed > 0: val32[0] = speed if fcntl.ioctl(self.fd, SPI_IOC_WR_MAX_SPEED_HZ, val32): raise Exception("Cannot write SPI Max speed") if fcntl.ioctl(self.fd, SPI_IOC_RD_MAX_SPEED_HZ, val32): raise Exception("Cannot read SPI Max speed") self.speed = struct.unpack('I', val32)[0] assert ((self.speed == speed) or (speed == 0))
def __init__(self, slave, allow_duplicates=False): global SLAVES if SLAVES[slave] != None and not allow_duplicates: raise Exception("SLAVE_ADDRESS_USED") self.channel = 0 hardware = Hardware() if BOARD_REVISION > 1 or hardware.isTinkerBoard(): self.channel = 1 elif hardware.isBeagleBone(): self.channel = 2 Bus.__init__(self, "I2C", "/dev/i2c-%d" % self.channel) self.slave = slave if fcntl.ioctl(self.fd, I2C_SLAVE, self.slave): raise Exception("Error binding I2C slave 0x%02X" % self.slave) # Since we now allow duplicates, e.g. BMP180_TEMPERATURE & BMP180_PRESSURE, we might need to # change the SLAVES list to store a reference count or base class name as a way of making sure # only the same base sensor type is duplicated. That doesn't seem to be an issue currently though # so for now we just ignore the SLAVES check. if not allow_duplicates: SLAVES[self.slave] = self
def Start(self): """Connect to server and start background threads""" try: self.installDate = None try: self.installDate = self.config.get('Agent', 'InstallDate', fallback=None) except: pass if not self.installDate: self.installDate = int(time()) self.config.set('Agent', 'InstallDate', self.installDate) if not self.username and not self.password and not self.clientId: self.CheckSubscription() if not self.Connect(): error('Error starting agent') return self.schedulerEngine = SchedulerEngine(self, 'client_scheduler') self.readQueue = Queue() self.writeQueue = Queue() self.hardware = Hardware() self.oSInfo = OSInfo() self.count = 10000 self.buff = bytearray(self.count) self.writerThread = WriterThread('writer', self) self.writerThread.start() self.processorThread = ProcessorThread('processor', self) self.processorThread.start() self.systemInfo = [] TimerThread(self.SendSystemInfo, 300) self.sensorsClient = sensors.SensorsClient(self) self.sensorsClient.SetDataChanged(self.OnDataChanged) # TimerThread(self.SendSystemState, 30, 5) self.updater = Updater(self.config) self.updater.start() events = self.schedulerEngine.get_scheduled_events() self.EnqueuePacket(events, cayennemqtt.JOBS_TOPIC) # self.sentHistoryData = {} # self.historySendFails = 0 # self.historyThread = Thread(target=self.SendHistoryData) # self.historyThread.setDaemon(True) # self.historyThread.start() except Exception as e: exception('Initialize error: ' + str(e))
def __checkFilesystemValue__(self, channel): if not self.valueFile[channel]: #debug("value file %d not open" %channel) valRet = self.__checkFilesystemExport__(channel) if not valRet: return mode = 'w+' if (gpio_library or Hardware().isBeagleBone()) and os.geteuid() != 0: #On devices with root permissions on gpio files open the file in read mode from non-root process mode = 'r' for i in range(10): try: self.valueFile[channel] = open(self.__getValueFilePath__(channel), mode) break except PermissionError: # Try again since the file group might not have been set to the gpio group # since there is a delay when the gpio channel is first exported sleep(0.01)
def ExecuteConfigCommand(config_id, parameters=''): """Execute specified command to modify configuration Args: config_id: Id of command to run parameters: Parameters to use when executing command """ if not Hardware().isRaspberryPi(): return (1, 'Not supported') debug('SystemConfig::ExecuteConfigCommand') if config_id == 0: return SystemConfig.ExpandRootfs() command = "sudo " + CUSTOM_CONFIG_SCRIPT + " " + str( config_id) + " " + str(parameters) (output, returnCode) = executeCommand(command) debug('ExecuteConfigCommand ' + str(config_id) + ' args: ' + str(parameters) + ' retCode: ' + str(returnCode) + ' output: ' + output) if "reboot required" in output: ThreadPool.Submit(SystemConfig.RestartDevice) return (returnCode, output)
def getConfig(): """Return dict containing configuration settings""" config = {} if not Hardware().isRaspberryPi(): return config commands = { 10: 'DeviceTree', 18: 'Serial', 20: 'OneWire', 21: 'I2C', 22: 'SPI' } for command, name in commands.items(): try: (returnCode, output) = SystemConfig.ExecuteConfigCommand(command) if output: config[name] = 1 - int( output.strip() ) #Invert the value since the config script uses 0 for enable and 1 for disable except: exception('Get config') debug('SystemConfig: {}'.format(config)) return config
class HarwareTest(unittest.TestCase): def setUp(self): setInfo() self.hardware = Hardware() def testGetManufacturer(self): manufacturer = self.hardware.getManufacturer() info(manufacturer) self.assertNotEqual(manufacturer, '') def testGetModel(self): model = self.hardware.getModel() info(model) self.assertNotEqual(model, 'Unknown') def testGetMac(self): mac = self.hardware.getMac() info(mac) self.assertRegex(mac, '^([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2})$') def testBoardRevision(self): info(BOARD_REVISION) self.assertGreaterEqual(BOARD_REVISION, 0) self.assertLessEqual(BOARD_REVISION, 3) def testCpuRevision(self): info(CPU_REVISION) self.assertNotEqual(CPU_REVISION, '0') def testCpuHardware(self): info(CPU_HARDWARE) self.assertNotEqual(CPU_HARDWARE, '') def testDeviceVerification(self): device_checks = (self.hardware.isRaspberryPi(), self.hardware.isTinkerBoard(), self.hardware.isBeagleBone()) self.assertEqual(device_checks.count(True), 1)
) os.chmod('/etc/myDevices/scripts/config.sh', 0o0755) # Add conf file to create /var/run/myDevices at boot with open('/usr/lib/tmpfiles.d/cayenne.conf', 'w') as tmpfile: tmpfile.write('d /run/myDevices 0744 {0} {0} -\n'.format(username)) relogin = False # Add user to the i2c group if it isn't already a member user_groups = [g.gr_name for g in grp.getgrall() if username in g.gr_mem] if not 'i2c' in user_groups: os.system('adduser {} i2c'.format(username)) relogin = True if Hardware().isTinkerBoard(): # Add spi group if it doesn't exist all_groups = [g.gr_name for g in grp.getgrall()] if not 'spi' in all_groups: os.system('groupadd -f -f spi') os.system('adduser {} spi'.format(username)) with open('/etc/udev/rules.d/99-com.rules', 'w') as spirules: spirules.write('SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"\n') os.system('udevadm control --reload-rules && udevadm trigger') relogin = True # Install GPIO library if it doesn't exist try: import ASUS.GPIO except: current_dir = os.getcwd() try:
def setUp(self): setInfo() self.hardware = Hardware()
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import time import subprocess from myDevices.utils.logger import debug, info from myDevices.system.version import OS_VERSION, OS_JESSIE, OS_WHEEZY from myDevices.system.hardware import Hardware hardware = Hardware() if hardware.isTinkerBoard(): # Tinker Board only supports I2C and SPI for now. These are enabled by default and # don't need to load any modules. BUSLIST = { "I2C": { "enabled": True, }, "SPI": { "enabled": True, } } elif hardware.isBeagleBone(): BUSLIST = { "I2C": {
def setPinMapping(self): hardware = Hardware() if hardware.isTinkerBoard(): self.MAPPING = [{ 'name': 'GPIO', 'map': [{ 'power': 'V33' }, { 'power': 'V50' }, { 'gpio': 252 }, { 'power': 'V50' }, { 'gpio': 253 }, { 'power': 'GND' }, { 'gpio': 17 }, { 'gpio': 161 }, { 'power': 'GND' }, { 'gpio': 160 }, { 'gpio': 164 }, { 'gpio': 184 }, { 'gpio': 166 }, { 'power': 'GND' }, { 'gpio': 167 }, { 'gpio': 162 }, { 'power': 'V33' }, { 'gpio': 163 }, { 'gpio': 257 }, { 'power': 'GND' }, { 'gpio': 256 }, { 'gpio': 171 }, { 'gpio': 254 }, { 'gpio': 255 }, { 'power': 'GND' }, { 'gpio': 251 }, { 'dnc': True }, { 'dnc': True }, { 'gpio': 165 }, { 'power': 'GND' }, { 'gpio': 168 }, { 'gpio': 239 }, { 'gpio': 238 }, { 'power': 'GND' }, { 'gpio': 185 }, { 'gpio': 223 }, { 'gpio': 224 }, { 'gpio': 187 }, { 'power': 'GND' }, { 'gpio': 188 }] }] elif hardware.isBeagleBone(): self.MAPPING = [{ 'name': 'P9', 'map': [{ 'power': 'GND' }, { 'power': 'GND' }, { 'power': 'V33' }, { 'power': 'V33' }, { 'power': 'V50' }, { 'power': 'V50' }, { 'power': 'V50' }, { 'power': 'V50' }, { 'power': 'PWR' }, { 'power': 'RST' }, { 'gpio': 30 }, { 'gpio': 60 }, { 'gpio': 31 }, { 'gpio': 50 }, { 'gpio': 48 }, { 'gpio': 51 }, { 'gpio': 5 }, { 'gpio': 4 }, { 'alt0': { 'channel': 'sys:i2c:2', 'name': 'SCL' } }, { 'alt0': { 'channel': 'sys:i2c:2', 'name': 'SDA' } }, { 'gpio': 3 }, { 'gpio': 2 }, { 'gpio': 49 }, { 'gpio': 15 }, { 'gpio': 117 }, { 'gpio': 14 }, { 'gpio': 115 }, { 'gpio': 113, 'alt0': { 'channel': 'sys:spi:1', 'name': 'CS0' } }, { 'gpio': 111, 'alt0': { 'channel': 'sys:spi:1', 'name': 'D0' } }, { 'gpio': 112, 'alt0': { 'channel': 'sys:spi:1', 'name': 'D1' } }, { 'gpio': 110, 'alt0': { 'channel': 'sys:spi:1', 'name': 'SCLK' } }, { 'power': 'VDD_ADC' }, { 'analog': 4 }, { 'power': 'GNDA_ADC' }, { 'analog': 6 }, { 'analog': 5 }, { 'analog': 2 }, { 'analog': 3 }, { 'analog': 0 }, { 'analog': 1 }, { 'gpio': 20 }, { 'gpio': 7 }, { 'power': 'GND' }, { 'power': 'GND' }, { 'power': 'GND' }, { 'power': 'GND' }] }, { 'name': 'P8', 'map': [{ 'power': 'GND' }, { 'power': 'GND' }, { 'gpio': 38 }, { 'gpio': 39 }, { 'gpio': 34 }, { 'gpio': 35 }, { 'gpio': 66 }, { 'gpio': 67 }, { 'gpio': 69 }, { 'gpio': 68 }, { 'gpio': 45 }, { 'gpio': 44 }, { 'gpio': 23 }, { 'gpio': 26 }, { 'gpio': 47 }, { 'gpio': 46 }, { 'gpio': 27 }, { 'gpio': 65 }, { 'gpio': 22 }, { 'gpio': 63 }, { 'gpio': 62 }, { 'gpio': 37 }, { 'gpio': 36 }, { 'gpio': 33 }, { 'gpio': 32 }, { 'gpio': 61 }, { 'gpio': 86 }, { 'gpio': 88 }, { 'gpio': 87 }, { 'gpio': 89 }, { 'gpio': 10 }, { 'gpio': 11 }, { 'gpio': 9 }, { 'gpio': 81 }, { 'gpio': 8 }, { 'gpio': 80 }, { 'gpio': 78 }, { 'gpio': 79 }, { 'gpio': 76 }, { 'gpio': 77 }, { 'gpio': 74 }, { 'gpio': 75 }, { 'gpio': 72 }, { 'gpio': 73 }, { 'gpio': 70 }, { 'gpio': 71 }] }] else: if BOARD_REVISION == 1: self.MAPPING = [{ 'name': 'P1', 'map': [{ 'power': 'V33' }, { 'power': 'V50' }, { 'gpio': 0, 'alt0': { 'channel': 'sys:i2c', 'name': 'SDA' } }, { 'power': 'V50' }, { 'gpio': 1, 'alt0': { 'channel': 'sys:i2c', 'name': 'SCL' } }, { 'power': 'GND' }, { 'gpio': 4, 'overlay': { 'channel': 'sys:1wire', 'name': 'DATA' } }, { 'gpio': 14, 'alt0': { 'channel': 'sys:uart', 'name': 'TX' } }, { 'power': 'GND' }, { 'gpio': 15, 'alt0': { 'channel': 'sys:uart', 'name': 'RX' } }, { 'gpio': 17 }, { 'gpio': 18 }, { 'gpio': 21 }, { 'power': 'GND' }, { 'gpio': 22 }, { 'gpio': 23 }, { 'power': 'V33' }, { 'gpio': 24 }, { 'gpio': 10, 'alt0': { 'channel': 'sys:spi', 'name': 'MOSI' } }, { 'power': 'GND' }, { 'gpio': 9, 'alt0': { 'channel': 'sys:spi', 'name': 'MISO' } }, { 'gpio': 25 }, { 'gpio': 11, 'alt0': { 'channel': 'sys:spi', 'name': 'SCLK' } }, { 'gpio': 8, 'alt0': { 'channel': 'sys:spi', 'name': 'CE0' } }, { 'power': 'GND' }, { 'gpio': 7, 'alt0': { 'channel': 'sys:spi', 'name': 'CE1' } }] }] elif BOARD_REVISION == 2: self.MAPPING = [{ 'name': 'P1', 'map': [{ 'power': 'V33' }, { 'power': 'V50' }, { 'gpio': 2, 'alt0': { 'channel': 'sys:i2c', 'name': 'SDA' } }, { 'power': 'V50' }, { 'gpio': 3, 'alt0': { 'channel': 'sys:i2c', 'name': 'SCL' } }, { 'power': 'GND' }, { 'gpio': 4, 'overlay': { 'channel': 'sys:1wire', 'name': 'DATA' } }, { 'gpio': 14, 'alt0': { 'channel': 'sys:uart', 'name': 'TX' } }, { 'power': 'GND' }, { 'gpio': 15, 'alt0': { 'channel': 'sys:uart', 'name': 'RX' } }, { 'gpio': 17 }, { 'gpio': 18 }, { 'gpio': 27 }, { 'power': 'GND' }, { 'gpio': 22 }, { 'gpio': 23 }, { 'power': 'V33' }, { 'gpio': 24 }, { 'gpio': 10, 'alt0': { 'channel': 'sys:spi', 'name': 'MOSI' } }, { 'power': 'GND' }, { 'gpio': 9, 'alt0': { 'channel': 'sys:spi', 'name': 'MISO' } }, { 'gpio': 25 }, { 'gpio': 11, 'alt0': { 'channel': 'sys:spi', 'name': 'SCLK' } }, { 'gpio': 8, 'alt0': { 'channel': 'sys:spi', 'name': 'CE0' } }, { 'power': 'GND' }, { 'gpio': 7, 'alt0': { 'channel': 'sys:spi', 'name': 'CE1' } }] }] elif BOARD_REVISION == 3: self.MAPPING = [{ 'name': 'P1', 'map': [{ 'power': 'V33' }, { 'power': 'V50' }, { 'gpio': 2, 'alt0': { 'channel': 'sys:i2c', 'name': 'SDA' } }, { 'power': 'V50' }, { 'gpio': 3, 'alt0': { 'channel': 'sys:i2c', 'name': 'SCL' } }, { 'power': 'GND' }, { 'gpio': 4, 'overlay': { 'channel': 'sys:1wire', 'name': 'DATA' } }, { 'gpio': 14, 'alt0': { 'channel': 'sys:uart', 'name': 'TX' } }, { 'power': 'GND' }, { 'gpio': 15, 'alt0': { 'channel': 'sys:uart', 'name': 'RX' } }, { 'gpio': 17 }, { 'gpio': 18 }, { 'gpio': 27 }, { 'power': 'GND' }, { 'gpio': 22 }, { 'gpio': 23 }, { 'power': 'V33' }, { 'gpio': 24 }, { 'gpio': 10, 'alt0': { 'channel': 'sys:spi', 'name': 'MOSI' } }, { 'power': 'GND' }, { 'gpio': 9, 'alt0': { 'channel': 'sys:spi', 'name': 'MISO' } }, { 'gpio': 25 }, { 'gpio': 11, 'alt0': { 'channel': 'sys:spi', 'name': 'SCLK' } }, { 'gpio': 8, 'alt0': { 'channel': 'sys:spi', 'name': 'CE0' } }, { 'power': 'GND' }, { 'gpio': 7, 'alt0': { 'channel': 'sys:spi', 'name': 'CE1' } }, { 'dnc': True }, { 'dnc': True }, { 'gpio': 5 }, { 'power': 'GND' }, { 'gpio': 6 }, { 'gpio': 12 }, { 'gpio': 13 }, { 'power': 'GND' }, { 'gpio': 19 }, { 'gpio': 16 }, { 'gpio': 26 }, { 'gpio': 20 }, { 'power': 'GND' }, { 'gpio': 21 }] }] if isinstance(self.MAPPING, list): self.pins = [] self.overlay_pins = [] self.spi_pins = [] self.i2c_pins = [] self.system_config = SystemConfig.getConfig() for header in self.MAPPING: self.pins.extend( [pin['gpio'] for pin in header['map'] if 'gpio' in pin]) try: if Hardware().isRaspberryPi(): if self.system_config['OneWire'] == 1: self.overlay_pins.extend([ pin['gpio'] for pin in header['map'] if 'overlay' in pin and pin['overlay']['channel'] == 'sys:1wire' ]) self.pins = [ pin for pin in self.pins if pin not in self.overlay_pins ] self.spi_pins.extend([ pin['gpio'] for pin in header['map'] if 'alt0' in pin and pin['alt0']['channel'] == 'sys:spi' ]) self.i2c_pins.extend([ pin['gpio'] for pin in header['map'] if 'alt0' in pin and pin['alt0']['channel'] == 'sys:i2c' ]) except: pass