gl-puli-mcu: Add power monitoring for XE3000 (Puli AX) variant

Signed-off-by: Jean Thomas <jean.thomas@wifirst.fr>
This commit is contained in:
Jean Thomas 2023-11-15 15:59:07 +01:00 committed by Nuno Goncalves
parent 2ae44d696f
commit 717c27a5c8
3 changed files with 106 additions and 5 deletions

View File

@ -0,0 +1,12 @@
choice
depends on PACKAGE_gl-puli-mcu
prompt "GL.iNet target"
default GL_PULI_MCU_XE300
config GL_PULI_MCU_XE300
bool "GL.iNet XE300 (Puli)"
config GL_PULI_MCU_XE3000
bool "GL.iNet XE3000 (Puli AX)"
endchoice

View File

@ -1,24 +1,40 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gl-puli-mcu
PKG_VERSION:=1
PKG_VERSION:=2
PKG_RELEASE:=1
PKG_MAINTAINER:=Nuno Goncalves <nunojpg@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later
PKG_CONFIG_DEPENDS:= \
CONFIG_GL_PULI_MCU_XE300 \
CONFIG_GL_PULI_MCU_XE3000
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/gl-puli-mcu/config
source "$(SOURCE)/Config.in"
endef
define Package/gl-puli-mcu
SECTION:=utils
CATEGORY:=Utilities
TITLE:=GL.iNet GL-XE300 (Puli) power monitoring support
DEPENDS:=+kmod-usb-serial-ch341 +libubus +libubox
TITLE:=GL.iNet power monitoring support
DEPENDS:=+CONFIG_GL_PULI_MCU_XE300:kmod-usb-serial-ch341 +libubus +libubox
MENU:=1
endef
ifeq ($(CONFIG_GL_PULI_MCU_XE300),y)
TARGET_CFLAGS+=-DGL_TARGET=1
endif
ifeq ($(CONFIG_GL_PULI_MCU_XE3000),y)
TARGET_CFLAGS+=-DGL_TARGET=2
endif
define Package/gl-puli-mcu/description
Interfaces with GL-XE300 (Puli) power monitoring MCU over
Interfaces with GL.iNet Puli family power monitoring MCU over
a USB to UART adapter present on the device and provides
battery SOC, temperature, charging state and cycle count at
ubus battery/info.

View File

@ -26,6 +26,17 @@
#include <libubox/uloop.h>
#include <libubus.h>
#define GL_TARGET_XE300 1
#define GL_TARGET_XE3000 2
#if GL_TARGET == GL_TARGET_XE300
#define MCU_PORT "/dev/ttyUSB0"
#elif GL_TARGET == GL_TARGET_XE3000
#define MCU_PORT "/dev/ttyS1"
#else
#error Please define GL_TARGET!
#endif /* GL_TARGET */
static struct ustream_fd stream;
static struct ubus_auto_conn conn;
static struct blob_buf b;
@ -39,6 +50,9 @@ struct Battery
bool set;
} battery;
#if GL_TARGET == GL_TARGET_XE300
// MCU status returns something like:
// {OK},100,275,1,0
static bool
process(char *read)
{
@ -66,6 +80,65 @@ process(char *read)
return false;
return true;
}
#elif GL_TARGET == GL_TARGET_XE3000
static bool
get_int_value(const char *read, const char *key, int *int_value, char **new_end)
{
char *from = NULL;
from = strstr(read, key);
if ((!from) || (from != read))
{
return false;
}
from = (char *)read + strlen(key);
*int_value = strtol(from, new_end, 10);
if (from == *new_end)
{
return false;
}
return true;
}
// MCU status returns something like:
// {"code":0,"capacity":100,"temp":28,"chg_state":1,"charge_cycle":0}
static bool
process(char *read)
{
int int_value = 0;
char *to = NULL;
if ((read[0] != '{') ||
(!get_int_value(&read[1], "\"code\":", &int_value, &to)) ||
(int_value != 0))
{
return false;
}
if (!get_int_value(to + 1, "\"capacity\":", &int_value, &to))
{
return false;
}
battery.soc = int_value;
if (!get_int_value(to + 1, "\"temp\":", &int_value, &to))
{
return false;
}
battery.temperature = (float) int_value;
if (!get_int_value(to + 1, "\"chg_state\":", &int_value, &to))
{
return false;
}
battery.charging = (bool) int_value;
if (!get_int_value(to + 1, "\"charge_cycle\":", &int_value, &to))
{
return false;
}
battery.cycles = (uint16_t) int_value;
return true;
}
#endif /* GL_TARGET */
static int
consume(struct ustream *s, char **a)
@ -202,7 +275,7 @@ main(int argc, char **argv)
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
if (serial_open("/dev/ttyUSB0") < 0)
if (serial_open(MCU_PORT) < 0)
return -1;
serial_query_timer.cb = serial_query_handler;