def CreateTable(tablename, columns, required_columns=None): try: with mutex: if not cursor or not connection: return False if required_columns and len(required_columns): cursor.execute('PRAGMA table_info(' + tablename + ')') actual_columns = [ column[1] for column in cursor.fetchall() ] if actual_columns != required_columns: try: if actual_columns: warn( tablename + ' table columns {} do not match required columns {}, dropping table' .format(actual_columns, required_columns) + " From: " + str(hex(id(connection))) + " " + str(hex(id(cursor)))) cursor.execute('DROP TABLE ' + tablename) connection.commit() except: pass del actual_columns cursor.execute('CREATE TABLE IF NOT EXISTS ' + tablename + ' (' + str(columns) + ')') connection.commit() # sleep(5) except Exception as ex: error("Failed to CreateTable: " + tablename + " " + str(ex)) return False return True
def __init__(self, client): """Initialize the bus and sensor info and start monitoring sensor states""" self.cloudClient = client self.sensorMutex = RLock() self.realTimeMutex = RLock() self.exiting = Event() self.onDataChanged = None self.systemData = [] self.currentSystemState = [] self.currentRealTimeData = {} self.queuedRealTimeData = {} self.disabledSensors = {} self.disabledSensorTable = "disabled_sensors" checkAllBus() self.gpio = GPIO() # self.downloadSpeed = DownloadSpeed(Config(APP_SETTINGS)) # self.downloadSpeed.getDownloadSpeed() manager.addDeviceInstance("GPIO", "GPIO", "GPIO", self.gpio, [], "system") manager.loadJsonDevices("rest") if not DYNAMIC_DEVICES: warn("loadJsonDevices is None") for sensor in sensors.values(): # info('--------{} {} {}'.format(sensor['name'], sensor['description'], sensor['device'])) self.AddSensor(sensor['name'], sensor['description'], sensor['device'], sensor['args']) # # info(DYNAMIC_DEVICES) self.config = Config(APP_SETTINGS) self.clientId = self.config.get('Agent', 'ClientID', None) self.mqtt_dis_prefix = self.config.get('Agent', 'MQTT_DIS_PREFIX', "homeassistant") self.serial = self.cloudClient.hardware.Serial for name, device in DYNAMIC_DEVICES.items(): for type in device['type']: if type in ['DAC', 'ADC']: continue topic, message = self.AddMQTTSensorDevice(name, type, device) if self.cloudClient: info("{} {}".format(topic, message)) self.cloudClient.EnqueuePacket(message, topic) # info(mqttsensor) results = DbManager.Select(self.disabledSensorTable) if results: for row in results: self.disabledSensors[row[0]] = 1 self.realTimeMonitorRunning = False self.pluginManager = PluginManager(self.OnPluginChange) self.pluginManager.load_plugins() self.InitCallbacks() self.StartMonitoring()
def __init__(self): try: self.wirelessModules = {} interfaces = self.Interfaces() for key in interfaces: self.wirelessModules[key] = Wireless(key) except Exception as ex: warn('Could not initialize Wireless module: ' + str(ex))
def RemoveScheduledItemById(self, id): with self.mutex: if id in self.schedules: try: scheduleItem = self.schedules[id] schedule.cancel_job(scheduleItem.job) del self.schedules[id] self.RemoveDbItem(scheduleItem.id) return True except KeyError: warn('RemoveScheduledItem key error: ' + str(Id)) error('RemoveScheduledItem id not found: ' + str(id)) return False
def OnFailure(component, error=0): #-3=Temporary failure in name resolution info('Daemon failure handling ' + str(error)) if error in errorList: Daemon.Restart() if component not in failureCount: Daemon.Reset(component) failureCount[component]+=1 now = datetime.now() if startFailure[component]==0: startFailure[component]=now elapsedTime=now-startFailure[component] if (elapsedTime.total_seconds() >= RESET_TIMEOUT) or ( failureCount[component] > FAILURE_COUNT): warn('Daemon::OnFailure myDevices is going to restart after ' +str(component) + ' failed: ' + str(elapsedTime.total_seconds()) + ' seconds and ' + str(failureCount) + ' times') Daemon.Restart()
def SensorCommand(self, command, sensorId, channel, value): """Execute sensor/actuator command Args: command: Type of command to execute sensorId: Sensor id channel: Pin/channel on device, None if there is no channel value: Value to use for setting the sensor state Returns: Command specific return value on success, False on failure """ result = False info('SensorCommand: {}, sensor {}, channel {}, value {}'.format(command, sensorId, channel, value)) try: if self.pluginManager.is_plugin(sensorId, channel): return self.pluginManager.write_value(sensorId, channel, value) commands = {'integer': {'function': 'write', 'value_type': int}, 'value': {'function': 'write', 'value_type': int}, 'function': {'function': 'setFunctionString', 'value_type': str}, 'angle': {'function': 'writeAngle', 'value_type': float}, 'float': {'function': 'writeFloat', 'value_type': float}, 'volt': {'function': 'writeVolt', 'value_type': float}} with self.sensorMutex: if sensorId in self.disabledSensors: info('Sensor disabled') return result sensor = instance.deviceInstance(sensorId) if not sensor: info('Sensor not found') return result if command in commands: device = instance.DEVICES[sensorId] info('Sensor found: {}'.format(device)) func = getattr(sensor, commands[command]['function']) value = commands[command]['value_type'](value) if channel: result = self.CallDeviceFunction(func, int(channel), value) else: result = self.CallDeviceFunction(func, value) if 'DigitalActuator' in device['type']: manager.updateDeviceState(sensorId, value) return result warn('Command not implemented: {}'.format(command)) return result except Exception: exception('SensorCommand failed') return result
def remove_scheduled_item_by_id(self, remove_id): """Remove a scheduled item with the specified id id: id specifying the item to remove""" with self.mutex: if remove_id in self.schedule_items: try: schedule_item = self.schedule_items[remove_id] schedule.cancel_job(schedule_item['job']) del self.schedule_items[remove_id] self.remove_database_record(remove_id) return True except KeyError: warn('Key error removing scheduled item: {}'.format(remove_id)) error('Remove id not found: {}'.format(remove_id)) return False
def CheckConnectionAndPing(self): ticksStart = time() with self.mutex: try: if (ticksStart - self.lastPing > self.pingTimeout): #debug('CheckConnectionAndPing EXPIRED - trying to reconnect') self.Stop() self.Start self.lastPing = time() - self.pingRate - 1 warn( 'Restarting cloud connection -> CheckConnectionAndPing EXPIRED: ' + str(self.lastPing)) if (ticksStart - self.waitPing >= self.pingRate): #debug("CheckConnectionAndPing sending ACK packet") self.SendAckPacket() except: debug('') error('CheckConnectionAndPing error')
def SensorCommand(self, commandType, sensorName, sensorType, driverClass, method, channel, value): retVal = False info( 'SensorCommand: {} SensorName {} SensorType {} DriverClass {} Method {} Channel {} Value {}' .format(commandType, sensorName, sensorType, driverClass, method, channel, value)) try: self.AddRefresh() debug('') actuators = ('GPIOPort', 'ServoMotor', 'AnalogActuator', 'LoadSensor', 'PiFaceDigital', 'DistanceSensor', 'Thermistor', 'Photoresistor', 'LightDimmer', 'LightSwitch', 'DigitalSensor', 'DigitalActuator', 'MotorSwitch', 'RelaySwitch', 'ValveSwitch', 'MotionSensor') gpioExtensions = ('GPIOPort', 'PiFaceDigital') if driverClass is None: hashKey = self.SHA_Calc_str(sensorName + sensorType) else: hashKey = self.SHA_Calc_str(sensorName + driverClass) with self.sensorMutex: if hashKey in self.disabledSensors: return retVal sensor = instance.deviceInstance(sensorName) if not sensor: info('Sensor not found') return retVal if (sensorType in actuators) or (driverClass in actuators): if sensorType in gpioExtensions or driverClass in gpioExtensions: if commandType == 'integer' or commandType == 'value': retVal = str( self.CallDeviceFunction( sensor.write, int(channel), int(value))) return retVal else: if commandType == 'integer': retVal = str( self.CallDeviceFunction( sensor.write, int(value))) return retVal if commandType == 'function': retVal = str( self.CallDeviceFunction(sensor.setFunctionString, channel, value)) return retVal if commandType == 'angle': retVal = self.CallDeviceFunction( sensor.writeAngle, value) return retVal if commandType == 'float': retVal = self.CallDeviceFunction( sensor.writeFloat, float(value)) return retVal if commandType == 'integer': retVal = float( self.CallDeviceFunction(sensor.write, int(channel), int(value))) return retVal if commandType == 'float': retVal = float( self.CallDeviceFunction(sensor.writeFloat, int(channel), float(value))) return retVal if commandType == 'volt': retVal = float( self.CallDeviceFunction(sensor.writeVolt, int(channel), float(value))) return retVal if commandType == 'angle': retVal = float( self.CallDeviceFunction(sensor.writeAngle, int(channel), float(value))) return retVal warn('Command not implemented: ' + commandType) return retVal except Exception as ex: exception('SensorCommand failed with: ' + str(ex)) pass finally: #looks like this breaks actuators refresh by updating and not sending data changed #then refresh never comes for the specific sensor #ThreadPool.SubmitParam(self.Monitor, hashKey) return retVal