Страница 1 из 2

Поддержка Python в Majordomo

Добавлено: Ср ноя 20, 2019 12:19 pm
sergejey
В систему (альфа-ветка) добавилась базовая поддержка Python в качестве языка программирования сценариев и методов объектов.

Как использовать?

Просто в коде сценариев и методов используйте синтаксис Python. Система пытается сама определить язык и использоваться соответствующий интерпретатор. В Linux-системах используется тот интерпретатор Python, который установлен по-умолчанию и вызывается через команду python (для системы на базовом образе (Raspberry Pi) это должно работать без дополнительных настроек). Если хотите использовать свой интерпретатор, то необходимо в файле config.php прописать константу PYTHON_PATH -- в Windows-системе это обязательно нужно сделать, чтобы данный функционал заработал.

Пример установки константы:

Код: Выделить всё

Define('PYTHON_PATH','/usr/bin/python');
Взаимодействие с другими компонентами системы

Для работы с системой для Python-кода автоматически подключается библиотека mjdm (/lib/python/mjdm.py) из которой доступны следующие функции:

mjdm.runScript(scriptName, params) -- запуск скрипта scriptName с параметрами (не обязательно), params -- здесь и далее переменная типа "словарь"

mjdm.callMethod(objectMethodName, params) -- запуск метода объекта "object.method" с параметрами (не обязательно)

mjdm.setGlobal(propertyName, value) -- установка свойства "object.property"

mjdm.getGlobal(propertyName) -- получение значения свойства

mjdm.callAPI(api_url, method, params) -- вызов функции API (например "/api/method/object.method") с параметрами (не обязательно)

Пример кода сценария:

Код: Выделить всё

print("This is Python script code")
x = 1
print("x is " + str(x) + ".")
mjdm.runScript("timeNow",{'add': 'Привет'})
mjdm.callMethod("openClose01.unblockSensor")
mjdm.setGlobal("Openclose01.blocked",0)
mjdm.sg("Openclose01.blocked",0)
print(mjdm.gg("Openclose01.blocked"))
Особенности использования методах

Python-код при использовании в методе может обращаться к данным/методам объекта, которому принадлежит, с помощью следующего кода:

self.setProperty(property_name,value) -- установка свойства "property_name" данного объекта

self.getProperty(property_name) -- получение свойства "property_name" данного объекта

self.callMethod(method_name , params); -- запуск метода "method" данного объекта с параметрами (не обязательно)

Пример кода метода:

Код: Выделить всё

print("This is Python method code")
self.setProperty("sampleProperty",2)
print(self.getProperty("sampleProperty"))
self.callMethod("sampleMethod2")
Разное

Вы можете без каких-либо проблем вызывать сценарии/методы "друг из друга" независимо от того, как они написаны (PHP/Blockly/Python).

При вызове сценария/метода на Python с передачей параметров, их можно использовать через переменную params -- она имеет тип "словарь" и будет содержать передаваемые параметры.

Python-код можно по идее и в модули встраивать, в системе появилась PHP-функция python_run_code($code, $params = '') -- она исполняет Python-код, но пока вариант встраивания в модуль лишь теоретический и на практике не использовался.

Обратите внимание! Поддержка Python реализована только в сценариях и методах. Если какой-то модуль позволяет в качестве реакции задавать код, то скорее всего поддерживается только код на PHP (например, код в Меню, Веб-переменных, Шаблонах поведения и т.п.)

Re: Поддержка Python в Majordomo

Добавлено: Ср ноя 20, 2019 1:08 pm
savenko_egor
Дабы не захламлять основную систему модулями Python-а, рекомендую использовать venv (виртуальное окружение).
Удобно это тем, что в случае если было установлено много модулей, или какие-то из модулей сломали зависимости, то можно удалить папку виртуального окружения и создать новое чистое окружение.


Python2:
Установка:

Код: Выделить всё

sudo apt-get install python-pip
sudo pip install virtualenv
Создание виртуального окружения:

Код: Выделить всё

virtualenv /var/www/html/python/
В конфигурационном файле заменить или добавить строку интерпретатора на:

Код: Выделить всё

Define('PYTHON_PATH',SERVER_ROOT.'/python/bin/python');
Установка модулей внутри виртуального окружения (venv) производится таким образом:
Вход в виртуальное окружение:

Код: Выделить всё

. /var/www/html/python/bin/activate
Успешным входом в окружение, будет добавление такой конструкции перед приглашением ввода коносли:

Код: Выделить всё

(python)
То есть если раньше приглашение было таким:

Код: Выделить всё

user@smart:/var/www/html$
То после входа оно станет таким:

Код: Выделить всё

(python) user@smart:/var/www/html$
Установка модуля внутри окружения:

Код: Выделить всё

pip install module_name
Список модулей можно найти по ссылке: https://pypi.org/

После установки необходимых модулей, нужно выйти из окружения. Это производится такой командой:

Код: Выделить всё

deactivate
Успешным выходом из окружения, будет удаление конструкции (которая описывалась выше) перед приглашением ввода коносли.

Python3:
Установка:

Код: Выделить всё

sudo apt-get install python3-venv
Создание виртуального окружения:

Код: Выделить всё

python3 -m venv /var/www/html/python
В конфигурационном файле заменить путь интерпретатора на:

Код: Выделить всё

Define('PYTHON_PATH',SERVER_ROOT.'/python/bin/python');
Установка и удаление модулей, выход из виртуального окружения производится так же как и для Python2.




Для правильной работы функций MajorDoMo в виртуальном окружении, необходимо установить модуль работы с mysql:
Python2:

