Форум самогонщиков Сайт Барахолка Магазин Помощь солдатам

Smart Distiller (Умный дистиллятор с управлением по интернет)

Форум самогонщиков Автоматика
1 ... 5 6 7 8 9 10 11 ... 13 8
OldBean Доцент Красноярск 1K 1.4K
Отв.140  28 Янв. 17, 09:26
Очень рад, что Владимир продолжил тему.HBB, 27 Янв. 17, 22:35
Присоединяюсь. Больше малины на форуме! :))) И линукса с питоном! Решения более взвешенными будут получаться. Да и вообще интересней будет. Пора, все-таки, переходить на более высокие уровни абстракции в деле автоматизации процессов.
Только вот  как быть с этими мордами? При копипасте эти гады пропадают. Я  однажды с этим попал. Может админу написать?HBB, 27 Янв. 17, 22:35
Конечно напишите. Тоже присоединяюсь. Такая беда часто просматривается на программистских форумах, где много кода.
А пока можно пользоваться совершенно нейтральным тегом
code
и выключать смайлы. Код не искажается никак. Жаль только красивой подсветки кода тоже не будет. Но может есть решения с нормальной подсветкой и без морд?
msg31 Научный сотрудник Барнаул 4.6K 2.5K
Отв.141  28 Янв. 17, 11:40
ты ради интереса посмотри на фузы ардуины, китайские товарищи там свинью подложили.m16, 28 Янв. 17, 00:11
Кстати, у Atmega2560 не нашел этот фьюз, SCOPT, кажется?
fiyzi.png
Fiyzi. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
HBB Кандидат наук Москва 356 94
Отв.142  28 Янв. 17, 14:53
C-Bell, Вот неплохая отправная точка для RasPI  и прочих
http://webiopi.trouch.com/
Сейчас ковыряю, однако получается на удивление быстро.capsolo, 13 Янв. 17, 18:25

Согласен! Я  тоже поначалу WEBiopi  начал юзать,  за пару часов  установил, настроил, получил данные и по локалке, и снаружи (у  меня статический IP) через 4G на Андроид.

local.jpg
Local. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
 
gpio.jpg
Gpio. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
 
gpio_snaryji.jpg
Gpio_snaryji. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.


Поэтому не прочь продолжить рыть в этом направлении. Но Владимира C-bell немного другой  подход к WEB-мордам  и  фреймворкам. Набрался терпения, жду, когда он озвучит свои мысли.

Хотелось бы (лично мне), по возможности, уйти от писанины на JavaScript, ибо, получая натурпродукт  на нашем оборудовании,  давно забыл, что такое головная боль:)
m16 Модератор Тамбов 1.9K 1K
Отв.143  28 Янв. 17, 16:52
у Atmega2560 не нашел этот фьюзmsg31, 28 Янв. 17, 11:40
в меге2560 несколько иначе -  CKSEL3. вот он, не прошит сука
fb_low.2.jpg
Fb_low. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.


т.е. осциллятор у тебя в режиме Low Power Crystal Oscillator а должен быть в Full Swing Crystal Oscillator
ckel3.jpg
Ckel3. Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.


должно быть так: Fusebits = F7 ..... Fusebit 98DCBA = 110111
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.144  05 Марта 17, 05:38
Правильная структура приложения python flask
Начиная с этого поста и далее разработка будет строиться на базе Raspberry PI 3 и python3.

Создаем правильную структуру python-flask-приложения
По мотивам статьи Python flask фреймворк - правильная структура приложения написал скрипт, который создает структуру папок для приложения и наполняет её виртуальным окружением.
Создатели flask очень рекомендуют использовать в проекте виртуальное окружение virtualenv.
Не вижу ни одной причины игнорировать их рекомендации. Ниже приведен текст скрипта bash:

текст скрипта bash

#!/bin/bash
# Скрипт для создания структуры рабочих папок приложения flask
# и виртуального окружения virtualenv.
# Запуск: bash MakeEnv.sh <Имя папки проекта>

if [ $# == 0 ]
then
   echo "Не задано имя папки!"
   exit 1
fi

echo
echo "Создание рабочей папки $1"
mkdir "$1"
cd "$1"
echo
echo "Создание виртуального окружения"
virtualenv -p python env
echo
echo "Создание папки для кода приложения"
mkdir app
echo
echo "Создание папки для шаблонов"
mkdir app/templates
echo
echo "Создание папки для статических файлов (стили, javascript, и т.д.)"
mkdir -p app/static/{css,js,img}
echo
echo "Активация виртуального окружения"
source env/bin/activate
echo
echo "Установка необходимых пакетов"
pip install flask flask-sqlalchemy flask-wtf flask-script
pip install matplotlib
echo
echo "Создание папки для хранения зависимостей"
mkdir requipments
echo
echo "Сбор базовых зависимостей"
pip freeze > requipments/base.txt
#######################################################################
echo
echo "Создание конфигурации - файл config.py"
echo '#coding=utf8
import os

class Config(object):
  """Содержит базовые параметры конфигурации приложения"""

   # Путь к каталогу запуска прграммы
   basedir = os.path.abspath(os.path.dirname(__file__))

   # Определяет, включен ли режим отладки
   # В случае если включен, flask будет показывать
   # подробную отладочную информацию. Если выключен -
   # - 500 ошибку без какой либо дополнительной информации.
   DEBUG = False

   # Включение защиты против "Cross-site Request Forgery (CSRF)"
   CSRF_ENABLED = True

   # Случайный ключ, который будет использоваться для подписи
   # данных, например cookies.
   SECRET_KEY = "YOUR_RANDOM_SECRET_KEY"

   # URI используемая для подключения к базе данных
   # SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
   SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "Distiller.db")
   SQLALCHEMY_TRACK_MODIFICATIONS = False


