Advertise with Googlier.com 주선의 블로그 https://blog.jusun.org Developer & Plants Sun, 18 May 2025 09:06:53 +0000 ko-KR hourly 1 https://wordpress.org/?v=7.1.4 https://blog.jusun.org/wp-content/uploads/2022/09/cropped-KakaoTalk_20210528_090339311-32x32.jpg 주선의 블로그 https://blog.jusun.org 32 32 Proxmox VE 모니터링용 디스플레이 https://blog.jusun.org/single-board-computer-microcontroller-unit/proxmox-ve-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81%ec%9a%a9-%eb%94%94%ec%8a%a4%ed%94%8c%eb%a0%88%ec%9d%b4/ https://blog.jusun.org/single-board-computer-microcontroller-unit/proxmox-ve-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81%ec%9a%a9-%eb%94%94%ec%8a%a4%ed%94%8c%eb%a0%88%ec%9d%b4/#respond Sun, 18 May 2025 09:02:54 +0000 https://blog.jusun.org/?p=119 시작은 우연히 알리에서 LVGL용 디스플레이를 발견했다. 아두이노 ESP32 기반에 2.8인치 디스플레이가 미리 만들어져있는(프리빌트) 그런 회로판인 것을 알고…

후딱 주문을~~

최근에 홈서버도 Proxmox로 재구성하기 시작했고, (비록 소소하지만 … ) 모니터링 할만큼의 부하가 오는건 아니지만, 그래도 궁금하달까…

뽀대가 있달까… +ㅁ+)b

결론적으로는 다음과 같은 화면이 만들어졌다.

엄청 삽질 하긴했지만 GPT넘의 도움으로 해결하긴했지만, 엄둥한 코드를 이것저것 던지는 바람에 더 해깔려서 오래 걸린거 같다.

아두이노 IDE 세팅까지는 물어봐도 될거 같고 핵심은 이녀석의 이름이다.

“싼 노란색 디스플레이” 즉, cheap yellow display 이걸로 구글에 검색하면 모든 설정 파일 및 이슈를 한번에 해결 할 수 있다. (참고: https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display )
TFT_eSPI 설정 파일을 꼭 참조하도록 하자 …

그리고 PROXMOX의 API를 이용하는데 키를 생성하면 위 화면상의 값들을 RestAPI로 받을 수 있게된다.
postMan으로 미리보기 할 때 생성한 키를 Bearer Token에 세팅하면 끝…

난 그리는 함수 따위 모르니 GTP 녀석에게 부분 부분 케물어서 다음과 같은 소스 코드를 완성할 수 있다.

#include <TFT_eSPI.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>


#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

TFT_eSPI tft = TFT_eSPI();


const char* ssid = "jusun";
const char* password = "와이파이비번";

const char* token = "Bearer PVEAPIToken=root@pam!LVGL=proxmox키이키키키";

void fnConnectWifi(){

  WiFi.begin(ssid, password);
  Serial.print("WiFi 연결 중");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi 연결 완료!");
  Serial.print("IP 주소: ");
  Serial.println(WiFi.localIP());
}

//공용변수
float g_cpu = 0;
uint64_t g_mem_used = 0;
uint64_t g_mem_total = 0;
unsigned long g_uptime = 0;
String g_loadavg1 = "";
String g_loadavg5 = "";
String g_loadavg15 = "";


void fnGetProxmoxStatus() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClientSecure client;
    client.setInsecure(); // 인증서 무시

    HTTPClient https;
    https.begin(client, "https://192.168.1.200:8006/api2/json/nodes/pve/status");
    https.addHeader("Authorization", token);

    int httpCode = https.GET();

    if (httpCode > 0) {
      String payload = https.getString();
      Serial.println("응답:");
      Serial.println(payload);

      // JSON 파싱
      StaticJsonDocument<2048> doc; // 크기 넉넉히 잡기
      DeserializationError error = deserializeJson(doc, payload);
      if (!error) {
        g_cpu = doc["data"]["cpu"].as<float>();
        g_mem_used = doc["data"]["memory"]["used"].as<uint64_t>();
        g_mem_total = doc["data"]["memory"]["total"].as<uint64_t>();
        g_uptime = doc["data"]["uptime"].as<unsigned long>();

        g_loadavg1 = doc["data"]["loadavg"][0].as<String>();
        g_loadavg5 = doc["data"]["loadavg"][1].as<String>();
        g_loadavg15 = doc["data"]["loadavg"][2].as<String>();

        Serial.printf("CPU 사용률: %.2f%%\n", g_cpu * 100);
        Serial.printf("메모리 사용량: %llu / %llu bytes\n", g_mem_used, g_mem_total);
        Serial.printf("업타임: %lus\n", g_uptime);
      } else {
        Serial.print("JSON 파싱 실패: ");
        Serial.println(error.c_str());
      }


    } else {
      Serial.printf("HTTP 오류: %s\n", https.errorToString(httpCode).c_str());
    }

    https.end();
  }
}

