Корректное получение JSON ответа с помощью Apache.HttpClient

Tags:

У Apache HttpClient есть небольшая, но неприятная бага. Всплыла она при работе с REST API Confluence (вообще очень много баг всплывает при работе с API  продуктов Atlassian, но это все лирика).

В чем, собственно, проблема? Проблема в том, что Confluence при запросе у него данных с Accept: application/json (собственно все JSON REST API) не выставляет заголовок content-encoding для отдаваемых данных. В целом, его можно понять т.к. по стандарту JSON всегда должен быть UTF-8, но HttpClient не понимает и потому разбирает входящие данные как ISO.

Соответственно, дальше JSONObject при парсинге Entity превращает русский текст в совершенно непотребное.

Лечится это элементарно, просто при работае с Entity принудительно указываем ей что кодировка у нас UTF-8.

Вот так:

JSONObject jsonObj = new JSONObject(EntityUtils.toString(response.getEntity, "UTF-8"));

После этого русский текст внутри JSON будет в нормальном UTF-8 и с ним можно спокойно работать.

How to fix sound issue with KODI on the orange pi

Tags:

I have Orange Pi One board. It's a great product, it is faster, cheaper and smaller then Raspberry Pi, but it uses AllWinner H3 SOC and it is its main disadvantage.

If you want to use this board as a media center with KODI, you face the problem with sound. The sound works in Armbian applications but doesn't work in KODI. It happens because KODI uses S24_LE sampling format which is not supported by Orange Pi hardware.

root@orangepione:~# speaker-test  -D hw:1 -c2 --format S24_LE

speaker-test 1.0.28

Format S24_LE is not supported...

Ok, we found out the root of the problem, time to fix it!

Now we need to set sampling format which is supported by Orange Pi hardware. One of supported sample formats is S32_LE. Check if it is correct:

root@orangepione:~# speaker-test  -D hw:1 -c2 --format S32_LE

speaker-test 1.0.28

Playback device is hw:1
Stream parameters are 48000Hz, S32_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 64 to 131072
Period size range from 32 to 16384
Using max buffer size 131072
Periods = 4

Now check soundcards, we need to get the device number which plays over HDMI output.

root@orangepione:~# cat /proc/asound/cards
 0 [audiocodec     ]: audiocodec - audiocodec
                      audiocodec
 1 [sndhdmi        ]: sndhdmi - sndhdmi
                      sndhdmi

The sndhdmi is a soundcard which attracts our interest. Remember the number of this one.

Now we can edit the Alsa config:

vim /etc/asound.conf

Delete old content and paste the following one:

pcm.snd_card {
        type hw
        card 1
        device 0
}

ctl.snd_card {
        type hw
        card 1
        device 0
}

pcm.dmixer {
    type dmix
    ipc_key 1024
    ipc_perm 0666
    slave.pcm "snd_card"
    slave {
        period_time 0
        period_size 1024
        buffer_size 4096
        rate 48000
        format S32_LE
        channels 2
    }
    bindings {
        0 0
        1 1
    }
}

Save the file and reboot.

After that the KODI will play sound. If it doesn't play, check the number in card fields of the config, it must be the number from sndhdmi card, and samplerate and samplerate format in slave section. The samplerate should be equal with one from the speaker-test command output.

Orange Pi power connector

Tags:

Orange Pi can't work with USB power. It needs power from power connector or GPIO.

If you need a fast and dirty way, use the GPIO pins. You may use standard smartphone charger with USB connector and 1A current. If you want to use external HDD with Orange Pi, you need power supply with 2+ A current. After you have found a charger, just connect +5V from USB to GPIO pin 2 (or pin 4, they are similar) and USB ground with pin 6.

GPIO pinout diagram

The first pin is marked with white triangle near the GPIO connector.

The right way is to use the power plug. But Orange Pi uses power connector which is not common. You need the connector with 4.0x1.7 mm diameter and 8mm long (or longer). In the shop where I bought the connector it was being sold as connector for Compaq notebooks. You need to solder +5V from the USB to the central contact of the connector and USB ground to the external contact.

Отправляем емейл из Perl с авторизацией и html

Tags:

Отправляем письмо в html с авторизацией из Perl.

use strict;
use Net::SMTP;
use Authen::SASL; #нужен для авторизации