class ProductionConfig(Config):
  DEBUG = False

class DevelopmentConfig(Config):
   DEVELOPMENT = True
   DEBUG = True
'
> config.py

#######################################################################
#######################################################################
echo
echo "Создание файла запуска приложения - manage.py"
echo '#!/usr/bin/env python
#coding=utf8
import os
from flask_script import Manager

from app import create_app

app = create_app()
#app.config.from_object(os.environ["APP_SETTINGS"])
manager = Manager(app)

if __name__ == "__main__":
  manager.run()
'
> manage.py
#######################################################################
#######################################################################
echo
echo "Файл создания объекта SQLAlchemy - app/database.py"
echo '#coding=utf8
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
'
> app/database.py
#######################################################################
#######################################################################
echo
echo "Файл инициализации приложения - app/__init__.py"
echo '#coding=utf8
import os
from flask import Flask
from .database import db

def create_app():
  """Функция-фабрика создает экземпляр приложения flask и инициализирует
   его всеми необходимыми настройками"""
   app = Flask(__name__)
   #app.config.from_object(os.environ["APP_SETTINGS"])
   app.config.from_object("config.Config")

   db.init_app(app)
   with app.test_request_context():
      db.create_all()

   #import app.firstmodule.controllers as firstmodule

   #app.register_blueprint(firstmodule.module)

   return app
'
> app/__init__.py
#######################################################################
echo
echo "Завершение"
exit 0


--------------------------------------
Colored with http://dumpz.org

Сама структура папок python flask приложения будет подобна структуре, указанной в вышеупомянутой статье.
структура папок python flask приложения
Distiller
├── app
│   ├── __init__.py
│   ├── database.py
│   ├── controllers.py
│   ├── forms.py
│   ├── models.py
│   ├── static
│   │   ├── css
│   │   ├── img
│   │   └── js
│   ├── templates
│   │   ├── base.html
│   │   ├── index.html
│   │   ├── _list.html
│   │   ├── create.html
│   │   ├── delete.html
│   │   ├── list.html
│   │   ├── update.html
│   │   └── view.html
│   ├── sensors
│   │   └── DS18B20.py
│   └── actuators
│       ├── power.py
│       ├── dephlegmator.py
│       └── cooler.py
├── config.py
├── env
├── manage.py
└── requipments
   ├── base.txt
   ├── development.txt
   └── production.txt

Чтобы запустить скрипт, нужно в LXTerminal ввести примерно такую команду:
bash MakeEnv.sh Distiller
где Distiller - имя рабочей папки проекта.

Для продолжения работы с проектом необходимо зайти в корневую папку проекта и активировать виртуальное окружение:
cd Distiller
source env/bin/activate

Вид подсказки в терминале изменится:
(env) pi@raspberrypi:~/Distiller $

C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.145  05 Марта 17, 06:05, через 28 мин
Конфигурация приложения python flask
Конфигурация приложения будет храниться в файле config.py в корневой папке Distiller.
В конфигурации содержатся различные перменные, необходимые для работы python flask приложения.
В отличие от первоисточника, конфигурационные параметры прописаны непосредственно в этом файле, а не берутся из переменных окружения:
#coding=utf8
import os

class Config(object):
   """Содержит базовые параметры конфигурации приложения"""

   # Путь к каталогу запуска прграммы
   basedir = os.path.abspath(os.path.dirname(__file__))

   # Определяет, включен ли режим отладки
   # В случае если включен, flask будет показывать
   # подробную отладочную информацию. Если выключен -
   # - 500 ошибку без какой либо дополнительной информации.
   DEBUG = False

   # Включение защиты против "Cross-site Request Forgery (CSRF)"
   CSRF_ENABLED = True

   # Случайный ключ, который будет использоваться для подписи
   # данных, например cookies.
   SECRET_KEY = "YOUR_RANDOM_SECRET_KEY"

   # URI используемая для подключения к базе данных
   # SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
   SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "Distiller.db")
   SQLALCHEMY_TRACK_MODIFICATIONS = False


class ProductionConfig(Config):
   DEBUG = False

class DevelopmentConfig(Config):
   DEVELOPMENT = True
   DEBUG = True


--------------------------------------
Colored with http://dumpz.org


Этот файл создается автоматически скриптом bash, приведенным выше.
В процессе развития проекта в конфигурацию добавятся различные определения (назначение управляющих GPIO Raspberry Pi, режимы работы автоматики и пр.)
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.146  05 Марта 17, 06:35, через 31 мин
Файл запуска приложения python flask
Файл запуска приложения в первоисточнике называется manage.py
На мой взгляд, более информативно назвать run.py или даже runserver.py
Но есть какая то непостижимая для меня хитрость в использовании flask-script, запуск приложения осуществляется примерно так:
 python3 manage.py runserver

Содержимое этого файла незамысловато: просто создается и запускается объект-приложение flask
#!/usr/bin/env python
#coding=utf8
import os
from flask_script import Manager

from app import create_app

app = create_app()
#app.config.from_object(os.environ["APP_SETTINGS"])
manager = Manager(app)

if __name__ == "__main__":
   manager.run()


--------------------------------------
Colored with http://dumpz.org


Приложение Flask создается функцией-фабрикой из модуля app/__init__.py:
#coding=utf8
import os
from flask import Flask
from .database import db

def create_app():
   """Функция-фабрика создает экземпляр приложения flask и инициализирует
   его всеми необходимыми настройками"""

   app = Flask(__name__)
   #app.config.from_object(os.environ["APP_SETTINGS"])
   app.config.from_object("config.Config")

   db.init_app(app)
   with app.test_request_context():
       db.create_all()

   #import app.firstmodule.controllers as firstmodule

   #app.register_blueprint(firstmodule.module)

   return app