Код: Выделить всё

sudo apt-get install python-dev default-libmysqlclient-dev

Код: Выделить всё

. /var/www/html/python/bin/activate
pip install mysqlclient
deactivate
Python3:

Код: Выделить всё

sudo apt-get install python3-dev

Код: Выделить всё

. /var/www/html/python/bin/activate
pip install mysqlclient
deactivate


Для переноса установленных модулей виртуального окружения между разными машинами, можно использовать такую команду:

Код: Выделить всё

pip freeze > requirements.txt
Эта команда создаст файл со списком всех установленных модулей и их версий внутри окружения.
Теперь для того чтобы развернуть идентичное окружение, которое было на машине где запускалась команда указанная выше, достаточно выполнить команду:

Код: Выделить всё

pip install -r requirements.txt
Не забывайте что команды необходимо выполнять находясь в виртуальном окружении.
Для чего это удобно? В случае если Вы написали какой-то код, для его работы устанавливали какие-то модули, и хотите поделиться этим кодом, то Вам достаточно выполнить freeze и передать полученный файл другому человеку. Человек имея этот файл и выполнив install -r, получит такое же окружение как у вас, и Ваш код 100% будет работать и у него.

Re: Поддержка Python в Majordomo

Добавлено: Ср ноя 20, 2019 8:47 pm
vitt76
Попытка выключить режим темного времени суток, валится такая ошибка
File "/var/www/cms/python/d1d615e8add820b954c66ff752d2d972.py", line 18 /* begin injection of {SDevices} */ ^ SyntaxError: invalid syntax
Режим не включается.

Re: Поддержка Python в Majordomo

Добавлено: Ср ноя 20, 2019 11:01 pm
savenko_egor
vitt76 писал(а):
Ср ноя 20, 2019 8:47 pm
Попытка выключить режим темного времени суток, валится такая ошибка
File "/var/www/cms/python/d1d615e8add820b954c66ff752d2d972.py", line 18 /* begin injection of {SDevices} */ ^ SyntaxError: invalid syntax
Режим не включается.
Покажи код.

Re: Поддержка Python в Majordomo

Добавлено: Чт ноя 21, 2019 7:17 am
vitt76
Уже все решили, спасибо Сергею!

Re: Поддержка Python в Majordomo

Добавлено: Сб дек 21, 2019 4:17 pm
pash4uga
Добрый день!
Не получается завести на win7x64, прописал путь в конфиге Define('PYTHON_PATH', 'C:\Users\pash4uga\AppData\Local\Programs\Python\Python37');
Но при выполнении кода в сценариях получаю ошибку:
СпойлерПоказать
Сохраненное изображение 2019-12-21_21-14-35.868.jpg
Сохраненное изображение 2019-12-21_21-14-35.868.jpg (79.39 КБ) 9110 просмотров
Путь до python.exe верный, что не так?

Re: Поддержка Python в Majordomo

Добавлено: Сб дек 28, 2019 8:02 pm
vitt76
У меня проблема с передачей параметров между скриптами на php и python. В шапке написано
можно использовать через переменную params -- она имеет тип "словарь" и будет содержать передаваемые параметры
Опытным путем я установил, что параметры в этом словаре лежат под одноименным ключом - params.
Я пытаюсь передавать параметр из php-скрипта в pyrhon-скрипт PlayYS, но такое впечатление, что обе следующих конструкции

Код: Выделить всё

runScript('PlayYS', $text);
runScript('PlayYS',"{'params' : '".$text."'}");
ничего не передают, по крайней мере через

Код: Выделить всё

video_url = params['params']
ничего считать не удается, а из GET параметр считывается нормально.

И вторая проблема, когда из python-скрипта я передаю параметр дальше в php

Код: Выделить всё

mjdm.runScript('sendAdminTelegram','привет')
в ответ просто тишина, даже если это просто текстовая строка.
Что я не так делаю?

Re: Поддержка Python в Majordomo

Добавлено: Пн мар 23, 2020 7:50 pm
artek
На Python 3 не работает setGlobal.

Сценарий состоит из следующей строчки:

Код: Выделить всё

 mjdm.setGlobal("ESP8266_SonoffSV.nightLightBrightness", 5)  
При запуске сценария возвращается ошибка:
Ошибка в кодеПоказать
Traceback (most recent call last): File "/var/www/cms/python/c629e955e8a45bfd259ecc5faba3fff3.py", line 17, in mjdm.setGlobal("ESP8266_SonoffSV.nightLightBrightness", 5) File "/var/www/lib/python/mjdm.py", line 48, in setGlobal callAPI("/api/data/"+property, "POST", {"data":value}) File "/var/www/lib/python/mjdm.py", line 23, in callAPI data = urllib.urlencode(params) AttributeError: module 'urllib' has no attribute 'urlencode'
В Python 2 всё работает хорошо.

Нагуглил следующее:
urllib has been split up in Python 3. The urllib.urlencode() function is now urllib.parse.urlencode(), and the urllib.urlopen() function is now urllib.request.urlopen().

Судя по всему, модуль mjdm не до конца портирован под Python3, или же что-то не так у меня.

Re: Поддержка Python в Majordomo

Добавлено: Пн мар 23, 2020 11:04 pm
savenko_egor
Всё ты правильно понял. Изначально там только под Python 2 было, мы немного правили под Python 3, но видимо не всё исправили =)

Re: Поддержка Python в Majordomo

Добавлено: Вт мар 24, 2020 3:04 pm
artek
Починил в новом Pull Request'е:
https://github.com/sergejey/majordomo/pull/714