struct VMInfo {
  uint64_t vmid;
  String name;
  String status;
  float cpu;
  uint64_t mem;
  uint64_t maxmem;
  unsigned long uptime;
};

//qemu
VMInfo g_qemu_list[20];
int g_qemu_count = 0;

void fnGetProxmoxQEMUStatus() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClientSecure client;
    client.setInsecure(); // 인증서 무시

    HTTPClient https;
    https.begin(client, "https://192.168.1.200:8006/api2/json/nodes/pve/qemu");
    https.addHeader("Authorization", token);

    int httpCode = https.GET();

    if (httpCode > 0) {
      String payload = https.getString();
      Serial.println("응답:");
      Serial.println(payload);

      // JSON 파싱
      StaticJsonDocument<2048> doc; // 크기 넉넉히 잡기
      DeserializationError error = deserializeJson(doc, payload);
      if (!error) {

        JsonArray data = doc["data"];
        g_qemu_count = min(20U, data.size());

        for (int i = 0; i < g_qemu_count; i++) {
          JsonObject vm = data[i];
          g_qemu_list[i].vmid = vm["vmid"].as<uint64_t>();
          g_qemu_list[i].name = vm["name"].as<String>();
          g_qemu_list[i].status = vm["status"].as<String>();
          g_qemu_list[i].cpu = vm["cpu"].as<float>();
          g_qemu_list[i].mem = vm["mem"].as<uint64_t>();
          g_qemu_list[i].maxmem = vm["maxmem"].as<uint64_t>();
          g_qemu_list[i].uptime = vm["uptime"].as<unsigned long>();
        } 
      } else {
        Serial.print("JSON 파싱 실패: ");
        Serial.println(error.c_str());
      }


    } else {
      Serial.printf("HTTP 오류: %s\n", https.errorToString(httpCode).c_str());
    }

    https.end();
  }
}


//LXC
VMInfo g_lxc_list[20];
int g_lxc_count = 0;

void fnGetProxmoxLXCStatus() {
  if (WiFi.status() == WL_CONNECTED) {
    WiFiClientSecure client;
    client.setInsecure(); // 인증서 무시

    HTTPClient https;
    https.begin(client, "https://192.168.1.200:8006/api2/json/nodes/pve/lxc");
    https.addHeader("Authorization", token);

    int httpCode = https.GET();

    if (httpCode > 0) {
      String payload = https.getString();
      Serial.println("응답:");
      Serial.println(payload);

      // JSON 파싱
      StaticJsonDocument<2048> doc; // 크기 넉넉히 잡기
      DeserializationError error = deserializeJson(doc, payload);
      if (!error) {

        JsonArray data = doc["data"];
        g_lxc_count = min(20U, data.size());

        for (int i = 0; i < g_lxc_count; i++) {
          JsonObject vm = data[i];
          g_lxc_list[i].vmid = vm["vmid"].as<uint64_t>();
          g_lxc_list[i].name = vm["name"].as<String>();
          g_lxc_list[i].status = vm["status"].as<String>();
          g_lxc_list[i].cpu = vm["cpu"].as<float>();
          g_lxc_list[i].mem = vm["mem"].as<uint64_t>();
          g_lxc_list[i].maxmem = vm["maxmem"].as<uint64_t>();
          g_lxc_list[i].uptime = vm["uptime"].as<unsigned long>();
        } 
      } else {
        Serial.print("JSON 파싱 실패: ");
        Serial.println(error.c_str());
      }


    } else {
      Serial.printf("HTTP 오류: %s\n", https.errorToString(httpCode).c_str());
    }

    https.end();
  }
}