--------------------------------------
Colored with http://dumpz.org


Конфигурация объекта-приложения flask берётся из файла config.py при создании этого объекта функцией-фабрикой create_app() модуля app/__init__.py
Файлы manage.py и app/__init__.py создаются автоматически  скриптом bash, приведенным выше.
С blueprint-ами пока не заморачиваемся.
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.147  05 Марта 17, 07:33, через 58 мин
База данных (с flask-sqlalchemy)
Использование flask-sqlalchemy (ещё ссылка) переводит работу с базами данных на новый уровень абстракции - объектно-реляционное отображение базы данных (ORM).
Не нужно будет оперировать SQL-запросами, а обращаться к базе как к объекту python.
Очень желательно изучить SQLAlchemy перед использованием flask-sqlalchemy.

Попробуем для начала помещать в таблицу базы данных значения температур, измеренных цифровыми термометрами DS18B20.
Структура таблицы представлена ниже:
Smart Distiller (Умный дистиллятор с управлением по интернет)
Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.

Колонки (поля) таблицы:
id- идентификационный номер термометра в таблице, присваивается автоматически при записи;
IDthermometer- уникальный идентификатор термометра, присваиваемый при изготовлении (вида 28-000000a82ec2);
Name- наименование термометра (как правило, указывает место его установки);
T- текущее значение температуры, измеренной термометром.
Timestamp- Момент фиксации значения температуры.


Структура таблиц в базе данных с помощью SQLAlchemy представляется классами python.
Хранить эти классы будем в файле app/models.py
# -*- coding: utf-8 -*-
from sqlalchemy import event

from app.database import db

class DS18B20(db.Model):
  __tablename__ = 'DS18B20'

   id = db.Column(db.Integer, primary_key=True)
   IDthermometer = db.Column(db.String(16), nullable=False, unique=True)
   Name = db.Column(db.String(64), nullable=False, unique=True)
   T = db.Column(db.Float)
   Timestamp = db.Column(db.DateTime)

   def __str__(self):
      return self.Name


@event.listens_for(DS18B20, 'after_delete')
def event_after_delete(mapper, connection, target):
  # Здесь будет очень важная бизнес логика
   # Или нет. На самом деле, старайтесь использовать сигналы только
   # тогда, когда других, более правильных вариантов не осталось.
   pass


--------------------------------------
Colored with http://dumpz.org

Этот модуль в дальнейшем будет наполняться новыми сущностями, отражающими другие таблицы базы данных, поэтому его создаем врукопашную, а не поручаем скрипту bash.

Модуль app/database.py, из которого берётся объект SQLAlchemy с именем db, создается автоматически скриптом при инициализации приложения:
#coding=utf8
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()


--------------------------------------
Colored with http://dumpz.org
2017-03-05_21-19-03.png
2017-03-05_21-19-03.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.148  05 Марта 17, 07:54, через 21 мин
План приложения
Веб-интерфейс приложения планируется примитивный.
На стартовой странице будет отображаться буквально три пункта навигации:
  • Настройка;
  • Перегон бражки;
  • Второй дробный перегон.
Плюс будут отображаться данные с датчиков (в том числе в графическом виде).
Пункты меню должны становится доступными только после авторизации пользователя через логин/пароль.

При запуске приложение:
  • настраивается в соответствии с конфигурацией;
  • проверяет работоспособность датчиков;
  • проверяет и, при необходимости, создает базы данных;
  • запускает отдельными объектами-потоками:
    • сборщика значений с датчиков;
    • регулятор мощности нагрева;
    • регулятор холодильников (конденсатора и дефлегматора);
    • рисовальщика графиков;
  • стартует веб-сервер.

При выборе в веб-интерфейсе одного из пунктов запуска процесса перегона стартует еще один объект-поток, который реализует последовательность этапов перегонки (разгон, стабилизация, отбор, в том числе - дробный) во взаимодействии с объектами-потоками, запущенными при старте приложения. Во время работы реализатора процесса перегона также должна прорисовываться статистика значений датчиков в виде графиков. Также должна отображаться информация о текущем этапе и его длительности.
HBB Кандидат наук Москва 356 94
Отв.149  05 Марта 17, 08:36, через 43 мин
Colored with http://dumpz.orgC-Bell, 05 Марта 17, 06:05
Может кому пригодится - вордовский скрипт для убивания смайлов
Smart Distiller (Умный дистиллятор с управлением по интернет)
Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.

:)
:o
:(
;)
:D 'D "D ;D
:P
:-*
:-[
8)
:'(
:-X
'DS18B20
')
")




Sub ReplaceSmiles()
'
' ReplaceSmiles Макрос
'
Dim test
test = Array("('D?)", "(:D?)", "(""D?)", "(;D?)", "(:P?)", _
"('[)]?)", "(""[)]?)", "(:[)]?)", "(:[(]?)", "(;[)]?)", "(:-[*]?)", _
"(:-[[]?)", "(8[)]?)", "(:'[(]?)", "(:-X?)", "(:Х?)", _
"(:о?)", "(:o?)", "(:0?)")
i = 1
For i = 0 To UBound(test)
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = test(i)
        .Replacement.Text = "[nobbc]\1[/nobbc]"
        .Forward = True
        .Wrap = wdFindContinue
        .MatchWildcards = True
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
Next i

