class MainChassis(): def __init__(self): """ Handles initilizing the initilal state of the MMS, including connecting to the database as well as detecting the connected sensors :return: an object representing the MMS unit :rtype: MainChassis """ self.isConnected = dict() self.sensors = dict() self.events = dict() self.connectedAddresses = dict() self._parseUnitInfo() self._configurationSensors = dict() self._setupDB() self._setupPins() self._initPeripherals() def _setupDB(self): """ Connects to the database by adding a reference to a database object (which connects to both MySQL + MongoDB) :return: None :rtype: None """ self._internalDB = Database(self.serialNumber) def _parseUnitInfo(self): """ Gathers meta data about the unit from a txt file stored in the device :return: None :rtype: None """ with open('unitinfo.txt') as f: lines = f.readlines() self.serialNumber = lines[0].split(':')[1] f.close() def _setupPins(self): """ Configures all the GPIO pins used in MMS to be GPIO :return: None :rtype: """ # set pins to GPIO.OUT and High for pin in POWER_PINS.values(): GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.HIGH) # set Connected_pins as inputs for pin in CONNECTED_PINS.values(): GPIO.setup(pin, GPIO.IN) #Detects if a peripheral is connected to a port or not def _detectPeripherals(self): """ Uses the detect pin on each channel to determine if a peripheral is currently connected on that channel :return: None :rtype: None """ for channelNumber,pin in CONNECTED_PINS.items(): print('Channel ' + str(channelNumber) + ' is :') print(GPIO.input(pin)) if GPIO.input(pin): # identify the p self.isConnected[channelNumber]= True else: self.isConnected[channelNumber]= False print('connected status is :') print(self.isConnected) #return the number of peripherals connected def _initPeripherals(self): """ initialzes the init state of all channels on the unit :return: None :rtype: None """ self._detectPeripherals() self._initSensors() def _initSensors(self): """ Sequentially reads all connected channels by turning off all byquad channels, turning on channel i and sensing the detected id on the I2C bus. It then creates an object and stores it at the channel # :return: None :rtype: None """ for channelNumber,valid in self.isConnected.items(): if(valid): self._powerOffAllChannels() self._powerChannel(channelNumber) addreses = self._detectI2CBus() if(len(addreses) == 0): print('no perihperals seem to be connected to this MMS') break address = addreses[0] #should only be one address in this case sensor = self._getSensorType(address,channelNumber) self.connectedAddresses[channelNumber] = address if(sensor is not None): self.sensors[channelNumber] = sensor self._powerOnAllChannels() print(self.sensors) def addNewPeripherals(self): """ Detects if the channel status has been changed sense last read :return: :rtype: """ changedStatus = False for channelNumber,pin in CONNECTED_PINS.items(): connected = GPIO.input(pin) if(connected): if(not self.isConnected[channelNumber]): print('new peripheral has been detect to be connected by channelNumber ' + str(channelNumber)) self.isConnected[channelNumber] = True changedStatus = True else: if(self.isConnected[channelNumber]): print('new peripheral has been detect to be connected by channelNumber ' + str(channelNumber)) self.isConnected[channelNumber] = False changedStatus = True if(changedStatus): self._initSensors() self.updateSensorMetaData() self.events = dict() self.checkForRecordings() self.checkForEvents() else: print('no peripheral status change') def _hardcodeInitPeripherals(self): self._detectPeripherals() for channelNumber,valid in self.isConnected.items(): if(valid): sensor = TemperatureSensor(0x41,channelNumber) self.connectedAddresses[channelNumber] = 0x41 if(sensor is not None): self.sensors[channelNumber] = sensor def _countPeripherals(self): return sum(self.isConnected.values()) def _getSensorType(self,address,channelNumber): #TODO: Can we pull the contructor info directly off the cloud so we dont have to code this??? sensorName = self._internalDB.getAddressConstructorType(address) print('For the address of ' + str(address) + ' I will use the sensor name' + sensorName) ''' print('hardcoded the sensor -channels') if(channelNumber == 0): sensorName = 'Temperature Sensor V1.01' address = 0x48 elif(channelNumber == 1): sensorName = 'Photo Sensor V1.01' address = 0x23 elif(channelNumber == 2): sensorName = 'Analog Sensor V1.01' address = 0x49 ''' if(sensorName == 'Temperature Sensor V1.01'): return TemperatureSensor(address,channelNumber) elif(sensorName == 'Photo Sensor V1.01'): return PhotoSensor(address,channelNumber) elif(sensorName == 'Analog Sensor V1.01'): return AnalogSensor(address,channelNumber) elif(sensorName == 'AC Relay Control V1.01'): return Relay(address,channelNumber) else: print('invalid sensor name') return None def _powerOffAllChannels(self): for channelNumber, powerPin in POWER_PINS.items(): GPIO.output(powerPin,GPIO.LOW) def _powerChannel(self,channelNumber): GPIO.output(POWER_PINS[channelNumber],GPIO.HIGH) def _powerOnAllChannels(self): for channelNumber, powerPin in POWER_PINS.items(): GPIO.output(powerPin,GPIO.HIGH) def _detectI2CBus(self): returnInt,resultString = commands.getstatusoutput('i2cdetect -y -r 2') foundAddresses = [] print(resultString) lines = resultString.split('\n')[1:] #remove row header for l in lines: l = l.strip() #remove white space on ends spots = l.split(' ')[1:] #remove column header for s in spots: s = s.strip() if(s != 'UU' and s != '--' and s != ''): foundAddresses.append(literal_eval('0x' + s)) return foundAddresses def read(self,channelNumber): if(not self.isConnected[channelNumber]): print('invalid...channel is not connected..returning none') return None return self.sensors[channelNumber].getData() def writeRawDict(self,collectionKey,jsonDocument): self._internalDB._insert(collectionKey,jsonDocument) def getSensorData(self): sensorData = [] for channelNumber,sensorObj in self.sensors.items(): if(self.isConnected[channelNumber]): sensorData.append(sensorObj.getData()) return sensorData def getAndPushSensorData(self): sensorCommands = self._internalDB.getSensorCommands() for channelNumber,sensorObj in self.sensors.items(): if(self.isConnected[channelNumber]): #print('pushing data ;)') data = sensorObj.getData() if(sensorObj.hasRecording): recorder = sensorObj.recorder if(not recorder.isComplete()): #push data to recorder #print('recorder handling data') recorder.handleData(data) else: #end recorder recorder.stopRecorder() sensorObj.setRecorder(None) self._internalDB.updateData(data,channelNumber) if(sensorObj.InputAndOutputControl): print('commands for output sensor received...sending') sensorObj.handleCommands(sensorCommands[channelNumber]) #self._internalDB.pushData(self.getSensorData()) def testForNewDevices(self): addresses = self._detectI2CBus() currentAddresses = self.connectedAddresses.values() for address in addresses: if(address not in currentAddresses): print('found new address.....need to implement detection method') def updateSensorMetaData(self): sensorInfo = [] print('updating sensor meta data') for channelNumber,status in self.isConnected.items(): if(self.isConnected[channelNumber]): #print(self.sensors) sensorObj = self.sensors[channelNumber] metaData = sensorObj.getMetaDataInfo() #print(metaData) self._internalDB.updateSensorMetaData(metaData,channelNumber) else: print('updating null sensor data') d = {'sensorName':"","signals":"", 'sensorReadingType':"", 'plotType':"",'lastSyncTime':""} self._internalDB.unsetSensorMetaData(d,channelNumber) #self._internalDB.updateSensorMetaData(sensorInfo) def checkForRecordings(self): print('checking for recordings.....') recordings = self._internalDB.checkForRecordings() print(recordings) if(recordings is not None): for channelNumber,recorder in recordings.items(): if(self.isConnected[channelNumber]): if(not self.sensors[channelNumber].hasRecording): self.sensors[channelNumber].setRecorder(recorder) else: print('Recording of id ' + str(recorder.recordingId) + ' was not set because sensor already has a recording of id ' + str(self.sensors[channelNumber].recorder.recordingId)) def checkForEvents(self): print('checking for events') events = self._internalDB.checkForEvents() if(events is not None): for struct in events: if struct['eventID'] not in self.events: #add the event #elf,inputSensor,inputType,outputSensor,outputType,conditionalString,threshold,id): try: e = EventTrigger(self.sensors[struct['inputSensorChannel']],struct['inputType'], self.sensors[struct['outputSensorChannel']],struct['outputType'], struct['conditionalString'],float(struct['threshold']),struct['eventID'],self._internalDB) self.events[e.id] = e except KeyError: print('One of the input or output channel select in the event is not connected...please try again') print(self.events) def handleEvents(self): for eventID,event in self.events.items(): event.handleEvent()
class MainChassis(): def __init__(self): self.isConnected = dict() self.sensors = dict() self._configurationSensors = dict() self._setupPins() self._initPeripherals() self._setupDB() def _setupDB(self): #TODO: populate unitInfo kwargs unitInfo = dict() self._internalDB = Database(**unitInfo) def _setupPins(self): # set pins to GPIO.OUT and High for pin in POWER_PINS.values(): GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.HIGH) # set Connected_pins as inputs for pin in CONNECTED_PINS.values(): GPIO.setup(pin, GPIO.IN) #Detects if a peripheral is connected to a port or not def _detectPeripherals(self): for channelNumber,pin in CONNECTED_PINS.items(): if GPIO.input(pin): # identify the p self.isConnected[channelNumber]= True else: self.isConnected[channelNumber]= False #return the number of peripherals connected def _initPeripherals(self): self._detectPeripherals() for channelNumber,valid in self.isConnected.items(): if(valid): self._powerOffAllChannels() self._powerChannel(channelNumber) addreses = self._detectI2CBus() address = addreses[0] #should only be one address in this case self.sensors[channelNumber] = self._getSensorType(address,channelNumber) def _countPeripherals(self): return sum(self.isConnected.values()) def _getSensorType(self,address,channelNumber): #TODO: actually pull what type of sensor this #for now lets just assume a thermocouple return TemperatureSensor(address,channelNumber) def _powerOffAllChannels(self): for channelNumber, powerPin in POWER_PINS.items(): GPIO.output(powerPin,GPIO.LOW) def _powerChannel(self,channelNumber): GPIO.output(POWER_PINS[channelNumber],GPIO.HIGH) def _powerOnAllChannels(self): for channelNumber, powerPin in POWER_PINS.items(): GPIO.output(powerPin,GPIO.HIGH) def _detectI2CBus(self): #TODO: implement way to detect I2C bus, parse output and return an array of detected addresses ''' resultString = commands.getstatusoutput('i2cdetect -i 1 -l') foundAddresses = [] lines = resultString.split('\n')[1:] #remove row header for l in lines: l = l.strip() #remove white space on ends spots = l.split(' ')[1:] #remove column header for s in spots: s = s.strip() if(s != 'UU' and s != '--' and s != ''): foundAddresses.append(literal_eval('0x' + s)) print(foundAddresses) return foundAddresses ''' return [0x48] def read(self,channelNumber): if(not self.isConnected[channelNumber]): print('invalid...channel is not connected..returning none') return None return self.sensors[channelNumber].getData() def writeRawDict(self,collectionKey,jsonDocument): self._internalDB._insert(collectionKey,jsonDocument) def getSensorData(self): sensorData = [] for channelNumber,sensorObj in self.sensors.items(): if(self.isConnected[channelNumber]): sensorData.append(sensorObj.getData()) return sensorData def getAndPushSensorData(self): for channelNumber,sensorObj in self.sensors.items(): if(self.isConnected[channelNumber]): print('pushing data ;)') self._internalDB.updateData(sensorObj.getData(),channelNumber) #self._internalDB.pushData(self.getSensorData()) def updateSensorMetaData(self): sensorInfo = [] for channelNumber,sensorObj in self.sensors.items(): if(self.isConnected[channelNumber]): print('pushing meta data') self._internalDB.updateSensorMetaData(sensorObj.getMetaDataInfo(),channelNumber) #self._internalDB.updateSensorMetaData(sensorInfo)