void fnDrawScreen() {
  static float last_cpu = -1;
  static uint64_t last_mem_used = 0;
  static uint64_t last_mem_total = 0;
  static unsigned long last_uptime = 0;

  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);  // 배경색 포함 덮어쓰기

 

  if (g_cpu != last_cpu) {
    tft.setCursor(6, 37);
    tft.print("CPU: ");
    tft.print(g_cpu * 100, 2);
    tft.print("%  ");

    tft.setCursor(160, 40);
    tft.setTextSize(1);
    tft.print("Load: ");
    tft.print(g_loadavg1);
    tft.print(" ");
    tft.print(g_loadavg5);
    tft.print(" ");
    tft.print(g_loadavg15);


    last_cpu = g_cpu;
  }

  tft.setTextSize(2);

  if (g_mem_used != last_mem_used || g_mem_total != last_mem_total) {
    tft.setCursor(6, 57);
    tft.printf("MEM: %llu / %llu MB    ", g_mem_used / (1024 * 1024), g_mem_total / (1024 * 1024));
    last_mem_used = g_mem_used;
    last_mem_total = g_mem_total;
  }

  if (g_uptime != last_uptime) {
    tft.setCursor(6, 77);
    unsigned long days = g_uptime / 86400;
    unsigned long hours = (g_uptime % 86400) / 3600;
    unsigned long minutes = (g_uptime % 3600) / 60;
    unsigned long seconds = g_uptime % 60;
    tft.printf("UPT: %lud %02luh %02lum %02lus   ", days, hours, minutes, seconds);
    last_uptime = g_uptime;
  }
}


//qemu list
void drawQemuList(){
  int y = 125;  // 시작 위치
  
  tft.setTextSize(1);


  int total_vm_slots = ARRAY_SIZE(g_qemu_list);

  std::sort(g_qemu_list, g_qemu_list + g_qemu_count, [](const VMInfo &a, const VMInfo &b) { 
    return a.vmid < b.vmid; 
  });
  
  for (int i = 0; i < total_vm_slots; i++) {
    if(g_qemu_list[i].name.length() == 0){
      continue;
    }

    tft.setCursor(4, y);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.print("[");
    tft.print(g_qemu_list[i].name.c_str());
    tft.print("] ");
    if(g_qemu_list[i].status == "running"){
      tft.print(g_qemu_list[i].cpu * 100);
    }else{
      tft.print("0.00");
    }
    tft.print("% ");
    tft.print("     ");
    //tft.print("/");
    //tft.print(g_qemu_list[i].mem / 1024.0 / 1024.0);

    if(g_qemu_list[i].status == "running"){
      tft.fillCircle(144, y+3, 5, TFT_GREEN);
    }else{
      tft.fillCircle(144, y+3, 5, TFT_RED);
    }
     


    /*
    tft.print(g_cpu * 100, 2);
    tft.print("%  ");
    
    tft.printf("[%s] %s | CPU: %.1f%% | MEM: %.1fMB     ",
    g_qemu_list[i].name.c_str(),
    g_qemu_list[i].status == "running" ? "ON " : "OFF",
    g_qemu_list[i].cpu * 100,
    g_qemu_list[i].mem / 1024.0 / 1024.0
    );
    */

    y += 16;
  }
}

//qemu list
void drawLXCList(){
  int y = 125;  // 시작 위치
  
  tft.setTextSize(1);


  int total_vm_slots = ARRAY_SIZE(g_lxc_list);

  std::sort(g_lxc_list, g_lxc_list + g_lxc_count, [](const VMInfo &a, const VMInfo &b) { 
    return a.vmid < b.vmid; 
  });
  
  for (int i = 0; i < total_vm_slots; i++) {
    if(g_lxc_list[i].name.length() == 0){
      continue;
    }

    tft.setCursor(164, y);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.print("[");
    tft.print(g_lxc_list[i].name.c_str());
    tft.print("] ");
    if(g_lxc_list[i].status == "running"){
      tft.print(g_lxc_list[i].cpu * 100);
    }else{
      tft.print("0.00");
    }
    tft.print("% ");
    tft.print("     ");
    //tft.print("/");
    //tft.print(g_qemu_list[i].mem / 1024.0 / 1024.0);

    if(g_lxc_list[i].status == "running"){
      tft.fillCircle(305, y+3, 5, TFT_GREEN);
    }else{
      tft.fillCircle(305, y+3, 5, TFT_RED);
    }
     

    y += 16;
  }
}


