Ejemplo n.º 1
0
    def __init__(self):
        super(Brumulus, self).__init__()

        # self.logger = logger

        # self.flight_recorder_file = open('brumulus.csv', 'a')
        # self.flight_recorder = csv.writer(self.flight_recorder_file)

        #TODO make this configurable
        self.temp = TemperatureSensor(device_id='28-000004f2300b')
        self.temp_2 = TemperatureSensor(device_id='28-000004f17ab8')
        self.control = ControlTemperature()
        self.setpoint = ControlSetPoint()

        self.chiller = ControlledOutput(ProtectedOutput(min_state_time=180,
                                                        pin=17),
                                        name='Chiller')
        self.heater = ControlledOutput(ProtectedOutput(min_state_time=30,
                                                       pin=23),
                                       name='Heater',
                                       control_scale=-1)

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = None
        self.current_temp = None
Ejemplo n.º 2
0
 def addTemperatureSensor(self,
                          sensor_type='boiler',
                          sensoridentifier='28-0000092c44f8'):
     temperatureSensor = TemperatureSensor(sensorAddress=sensoridentifier)
     temperatureSensor.setupSensor()
     if sensor_type == 'boiler':
         self._boilerTempSensors.append(temperatureSensor)
         self._boilerTempSensorsIter = cycle(self._boilerTempSensors)
     elif sensor_type == 'steam':
         self._steamTempSensors.append(temperatureSensor)
     else:
         raise ValueError('sensor_type must be "boiler" or "steam"')
Ejemplo n.º 3
0
    def __init__(self, ip_address, port, name, config):
        self.client = Client(ip_address, port, timeout=1)
        self.name = name

        self.ledstrip = None
        self.temperature_sensor = None
        self.humidity_sensor = None
        self.light_sensor = None
        self.motion_sensor = None
        self.light_control = None

        for node in self.client.root.get_children():
            if node.get_name() == 'LEDSTRIP':
                self.ledstrip = LedStrip(node)
            elif node.get_name() == 'HTU':
                self.temperature_sensor = TemperatureSensor(node)
                self.humidity_sensor = HumiditySensor(node)
            elif node.get_name() == 'LIGHT':
                self.light_sensor = LightSensor(self.client.root.LIGHT)
            elif node.get_name() == 'MOTION':
                self.motion_sensor = MotionSensor(self.client.root.MOTION)

        if self.ledstrip and self.light_sensor and self.motion_sensor:
            self.light_control = LightControl(config, self.ledstrip,
                                              self.light_sensor,
                                              self.motion_sensor)
Ejemplo n.º 4
0
    def __init__(self):
        super(Brumulus, self).__init__()

        # self.logger = logger

        # self.flight_recorder_file = open('brumulus.csv', 'a')
        # self.flight_recorder = csv.writer(self.flight_recorder_file)

        #TODO make this configurable
        self.temp = TemperatureSensor(device_id='28-000004f2300b')
        self.temp_2 = TemperatureSensor(device_id='28-000004f17ab8')
        self.control = ControlTemperature()
        self.setpoint = ControlSetPoint()

        self.chiller = ControlledOutput(ProtectedOutput(min_state_time=180, pin=17), name='Chiller')
        self.heater = ControlledOutput(ProtectedOutput(min_state_time=30, pin=23), name='Heater', control_scale=-1)

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = None
        self.current_temp = None
Ejemplo n.º 5
0
    def __init__(self):
        super(Brumulus, self).__init__()

        # TODO make this configurable
        self.temp = TemperatureSensor(device_id='28-000004f2300b')
        self.temp_2 = TemperatureSensor(device_id='28-000004f17ab8')
        self.control = ControlTemperature()
        self.setpoint = ControlSetPoint()

        self.chiller = ControlledOutput(
            ProtectedOutput(EnergenieOutput(1), min_state_time=180),
            name='Chiller')

        self.heater = ControlledOutput(
            ProtectedOutput(EnergenieOutput(2), min_state_time=30),
            name='Heater',
            control_scale=-1)

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = None
        self.current_temp = None
Ejemplo n.º 6
0
class Brumulus(object):
    """docstring for Brumulus"""
    def __init__(self):
        super(Brumulus, self).__init__()

        # self.logger = logger

        # self.flight_recorder_file = open('brumulus.csv', 'a')
        # self.flight_recorder = csv.writer(self.flight_recorder_file)

        #TODO make this configurable
        self.temp = TemperatureSensor(device_id='28-000004f2300b')
        self.temp_2 = TemperatureSensor(device_id='28-000004f17ab8')
        self.control = ControlTemperature()
        self.setpoint = ControlSetPoint()

        self.chiller = ControlledOutput(ProtectedOutput(min_state_time=180, pin=17), name='Chiller')
        self.heater = ControlledOutput(ProtectedOutput(min_state_time=30, pin=23), name='Heater', control_scale=-1)

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = None
        self.current_temp = None

        # self.thingsspeak = Thingsspeak()

        # self.control_loop_timer = task.LoopingCall(self.control_loop)
        # self.lager_api = LagerThread(self)

        # self.history = deque()
        # self.history_max = 20

    # def start(self):
    #     self.control_loop_timer.start(30)
    #     self.lager_api.start()
    #     reactor.run()
    #
    # def stop(self):
    #     try:
    #         reactor.callFromThread(reactor.stop)
    #     except:
    #         pass
    #
    #     try:
    #         self.lager_api.stop()
    #     except:
    #         pass

    def control_loop(self):
        prev_datetime = self.datetime
        prev_temp = self.current_temp

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = datetime.now()
        self.time = str(self.datetime.isoformat(' '))
        self.err = ''
        self.current_temp = self.temp.read_temp_decimal()
        self.current_temp_2 = self.temp_2.read_temp_decimal()
        print "current_temp: {} setpoint: {}".format(self.current_temp, self.target_temp)

        # if self.current_temp is None:
        #     self.err = "current_temp cannot be read"
        #     print self.err
        # else:
        #     try:
        #         self.temp_delta = self.get_temp_delta(prev_datetime, prev_temp)
        #         print "Temp delta ", self.temp_delta
        #         self.control_value = self.control.get_output(self.current_temp, self.target_temp, self.temp_delta)
        #         print "control_value", self.control_value
        #         self.chiller.control(self.control_value)
        #         self.heater.control(self.control_value)
        #
        #         # self.recorder()
        #         # values = self.get_all()
        #         # self.history.append(values)
        #         # if len(self.history) > self.history_max:
        #         #     self.history.popleft()
        #         # self.thingsspeak.send(values)
        #     except Exception as e:
        #         print e
        #         self.err = str(e)
        #         print '-' * 60
        #         traceback.print_exc(file=sys.stdout)
        #         print '-' * 60

    def get_temp_delta(self, prev_datetime, prev_temp):
        if (prev_datetime is None or prev_temp is None):
            return 0

        time_delta = Decimal((self.datetime - prev_datetime).total_seconds())
        temp_delta = self.current_temp - prev_temp

        return Decimal((temp_delta / time_delta) * 60)

    # def recorder(self):
    #     data = [self.time, self.target_temp, '{0:.3f}'.format(self.current_temp), self.chiller_ssr_raw, self.control_value, self.err]
    #     print data
    #     self.flight_recorder.writerow(data)

    actions = {'increment_target_temp', 'decrement_target_temp'}

    def action(self, action):
        if action == 'decrement_target_temp':
            return self.decrement_target_temp()

        if action == 'increment_target_temp':
            return self.increment_target_temp()

        if action == 'get_all':
            return self.get_all()

        if action == 'toggle_chiller_mode':
            self.chiller.mode_toggle()

        if action == 'toggle_heater_mode':
            self.heater.mode_toggle()

        if action == 'get_history':
            return self.get_history()

    def decrement_target_temp(self):
        self.setpoint.set_gui_setpoint(self.target_temp - 1)
        self.target_temp = self.setpoint.get_setpoint()
        return self.get_all()

    def increment_target_temp(self):
        self.setpoint.set_gui_setpoint(self.target_temp + 1)
        self.target_temp = self.setpoint.get_setpoint()
        return self.get_all()

    def get_history(self, count=60):
        print "current hist: {}".format(self.history)
        return list(self.history)[-1 * count:]

    def get_all(self):
        values = {'created_at': self.time,
                  'target_temp': str(self.target_temp),
                  'target_temp_mode': self.setpoint.get_mode(),
                  'current_temp': '{0:.3f}'.format(self.current_temp),
                  'current_temp_2': '{0:.3f}'.format(self.current_temp_2),
                  'temp_delta': '{0:.3f}'.format(self.temp_delta),
                  'control_value': '{0:.0f}'.format(self.control_value),
                  'chiller': self.chiller.get_state_str(),
                  'chiller_raw': self.chiller.get_raw(),
                  'chiller_info': self.chiller.get_info(),
                  'chiller_mode': self.chiller.get_mode(),
                  'heater': self.heater.get_state_str(),
                  'heater_info': self.heater.get_info(),
                  'heater_raw': self.heater.get_raw(),
                  'heater_mode': self.heater.get_mode(),
                  }
        return values