End Sub
Михаил Литвинов Студент Тольятти 41 5
Отв.150  17 Апр. 17, 22:00
Веб-интерфейс приложения планируется примитивный.
На стартовой странице будет отображаться буквально три пункта навигации:
Настройка;
Перегон бражки;
Второй дробный перегон.C-Bell, 05 Марта 17, 07:54
С нетерпением жду продолжения...
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.151  28 Мая 17, 07:27
Использование Visual Studio 2015 для создания Flask-приложения Python.
Использование Visual Studio 2015 для создания Flask-приложения Python.

    Для создания приложений python в среде Visual Studio 2015 фирма Microsoft выпустила специальное дополнение - Python Tools for Visual Studio.
Скачать его можно с github: http://microsoft.github.io/PTVS/
В этом дополнении в том числе есть шаблон создания веб-сайтов на языке python с использованием микрофреймворка Flask.

При использовании русских букв в файлах проекта могут возникать ошибки.
Это связано с тем, что далеко не все файлы при создании проекта Visual Studio сохраняет в кодировке utf-8.
Исправляется это несложно: в обозревателе решения открывается файл, в меню файл->сохранить <имя файла> как... справа от кнопки "Сохранить" нажать треугольник и выбрать Сохранить с кодировкой..

Использование Visual Studio удобно:
- создается работоспособная структура приложения python Flask;
- все файлы (и питона и html) редактируются в одном месте;
- можно сразу проверить работоспособность программы в любом установленном браузере.




Добавлено через 8ч. 28мин.:

Есть какая то проблема со ссылками - браузер упорно не хочет найти папку 'static', где расположены стили и рисунки.
Пока решения не нашел...

Добавлено через 2дн. 8ч. 23мин.:

Похоже, это проблема Windows 10, любые ссылки в файле html вызывают ошибку HTTP/1.1 500.
Под Windows 7 всё работает.

Добавлено через 8дн. 18ч. 41мин.:

Поставил Visual Studio 2017 comunity. Вроде пока глюков нет, всё работает.

Разобрался почему не работают ссылки на файлы проекта.
Всё оказалось банально: python не воспринимает русские буквы в путях к файлам.
Решение тоже незамысловатое: создал в корне диска C: папку VS2017 и уже в ней папки проектов.
Само собой в названиях файлов и папок только латинские буквы.
Все файлы сохранены в кодировке utf-8.
В начале питоновских файлов поставил указатель кодировки # -*- coding: utf-8 -*-

Visual Studio реально удобная вещь.

Inco Студент Донецк 47 10
Отв.152  22 Авг. 17, 14:38
Поставил эту Visual Studio 2017 Community Edition.
Выглядит неплохо. И питон поддерживает и даже C\C++ для Linux.

Очень интересно продолжение проекта. Будет?

А пока закупился DS-ками и нержавеющими гильзами для них - делаю датчики...
lesbeg Доктор наук Екатеринбург 657 458
Отв.153  27 Авг. 17, 17:10
Поставил эту Visual Studio 2017 Community Edition.
Выглядит неплохо. И питон поддерживает и даже C\C++ для Linux.Inco, 22 Авг. 17, 14:38

Лучшей IDE под питоновские проекты считается PyCharm. WingIDE где-то рядом, но хуже. PyDev (Eclipse) тоже имеет много поклонников.

Однако большая часть python-разработчиков мне знакомых пишут или на vim или на Sublime Text -- это не IDE, а достаточно навороченные редакторы, которые с помощью плагинов и тонкой настройки становятся "почтиIDE", но работают при том на порядок шустрее истинных IDE. Из интересных редакторов есть еще Emacs и Atom (однако он больше пригоден для фронтендовсих задач). Но, опять же, большая часть вышеупомянутых разработчиков работают или на маках, или на линуксах.

Если все таки хочется писать код в Windows, но продакш будет на никсах, то опитимальный вариант на текущий день это PyCharm + Vagrant. Vagrant это обертка-абстракция над популярными виртуальными машинами, т.е. это что-то вроде единого API к разным системам виртуализации. PyCharm из коробки умеет умеет работать с вагрантом. Т.е. твоя IDE стоит на винде и ты пишешь в привычной системе, но запуск и отладка кода через вагрант осуществляется в виртуальной машине с экосистемой аналогичной продакшину.

Почему написание кода для никсов на винде -- плохая идея?

  • Ты лишается возможностей использовать вещи, которых не существует под Windows. Самый яркий пример -- Redis. Redis идеально вписывается в в решения на SOC. Он есть почти в любом мало-мальски серьезном IoT проекте. И таких решений, весьма годных для IoT, можно перечислить много.
  • Никто не гарантирует, что твой код будет работать одинаково хорошо на обоих системах. Например, в Win нет системного метода аналогичного fork() (в python == os.fork()), который применяется во множестве питоновских модулей связанных с многопоточностью. Питоновский метод time.clock() в никсах и винде возвращает разные сущности (осмысли это!). Я выше привел две ссылки на документацию по двум часто используемым модулям (time, os). Браузерным поиском поищи на эти страницах "Availability: Unix.". В модуле time всего 8 методов unix-only. В os -- 105. Если чего, то к Юниксам относится не только Linux, BSD и прочие хардкоры, но и MacOs с Андроидом. Резюмируя: в Windows ты лишаешься значительной части стандартной библиотеки Python.
  • Аналогично предыдущему Win и никсы имеют разный взгляд на регистр имен файловой системы. Для Windows папка MyFolder и myfolder -- одно и тоже. Для никса -- две разных директории (папки в виндовсе остались). Т.е. если в коде допустить неопрятность в именах файлов и каталогов, то под виндой все будет работать, а после выкатывания на продакшн вылезут баги.
  • Установка пакетов в окружение, содержащих не только питоновский код (таких очень много), на винде и в никсе -- две большие разницы. В никсах из коробки есть gcc и все пакеты ориентированны на него. В винде компилятора нет и каждая версия питона и даже отдельного пакета может требоваться на свой. Кратко проблема дистрибуции под виндой описана здесь. Апофеозом этой проблемы является компьютер разработчика, где стоят все версии Visual C++ начиная с VCC6, mingw и CodeBlocks.
  • Есть и обратное движение. Например, лок файлов в Винде намного лучше чем в никсах (fcntl).
  • И т.д. Этот список, на самом деле, может быть большим.