void drawLayoutLine(){

  tft.fillRect(0, 0, tft.width(), tft.height(), TFT_BLACK); //전체 배경
  tft.fillRect(0, 0, tft.width(), 32, TFT_BLUE); //상단 배경

  
  tft.drawLine(0,32,tft.width(),32,TFT_WHITE); //상단줄

  tft.drawLine(0,32,tft.width(),32,TFT_WHITE); //상단줄

  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_BLUE);  // 배경색 포함 덮어쓰기
  tft.setCursor(6, 10);
  tft.printf("Jusun Lab. Proxmox Monitor");


  tft.fillRect(0, 97, tft.width(), 117-97, TFT_BLUE); //중단 배경
  tft.drawLine(0,97,tft.width(),97,TFT_WHITE); //중간줄
  
  tft.setTextSize(1);
  tft.setCursor(70, 104);
  tft.printf("QEMU");
  
  tft.setCursor(230, 104);
  tft.printf("LXC");


  tft.drawLine(0,117,tft.width(),117,TFT_WHITE); //중간줄2
  tft.drawLine(tft.width()/2,97,tft.width()/2,tft.height(),TFT_WHITE); //세로줄


  tft.drawRect(0, 0, tft.width(), tft.height(), TFT_WHITE); //틀

  
}

void setup() {
  Serial.begin(115200);
  
  //wifi Connect
  fnConnectWifi();

  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);  // 백라이트 켜기(중요!)

  // Start the tft display and set it to black
  tft.init();
  tft.setRotation(1); //This is the display in landscape

  drawLayoutLine();
  

}

void loop() {
  static unsigned long lastRequest = 0;
  if (millis() - lastRequest > 1000) {
    fnGetProxmoxStatus();
    fnGetProxmoxQEMUStatus();
    fnGetProxmoxLXCStatus();

    lastRequest = millis();

    fnDrawScreen();
    drawQemuList();
    drawLXCList();
  }
  
  //delay(200);
}

비워진 부분은 체워서 가동해보면 문제 없다면, 잘 작동할 것이다.
proxmox API 주소도 자신의 네트워크에 맞는걸로… 1초에 한번씩 고치는데 … 이걸 통해서 부하기 크게 생기진 않는것 같으니 적당히 고쳐서 쓰도록 하자 -ㅅ-)

할사람이 있을지 모르겠지만….

난 이 디스플레이가 너무 마음에 들어서 가지고 놀려고 하나더 주문함..

굳럭!

]]>
https://blog.jusun.org/single-board-computer-microcontroller-unit/proxmox-ve-%eb%aa%a8%eb%8b%88%ed%84%b0%eb%a7%81%ec%9a%a9-%eb%94%94%ec%8a%a4%ed%94%8c%eb%a0%88%ec%9d%b4/feed/ 0
MQTT를 설치해보자. https://blog.jusun.org/proxmox-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b5%ac%ec%84%b1-%ea%b0%80%ec%83%81%ed%99%94/mqtt%eb%a5%bc-%ec%84%a4%ec%b9%98%ed%95%b4%eb%b3%b4%ec%9e%90/ https://blog.jusun.org/proxmox-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b5%ac%ec%84%b1-%ea%b0%80%ec%83%81%ed%99%94/mqtt%eb%a5%bc-%ec%84%a4%ec%b9%98%ed%95%b4%eb%b3%b4%ec%9e%90/#comments Wed, 07 May 2025 12:45:26 +0000 https://blog.jusun.org/?p=116 MQTT이걸 왜 까냐?

집안 네트워크에서 간단한 통신을 하기 위해서 미리 설치해보는 용도입니다. 정확한 용도는 아직 비밀…

(데비안 기반에서 설치하는겁니다. 다른 OS도 크게 다르지 않을 듯… )

일단 넵다 설치…

서버 설치

sudo apt install mosquitto mosquitto-clients

mosquitto : 모기?? MQTT프로토콜을 위한 브로커 서버 역할인건가…

mosquitto-clients: 이건 일단 테스트를 위해서 설치

서버 시작시 시작하도록 설정하기

sudo systemctl enable mosquitto
/etc/mosquitto/mosquitto.conf 편집
listener 1883
bind_address 0.0.0.0 #이건 적당히 내부 네트워크만 접근해야해서 192.168.1.0 하면될듯... 

테스트

받는놈 부터 가동(subscribe? )

mosquitto_sub -h localhost -t "test/topic"

수신을 확인해야 하기 때문에 다른 터미널에서 가동하도록 하자…

보내는놈(퍼블리싱?)

mosquitto_pub -h localhost -t "test/topic" -m "Hello, MQTT!"

