def run(self): self.__Run = True while self.__Run: if self.ReadyLog.isSet(): self.ReadyLog.clear() ds18B20toDB.ReadyDS18B20.wait( ) #Дождаться сигнала об окончании измерения температур #Записать новые данные в лог dbLock.acquire() timestamp = models.log(TimeStamp=datetime.now(), P=power.Value) for Th in models.DS18B20.query.all(): newT = models.logT(T=Th.T, Thermometer=Th, TimeStamp=timestamp) models.db.session.commit() dbLock.release() self.ReadyLog.set()
def GiveTemperatureFromDB(self): u'''Собирает и возвращает список кортежей имен термометров и значений температур в том порядке, в котором они прописаны в config.py''' dbLock.acquire() self.TlistToClient = [] if len(models.DS18B20.query.filter( models.DS18B20.Name != '').all()) != 0: for NameT in app.config['T_LOCATION']: Thrmmtr = models.DS18B20.query.filter_by(Name=NameT).first() if Thrmmtr != None: self.TlistToClient.append((Thrmmtr.Name, Thrmmtr.T)) Tlist = models.DS18B20.query.filter(models.DS18B20.Name == '').all() for eachT in Tlist: self.TlistToClient.append((eachT.IDthermometer, eachT.T)) dbLock.release() app.config['Thermometers'] = self.DataFromServer
def run(self): self.__Run = True while self.__Run: # Если флаг готовности температурных данных в БД установлен, # сбросить его if self.ReadyDS18B20.isSet(): self.ReadyDS18B20.clear() # Получаем температурные данные(параметром передаётся таймаут в # секундах) Tlist = Measure(6) # Блокируем другие потоки dbLock.acquire() # Признак изменения температурных данных IsNew = False # Ложим в базу температурные данные for eashT in Tlist: Thrmmtr = models.DS18B20.query.filter_by( IDthermometer=eashT[0]).first() if Thrmmtr == None: #Если в БД не найден термометр с соответствующим ID, #сохраняем новый термометр Thrmmtr = models.DS18B20(IDthermometer=eashT[0], Name='', T=eashT[1], Timestamp=eashT[2]) IsNew = True else: #Если найден, изменяем температуру и время её фиксации if Thrmmtr.T != eashT[1]: IsNew = True Thrmmtr.T = eashT[1] Thrmmtr.Timestamp = eashT[2] models.db.session.add(Thrmmtr) models.db.session.commit() #сохраняем изменения в БД # Разблокируем другие потоки dbLock.release() # Обновление и передача температурных значений только если они отличаются от предыдущих if IsNew: Transmit({ 'Thermometers': self.TlistToClient, 'DateTime': time.time() }) self.GiveTemperatureFromDB() # Вскидываем флаг готовности свежих температурных данных в БД self.ReadyDS18B20.set() return
def run(self): # Сброс переменной прерывания/перехода процесса app.config['AB_CON'] = '' #Сохранение состояния веб-интерфейса self.Display = app.config['Display'] self.Buttons = app.config['Buttons'] # Фиксация момента запуска процесса self._Begin = datetime.now() # Старт процесса журналирования self.Log.start() # Вывести сообщение на дисплей и прикрутить кнопку "Останов" self.pageUpdate('Заполнение холодильников<br>' + self.Duration(), 'ABORT.html') #Заполнение холодильников condensator.On() dephlegmator.On() time.sleep(2) condensator.Off() dephlegmator.Off() #старт регулятора охлаждения self.CoolsRegl.start() #Мощность нагрева=100% power.Value = 100 #Ожидание закипания while True: # Вывести на дисплей состояние self.pageUpdate('Разгон (ожидание закипания)<br>' + self.Duration()) # При получении команды прервать процесс if app.config['AB_CON'] == 'Abort': self.abort() return # Отдохнуть секундочку time.sleep(1) #Проверить скорость роста температур #Извлекаем из лога два последних момента фиксации температур dbLock.acquire() LastMeasures = models.log.query.order_by( models.db.desc(models.log.id)).limit(2).all() #Если их ещё не два, то пропускаем if len(LastMeasures) < 2: dbLock.release() continue # Секунд между двумя последними измерениями sec = (LastMeasures[0].TimeStamp - LastMeasures[1].TimeStamp).total_seconds() for Samp in LastMeasures[0].Tsample: #Если скорость роста температуры на каком-либо термометре более 1°C в секунду, значит закипание V = (Samp.T - LastMeasures[1].Tsample.filter_by( id_DS18B20=Samp.id_DS18B20).first().T) / sec #print(V) if V > 1.0: dbLock.release() break else: dbLock.release() continue break #Стабилизация tBgn = time.time() #фиксация времени начала стабилизации dbLock.acquire() power.Value = models.Parameters2.query.filter( models.Parameters2.Symbol == u'Pst').first().Value durationSt = int(60 * models.Parameters2.query.filter( models.Parameters2.Symbol == u'tSt').first().Value) #durationSt=10 # ВРЕМЕННО!!!УБРАТЬ!!! dbLock.release() #print(u'Стабилизация=%sсек'%durationSt) # Врезать две кнопки "Останов" и "След.этап" self.pageUpdate('Стабилизация<br><br>%s' % (self.Duration()), 'ABORT_NEXT.html') while (time.time() - tBgn) < durationSt: # Вывести на дисплей состояние sec = int(durationSt - int(time.time() - tBgn)) sec_str=u'{:02}:{:02}'\ .format((sec//60)%60, sec%60) self.pageUpdate('Стабилизация<br>%s<br>%s' % (sec_str, self.Duration())) # При получении команды прервать процесс if app.config['AB_CON'] == 'Abort': self.abort() return # переход к отбору голов if app.config['AB_CON'] == 'Next': app.config['AB_CON'] = '' break # Отдохнуть секундочку time.sleep(1) # Отбор голов tBgn = time.time() #фиксация времени начала отбора голов dbLock.acquire() self.CoolsRegl.Tdeph = models.Parameters2.query.filter( models.Parameters2.Symbol == u'Thdeph').first().Value dbLock.release() while True: # При получении команды прервать процесс if app.config['AB_CON'] == 'Abort': self.abort() return # переход к отбору тела if app.config['AB_CON'] == 'Next': app.config['AB_CON'] = '' break # Вывести состояние на дисплей sec = int(time.time() - tBgn) sec_str=u'{}:{:02}:{:02}'\ .format(sec//3600, (sec//60)%60, sec%60) self.pageUpdate('Отбор голов<br>%s<br>%s' % (sec_str, self.Duration())) # Регулировать мощность нагрева dbLock.acquire() Kp = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Kp').first().Value Pbase = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Pbase').first().Value Tbott = models.DS18B20.query.filter( models.DS18B20.Name == 'Низ').first().T power.Value = (Pbase + Kp * Tbott) dbLock.release() # Отдохнуть секундочку time.sleep(1) # Отбор тела self.pageUpdate('Отбор тела<br><br>%s' % (self.Duration()), 'ABORT.html') while True: if app.config['AB_CON'] == 'Abort': self.abort() return # Освежить дисплей self.pageUpdate('Отбор тела<br><br>%s' % (self.Duration())) # Регулировать дефлегматор и нагрев dbLock.acquire() Tbdeph = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Tbdeph').first().Value Kdeph = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Kdeph').first().Value Pbase = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Pbase').first().Value Kp = models.Parameters2.query.filter( models.Parameters2.Symbol == 'Kp').first().Value Tbott = models.DS18B20.query.filter( models.DS18B20.Name == 'Низ').first().T self.CoolsRegl.Tdeph = (Tbdeph - Kdeph * Tbott) power.Value = (Pbase + Kp * Tbott) if models.DS18B20.query.filter(models.DS18B20.Name == 'Низ').first( ).T > models.Parameters2.query.filter( models.Parameters2.Symbol == 'Tend').first().Value: dbLock.release() break dbLock.release() # Отдохнуть секундочку time.sleep(1) # Остановить всё self.stop() self.pageUpdate('Второй перегон завершен<br>%s' % (self.Duration()), 'END.html') return
def run(self): """Процесс автоопределения мест расположения термометров""" # сброс переменной прерывания/перехода процесса app.config['AB_CON']='' #Фиксация момента запуска процесса self._Begin=datetime.now() #Сохранение состояния веб-интерфейса self.Display = app.config['Display'] self.Buttons = app.config['Buttons'] # создание и запуск объекта ведения журнала self.logger.start() # Вывести сообщение на дисплей и прикрутить кнопку "Останов" self.pageUpdate('Заполнение холодильников<br>'+self.Duration(), 'ABORT.html') #Заполнение холодильников 2сек condensator.On() dephlegmator.On() time.sleep(2) condensator.Off() dephlegmator.Off() #Мощность нагрева=100% self.pageUpdate('Мощность нагрева=100%<br>ожидание закипания<br>'+self.Duration()) power.Value=100 #Ожидание закипания while True: # При получении команды прервать процесс if app.config['AB_CON']=='Abort': self.abort() return #self.logger.ReadyLog.wait() #Ждем завершение записи в журнал #спим одну секунду time.sleep(1) self.pageUpdate('Мощность нагрева=100%<br>ожидание закипания<br>'+self.Duration()) #Проверить скорость роста температур #Извлекаем из лога два последних момента фиксации температур dbLock.acquire() LastMeasures=models.log.query.order_by(models.db.desc(models.log.id)).limit(2).all() #Если их ещё не два, то пропускаем if len(LastMeasures)==2: #Количество секунд между двумя последними измерениями sec=(LastMeasures[0].TimeStamp-LastMeasures[1].TimeStamp).total_seconds() for Samp in LastMeasures[0].Tsample: #Если скорость роста температуры на каком-либо термометре более 1°C в секунду, значит закипание if (Samp.T - LastMeasures[1].Tsample.filter_by(id_DS18B20=Samp.id_DS18B20).first().T)/sec>1: dbLock.release() break else: #если цикл for не был прерван, продолжаем цикл while dbLock.release() continue break #при прерывании цикла for прерываем цикл while #Уменьшаем мощность до 30% power.Value=25 # Пауза 30 сек tBegin=time.time() while time.time()-tBegin<30: # При получении команды прервать процесс if app.config['AB_CON']=='Abort': self.abort() return sec=20-int(time.time()-tBegin) sec_str=u'{:02}:{:02}'\ .format((sec//60)%60, sec%60) self.pageUpdate('Мощность нагрева=25%%<br>Пауза %s<br>%s'% (sec_str,self.Duration())) time.sleep(1) #Включаем клапаны дефлегматора и конденсатора на 40 сек condensator.On() dephlegmator.On() tBegin=time.time() while time.time()-tBegin<40: # При получении команды прервать процесс if app.config['AB_CON']=='Abort': self.abort() return sec=40-int(time.time()-tBegin) sec_str=u'{:02}:{:02}'\ .format((sec//60)%60, sec%60) self.pageUpdate('Мощность нагрева=25%%<br>Охладители %s<br>%s'% (sec_str,self.Duration())) time.sleep(1) #Отключаем клапан дефлегматора и ждем ещё 40 сек dephlegmator.Off() tBegin=time.time() while time.time()-tBegin<40: # При получении команды прервать процесс if app.config['AB_CON']=='Abort' or app.config['AB_CON']=='Error': self.stop() return sec=40-int(time.time()-tBegin) sec_str=u'{:02}:{:02}'\ .format((sec//60)%60, sec%60) self.pageUpdate('Прогрев дефлегматора<br>%s<br>%s'% (sec_str,self.Duration())) time.sleep(1) #Читаем из базы в порядке убывания температур, присваиваем имена и завершаем self.pageUpdate('Присвоение имен термометрам<br>%s'% (self.Duration())) dbLock.acquire() Tlist=models.DS18B20.query.order_by(models.db.desc(models.DS18B20.T)).all() for i in range(len(Tlist)): Tlist[i].Name=app.config['T_LOCATION'][i] models.db.session.commit() dbLock.release() self.stop() self.pageUpdate('Автоопределение завершено<br>%s'%(self.Duration()), 'END.html') return
def CheckTlist(self): '''Проверяет списки термометров на шине 1-Wire и в базе данных, дает заключение о необходимости определения мест их расположения.''' # Список термометров на шине Tlist = Measure() '''Если длина списка термометров в конфиге не совпадает с количеством термометров на 1-Wire, поднять исключение.''' if len(Tlist) != len(app.config['T_LOCATION']): raise NumThermometersMismatch( 'Number of thermometers on 1-Wire bus mismatched number of thermometers in config.' ) # Список ID термометров TIDlist = [T[0] for T in Tlist] dbLock.acquire() # список термометров в БД TfromDB = models.DS18B20.query.all() #Если БД ещё пустая if len(TfromDB) == 0: # Набор кнопок для запуска app.config['Buttons'] = 'WAITAL.html' # Надпись на дисплее app.config[ 'Display'] = 'Требуется определение мест расположения термометров' dbLock.release() return for TDB in TfromDB: if not TDB.IDthermometer in TIDlist: print('Удаление термометра %s из БД' % TDB.IDthermometer) models.db.session.delete(TDB) # Количество несовпадений имен термометров Mismatch = 0 # Имя нового термометра Tm = '' # Проверка мест расположения термометров for Tname in app.config['T_LOCATION']: Thrmmtr = models.DS18B20.query.filter_by(Name=Tname).all() if len(Thrmmtr) == 0: Mismatch += 1 Tm = Tname #print('Термометр с именем %s не найден'%Tname) elif len(Thrmmtr) > 1: Mismatch += 2 #print('Более одного термометра с именем %s'%Tname) else: #print('Термометр %s имеет ID %s'%(Tname,Thrmmtr[0].IDthermometer)) pass # Набор кнопок для запуска app.config['Buttons'] = 'WAIT.html' # Надпись на дисплее app.config['Display'] = 'Жду команду.' # Заменён один термометр if Mismatch == 1: Thrmmtr = models.DS18B20.query.filter_by(Name='').first() Thrmmtr.Name = Tm # Требуется определение расположения термометров elif Mismatch > 1: # Набор кнопок для запуска app.config['Buttons'] = 'WAITAL.html' # Надпись на дисплее app.config[ 'Display'] = 'Требуется определение мест расположения термометров' models.db.session.commit() dbLock.release()