Электрокарнизу Akko ac-72e по rs485


#1

Добрый день. Купил Электрокарниз. Он работает по rs485, но не modbus. Во вложении спецификация на протокол. Подключался через serial_tool. Все работает по спеке. Шторы открываются, закрываются, положение считывается.
Как вы посоветуете подключить карниз? Возможно ли определить как виртуальное устройство? Или можно определить шаблон? Можете ли вы добавить этот карниз в поддерживаемые устройства?
Спасибо заранее.
Ps. Порядок вложений обратный.

Uploading: Screenshot_20190215_194607_com.google.android.apps.docs.jpg…


#2

Похоже для управления используется Modbus ASCII.
Хорошо уже, что работает!
Уточните пожалуйста модель карниза.
По поиску Akko ac-72e ничего не находится.


#3

На сайте продавца он называется “Электрокарниз AM82TV с управлением по радио, RS-485 и пофазно”
В спецификации, на протокол было указано “мотор ac-72e”


#4

Пока сделал через виртуальное устройство, которое вызывает perl скрипт, perl программа на вход принимает позицию штор и отправляет запрос в серийный порт. Позже выложу настройки и код.
Все заработало. Из минусов- виртуальное устройство пока не получает информацию об изменении положения штор, если их двигают не через wirenboard.

Вы планируете поддержать этот протокол?


#5

costa, добрый день! к сожалению, поддержку вашего устройства мы вряд ли сможем реализовать.
Сложно разглядеть на скриншотах, можно ли получать ответную информацию о положении устройства: может, дадите ссылку на документацию?


#6

После включения карниза отправил команду 55 00 00 02 00 02 12 34 50 7F - установка адреса устройства в “12 34” (по умолчанию был FE FE, судя по спеке, но я не проверял).
Соответственно CRC16 нужно будет пересчитать (я пользовался https://crccalc.com/), если будете использовать адрес по умолчанию.

Далее настроил виртуальное устройство в wirenboard:

файл /etc/wb-rules/wb-rules

defineVirtualDevice("akko",{
    title: "Шторы",
    cells:{
        position: {
            type: "range",
            value: 100,
            min: 0,
            max: 100,
        },
    }
});

defineRule("set_position", {
    whenChanged: "akko/position",
    then: function (newValue, devName, cellName){
        runShellCommand("./etc/wb-rules/akko.perl "+newValue);
    }
});

И perl скрипт, который устанавливает положение штор c шагом в 10%, например установить в 20 процентов:

./akko.perl 20

или считывает текущее положение штор - в ответе вернется число процентов:

./akko.perl

искать функции по расчету CRC16 для modbus мне было лень, поэтому команды все захардкодил.

файл /etc/wb-rules/akko.perl

#!/usr/bin/perl

use Device::SerialPort;
my $port = Device::SerialPort->new("/dev/ttyRS485-2");

$port->baudrate(9600); 
$port->databits(8);
$port->parity("none");
$port->stopbits(1);

$output = "";
if ($ARGV[0]==100) # команда Установить положение эл.карниза в 100% (0x64)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x64,0x49,0x06);
    }
elsif ($ARGV[0]>=90) # .. в 90% (0x5A)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x5A,0xC8,0xD6);
    }
elsif ($ARGV[0]>=80) # .. в 80%
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x50,0x48,0xD1);
    }
elsif ($ARGV[0]>=70) # .. в 70%
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x46,0xC9,0x1F);
    }
elsif ($ARGV[0]>=60) # .. в 60%
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x3C,0x48,0xFC);
    }
elsif ($ARGV[0]>=50)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x32,0xC9,0x38);
    }
elsif ($ARGV[0]>=40)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x28,0x48,0xF3);
    }
elsif ($ARGV[0]>=30)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x1E,0xC8,0xE5);
    }
elsif ($ARGV[0]>=20)
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x14,0x48,0xE2);
    }
elsif ($ARGV[0]>=10) # .. в 10%
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x0A,0xC8,0xEA);
    }
elsif (@ARGV) # .. в 0%
    {
        $output = pack("C*",0x55,0x12,0x34,0x03,0x04,0x00,0x48,0xed);
    }
else # считать текущее положение эл.карниза
    {
        $output = pack("C*",0x55,0x12,0x34,0x01,0x02,0x01,0x2B,0x4D);
    }

$port->write($output);
sleep(1);
$in = $port->read("100");
$per = substr($in,5,1);
printf ("%s\n",ord($per)); # вывести на экран ответ от эл.карниза

$port->close;

#7

Да, получать можно.
В ответ на команду “0x55,0x12,0x34,0x01,0x02,0x01,0x2B,0x4D”

55 - фиксированный префикс
12 34  - адрес устройства 
01 - получить данные
02 - положение карниза
01 - я не понял что это )
2B 4D - CRC16/modbus с обратным расположением байтов

В ответном сообщении (такое же по структуре) 6 байте вернет положение карниза в процентах.


Формат команды по установке положения карниза в 50%:
Команда 0x55,0x12,0x34,0x03,0x04,0x32,0xC9,0x38

55 - фиксированный префикс
12 34  - адрес устройства 
03 - отправить команду
04 - положение карниза
32 - число 50 в hex
С9 38 - CRC16/modbus с обратным расположением байтов

В ответном сообщении (такое же по структуре) 6 байте вернет положение карниза в процентах.



#8

Подскажите, как можно сделать через виртуальные устройства в правилах (или другими штатными средствами wirenboard):

  • периодический вызов perl программы (которая возвращает на stdout текущее положение эл. карниза)
  • считывание этого значения
  • запись в topic

NB: могу конечно сделать вызов по cron скрипта, который будет писать полученное значение в топик, но как-то хочется родными средствами wirenboard’а это решить.


#9

costa, в движке есть cron-правила, тут подробнее: https://github.com/contactless/wb-rules
При их использовании, правда, некоторые пользователи наблюдали падение движка правил.