특정 브로커(localhost)에 특정 토픽(test/topic)에 메시지(Hello, MQTT!)를 전달하는 것 같군….

※ 이 문서는 내가 알아볼 수있게 작성한거라서 나중에 다시 업데이트 될 수 있음.

]]>
https://blog.jusun.org/proxmox-%eb%84%a4%ed%8a%b8%ec%9b%8c%ed%81%ac-%ea%b5%ac%ec%84%b1-%ea%b0%80%ec%83%81%ed%99%94/mqtt%eb%a5%bc-%ec%84%a4%ec%b9%98%ed%95%b4%eb%b3%b4%ec%9e%90/feed/ 1
Orange Pi Zero3 OLED 연결하기 https://blog.jusun.org/single-board-computer-microcontroller-unit/orange-pi-zero3-oled-%ec%97%b0%ea%b2%b0%ed%95%98%ea%b8%b0/ https://blog.jusun.org/single-board-computer-microcontroller-unit/orange-pi-zero3-oled-%ec%97%b0%ea%b2%b0%ed%95%98%ea%b8%b0/#respond Sun, 04 May 2025 02:18:35 +0000 https://blog.jusun.org/?p=100

다른 OS 사용해봤는데.. 잘 안되는 것 같고… ARMBIAN에서 잘 연동되고 작동되네요..

우선 핀 배치가 필요한데.. OLED는 I2C 방식이라 4개의 핀을 연결해줘야합니다. 판매 패이지에 가보면 핀을 확인할 수 있는데 I2C3 라는 부분에 OLED의 SDA, SCK 를 연결하하고, 5V 를 VDD, GND는 GND에 연결합니다.
(참고로, SPI는 TFT 스크린방식으로 연결 하는 방법)

주의: VDD, GND 거꾸로 끼우면 OLED에서 연기납니다.(당함;; ㅠ_ㅠ )

그다음에 콘솔에 접속하여 명령줄에 armbian-config 를 입력.
System -> Kennel -> Manage device tree overlays -> “i2c3-ph” 라고 붙은걸 선택합니다.

Save후 Back을 선택하면 리부팅하게됩니다.

이 부분 버전에 따라 다를 수는 있는데 최대한 비슷한걸로 i2c3 중에 하나 선택해서 써보심 됨.

이건 안되면 여러번 시도 해볼 수 밖에 없는거 같네요….

원래라면 이렇게 해야되지만……armbian 버전업하면서 목록에서 사라진거 같네요..

/boot/armbianEnv.txt 파일에 다음 내용을 직접 추가해야합니다.

overlays=i2c3-ph

작성 후 리부팅…

초기 설치시 다음과 같은 패키지를 설치해야합니다. 그때그때 필요하다고 한걸 하나씩 추가한거라 진행할려고하는 프로젝트와 차이가 있을 순 있어요..

apt install i2c-tools python3 python3-pip python3-dev python3-rpi.gpio python3-spidev

그 다음에 파이선 패키지 설치. 호환이 안되는건지 break system packages를 넣어줘야 설치가되네요

pip install luma.oled --break-system-packages


i2cdetect로 제대로 연결되었는지 확인해봅니다. 포트를3을 열었으니 0,1,2 순으로 적용되어 2번을 찾아야합니다.

root@orangepizero3:~# i2cdetect -y 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

올바른 연결이 되어있다면 3C로 확인됩니다. 코드에서 사용되는 연결 정보임으로 잘 기록해둡니다.

안되면, amrbian-config 다시 반복 …

0번 1번도 있는데 다른용도로 사용되는거 같에요. (라즈베리파이는 0번 쓸겁니다.)
0번으로 연결되어있다고 믿고 뭔가 하다보면 연결된 모니터가 줄이거거나 모니터 프로그램에 오류를 일으키더군요 -_-

이제 파이선 코드를 짜봅시다. 프롬프트에서 nano test.py 이렇게 하시면 파일 작성되죠…

from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
import time

serial = i2c(port=2, address=0x3C)
device = ssd1306(serial, rotate=0)

with canvas(device) as draw:
    draw.text((10, 0), "Hello World!", fill="white")
    draw.text((10, 20), "Hello World!", fill="white")

while 1:
    time.sleep(1)

위 코드 처럼 i2c부분은 i2cdetect에서 확인된 값으로 맞춰줘야합니다.