Ejemplo n.º 7
0
from flask import Flask
app = Flask(__name__)

from TemperatureSensor import TemperatureSensor

from Led import Led

from flask import render_template

lightr = Led(18)
lightb = Led(24)

pierre = TemperatureSensor()


@app.route('/hello')
def hello_world():
    return 'Hello World!'


@app.route('/')
def index():
    return render_template('base.html')


@app.route('/<bleu_rouge>/<on_off>')
def ledonb(bleu_rouge, on_off):
    if on_off == 'on' and bleu_rouge == 'bleu':
        lightb.on()
    elif on_off == 'off' and bleu_rouge == 'bleu':
        lightb.off()
Ejemplo n.º 8
0
class Brumulus(object):
    """docstring for Brumulus"""
    def __init__(self):
        super(Brumulus, self).__init__()

        # self.logger = logger

        # self.flight_recorder_file = open('brumulus.csv', 'a')
        # self.flight_recorder = csv.writer(self.flight_recorder_file)

        #TODO make this configurable
        self.temp = TemperatureSensor(device_id='28-000004f2300b')
        self.temp_2 = TemperatureSensor(device_id='28-000004f17ab8')
        self.control = ControlTemperature()
        self.setpoint = ControlSetPoint()

        self.chiller = ControlledOutput(ProtectedOutput(min_state_time=180,
                                                        pin=17),
                                        name='Chiller')
        self.heater = ControlledOutput(ProtectedOutput(min_state_time=30,
                                                       pin=23),
                                       name='Heater',
                                       control_scale=-1)

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = None
        self.current_temp = None

        # self.thingsspeak = Thingsspeak()

        # self.control_loop_timer = task.LoopingCall(self.control_loop)
        # self.lager_api = LagerThread(self)

        # self.history = deque()
        # self.history_max = 20

    # def start(self):
    #     self.control_loop_timer.start(30)
    #     self.lager_api.start()
    #     reactor.run()
    #
    # def stop(self):
    #     try:
    #         reactor.callFromThread(reactor.stop)
    #     except:
    #         pass
    #
    #     try:
    #         self.lager_api.stop()
    #     except:
    #         pass

    def control_loop(self):
        prev_datetime = self.datetime
        prev_temp = self.current_temp

        self.target_temp = self.setpoint.get_setpoint()
        self.datetime = datetime.now()
        self.time = str(self.datetime.isoformat(' '))
        self.err = ''
        self.current_temp = self.temp.read_temp_decimal()
        self.current_temp_2 = self.temp_2.read_temp_decimal()
        print "current_temp: {} setpoint: {}".format(self.current_temp,
                                                     self.target_temp)

        # if self.current_temp is None:
        #     self.err = "current_temp cannot be read"
        #     print self.err
        # else:
        #     try:
        #         self.temp_delta = self.get_temp_delta(prev_datetime, prev_temp)
        #         print "Temp delta ", self.temp_delta
        #         self.control_value = self.control.get_output(self.current_temp, self.target_temp, self.temp_delta)
        #         print "control_value", self.control_value
        #         self.chiller.control(self.control_value)
        #         self.heater.control(self.control_value)
        #
        #         # self.recorder()
        #         # values = self.get_all()
        #         # self.history.append(values)
        #         # if len(self.history) > self.history_max:
        #         #     self.history.popleft()
        #         # self.thingsspeak.send(values)
        #     except Exception as e:
        #         print e
        #         self.err = str(e)
        #         print '-' * 60
        #         traceback.print_exc(file=sys.stdout)
        #         print '-' * 60

    def get_temp_delta(self, prev_datetime, prev_temp):
        if (prev_datetime is None or prev_temp is None):
            return 0

        time_delta = Decimal((self.datetime - prev_datetime).total_seconds())
        temp_delta = self.current_temp - prev_temp

        return Decimal((temp_delta / time_delta) * 60)

    # def recorder(self):
    #     data = [self.time, self.target_temp, '{0:.3f}'.format(self.current_temp), self.chiller_ssr_raw, self.control_value, self.err]
    #     print data
    #     self.flight_recorder.writerow(data)

    actions = {'increment_target_temp', 'decrement_target_temp'}

    def action(self, action):
        if action == 'decrement_target_temp':
            return self.decrement_target_temp()

        if action == 'increment_target_temp':
            return self.increment_target_temp()

        if action == 'get_all':
            return self.get_all()

        if action == 'toggle_chiller_mode':
            self.chiller.mode_toggle()

        if action == 'toggle_heater_mode':
            self.heater.mode_toggle()

        if action == 'get_history':
            return self.get_history()

    def decrement_target_temp(self):
        self.setpoint.set_gui_setpoint(self.target_temp - 1)
        self.target_temp = self.setpoint.get_setpoint()
        return self.get_all()

    def increment_target_temp(self):
        self.setpoint.set_gui_setpoint(self.target_temp + 1)
        self.target_temp = self.setpoint.get_setpoint()
        return self.get_all()

    def get_history(self, count=60):
        print "current hist: {}".format(self.history)
        return list(self.history)[-1 * count:]

    def get_all(self):
        values = {
            'created_at': self.time,
            'target_temp': str(self.target_temp),
            'target_temp_mode': self.setpoint.get_mode(),
            'current_temp': '{0:.3f}'.format(self.current_temp),
            'current_temp_2': '{0:.3f}'.format(self.current_temp_2),
            'temp_delta': '{0:.3f}'.format(self.temp_delta),
            'control_value': '{0:.0f}'.format(self.control_value),
            'chiller': self.chiller.get_state_str(),
            'chiller_raw': self.chiller.get_raw(),
            'chiller_info': self.chiller.get_info(),
            'chiller_mode': self.chiller.get_mode(),
            'heater': self.heater.get_state_str(),
            'heater_info': self.heater.get_info(),
            'heater_raw': self.heater.get_raw(),
            'heater_mode': self.heater.get_mode(),
        }
        return values
Ejemplo n.º 9
0
	print("Running Production Environment Configuration")
	environment = cfg.env_prod

# Application constants from Environment and Configuration file
sampleTime = cfg.sampleTime
debug = cfg.debug
deviceID = cfg.deviceID
webApiUrl = environment["webApi"]
webApiUsername = environment["username"]
webApiPassword = environment["password"]

# Create an indicator LED on GPIO pin 17
led = LED(17)

# Create the Temperature Sensor on GPIO pin 4
temperatureSensor = TemperatureSensor(4)

# Dictionary to hold Temperature Sensor data
temperatureData = {}

# Sit in a loop reading the sensors every sampleTime, convert result to JSON, and POST to the Web API
while True:
        # Turn LED ON
	led.on()
	
        # Read the Temperature Sensor
	temperatureSensor.read()
	if temperatureSensor.valid:
		# Save the Temperature Sensor results in a Temperature Data Object
		temperatureData["deviceID"] = deviceID
		temperatureData["temperature"] = temperatureSensor.temperatureF