Поэтому мой совет таков: если ты сеньор и твой код имеет 100% покрытие тестами, то ты можешь писать код предназначенный для одной ОС в другой. Опыт и скилл помогут избежать ошибок, а автотесты выявят их на целевой ОС, если они все-таки проявятся. В противном случае лучше использовать PyCharm + Vagrant, т.к. это best practice для тех кто пишет на Windows или использовать в разработке какую-то unix-систему.
Inco Студент Донецк 47 10
Отв.154  27 Авг. 17, 20:37
Спасибо, питон я смотрю впервые, поэтому любая информация для меня очень полезна. А так я больше по базам данных... Но ничего, будет надо - освоим. Линукс в виртуал боксе уже поселил на комп.
lesbeg Доктор наук Екатеринбург 657 458
Отв.155  27 Авг. 17, 23:49
питон я смотрю впервые, поэтому любая информация для меня очень полезна.Inco, 27 Авг. 17, 20:37

Тогда вот тебе еще один очень полезный совет Улыбающийся

Пиши в соответствии с PEP8. Это стандарт оформления python-кода. Если ты думаешь, что это неважно, то прочти философию языка, на котором хочешь писать. Для текущего совета тебе стоит особенно осмыслить пункты 7 и 8.

Что лично тебе даст PEP8Если ты станешь писать в соответствии с PEP8, то:

Во-первых, тебе станет намного легче читать чужой код, потому что большинство опытных разработчиков соблюдают PEP8 или производный от него Google Python Style Guide.

Во-вторых, ты сильно снизишь вероятность того, что тебя пошлют лесом более опытные товарищи, когда ты обратишься к ним за помощью на профильных ресурсах (не PEP8-код часто воспринимается как неопрятный, кроме того большинство средств разработки его активно и агрессивно подсвечивают и просьба найти баг в таком коде может быть воспринята как проявление неуважения). \

В третьих, ты повысишь совместимость своего кода с тем что предлагает тебе интернет. Т.е. если ты в качестве одного отступа используешь 8 пробелов или 2, то вставка нормального питоновского кода у тебя вызовет indentation error.

Итого:
В Питон упор сделан на высокую читаемость и сопровождаемость кода.
Для того чтобы поддерживать высокую читаемость кода придуманы правила его оформления.
Особые случаи не настолько особые, чтобы нарушать правила.
PEP8 -- это самый первый критерий качества твоего кода (их много). Если твое средство разработки не умеет само на лету валидировать PEP8, то его место на помойке воспользуйся этим сервисом. Просто скопируй в него свой код и нажми на "Check..."

Линукс в виртуал боксе уже поселил на комп
Inco, 27 Авг. 17, 20:37

Linux достаточно дружелюбен, просто он разборчив в друзьях. Если ты его изучишь, то дискомфорта от него у тебя не будет. Второй момент, но он очень важен (применительно к колоннам полным спирта с источником нагрева под ними) -- если ты освоишь эту ОС, то ты сможешь ей доверять. Человек обычно мало доверяет тому, что плохо понимает. Это нормально. Но поверь, при определенном скилле у тебя появится доверие к ней и возможность построить систему которой можно доверится (на Debian МКС летает).

Я советую начинать с Debian Stable (лучше, но сложнее) или LMDE (дружелюбней, изкоробчней). А через год-полтора попробовать Arch (появится понимание как работает ОС).
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.156  01 Сент. 17, 15:50
Visual Studio 2017 для разработки python web проектов
     Использование Microsoft Visual Studio 2017 community для разработки python web приложений позволяет значительно увеличить скорость создания этих приложений.
    Хотя заявление Microsoft, что Visual Studio 2017 – «Лучший инструмент для разработки любого приложения под любую платформу» и вызывает некоторое сомнение, разрабатывать программы python с web-интерфейсом для работы в среде Raspbian одноплатного компьютера Raspberry Pi в VS2017 весьма удобно.
    Бесплатную версию Microsoft Visual Studio 2017 community можно скачать с сайта этого продукта. После скачивания установщика нужно его запустить. Если прочитали сообщение «Одну минуту, скоро все будет готово», не верьте, пройдет значительно больше времени. В открывшемся далее окне нужно выбрать на чем будет вестись разработка (рабочие нагрузки). В том числе нужно поставить галочку и на пункте «Разработка на Python”, нажать кнопку «Установить» и идти пить кофь (много).
    При первом запуске VS2017 попросит зарегистрироваться в Microsoft либо использовать существующую учетную запись, лучше это сделать, будут доступны дополнительные возможности.
    После запуска выбрать меню Файл->Создать->Проект, на правой панели Python->Web в качестве образца выбрать Веб-проект Flask. Задать имя решения (например, Distiller, без русских букв) расположение лучше выбрать короткое и также без русских букв (например, C:VS2017 или C:Projects) и нажать кнопку OK.
    Далее в окне поддержки Python выбрать «Установить в виртуальном окружении...».
    При установке Visual Studio 2017 community установил Python 3.6. Поэтому в окне Добавление виртуального окружения остается нажать кнопку Создать.