ssd1306 이라고 된 부분은 연결되는 oled의 칩에 따라 다른데
보통 알리에서 샀으면
0.9 인치는 ssd1306이였고
1.3인치는 sh1306으로 맞추니 되더군요.. (이건 판매 패이지 참조)

위 코드는 hello world 만 2번 찍힐 뿐이고….

이제 열심히 꾸며볼수있겠죠… 시간이라든가 날씨라든가… 시스템 정보라든가…..

그럼 여기까지 삽질기였습니다.

※ 삽질한거 다시 정리한거라 이글 보고 다 안될수도 있음…

끝~

]]>
https://blog.jusun.org/single-board-computer-microcontroller-unit/orange-pi-zero3-oled-%ec%97%b0%ea%b2%b0%ed%95%98%ea%b8%b0/feed/ 0
‘아누비아스 마블 나나’ 수상 세팅 https://blog.jusun.org/%ec%88%98%ec%b4%88/%ec%95%84%eb%88%84%eb%b9%84%ec%95%84%ec%8a%a4-%eb%a7%88%eb%b8%94-%eb%82%98%eb%82%98-%ec%88%98%ec%83%81-%ec%84%b8%ed%8c%85/ https://blog.jusun.org/%ec%88%98%ec%b4%88/%ec%95%84%eb%88%84%eb%b9%84%ec%95%84%ec%8a%a4-%eb%a7%88%eb%b8%94-%eb%82%98%eb%82%98-%ec%88%98%ec%83%81-%ec%84%b8%ed%8c%85/#respond Wed, 07 Sep 2022 05:52:39 +0000 https://blog.jusun.org/?p=36 잘 되지도.. 잘 안되지도…. 않는 수조가 있습니다.

​

(후… 사진입니다. )

​

-ㅁ-)… 그나마 청소를 했으니 조금 볼만해졌네요 ^^

​

무지성으로 물만 갈아줬더니 녹조에 녹점에 그냥 ㄷㄷㄷ …

​

여기는 시판 나나를 종류별로 모아서 키우는 용도로 썼었는데 조금씩 녹고 있어서 청소를 한번 싹 했습니다.

​

가운데 있던 커피폴리아는 스르르륵… 녹아서 잎만 다 떨궜네요 -_-… 그러면서 백탁도 확 오고…

(나나 녹으면 백탁 오나봐요… -_-a, 커피폴리아 녹은건 넘 잔인해서 생략합니다. ㄷㄷ )

​

다른 나나에도 영향을 주나 보더라고요… 같이 좀 녹았습니다. 새우도 다 사라졌습니다. (독성?)

​

그 와중에 물미역모스는 5배는 커진거 같에요…

​

나나항 이야기는 여기까지 … -ㅅ-).. 날 잡아서 어떻게든 해봐야겠어요… ㅋㅋ

​

​

​

예전에 넣어두었던 마블 나나 두촉을 빼왔습니다.

​

그러고는 수상 세팅을 시작했어요..

(와비쿠사통이 였지만… 잘 되고 있지 않아서 다른통으로 이사갔어요… )

​

어디서 본건있어서 빨대(?)를 새워둡니다. =_=) 이게 22mm 여과기 파이프였나 그럴겁니다.

​

제가 하는게 올바르지 않을수도 있어서 …. ㅋㅋㅋ 참고만 참고만요! (참지마요… 참치마요?)

​

난석을 깔고~

​

태운 흑미를 깔아줍니다.

(응????)

​

죄송합니다 훈탄입니다. =_=) 왕겨 같은건데 태웠나바여

​

적옥토와 쓰던 소일을 섞었어요..

​

한숱가락씩 정성스럽게 … 너도 한잎 나도 한잎…..

​

이게 알아보니 사람마다 다 다릅니다. 전 그냥 이렇게 했습니다.

​

아까 어항에서 빼온 나나를 준비합니다.

​

힘순찐이네요 ㅎㅎㅎ 위는 다 초록이지만 아래에서 무늬 잎이 나오고 있었어요…

​

하나더 있는데 안찍었군요 =_=) 다음 사진에 있어요..

​

심습니다.

​

환수 구멍은 돌로 막아놨습니다.

​

그러고는 촉초옥~~하게 분무질 해줬어요..

​

​

뭐 더 심을건 없고해서 이렇게 마무리했어요…

​

오늘은 여기까지 -ㅅ-)/”

​