Ejemplo n.º 10
0
    def __init__(self, parent=None):
        super(ECUI, self).__init__(parent)

        # Settings
        self.autoabortEnabled = True

        # Hedgehog
        self.stack = ExitStack()
        self.hedgehog = self.stack.enter_context(
            connect(endpoint='tcp://raspberrypi.local:10789'))  # FIXME

        # Simulated Hedgehog
        #self.hedgehog = SimulatedHedgehog()

        #Strain data received
        self.measure = StrainData()
        #Neopixel test
        self.socket_neo(b'SafeOn')

        # Actuators and Sensors
        self.servo_fuel = Servo(name='fuel',
                                hedgehog=self.hedgehog,
                                servoPort=0,
                                feedbackPort=0)
        self.servo_oxidizer = Servo(name='oxidizer',
                                    hedgehog=self.hedgehog,
                                    servoPort=1,
                                    feedbackPort=1)
        self.igniter_arc = Igniter(name='arc',
                                   hedgehog=self.hedgehog,
                                   igniterPort=0)
        self.igniter_pyro = Igniter(name='pyro',
                                    hedgehog=self.hedgehog,
                                    igniterPort=1,
                                    feedbackPort=2)
        self.pressureSensor_fuel = PressureSensor(name='fuel',
                                                  hedgehog=self.hedgehog,
                                                  port=8)
        self.pressureSensor_oxidizer = PressureSensor(name='oxidizer',
                                                      hedgehog=self.hedgehog,
                                                      port=9)
        self.pressureSensor_chamber = PressureSensor(name='chamber',
                                                     hedgehog=self.hedgehog,
                                                     port=10)
        self.temperatureSensor_chamber = TemperatureSensor(
            name='chamber', hedgehog=self.hedgehog, port=11)

        # Countdown Timer and Sequence
        self.countdownTimer = CountdownTimer(self.countdownEvent)
        self.sequence = Sequence()

        # Regular Timer
        self.timer = QTimer()
        self.timer.setInterval(100)
        self.timer.timeout.connect(self.__timerTick)

        self.inputVoltage = 0.0

        self.set_safe = True
        self.set_igniter = False

        self.loggingValues = []

        # Main tab
        self.tab_main = QWidget()
        self.tab_main.layout = QVBoxLayout(self)
        self.tab_main.setLayout(self.tab_main.layout)

        self.label_countdownClock = QLabel(self.countdownTimer.getTimeString(),
                                           self)
        self.label_countdownClock.setStyleSheet('color: #000000')
        self.label_countdownClock.setToolTip("Countdown Clock")

        self.label_inputVoltage = QLabel("Input Voltage: 0.0V", self)
        self.label_inputVoltage.setStyleSheet('color: #000000')
        self.label_inputVoltage.setToolTip("Input Voltage")

        self.btn_countdownStartStop = QPushButton("Start", self)
        self.btn_countdownStartStop.setToolTip("Start the Countdown")
        self.btn_countdownStartStop.clicked.connect(
            self.countdownStartStopReset)
        self.btn_countdownStartStop.resize(
            self.btn_countdownStartStop.sizeHint())
        self.btn_countdownStartStop.setStyleSheet('background-color: #00ff00;')

        self.layout_countdown = QHBoxLayout()
        self.layout_countdown.addWidget(self.label_inputVoltage,
                                        alignment=Qt.AlignLeft)
        self.layout_countdown.addWidget(self.label_countdownClock,
                                        alignment=Qt.AlignCenter)
        self.layout_countdown.addWidget(self.btn_countdownStartStop,
                                        alignment=Qt.AlignRight)

        self.tab_main.layout.addLayout(self.layout_countdown)

        self.sequencePlot = SequencePlot(self,
                                         sequence=self.sequence,
                                         countdownTimer=self.countdownTimer,
                                         width=5,
                                         height=4)
        self.tab_main.layout.addWidget(self.sequencePlot,
                                       alignment=Qt.AlignTop)

        self.checkbox_manualControl = QCheckBox("Manual Control", self)
        self.checkbox_manualControl.setToolTip("Enable Manual Control")
        self.checkbox_manualControl.clicked.connect(
            self.manualControlEnableDisable)
        self.checkbox_manualControl.resize(
            self.checkbox_manualControl.sizeHint())

        self.checkbox_manualControlIgniter = QCheckBox("Igniter", self)
        self.checkbox_manualControlIgniter.setToolTip("Igniter Manual Control")
        self.checkbox_manualControlIgniter.clicked.connect(
            self.manualControlIgniterEnableDisable)
        self.checkbox_manualControlIgniter.resize(
            self.checkbox_manualControlIgniter.sizeHint())
        self.checkbox_manualControlIgniter.setEnabled(False)

        self.label_manualControlFuel = QLabel(
            "Fuel Target: %3d%%   Fuel Currently: %3d%%   Fuel Pressure: %2.1fbar"
            % (self.servo_fuel.getPositionTargetPercent(),
               self.servo_fuel.getPositionCurrentPercent(),
               self.pressureSensor_fuel.getValue()), self)
        self.slider_manualControlFuel = QSlider(
            Qt.Horizontal
        )  # FIXME: buggy when slided manually, goes out of range or doesnt reach limits
        self.slider_manualControlFuel.setToolTip("Fuel Manual Control")
        self.slider_manualControlFuel.setRange(0, 100)
        self.slider_manualControlFuel.sliderMoved.connect(
            self.manualControlFuelChange)
        self.slider_manualControlFuel.resize(
            self.slider_manualControlFuel.sizeHint())
        self.slider_manualControlFuel.setEnabled(False)
        self.layout_manualControlFuel = QVBoxLayout()
        self.layout_manualControlFuel.addWidget(self.label_manualControlFuel,
                                                alignment=Qt.AlignLeft)
        self.layout_manualControlFuel.addWidget(self.slider_manualControlFuel,
                                                alignment=Qt.AlignTop)

        self.label_manualControlOxidizer = QLabel(
            "Oxidizer Target: %3d%%   Oxidizer Currently: %3d%%   Oxidizer Pressure: %2.1fbar"
            % (self.servo_oxidizer.getPositionTargetPercent(),
               self.servo_oxidizer.getPositionCurrentPercent(),
               self.pressureSensor_oxidizer.getValue()), self)
        self.slider_manualControlOxidizer = QSlider(
            Qt.Horizontal
        )  # FIXME: buggy when slided manually, goes out of range or doesnt reach limits
        self.slider_manualControlOxidizer.setToolTip("Oxidizer Manual Control")
        self.slider_manualControlOxidizer.setRange(0, 100)
        self.slider_manualControlOxidizer.sliderMoved.connect(
            self.manualControlOxidizerChange)
        self.slider_manualControlOxidizer.resize(
            self.slider_manualControlOxidizer.sizeHint())
        self.slider_manualControlOxidizer.setEnabled(False)
        self.layout_manualControlOxidizer = QVBoxLayout()
        self.layout_manualControlOxidizer.addWidget(
            self.label_manualControlOxidizer, alignment=Qt.AlignLeft)
        self.layout_manualControlOxidizer.addWidget(
            self.slider_manualControlOxidizer, alignment=Qt.AlignTop)

        self.layout_manualControl = QVBoxLayout()
        self.layout_manualControl.addWidget(self.checkbox_manualControl,
                                            alignment=Qt.AlignLeft)
        self.layout_manualControl.addWidget(self.checkbox_manualControlIgniter,
                                            alignment=Qt.AlignLeft)
        self.layout_manualControl.addLayout(self.layout_manualControlFuel)
        self.layout_manualControl.addLayout(self.layout_manualControlOxidizer)

        self.tab_main.layout.addLayout(self.layout_manualControl)

        # Settings tab
        self.tab_settings = QWidget()
        self.tab_settings.layout = QHBoxLayout(self)
        self.tab_settings.setLayout(self.tab_settings.layout)

        self.checkbox_calibration = QCheckBox("Servo Calibration", self)
        self.checkbox_calibration.setToolTip("Enable Servo Calibration Mode")
        self.checkbox_calibration.clicked.connect(
            self.calibrationEnableDisable)
        self.checkbox_calibration.resize(self.checkbox_calibration.sizeHint())

        self.label_cal_fuel = QLabel(
            "Fuel (min=%dus, max=%dus)" %
            (self.servo_fuel.getMinUs(), self.servo_fuel.getMaxUs()), self)

        self.spinbox_cal_fuel = QSpinBox(self)
        self.spinbox_cal_fuel.setMinimum(500)
        self.spinbox_cal_fuel.setMaximum(2500)
        self.spinbox_cal_fuel.setSingleStep(1)
        self.spinbox_cal_fuel.setValue(self.servo_fuel.getPositionTargetUs())
        self.spinbox_cal_fuel.setEnabled(False)
        self.spinbox_cal_fuel.valueChanged.connect(self.calFuelValueChanged)

        self.btn_cal_fuel_min = QPushButton("Set Min", self)
        self.btn_cal_fuel_min.setToolTip(
            "Set the Minimum Value, corresponds to 0%")
        self.btn_cal_fuel_min.clicked.connect(self.calFuelSetMin)
        self.btn_cal_fuel_min.setEnabled(False)
        self.btn_cal_fuel_min.resize(self.btn_cal_fuel_min.sizeHint())

        self.btn_cal_fuel_max = QPushButton("Set Max", self)
        self.btn_cal_fuel_max.setToolTip(
            "Set the Maximum Value, corresponds to 100%")
        self.btn_cal_fuel_max.clicked.connect(self.calFuelSetMax)
        self.btn_cal_fuel_max.setEnabled(False)
        self.btn_cal_fuel_max.resize(self.btn_cal_fuel_max.sizeHint())

        self.label_cal_oxidizer = QLabel(
            "Oxidizer (min=%dus, max=%dus)" %
            (self.servo_oxidizer.getMinUs(), self.servo_oxidizer.getMaxUs()),
            self)

        self.spinbox_cal_oxidizer = QSpinBox(self)
        self.spinbox_cal_oxidizer.setMinimum(500)
        self.spinbox_cal_oxidizer.setMaximum(2500)
        self.spinbox_cal_oxidizer.setSingleStep(1)
        self.spinbox_cal_oxidizer.setValue(
            self.servo_oxidizer.getPositionTargetUs())
        self.spinbox_cal_oxidizer.setEnabled(False)
        self.spinbox_cal_oxidizer.valueChanged.connect(
            self.calOxidizerValueChanged)

        self.btn_cal_oxidizer_min = QPushButton("Set Min", self)
        self.btn_cal_oxidizer_min.setToolTip(
            "Set the Minimum Value, corresponds to 0%")
        self.btn_cal_oxidizer_min.clicked.connect(self.calOxidizerSetMin)
        self.btn_cal_oxidizer_min.setEnabled(False)
        self.btn_cal_oxidizer_min.resize(self.btn_cal_oxidizer_min.sizeHint())

        self.btn_cal_oxidizer_max = QPushButton("Set Max", self)
        self.btn_cal_oxidizer_max.setToolTip(
            "Set the Maximum Value, corresponds to 100%")
        self.btn_cal_oxidizer_max.clicked.connect(self.calOxidizerSetMax)
        self.btn_cal_oxidizer_max.setEnabled(False)
        self.btn_cal_oxidizer_max.resize(self.btn_cal_oxidizer_max.sizeHint())

        self.layout_calibration_fuel = QHBoxLayout()
        self.layout_calibration_fuel.addWidget(self.label_cal_fuel,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.spinbox_cal_fuel,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.btn_cal_fuel_min,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.btn_cal_fuel_max,
                                               alignment=Qt.AlignTop)

        self.layout_calibration_oxidizer = QHBoxLayout()
        self.layout_calibration_oxidizer.addWidget(self.label_cal_oxidizer,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.spinbox_cal_oxidizer,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.btn_cal_oxidizer_min,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.btn_cal_oxidizer_max,
                                                   alignment=Qt.AlignTop)

        self.layout_calibration = QVBoxLayout()
        self.layout_calibration.addWidget(self.checkbox_calibration,
                                          alignment=Qt.AlignTop)
        self.layout_calibration.addLayout(self.layout_calibration_fuel)
        self.layout_calibration.addLayout(self.layout_calibration_oxidizer)

        self.tab_settings.layout.addLayout(self.layout_calibration)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)
        self.tabs.addTab(self.tab_main, "Main")
        self.tabs.addTab(self.tab_settings, "Settings")

        # Window
        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.tabs, alignment=Qt.AlignTop)
        self.setLayout(self.layout)
        self.setGeometry(500, 200, 900, 700)
        self.setWindowTitle("Engine Control UI")
        self.setWindowIcon(QIcon('icon.png'))

        #Timer
        self.timer.start()