VS создает полностью работоспособный проект python flask.
    В обозревателе решений (панель справа) можно увидеть, какие пакеты python установлены в виртуальное окружение и структуру всего проекта. Файл runserver.py – файл запуска проекта.
    Запуск проекта осуществляется клавишей F5 или кнопкой с зеленым треугольником и названием браузера. При этом возможно появится запрос на пересборку проекта, нужно согласиться.
    Если возникла проблема с кодировкой, скорее всего, нужно поменять имя компьютера с User-ПК на User-PC (чтобы не было в имени кириллицы).
Созданный проект можно взять как основу для разработки собственных веб-проектов. Полезно также изучение его структуры и состава.

    Продукты Microsoft не стесняют себя в потреблении ресурсов компьютера. Microsoft Visual Studio 2017 не является исключением. Поэтому на слабеньких машинах придётся ожидать завершения некоторых операций студии.

P.S. Собираюсь продолжить цикл статей по созданию веб-интерфейса. Поэтому тему пока прикрываю до выкладывания всейи нформации. Обсуждение потом.
P.P.S. Веб интерфейс уже работает, правда пока возникают ошибки.


Меню создание проекта.png
Меню создание проекта.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
Flask-шаблон.png
Flask-шаблон.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
поддержка Python.png
поддержка Python.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
Виртуальное окружение.png
Виртуальное окружение.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
Окружение Python.png
Окружение Python.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.157  02 Сент. 17, 15:36
Структура проекта python flask в Visual Studio 2017
     Потыкав ссылки на отображаемой в браузере странице проекта понимаешь, что проект пока умеет не так уж и много. Собственно, своих страничек всего три, плюс ссылки на Flask-ресурсы.
    На этом этапе важно, что проект работает.
    В чёрном командном окне можем видеть лог работы встроенного веб-сервера Flask.
    Структура созданного проекта несколько отличается от рекомендуемой гуру питона. Но нам же ехать, а не шашечки:
   
     Distiller
    ├── requipments.txt
    ├── runserver.py
    ├── Distiller
    │   ├── __init__.py
    │   ├── views.py
    │   ├── static
    │   │   ├── content
    │   │   ├── fonts
    │   │   └── scripts
    │   └── templates
    │       ├── about.html
    │       ├── contact.html
    │       ├── index.html
    │       └── layout.html
    └── env

   
    В корневой папке проекта два файла (requipments.txt и runserver.py) и две подпапки (Distiller и env).
    В env хранится виртуальное окружение Python, Distiller – это пакет программ проекта вместе с необходимыми данными.
    Файл requipments.txt содержит список модулей Python, которые нужно установить в виртуальное окружение для нормальной работы проекта.
    Файл runserver.py – файл запуска проекта.
    В файле __init__.py происходит начальная инициализация переменных и объектов проекта.
    Вся магия веб-вывода осуществляется с помощью функций файла views.py.
    В папке static хранятся файлы разметки страниц (content), фонты (fonts) и подключаемые скрипты (scripts).
    Папка templates содержит шаблоны веб-страниц (один базовый - layout.html и три производных от базового).
   
    Содержимое стартового файла runserver.py:
"""
This script runs the Distiller application using a development server.
"""


from os import environ
from Distiller import app

if __name__ == '__main__':
   HOST = environ.get('SERVER_HOST', 'localhost')
   try:
       PORT = int(environ.get('SERVER_PORT', '5555'))
   except ValueError:
       PORT = 5555
   app.run(HOST, PORT)


--------------------------------------
Colored with http://dumpz.org

    незамысловато. В нем запускается приложение Flask (строка app.run(HOST, PORT)). Приложение app импортируется из пакета Distiller (from Distiller import app), где оно инициализируется в файле __init__.py.

    Файл инициализации проекта __init__.py тоже несложный:
"""
The flask application package.
"""


from flask import Flask
app = Flask(__name__)

import Distiller.views


--------------------------------------
Colored with http://dumpz.org


    В нем импортируется класс Flask пакета flask и из этого класса создается экземпляр приложения flask.
    Завершается инициализация импортом функций отображения веб-страниц, которые описаны в файле views.py:
"""
Routes and views for the flask application.
"""


from datetime import datetime
from flask import render_template
from Distiller import app

@app.route('/')
@app.route('/home')
def home():
   """Renders the home page."""
   return render_template(
       'index.html',
       title='Home Page',
       year=datetime.now().year,
   )

@app.route('/contact')
def contact():
   """Renders the contact page."""
   return render_template(
       'contact.html',
       title='Contact',
       year=datetime.now().year,
       message='Your contact page.'
   )

@app.route('/about')
def about():
   """Renders the about page."""
   return render_template(
       'about.html',
       title='About',
       year=datetime.now().year,
       message='Your application description page.'
   )