뭘 더 심을지는 고민좀 해봐야겠어요..

]]>
https://blog.jusun.org/%ec%88%98%ec%b4%88/%ec%95%84%eb%88%84%eb%b9%84%ec%95%84%ec%8a%a4-%eb%a7%88%eb%b8%94-%eb%82%98%eb%82%98-%ec%88%98%ec%83%81-%ec%84%b8%ed%8c%85/feed/ 0
부세파란드라 사육에 관하여… https://blog.jusun.org/%ec%88%98%ec%b4%88/bucephalandra/%eb%b6%80%ec%84%b8%ed%8c%8c%eb%9e%80%eb%93%9c%eb%9d%bc-%ec%82%ac%ec%9c%a1%ec%97%90-%ea%b4%80%ed%95%98%ec%97%ac/ https://blog.jusun.org/%ec%88%98%ec%b4%88/bucephalandra/%eb%b6%80%ec%84%b8%ed%8c%8c%eb%9e%80%eb%93%9c%eb%9d%bc-%ec%82%ac%ec%9c%a1%ec%97%90-%ea%b4%80%ed%95%98%ec%97%ac/#comments Thu, 01 Sep 2022 07:29:24 +0000 http://blog.jusun.org/?p=23 주선입니다. ( _ _) 넙쭉…

​부세파란드라의 사육법에 대해서 정리해 놓으려고합니다.

​저도 수문원에서 어깨넘어로 이리저리 배우고 좋다는거 해보고 있습니다.

​전경옹한테 진짜 많이 배웠어요.. -ㅅ-)b (동지님이 잠시 자리를 비우셔서 아쉽지만요… )

​​​

1. 마음가짐

케다강 오리지널입니다.(아직 작음)

내 부세가 반짝반짝 빛나지 않는다고 실망마세요..

​

얘도 원래는 ….

예쁜거 사왔는데 키우다보니.. 잎도 다 떨어지고 거의 벌브만 남았으니깐요.. ㄷㄷ

​첨에는 이렇게 하면 죽는다 생각했는데… 부세는 유경이랑 다릅니다…

​살아요! +ㅁ+)/” 삽니다.

​환경이 바껴서 새로운 물에 적응하도록 변화하고 있을 뿐이죠…. 가끔 새로운뿌리가 돋지 않는다면,

​한번씩 꺼내서 줄기를 확인해보고 물러 있다면 뜯어줘야합니다.

​너덜너덜 한게 보기 좀 그렇다면 같은 어항 내에 안보이는데 짱박아두세요 =_=)…. (저도 자주 그래요 ㅋㅋ)

​아래 사진에서 위사진으로 바뀌기까지 최소 3~6개월 걸릴겁니다.

​그래도 죽으면 .. 나랑 안 맞는거라고 배웠…. (퍽… )

​​

2. 활착

활착은… 눕혀서 합니다. -_-… 이게 뭔가 극단적일 수도 있는데…. 어짜피 내 어항에 오면… 잎 다 떨어지지 않을까 하는 우려도 있고 … 다글다글하게 자라는 것을 기대하는 마음도 있습니다. -ㅁ- ㅋㅋ

작고 깜찍한게 더 이쁘잖아요…

​

식물에는 생장점이라는게 있다더군요.. 보통 우리가 사온 위쪽으로 자라는 한촉.. 생장점이 1개 있는거죠 …

눞여서 키우면 생장점이 있는 자리는 빛을 따라갑니다. ㄴ자로 굽어져서 자라게되죠..

그러다가 무슨일이 있어서 생장점이 죽으면, 벌브에서 수많은 생장점이 나타나더군요.. 그러면서 잎이 다글다글 해지는…

부세가 뿔어나는 기적-_-a

​

다글다글 해지고나서 부터는 어떻게 해야할지 아직 모르겠습니다. ㅋㅋ

​

이건 부세에 따라 다릅니다. 말짱히 식형 좋은 부세 괜히 눞여서 당분간 안이뻐 질수도 있으니 … -ㅁ- ㅋㅋ

이쁜건 이쁜데로 키우는게 잴 좋아요..

​

3. 환수

<물 뺐을때 예쁜 부세항 전경> 사진보니 눈에 띄는 이쁜건 별로 없….

​부세 환수는 물 쫙~ 빼리고 배웠습니다. -ㅁ-)

부세의 환경이 수륙양용이라고…

​그래서 90%쯤 부세가 물 밖으로 다 나오게 환수합니다. 이때 물빼고 바로 물을 넣지 않고 살짝 건조하게 둡니다.