use utf8;
use Encode;
use MIME::Base64


  my $message = "<html><body>Тестовое письмо</body></html>";

# авторизационные данные
my $smtp_host = 'smtp.server.address';
my $smtp_user = 'user_name';
my $smtp_pass = 'password';


my $debug = 1; # рассматриваем процесс подключения в деталях

# mail properties
my $mail_from = 'user@example.com';
my $mail_to = 'recipient@example.com';
my $mail_subject = 'Тестовое письмо';

# Выставляем заголовки. Сюда можно добавить еще всякого при необходимости
my $mail_headers = "From: $mail_from\n".
"To: $mail_to\n".
"Subject: ".encode('MIME-Header',$mail_subject)."\n".
"MIME-Version: 1.0\n".
"Content-type: text/html; charset=UTF-8\n".
"Content-Transfer-Encoding: base64\n\n";

my $mail_body = $message;

# Отправляем письмо
my $smtp = Net::SMTP->new($smtp_host, Debug => $debug) or die "cannot connect to server";
$smtp->auth($smtp_user,$smtp_pass) or die "could not authenticate";
$smtp->mail($mail_from);
$smtp->to($mail_to);
$smtp->data();
$smtp->datasend($mail_headers);
$smtp->datasend(encode_base64(encode('UTF-8', $mail_body)));
$smtp->dataend();
$smtp->quit;

При необходимости можно добавить файлы, PGP подписи и так далее.

Добавляем второй экструдер к RAMPS 1.4/Marlin

Tags:

В прошлой серии мы установили прошивку Marin на Arduino Mega+RAMPS 1.4 и откалибровали все это дело. Теперь пришло время добавить второй экструдер.

Для этого нам понадобится:

  • второй экструдер
  • второй хот-энд в сборе и все прилегающие детали, типа трубки боудена
  • каретка на два экструдера. Я использую такую.

В общем случае все просто идем в Arduino IDE и правим конфигурацию.

Меняем конфигурацию платы управления на RAMPS 1.4 c 2 экструдерами и подогреваемым столом

#ifndef MOTHERBOARD
  #define MOTHERBOARD BOARD_RAMPS_14_EEB
#endif

Указываем кол-во экструдеров:

#define EXTRUDERS 2

Указываем тип датчика температуры для второго экструдера:

#define TEMP_SENSOR_1 1

Максимальную температуру:

#define HEATER_1_MAXTEMP 250

Если надо, устанавливаем направление вращения мотора:

#define INVERT_E1_DIR true

В целом, если у вас одинаковые моторы на обоих экструдерах, то на этом настройка закончена.

Но если у моторы разные или на одном экструдере у меня мотор с шестерней подачи диаметром 10мм, а на втором - 7мм, то тут начинаются проблемы с калибровкой.

Как откалибровать второй экструдер? Идем в пронтерфейс и говорим:

T1

Эта команда указывает что сейчас активен экструдер номер 2 (отсчет начинается с 0). Включаем подачу филамента, для подачи будет использоваться число шагов из прошивки, т.е. для первого экструдера. Смотрим разницу и с помощью пропорции получаем кол-во шагов для активного экструдера. У меня из-за разницы в подающих шестернях получилось 80 шагов на мм.

Говорим:

M92 E80

Этим мы устанавливаем новое кол-во шагов для текущего экструдера. Проверяем, при необходимости подгоняем значение.

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

Напишем небольшой фильтр которым будем обрабатывать готовый g-code файл.

#!/usr/bin/env perl

use strict;

my $T0 = 'M92 E95';
my $T1 = 'M92 E80';

local $^I = '.bak';
while (<>) {
    s/^T0/T0\n$T0/;
    s/^T1/T1\n$T1/;
    print;
}

Этот скрипт ищет команду T и заменяет ее нужным нам значением. В данном случае добавляет команду M92 E. Скрипт получает на вход имя файла, перебирает его построчно и в каждой строке заменяет совпадения на то что мы указали. Оригинальный файл сохраняется с расширением .bak.

Дальше нам надо задать смещение экструдеров

Для Slic3r идем в Printer Settings -> Extruder 2 и выставляем смещение. Примерное смещение можно получить если измерив расстояние между соплами, однако программое расстояние может отличаться от физического расстояния, так что все равно придется заняться калибровкой.

Для этого печатаем деталь для калибровки 2х экструдеров и точно подгоняем все для идеальной работы.