--------------------------------------
Colored with http://dumpz.org


    Нужно отметить, что __init__.py и views.py имеют циклические импорты друг у друга. Для исключения отрицательных последствий в файле __init__.py Distiller.views импортируется в последней строчке.
    Три функции home(),contact() и about() возвращают сформированные из шаблонов страницы при обращении на соответствующий адрес сервера.

    Таким образом, ничего сверхъестественного и никакого колдунства нет. Flask берёт всю работу по предоставлению страниц на себя. Естественно, нужно подготовить соответствующие шаблоны html, их разметку css и необходимые скрипты.
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.158  03 Сент. 17, 21:59
Фейк температурных данных
     Прежде чем продолжить описание процесса создания веб-интерфейса, придется сделать некоторое добавление в проект, без которого нет смысла его создавать.
    Ещё раз вспоминаем, что автоматизируем протекание тепловых процессов. И основные контролируемые параметры – это температура разных участков тепловой системы. Актуальные температурные данные должны отображаться на веб-странице.
    Как подключать термометры DS18B20 к Raspberry PI было рассмотрено выше ([сообщение #12926952]).
    Можно было бы и к компьютеру Windows подключить гирлянду цифровых термометров DS18B20 через какой-либо USB-адаптер. Но для проектирования и отладки веб-интерфейса можно поступить иначе – написать программу-фейк, которая возвращает «температурные данные», сформированные случайным образом.
    Для добавления к проекту такого модуля и лучшей структурности проекта нужно создать отдельную папку-пакет, в которую в дальнейшем возможно будут включены и другие модули-драйверы различных датчиков (давления, напряжения, тока и пр.) Для создания такой папки нужно ткнуть в обозревателе решений (панель справа) правой клавишей на папке пакета Distiller (не всего решения), выбрать Добавить->Создать папку и задать имя этой папки «sensors». Чтобы эта папка стала пакетом python, в ней нужно создать пустой файл с именем __init__.py, для этого кликаем на папке sensors правой клавишей мыши, из контекстного меню выбираем Добавить->Создать элемент... В открывшемся окне выбираем Пустой файл Python, задаем имя __init__.py и нажимаем кнопку Добавить.
    Осталось добавить в папку-пакет программу-фейк, имитирующую наличие цифровых термометров: на папке sensors правой клавишей мыши, из контекстного меню Добавить->Создать элемент..., Пустой файл Python, задать имя DS18B20.py и нажать кнопку Добавить.
    В пустой файл Python вставить следующее содержимое:
"""
$Id: DS18B20.py, 2017/01/23
Copyright (c) 2017 C-Bell (VAGor).
Программа-фэйк.
Имитирует выдачу показаний цифровых термометров DS18B20
значения температур формируются случайным образом.
Количество термометров - 5 с предустановленными номерами.


Использование:
import DS18B20
DS18B20list=DS18B20.Measure()
где DS18B20list - список кортежей (ID термометра, значение температуры,
                 момент фиксации температуры)

Особенности:
используется модуль threading для "одновременного"
запуска "измерения" температуры всеми "цифровыми термометрами DS18B20"
так же как в реальном модуле
"""


import random   #Модуль случайных чисел
import os       #Модуль функций для работы с операционной системой
import sys      #Модуль доступа к некоторым системным переменным и функциям
import glob     #находит все пути, совпадающие с заданным шаблоном
import time     #Модуль для работы со временем
import datetime #Модуль для работы с датой и временем
import threading    #Модуль для работы с потоками

#Шаблон ID термометра
TemplateDS18B20="28-000000"

#Класс исключения отсутствия наличия шины 1-wire
class NoOneWireError(Exception):
   u'''Исключение отсутствия наличия шины 1-wire'''
   pass

#Класс исключения при отсутствии цифровых термометров на шине 1-wire
class NoDS18B20Error(Exception):
   u'''Исключение при отсутствии цифровых термометров на шине 1-wire'''
   pass

#Класс исключения при таймауте цифровых термометров на шине 1-wire
class TimeOutDS18B20Error(Exception):
   u'''Исключение при таймауте измерения температуры'''
   pass

#Проверка наличия шины 1-wire (редкий случай)
if random.random()>0.99:
   #Генерить исключение.
   raise NoOneWireError('No 1-wire bus')
   print(u"Включите поддержку 1-Wire в  конфигурации Raspberry!")
   exit()

#Создание списка термометров
Tlist=[]    #Пустой список термометров
NumbT=5  #Количество термометров
#Создать ID каждому термометру
for i in range(NumbT):
   Tlist.append(TemplateDS18B20+chr(ord('E')-i)*6)
   
#Генерирует и возвращает значение температуры с указанного термометра
def read_temp_raw(device_folder):
   u'''Возвращает сгенерированное значение температуры'''
   time.sleep(1+random.random()*0.05)  #Имитируем процесс измерения
   return (device_folder, round(random.random()*100,1), datetime.datetime.utcnow())
#--------------------

class T(threading.Thread):
   u'''Класс для получения температуры от одного цифрового термометра'''
   def __init__(self, device_folder):
       '''Инициализация класса'''
       threading.Thread.__init__(self)
       self._device_folder = device_folder
       #self.name = device_folder
       self._T = None
   def run(self):
       u'''Функция, вызываемая при старте потока'''
       self._T = read_temp_raw(self._device_folder)
   @property
   def T(self):
       u"""Возвращает текущее значение температуры"""
       return self._T
   @property
   def name(self):
       u'''Возвращает название папки термометра'''
       return self._device_folder
   
#Возвращает кортеж из списка кортежей названий термометров с температурами
#и временем измерения
def Measure(Sort=False, SortByT=False, TimeOut=None):
   u'''Функция Measure() ищет все цифровые термометры DS18B20 на шине 1-wire
   читает значения измеренных ими температур и возвращает в виде кортежа
   (список кортежей (ID термометра, температура), момент времени измерения)'''

   device_folders = Tlist
   #Если термометры DS18B20 на шине не найдены, генерировать исключение
   if len(device_folders)==0:
       #Генерить исключение.
       raise NoDS18B20Error('DS18B20 not found on 1-wire bus')
   
   #Список объектов-потоков
   Threads=[]

   #Список термометров
   DS18B20list=[]

   #Создание объектов-потоков для каждого термометра
   for device_folder in device_folders:
       Threads.append(T(device_folder))

   #Запуск всех потоков
   for eashT in Threads:
       eashT.start()

   #Присоединение потоков к текущему, чтобы ожидать завершение измерения
   for eashT in Threads:
       eashT.join(TimeOut)

   # Проверить таймауты потоков
   for eashT in Threads:
       if eashT.isAlive():
           raise TimeOutDS18B20Error('Timeout of measure of temperature at %s'%eashT.name)

   #Сбор значений температур термометров
   for eashT in Threads:
       DS18B20list.append(eashT.T)

   def sortByT(ThermoData):
       return ThermoData[1]

   #Если заказано, сортируем список по ID термометров
   if Sort: DS18B20list.sort()
   #Если заказано отсортировать по температуре, сортируемо
   if SortByT: DS18B20list.sort(key=sortByT, reverse=True)
   #Выдача результатов
   return DS18B20list

def main():
   u'''Тестовая функция, работающая при запуске модуля непосредственно'''
   t=0
   tMax=0
   tMin=10
   for i in range(1, 9999999):
       timeBegin=time.time()
       DS18B20list=Measure()
       tMeasure=time.time()
       #os.system('clear')
       for DS18B20 in DS18B20list:
           print(u"%s\t%3.1f градC %s" % DS18B20)
       print(u'Время измерения=%ssec' % (tMeasure-timeBegin))
       t+=(tMeasure-timeBegin)
       print(u'Среднее время измерения=%ssec' % (t/i))
       if (tMax<(tMeasure-timeBegin)):
             tMax=(tMeasure-timeBegin)
       print(u'(mt)Максимальная продолжительность измерения=%ssec' % tMax)
       if (tMin>(tMeasure-timeBegin)):
             tMin=(tMeasure-timeBegin)
       print(u'(mt)Минимальная продолжительность измерения=%ssec' % tMin)
       print('')

if __name__ == '__main__':
   main()


--------------------------------------
Colored with http://dumpz.org


    Программа имитирует гирлянду из пяти DS18B20, в комментариях можно почерпнуть сведения об использовании этого модуля.
    Пакет python (без виртуального окружения) приложен в архиве Distiller.zip
    При переносе проекта на Raspberry Pi этот модуль будет заменён на боевой.



2017-09-04_02-01-57.png
2017-09-04_02-01-57.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
2017-09-04_02-10-09.png
2017-09-04_02-10-09.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
2017-09-04_02-17-25.png
2017-09-04_02-17-25.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.
2017-09-04_03-07-03.png
2017-09-04_03-07-03.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.

Distiller.zip 357.0 Кб
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.159  04 Сент. 17, 08:40
Веб интерфейс – первое приближение.
     После внедрения в проект источника температурных данных можно приступить к процессу создания механизма представления этих данных на веб-странице.
    Нужно отметить, что для создания веб-интерфейса приемлемого качества придётся помимо python освоить ещё три языка: гипертекстовой разметки HTML, разметки CSS и программирования JavaScript.
    Упростим проект, уберём ненужные шаблоны веб-страниц из папки templates (about.html, contact.html, index.html), кликнув правой клавишей мыши на каждом из них и выбрав Удалить.
    Для вывода температурных данных будем использовать шаблон layout.html, соответствующим образом его отредактировав:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>{{ title }} - Distiller</title>
   <link rel="stylesheet" type="text/css" href="/static/content/bootstrap.min.css" />
   <link rel="stylesheet" type="text/css" href="/static/content/site.css" />
   <script src="/static/scripts/modernizr-2.6.2.js"></script>
</head>

<body>
   <div class="navbar navbar-inverse navbar-fixed-top">
       <div class="container">
           <div class="navbar-header">
               <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
               </button>
               <a href="/" class="navbar-brand">Дистиллятор</a>
           </div>
       </div>
   </div>

   <div class="container body-content">
       {% for T in Tlist %}
           <p>{{T[0]}} = {{T[1]}}°C</p>
       {% endfor %}
       <hr />
       <footer>
           <p>© {{ year }} - Distiller</p>
       </footer>
   </div>

   <script src="/static/scripts/jquery-1.10.2.js"></script>
   <script src="/static/scripts/bootstrap.js"></script>
   <script src="/static/scripts/respond.js"></script>
   {% block scripts %}{% endblock %}

</body>
</html>


--------------------------------------
Colored with http://dumpz.org


    В цикле for в шаблоне формируются абзацы <p>, содержащие наименование термометра и его показания.

    Упростим модуль визуализации views.py, оставив лишь одну функцию представления шаблона по корневому адресу “/” и дополнив её получением температурных данных:
"""
Routes and views for the flask application.
"""


from datetime import datetime
from flask import render_template
from Distiller import app
from Distiller.sensors import DS18B20

@app.route('/')
def home():
   """Renders the home page with temperature data."""
   return render_template(
       'layout.html',
       Tlist=DS18B20.Measure(),
       title='Home Page',
       year=datetime.now().year,
   )


--------------------------------------
Colored with http://dumpz.org

    Запускаем проект (F5) и о чудо – видим на веб-странице в браузере список термометров с их показаниями.
    Только эта картинка стоит застывшая, чтобы получить свежие данные, нужно обновить веб-страницу, нажав F5 или соответствующую кнопку.
    Чтобы браузер автоматически обновлял страницу через каждую секунду можно использовать специальный мета-тег, вставив его в тег <head>:
<meta http-equiv="Refresh" content="1" />
    Теперь страничка оживает и температурные данные обновляются.
Но наблюдается несколько негативных моментов:
1. период обновления больше одной секунды;
2. при обновлении страничка моргает;
3. обновляется вся страничка целиком (если бы на страничке были картинки, то они обновлялись бы тоже, что увеличивает трафик сервера).

Текущая версия проекта – в файле Distiller.zip

2017-09-04_13-49-35.png
2017-09-04_13-49-35.png Smart Distiller (Умный дистиллятор с управлением по интернет). Автоматика.

Distiller.zip 360.1 Кб