​왠지는 모르겠지만 이끼 방지에 도움이 되는거 같에요… 벽면 열심히 닦아주고 ^^ 벽면만 깔끔깔끔….~

​이때 나온짐에 플로엑셀 이런거 뿌리면 안되요…. 제가 해보니.. 탈색되고… 클나유… (야한거 안대~)

​식물에 이끼 있다고 닦으면 안됩니다. (헉ㅋㅋㅋ)

​

환수의 주기는 3~4일로 하고 있지만… 물을 많이 빼고 하는 환수라 일주일에 한번씩해도 괜찮을 것 같습니다.

​​

4. 비료 & 바닥재

부세 비료 필요없다 들었는데 어떨진 모르겠습니다. 전 일단 주고 있습니다. 안먹으면 모스가 먹겠죠 -ㅁ-);;

​액비를 주로 쓰고있습니다.

​쫄아서 많이 안주고 있어요…

환수 후 권장량의 1/3 정도 네오2 넣어줍니다.

​부스터, 에센스 넣어줍니다.

부스터는 여과기 슬러지를 발생시키더군요.. 여과기에 스펀지는 빼주는게 좋더군요..

스펀지 여과기 쓰는 어항에는 부스터 비추입니다.

이틀뒤 네오1 넣어줍니다. 마찬가지로 권장량의 1/3…

자작비료도 있지만 생각하기 싫어서 (네오1,2 써요 -_-;; ㅋㅋ)

​비료 과하면 뒷탈이 어우~ … 1/3 보다 더 적게 넣으세요..

​비료의 양은 수조내의 수초의 량에 따라 다르지 않나 싶어요 …

​바닥재는 비료끼가 없어야할겁니닭…. 다른데 쓰다가 뺀 마피드 씻어서 깔아놨어요..

(다른 소일은 못씻는데 이건 씻어서 써도 괜찮…)

프리미엄소일이런건 안된다 그러더군요.. (안된다 그래서 시도도 안해봄.. ㅋㅋ)

안까는검 좀 허전하고… 뭔가 떠다니는 찌꺼기만 가둘수 있으면 괜찮지 않을까요… 흑사 권장!

​​

5. 이끼의 제거

<제가 키운건 한 잎뿐>

이끼 제거는 예전에 제가 해둔 메모로 대신합니다.

동지님 +ㅁ+)b

​

큰환수와 이탄과 여러가지 이유로 새우는 자꾸 죽어나갑니다. (이끼관리상 분기별로 새우 보급필요)

​

​

6. 조명 & 이탄

조명에 대해서 뭘 찍어오질 않았네요 -_-

​

고광량 하면 부세가 하얗게 되더군요 환경변화 때문인진 모르겠지만, 하얗게된 잎은 결국 구멍나거나 떨어지더군요..

​적당한 광량이 중요한것 같습니다. 전 메탈라이트 ver2 디머로 40% 정도로 조정해서 사용합니다.

​플랜츠 라이트 마렵긴하지만… 일단 있는데로 할려고요.. (주인마님의 허락이 … ) 플라는 2~30% 쓴다고 그러더라고요.

​고수님들만의 세팅값이 있던거 같아요 ^^ (찾아보시길…)

​좋은 조명쓰면 활용할 수 있는 스펙트럼이 확실히 넓어서 >_<)b 권장합니다.

​​

이탄은 -ㅅ- 수조내에 잔잔히 흩어지도록 적당량을 풀어주세요…

​(너무 많이 풀면 새우 용병들이 좀 힘들어해서 … 수조 크기에 따른 일반적인 수준이면 되지 않을까요… )

​​

7. 시간

시간이 걸립니다. 꾸준히 환수해주고 관리해주신다면, 예쁨으로 보답할거에요 ^^

​남에집 부세만 예뻐보인다고 실망마시고 꾸준히 가보세요 ~ ㅎㅎ

​​​

홧팅!!

​

​

수초 문화원에서 제가 적었던 글 : ​https://cafe.naver.com/iaplc/54997

]]>
https://blog.jusun.org/%ec%88%98%ec%b4%88/bucephalandra/%eb%b6%80%ec%84%b8%ed%8c%8c%eb%9e%80%eb%93%9c%eb%9d%bc-%ec%82%ac%ec%9c%a1%ec%97%90-%ea%b4%80%ed%95%98%ec%97%ac/feed/ 1