Ejemplo n.º 11
0
class ECUI(QWidget):
    def __init__(self, parent=None):
        super(ECUI, self).__init__(parent)

        # Settings
        self.autoabortEnabled = True

        # Hedgehog
        self.stack = ExitStack()
        self.hedgehog = self.stack.enter_context(
            connect(endpoint='tcp://raspberrypi.local:10789'))  # FIXME

        # Simulated Hedgehog
        #self.hedgehog = SimulatedHedgehog()

        #Strain data received
        self.measure = StrainData()
        #Neopixel test
        self.socket_neo(b'SafeOn')

        # Actuators and Sensors
        self.servo_fuel = Servo(name='fuel',
                                hedgehog=self.hedgehog,
                                servoPort=0,
                                feedbackPort=0)
        self.servo_oxidizer = Servo(name='oxidizer',
                                    hedgehog=self.hedgehog,
                                    servoPort=1,
                                    feedbackPort=1)
        self.igniter_arc = Igniter(name='arc',
                                   hedgehog=self.hedgehog,
                                   igniterPort=0)
        self.igniter_pyro = Igniter(name='pyro',
                                    hedgehog=self.hedgehog,
                                    igniterPort=1,
                                    feedbackPort=2)
        self.pressureSensor_fuel = PressureSensor(name='fuel',
                                                  hedgehog=self.hedgehog,
                                                  port=8)
        self.pressureSensor_oxidizer = PressureSensor(name='oxidizer',
                                                      hedgehog=self.hedgehog,
                                                      port=9)
        self.pressureSensor_chamber = PressureSensor(name='chamber',
                                                     hedgehog=self.hedgehog,
                                                     port=10)
        self.temperatureSensor_chamber = TemperatureSensor(
            name='chamber', hedgehog=self.hedgehog, port=11)

        # Countdown Timer and Sequence
        self.countdownTimer = CountdownTimer(self.countdownEvent)
        self.sequence = Sequence()

        # Regular Timer
        self.timer = QTimer()
        self.timer.setInterval(100)
        self.timer.timeout.connect(self.__timerTick)

        self.inputVoltage = 0.0

        self.set_safe = True
        self.set_igniter = False

        self.loggingValues = []

        # Main tab
        self.tab_main = QWidget()
        self.tab_main.layout = QVBoxLayout(self)
        self.tab_main.setLayout(self.tab_main.layout)

        self.label_countdownClock = QLabel(self.countdownTimer.getTimeString(),
                                           self)
        self.label_countdownClock.setStyleSheet('color: #000000')
        self.label_countdownClock.setToolTip("Countdown Clock")

        self.label_inputVoltage = QLabel("Input Voltage: 0.0V", self)
        self.label_inputVoltage.setStyleSheet('color: #000000')
        self.label_inputVoltage.setToolTip("Input Voltage")

        self.btn_countdownStartStop = QPushButton("Start", self)
        self.btn_countdownStartStop.setToolTip("Start the Countdown")
        self.btn_countdownStartStop.clicked.connect(
            self.countdownStartStopReset)
        self.btn_countdownStartStop.resize(
            self.btn_countdownStartStop.sizeHint())
        self.btn_countdownStartStop.setStyleSheet('background-color: #00ff00;')

        self.layout_countdown = QHBoxLayout()
        self.layout_countdown.addWidget(self.label_inputVoltage,
                                        alignment=Qt.AlignLeft)
        self.layout_countdown.addWidget(self.label_countdownClock,
                                        alignment=Qt.AlignCenter)
        self.layout_countdown.addWidget(self.btn_countdownStartStop,
                                        alignment=Qt.AlignRight)

        self.tab_main.layout.addLayout(self.layout_countdown)

        self.sequencePlot = SequencePlot(self,
                                         sequence=self.sequence,
                                         countdownTimer=self.countdownTimer,
                                         width=5,
                                         height=4)
        self.tab_main.layout.addWidget(self.sequencePlot,
                                       alignment=Qt.AlignTop)

        self.checkbox_manualControl = QCheckBox("Manual Control", self)
        self.checkbox_manualControl.setToolTip("Enable Manual Control")
        self.checkbox_manualControl.clicked.connect(
            self.manualControlEnableDisable)
        self.checkbox_manualControl.resize(
            self.checkbox_manualControl.sizeHint())

        self.checkbox_manualControlIgniter = QCheckBox("Igniter", self)
        self.checkbox_manualControlIgniter.setToolTip("Igniter Manual Control")
        self.checkbox_manualControlIgniter.clicked.connect(
            self.manualControlIgniterEnableDisable)
        self.checkbox_manualControlIgniter.resize(
            self.checkbox_manualControlIgniter.sizeHint())
        self.checkbox_manualControlIgniter.setEnabled(False)

        self.label_manualControlFuel = QLabel(
            "Fuel Target: %3d%%   Fuel Currently: %3d%%   Fuel Pressure: %2.1fbar"
            % (self.servo_fuel.getPositionTargetPercent(),
               self.servo_fuel.getPositionCurrentPercent(),
               self.pressureSensor_fuel.getValue()), self)
        self.slider_manualControlFuel = QSlider(
            Qt.Horizontal
        )  # FIXME: buggy when slided manually, goes out of range or doesnt reach limits
        self.slider_manualControlFuel.setToolTip("Fuel Manual Control")
        self.slider_manualControlFuel.setRange(0, 100)
        self.slider_manualControlFuel.sliderMoved.connect(
            self.manualControlFuelChange)
        self.slider_manualControlFuel.resize(
            self.slider_manualControlFuel.sizeHint())
        self.slider_manualControlFuel.setEnabled(False)
        self.layout_manualControlFuel = QVBoxLayout()
        self.layout_manualControlFuel.addWidget(self.label_manualControlFuel,
                                                alignment=Qt.AlignLeft)
        self.layout_manualControlFuel.addWidget(self.slider_manualControlFuel,
                                                alignment=Qt.AlignTop)

        self.label_manualControlOxidizer = QLabel(
            "Oxidizer Target: %3d%%   Oxidizer Currently: %3d%%   Oxidizer Pressure: %2.1fbar"
            % (self.servo_oxidizer.getPositionTargetPercent(),
               self.servo_oxidizer.getPositionCurrentPercent(),
               self.pressureSensor_oxidizer.getValue()), self)
        self.slider_manualControlOxidizer = QSlider(
            Qt.Horizontal
        )  # FIXME: buggy when slided manually, goes out of range or doesnt reach limits
        self.slider_manualControlOxidizer.setToolTip("Oxidizer Manual Control")
        self.slider_manualControlOxidizer.setRange(0, 100)
        self.slider_manualControlOxidizer.sliderMoved.connect(
            self.manualControlOxidizerChange)
        self.slider_manualControlOxidizer.resize(
            self.slider_manualControlOxidizer.sizeHint())
        self.slider_manualControlOxidizer.setEnabled(False)
        self.layout_manualControlOxidizer = QVBoxLayout()
        self.layout_manualControlOxidizer.addWidget(
            self.label_manualControlOxidizer, alignment=Qt.AlignLeft)
        self.layout_manualControlOxidizer.addWidget(
            self.slider_manualControlOxidizer, alignment=Qt.AlignTop)

        self.layout_manualControl = QVBoxLayout()
        self.layout_manualControl.addWidget(self.checkbox_manualControl,
                                            alignment=Qt.AlignLeft)
        self.layout_manualControl.addWidget(self.checkbox_manualControlIgniter,
                                            alignment=Qt.AlignLeft)
        self.layout_manualControl.addLayout(self.layout_manualControlFuel)
        self.layout_manualControl.addLayout(self.layout_manualControlOxidizer)

        self.tab_main.layout.addLayout(self.layout_manualControl)

        # Settings tab
        self.tab_settings = QWidget()
        self.tab_settings.layout = QHBoxLayout(self)
        self.tab_settings.setLayout(self.tab_settings.layout)

        self.checkbox_calibration = QCheckBox("Servo Calibration", self)
        self.checkbox_calibration.setToolTip("Enable Servo Calibration Mode")
        self.checkbox_calibration.clicked.connect(
            self.calibrationEnableDisable)
        self.checkbox_calibration.resize(self.checkbox_calibration.sizeHint())

        self.label_cal_fuel = QLabel(
            "Fuel (min=%dus, max=%dus)" %
            (self.servo_fuel.getMinUs(), self.servo_fuel.getMaxUs()), self)

        self.spinbox_cal_fuel = QSpinBox(self)
        self.spinbox_cal_fuel.setMinimum(500)
        self.spinbox_cal_fuel.setMaximum(2500)
        self.spinbox_cal_fuel.setSingleStep(1)
        self.spinbox_cal_fuel.setValue(self.servo_fuel.getPositionTargetUs())
        self.spinbox_cal_fuel.setEnabled(False)
        self.spinbox_cal_fuel.valueChanged.connect(self.calFuelValueChanged)

        self.btn_cal_fuel_min = QPushButton("Set Min", self)
        self.btn_cal_fuel_min.setToolTip(
            "Set the Minimum Value, corresponds to 0%")
        self.btn_cal_fuel_min.clicked.connect(self.calFuelSetMin)
        self.btn_cal_fuel_min.setEnabled(False)
        self.btn_cal_fuel_min.resize(self.btn_cal_fuel_min.sizeHint())

        self.btn_cal_fuel_max = QPushButton("Set Max", self)
        self.btn_cal_fuel_max.setToolTip(
            "Set the Maximum Value, corresponds to 100%")
        self.btn_cal_fuel_max.clicked.connect(self.calFuelSetMax)
        self.btn_cal_fuel_max.setEnabled(False)
        self.btn_cal_fuel_max.resize(self.btn_cal_fuel_max.sizeHint())

        self.label_cal_oxidizer = QLabel(
            "Oxidizer (min=%dus, max=%dus)" %
            (self.servo_oxidizer.getMinUs(), self.servo_oxidizer.getMaxUs()),
            self)

        self.spinbox_cal_oxidizer = QSpinBox(self)
        self.spinbox_cal_oxidizer.setMinimum(500)
        self.spinbox_cal_oxidizer.setMaximum(2500)
        self.spinbox_cal_oxidizer.setSingleStep(1)
        self.spinbox_cal_oxidizer.setValue(
            self.servo_oxidizer.getPositionTargetUs())
        self.spinbox_cal_oxidizer.setEnabled(False)
        self.spinbox_cal_oxidizer.valueChanged.connect(
            self.calOxidizerValueChanged)

        self.btn_cal_oxidizer_min = QPushButton("Set Min", self)
        self.btn_cal_oxidizer_min.setToolTip(
            "Set the Minimum Value, corresponds to 0%")
        self.btn_cal_oxidizer_min.clicked.connect(self.calOxidizerSetMin)
        self.btn_cal_oxidizer_min.setEnabled(False)
        self.btn_cal_oxidizer_min.resize(self.btn_cal_oxidizer_min.sizeHint())

        self.btn_cal_oxidizer_max = QPushButton("Set Max", self)
        self.btn_cal_oxidizer_max.setToolTip(
            "Set the Maximum Value, corresponds to 100%")
        self.btn_cal_oxidizer_max.clicked.connect(self.calOxidizerSetMax)
        self.btn_cal_oxidizer_max.setEnabled(False)
        self.btn_cal_oxidizer_max.resize(self.btn_cal_oxidizer_max.sizeHint())

        self.layout_calibration_fuel = QHBoxLayout()
        self.layout_calibration_fuel.addWidget(self.label_cal_fuel,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.spinbox_cal_fuel,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.btn_cal_fuel_min,
                                               alignment=Qt.AlignTop)
        self.layout_calibration_fuel.addWidget(self.btn_cal_fuel_max,
                                               alignment=Qt.AlignTop)

        self.layout_calibration_oxidizer = QHBoxLayout()
        self.layout_calibration_oxidizer.addWidget(self.label_cal_oxidizer,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.spinbox_cal_oxidizer,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.btn_cal_oxidizer_min,
                                                   alignment=Qt.AlignTop)
        self.layout_calibration_oxidizer.addWidget(self.btn_cal_oxidizer_max,
                                                   alignment=Qt.AlignTop)

        self.layout_calibration = QVBoxLayout()
        self.layout_calibration.addWidget(self.checkbox_calibration,
                                          alignment=Qt.AlignTop)
        self.layout_calibration.addLayout(self.layout_calibration_fuel)
        self.layout_calibration.addLayout(self.layout_calibration_oxidizer)

        self.tab_settings.layout.addLayout(self.layout_calibration)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)
        self.tabs.addTab(self.tab_main, "Main")
        self.tabs.addTab(self.tab_settings, "Settings")

        # Window
        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.tabs, alignment=Qt.AlignTop)
        self.setLayout(self.layout)
        self.setGeometry(500, 200, 900, 700)
        self.setWindowTitle("Engine Control UI")
        self.setWindowIcon(QIcon('icon.png'))

        #Timer
        self.timer.start()

    def socket_neo(self, string):
        #Socket for neopixel
        self.clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.clientsocket.connect(('raspberrypi.local', 25565))
        self.clientsocket.send(string)
        self.clientsocket.close()

    def closeEvent(self, event):
        if self.btn_countdownStartStop.text() == "Abort":
            reply = QMessageBox.question(
                self, 'Message', "The countdown is running.\nQuit anyways?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        else:
            reply = QMessageBox.Yes

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def cleanup(self):
        self.servo_fuel.disable()
        self.servo_oxidizer.disable()
        self.stack.close()
        self.countdownTimer.stop()
        self.sequence.saveSequence()
        self.servo_fuel.saveSettings()
        self.servo_oxidizer.saveSettings()

    def countdownStartStopReset(self):
        if self.btn_countdownStartStop.text() == "Start":
            self.socket_neo(b'Testing')
            self.checkbox_calibration.setEnabled(False)
            self.calibrationDisable()
            self.checkbox_manualControl.setEnabled(False)
            self.manualControlDisable()
            self.countdownTimer.start()
            self.sequence.setStatus('running')
            self.btn_countdownStartStop.setText("Abort")
            self.btn_countdownStartStop.setToolTip("Stop the Countdown")
            self.btn_countdownStartStop.setStyleSheet(
                'background-color: #FF0000;')
            self.servo_fuel.enable()
            self.servo_oxidizer.enable()

        elif self.btn_countdownStartStop.text() == "Abort":
            self.socket_neo(b'Error')
            if self.countdownTimer.getTime() < 0:
                self.countdownTimer.stop()
                self.btn_countdownStartStop.setText("Reset and Save Log")
                self.btn_countdownStartStop.setToolTip(
                    "Reset the countdown and save logging data to a file")
                os.system("espeak -v en+f3 \"hold, hold, hold\" &")
            else:
                self.btn_countdownStartStop.setText("Stop")
                self.btn_countdownStartStop.setToolTip("Stop logging")
                os.system("espeak -v en+f3 \"abort\" &")
            self.sequence.setStatus('abort')
            self.countdownEvent()
            self.label_countdownClock.setStyleSheet('color: #ff0000')
            self.btn_countdownStartStop.setStyleSheet(
                'background-color: #EEEEEE;')

        elif self.btn_countdownStartStop.text() == "Stop":
            self.countdownTimer.stop()
            os.system("espeak -v en+f3 \"stopped logging\" &")
            self.sequence.setStatus('abort')
            self.countdownEvent()
            self.label_countdownClock.setStyleSheet('color: #ff0000')
            self.btn_countdownStartStop.setText("Reset and Save Log")
            self.btn_countdownStartStop.setToolTip(
                "Reset the countdown and save logging data to a file")
            self.btn_countdownStartStop.setStyleSheet(
                'background-color: #EEEEEE;')

        elif self.btn_countdownStartStop.text() == "Reset and Save Log":
            self.socket_neo(b'NoConn')
            self.set_safe = False
            logfile_name = f"{datetime.datetime.now():%Y%m%d_%H%M%S}.csv"  # TODO: move logging to own class
            logfile_name_dir = 'log/' + logfile_name
            os.makedirs(
                os.path.dirname(logfile_name_dir),
                exist_ok=True)  # generate log directory if non existent
            with open(logfile_name_dir, 'w', newline='') as logfile:
                fieldnames = [
                    'Timestamp', 'ServoFuelPercentageTarget',
                    'ServoOxidizerPercentageTarget',
                    'ServoFuelPercentageCurrent',
                    'ServoOxidizerPercentageCurrent', 'PressureFuel',
                    'PressureOxidizer', 'PressureChamber',
                    'TemperatureChamber', 'Strain_data'
                ]
                writer = csv.DictWriter(logfile, fieldnames=fieldnames)
                writer.writeheader()
                for line in self.loggingValues:
                    writer.writerow(line)
            self.loggingValues.clear()

            self.checkbox_calibration.setEnabled(True)
            self.checkbox_manualControl.setEnabled(True)
            self.countdownTimer.reset()
            self.sequence.setStatus('reset')
            self.countdownEvent()
            self.label_countdownClock.setStyleSheet('color: #000000')
            self.btn_countdownStartStop.setText("Start")
            self.btn_countdownStartStop.setToolTip("Start the Countdown")
            self.btn_countdownStartStop.setStyleSheet(
                'background-color: #00FF00;')

        else:
            print("Error: invalid button state")

    def __timerTick(
        self
    ):  # FIXME: bc of the hedgehog commands this often takes longer than 100ms, slowing down the countdown
        self.servo_fuel.updatePositionCurrentPercent()
        self.servo_oxidizer.updatePositionCurrentPercent()
        self.igniter_pyro.updateArmed()
        self.pressureSensor_fuel.updateValue()
        self.pressureSensor_oxidizer.updateValue()
        self.pressureSensor_chamber.updateValue()
        self.temperatureSensor_chamber.updateValue()

        voltageNew = self.hedgehog.get_analog(0x80) / 1000
        self.inputVoltage = self.inputVoltage * 0.6 + voltageNew * 0.4
        self.label_inputVoltage.setText("Input Voltage: %.1fV" %
                                        self.inputVoltage)

        self.label_manualControlFuel.setText(
            "Fuel Target: %3d%%   Fuel Currently: %3d%%   Fuel Pressure: %2.1fbar"
            % (self.servo_fuel.getPositionTargetPercent(),
               self.servo_fuel.getPositionCurrentPercent(),
               self.pressureSensor_fuel.getValue()))
        self.label_manualControlOxidizer.setText(
            "Oxidizer Target: %3d%%   Oxidizer Currently: %3d%%   Oxidizer Pressure: %2.1fbar"
            % (self.servo_oxidizer.getPositionTargetPercent(),
               self.servo_oxidizer.getPositionCurrentPercent(),
               self.pressureSensor_oxidizer.getValue()))

        if self.igniter_pyro.getArmed() is not None:
            if self.igniter_pyro.getArmed() is True:
                self.checkbox_manualControlIgniter.setText("Igniter (Armed)")
                if not self.set_igniter:
                    self.socket_neo(b'Error')
                    self.set_igniter = True
            else:
                self.checkbox_manualControlIgniter.setText(
                    "Igniter (Disarmed)")
                if self.set_igniter:
                    if (not self.set_safe) and (
                            self.pressureSensor_oxidizer.getValue() < 0.5
                            and self.pressureSensor_fuel.getValue() < 0.5):
                        self.socket_neo(b'SafeOn')
                        self.set_safe = True
                    if self.set_safe and (
                            self.pressureSensor_oxidizer.getValue() > 2
                            and self.pressureSensor_fuel.getValue() > 2):
                        self.socket_neo(b'NoConn')
                        self.set_safe = False
                    self.set_igniter = False
        else:
            self.checkbox_manualControlIgniter.setText("Igniter (Unknown)")

        if (not self.set_safe) and (
                self.pressureSensor_oxidizer.getValue() < 0.5
                and self.pressureSensor_fuel.getValue() < 0.5):
            self.socket_neo(b'SafeOn')
            self.set_safe = True
        if self.set_safe and (self.pressureSensor_oxidizer.getValue() > 2
                              or self.pressureSensor_fuel.getValue() > 2):
            self.socket_neo(b'NoConn')
            self.set_safe = False

    def countdownEvent(self):
        # abort if no ignition detected TODO: improve
        if self.autoabortEnabled:
            if self.pressureSensor_chamber.getValue(
            ) < self.sequence.getChamberPressureMinAtTime(
                    self.countdownTimer.getTime(
                    )) and not self.btn_countdownStartStop.text() == "Stop":
                self.socket_neo(b'Error')
                self.btn_countdownStartStop.setText("Stop")
                os.system("espeak -v en+f3 \"auto abort\" &")
                #self.countdownTimer.stop()  # TODO: make timer continue
                self.sequence.setStatus('abort')
                self.label_countdownClock.setStyleSheet('color: #ff0000')
                self.btn_countdownStartStop.setToolTip("Stop logging")
                self.btn_countdownStartStop.setStyleSheet(
                    'background-color: #EEEEEE;')

        if self.countdownTimer.getTime() > 3 + self.sequence.getTimestampList(
        )[len(self.sequence.getTimestampList()) - 2] and (
                self.btn_countdownStartStop.text() == "Abort"
                or self.btn_countdownStartStop.text()
                == "Stop") and self.servo_fuel.getPositionTargetPercent(
                ) == 0 and self.servo_oxidizer.getPositionTargetPercent(
                ) == 0:  #Yes I hate myself for this crude fix
            self.btn_countdownStartStop.setText("Reset and Save Log")
            os.system("espeak -v en+f3 \"sequence finished\" &")
            self.countdownTimer.stop()
            self.sequence.setStatus('abort')
            self.countdownEvent()
            self.label_countdownClock.setStyleSheet('color: #ff0000')
            self.btn_countdownStartStop.setToolTip(
                "Reset the countdown and save logging data to a file")
            self.btn_countdownStartStop.setStyleSheet(
                'background-color: #EEEEEE;')

        # outputs set values
        self.label_countdownClock.setText(self.countdownTimer.getTimeString())
        self.servo_fuel.setPositionTargetPercent(
            self.sequence.getFuelAtTime(self.countdownTimer.getTime()))
        self.servo_oxidizer.setPositionTargetPercent(
            self.sequence.getOxidizerAtTime(self.countdownTimer.getTime()))
        self.igniter_arc.set(
            self.sequence.getIgniterAtTime(self.countdownTimer.getTime()))
        self.igniter_pyro.set(
            self.sequence.getIgniterAtTime(self.countdownTimer.getTime()))
        self.sequencePlot.redrawMarkers()

        # update ui
        self.checkbox_manualControlIgniter.setChecked(
            self.sequence.getIgniterAtTime(self.countdownTimer.getTime()))
        self.slider_manualControlFuel.setValue(
            self.sequence.getFuelAtTime(self.countdownTimer.getTime()))
        self.slider_manualControlOxidizer.setValue(
            self.sequence.getOxidizerAtTime(self.countdownTimer.getTime()))

        # sensors get values
        self.loggingValues.append({
            'Timestamp':
            self.countdownTimer.getTime(),
            'ServoFuelPercentageTarget':
            self.servo_fuel.getPositionTargetPercent(),
            'ServoOxidizerPercentageTarget':
            self.servo_oxidizer.getPositionTargetPercent(),
            'ServoFuelPercentageCurrent':
            self.servo_fuel.getPositionCurrentPercent(),
            'ServoOxidizerPercentageCurrent':
            self.servo_oxidizer.getPositionCurrentPercent(),
            'PressureFuel':
            self.pressureSensor_fuel.getValue(),
            'PressureOxidizer':
            self.pressureSensor_oxidizer.getValue(),
            'PressureChamber':
            self.pressureSensor_chamber.getValue(),
            'TemperatureChamber':
            self.temperatureSensor_chamber.getValue(),
            'Strain_data':
            self.measure.read_data()
        })

    def manualControlEnable(self):
        print("Manual Control Enabled")
        os.system("espeak -v en+f3 -s 140 \"manuel override enable\" &")
        self.checkbox_manualControl.setChecked(True)
        self.btn_countdownStartStop.setEnabled(
            False)  # FIXME: doesn't do anything?!
        self.checkbox_calibration.setEnabled(False)
        self.calibrationDisable()
        self.checkbox_manualControlIgniter.setEnabled(True)
        self.slider_manualControlFuel.setEnabled(True)
        self.slider_manualControlOxidizer.setEnabled(True)
        self.servo_fuel.enable()
        self.servo_oxidizer.enable()

    def manualControlDisable(self):
        print("Manual Control Disabled")
        #os.system("espeak -v en+f3 -s 140 \"manuel override disabled\" &")
        self.checkbox_manualControl.setChecked(False)
        self.checkbox_manualControlIgniter.setEnabled(False)
        self.checkbox_manualControlIgniter.setChecked(False)
        self.slider_manualControlFuel.setEnabled(False)
        self.slider_manualControlOxidizer.setEnabled(False)
        self.manualControlIgniterDisable()
        self.countdownEvent()
        self.btn_countdownStartStop.setEnabled(True)
        self.checkbox_calibration.setEnabled(True)

    def manualControlEnableDisable(
        self
    ):  # TODO: rename to __checkbox_manualControl_onClick, same for other callbacks
        if self.checkbox_manualControl.isChecked():
            self.manualControlEnable()
        else:
            self.manualControlDisable()

    def manualControlIgniterEnable(self):
        print("Manual Igniter ON")
        self.igniter_arc.set(True)
        self.igniter_pyro.set(True)

    def manualControlIgniterDisable(self):
        print("Manual Igniter OFF")
        self.igniter_arc.set(False)
        self.igniter_pyro.set(False)

    def manualControlIgniterEnableDisable(self):
        if self.checkbox_manualControlIgniter.isChecked():
            self.manualControlIgniterEnable()
        else:
            self.manualControlIgniterDisable()

    def manualControlFuelChange(self):
        self.servo_fuel.setPositionTargetPercent(
            self.slider_manualControlFuel.value())
        self.label_manualControlFuel.setText(
            "Fuel Target: %3d%%   Fuel Currently: %3d%%   Fuel Pressure: %2.1fbar"
            % (self.servo_fuel.getPositionTargetPercent(),
               self.servo_fuel.getPositionCurrentPercent(),
               self.pressureSensor_fuel.getValue()))

    def manualControlOxidizerChange(self):
        self.servo_oxidizer.setPositionTargetPercent(
            self.slider_manualControlOxidizer.value())
        self.label_manualControlOxidizer.setText(
            "Oxidizer Target: %3d%%   Oxidizer Currently: %3d%%   Oxidizer Pressure: %2.1fbar"
            % (self.servo_oxidizer.getPositionTargetPercent(),
               self.servo_oxidizer.getPositionCurrentPercent(),
               self.pressureSensor_oxidizer.getValue()))

    def calibrationEnable(self):
        print("Calibration Mode Enabled")
        self.btn_countdownStartStop.setEnabled(False)
        self.checkbox_manualControl.setEnabled(False)
        self.manualControlDisable()
        self.checkbox_calibration.setChecked(True)
        self.spinbox_cal_fuel.setEnabled(True)
        self.spinbox_cal_oxidizer.setEnabled(True)
        self.btn_cal_fuel_min.setEnabled(True)
        self.btn_cal_fuel_max.setEnabled(True)
        self.btn_cal_oxidizer_min.setEnabled(True)
        self.btn_cal_oxidizer_max.setEnabled(True)
        self.servo_fuel.enable()
        self.servo_oxidizer.enable()

    def calibrationDisable(self):
        print("Calibration Mode Disabled")
        self.checkbox_calibration.setChecked(False)
        self.spinbox_cal_fuel.setEnabled(False)
        self.spinbox_cal_oxidizer.setEnabled(False)
        self.btn_cal_fuel_min.setEnabled(False)
        self.btn_cal_fuel_max.setEnabled(False)
        self.btn_cal_oxidizer_min.setEnabled(False)
        self.btn_cal_oxidizer_max.setEnabled(False)
        self.countdownEvent()
        self.btn_countdownStartStop.setEnabled(True)
        self.checkbox_manualControl.setEnabled(True)

    def calibrationEnableDisable(self):
        if self.checkbox_calibration.isChecked():
            self.calibrationEnable()
        else:
            self.calibrationDisable()

    def calFuelValueChanged(self):
        if self.checkbox_calibration.isChecked():
            self.servo_fuel.setPositionTargetUs(self.spinbox_cal_fuel.value())

    def calOxidizerValueChanged(self):
        if self.checkbox_calibration.isChecked():
            self.servo_oxidizer.setPositionTargetUs(
                self.spinbox_cal_oxidizer.value())

    def calFuelSetMin(self):
        if self.checkbox_calibration.isChecked():
            self.servo_fuel.calMin()
            self.label_cal_fuel.setText(
                "Fuel (min=%dus, max=%dus)" %
                (self.servo_fuel.getMinUs(), self.servo_fuel.getMaxUs()))

    def calFuelSetMax(self):
        if self.checkbox_calibration.isChecked():
            self.servo_fuel.calMax()
            self.label_cal_fuel.setText(
                "Fuel (min=%dus, max=%dus)" %
                (self.servo_fuel.getMinUs(), self.servo_fuel.getMaxUs()))

    def calOxidizerSetMin(self):
        if self.checkbox_calibration.isChecked():
            self.servo_oxidizer.calMin()
            self.label_cal_oxidizer.setText("Oxidizer (min=%dus, max=%dus)" %
                                            (self.servo_oxidizer.getMinUs(),
                                             self.servo_oxidizer.getMaxUs()))

    def calOxidizerSetMax(self):
        if self.checkbox_calibration.isChecked():
            self.servo_oxidizer.calMax()
            self.label_cal_oxidizer.setText("Oxidizer (min=%dus, max=%dus)" %
                                            (self.servo_oxidizer.getMinUs(),
                                             self.servo_oxidizer.getMaxUs()))
Ejemplo n.º 12
0
def main():
    # Declare paths.
    src = './CompostMonitoringData'
    destination = '/media/pi/537D-B88D/Sensor_Data'  # Change the destination according to your uSB address.
    save_timer = 0

    # Declare the lcd display screen.
    lcd = lcddriver.lcd()

    # Declaring the objects.
    moisture_one = MoistureSensor(MCP.P0)
    moisture_two = MoistureSensor(MCP.P1)
    moisture_three = MoistureSensor(MCP.P3)
    temp_one = TemperatureSensor(0)
    temp_two = TemperatureSensor(1)
    temp_three = TemperatureSensor(2)

    # Calibrates the sensors in parallel.
    p1 = Process(target=moisture_one.calibrate())
    p1.start()
    p2 = Process(target=moisture_two.calibrate())
    p2.start()
    p3 = Process(target=moisture_three.calibrate())
    p3.start()

    p1.join()
    p2.join()
    p3.join()

    db = PickleShareDB('./CompostMonitoringData')

    while (True):
        # Sets up the temperature variables.
        temperature_one = temp_one.read_temp()
        temperature_two = temp_two.read_temp()
        temperature_three = temp_three.read_temp()
        current_M1_Val = moisture_one.mapSensorVals()
        current_M2_Val = moisture_two.mapSensorVals()
        current_M3_Val = moisture_three.mapSensorVals()

        dt_string = dt.now().strftime("%d/%m/%Y %H:%M:%S")

        # Loads the json from the database.
        if 'data' not in db.keys():
            db['data'] = []

        # Stores existing data from pickleShare db into existing_data.
        existing_data = db['data']

        # Creates a dict of the current vals.
        curr_data = {
            'moisture_value_1': current_M1_Val,
            'moisture_value_2': current_M2_Val,
            'moisture_value_3': current_M3_Val,
            'temp_value_1': temperature_one,
            'temp_value_2': temperature_two,
            'temp_value_3': temperature_three,
            'time': dt_string,
        }

        # Appends the new data.
        existing_data.append(curr_data)

        # if(check_connection()):
        #     db.clear()

        store_locally(db, existing_data)

        # Prints the current values.
        print("Current value", current_M1_Val, current_M2_Val, current_M3_Val,
              '\n\tCurrent Time:', dt_string)
        print("Current Temps:\n\t" + str(temperature_one) + "\n\t" +
              str(temperature_two) + "\n\t" + str(temperature_three))

        avg_moisture_val = (current_M1_Val + current_M2_Val +
                            current_M3_Val) / 3
        avg_temperature = (temperature_one + temperature_two +
                           temperature_three) / 3

        # Display the values on the lcd.
        lcd.lcd_display_string(
            "Avg Val: " + str(avg_moisture_val) + " " + str(avg_temperature),
            1)
        lcd.lcd_display_string(
            "Probe 1: " + str(current_M1_Val) + " " + str(temperature_one), 2)
        lcd.lcd_display_string(
            "Probe 2: " + str(current_M2_Val) + " " + str(temperature_two), 3)
        lcd.lcd_display_string(
            "Probe 3: " + str(current_M3_Val) + " " + str(temperature_three),
            4)

        save_timer += 1
        # Tries to save data to removable drive every 30 minutes.
        if (save_timer == 1800):
            store_to_removable(src, destination)
            if store_to_removable == 1:
                save_timer = 0
            else:
                # If it can't save it tries every 10 minutes
                save_timer = 1200

        time.sleep(5)
Ejemplo n.º 13
0
socketio = SocketIO(app)


@app.route("/")
def index():
    return render_template('index.html')


#def message_loop():
#    while True:
#        message = input('Mouvement détecté')
#        socketio.emit('alert', message, Broadcast=True)

# Vue que notre méthode pour lire nos message est une boucle infinie
# Elle bloquerait notre serveur. Qui ne pourrait répondre à aucune requête.
# Ici nous créons un Thread qui va permettre à notre fonction de se lancer
# en parallèle du serveur.
#read_messages = threading.Thread(target=message_loop)
#read_messages.start()

mouvement = Mouvement(17)
temp_c = TemperatureSensor()

read_mouvement = threading.Thread(target=mouvement.mouvement_loop,
                                  args=(socketio, ))
read_mouvement.start()

read_temperature = threading.Thread(target=temp_c.temperature_loop,
                                    args=(socketio, ))
read_temperature.start()
Ejemplo n.º 14
0
from time import sleep
from Wifi import is_connected
from Server import Server
from TemperatureSensor import TemperatureSensor
from config import config

if not is_connected():
    print('No connection found, exiting...')
    exit()

sensor = TemperatureSensor(pin_id=config['sensor']['pin'])
server = Server(
    host=config['server']['host'],
    port=config['server']['port'],
)

while True:
    temperatures = sensor.read()
    if not temperatures:
        print('Error while reading temperatures, exiting...')
        exit()
    print('Temperatures read:', temperatures)

    server.post('sensor/' + config['sensor']['id'],
                {'temperature': temperatures[0]})

    sleep(config['measure']['period'])