A library and tools for managing an ODROID Smart Power device.
NOTE: If you're using a newer generation ODROID Smart Power 3 device, see the hosp project instead.
This project is tested with firmware version "SMART POWER V3.0".
You need an ODROID Smart Power device with a USB connection.
You will also need CMake, pkg-config, and a HIDAPI library.
On Debian-based Linux systems (including Ubuntu):
sudo apt install cmake libhidapi-dev pkg-config
On macOS, using Homebrew:
brew install cmake hidapi pkg-config
To build, run:
mkdir _build
cd _build
cmake ..
cmake --build .
To build a shared object library (instead of a static library), add -DBUILD_SHARED_LIBS=On
to the first cmake command.
Add -DCMAKE_BUILD_TYPE=Release
for an optimized build.
Refer to CMake documentation for more a complete description of build options.
The build uses pkg-config to search for a supported HIDAPI library.
By default, it first searches for libraries using native OS backends (e.g., hidraw
for Linux, IOHIDManager
for macOS), then searches for the libusb
backend (for Linux, macOS, BSD, and other UNIX-like systems).
To change the default search order, set the HOSP_HIDAPI_PC_MODULES
variable with a ;-delimited list of pkg-config module name(s), e.g., to prioritize libusb
:
cmake .. -DHOSP_HIDAPI_PC_MODULES="hidapi-libusb;hidapi;hidapi-hidraw"
To install, run with proper privileges:
cmake --build . --target install
On Linux, installation typically places libraries in /usr/local/lib
and header files in /usr/local/include/hosp
.
Install must be run before uninstalling in order to have a manifest. To uninstall, run with proper privileges:
cmake --build . --target uninstall
To link with libhosp, get linker information (including transitive dependencies) with pkg-config
:
pkg-config --libs --static hosp
The --static
flag is unnecessary if you built/installed a shared object library.
You may also need additional compile flags, e.g., to get headers:
pkg-config --cflags hosp
To use an ODROID Smart Power without needing sudo/root at runtime, set appropriate udev privileges.
You can give access to a specific group, e.g. plugdev
, by creating/modifying a udev
config file like /etc/udev/rules.d/10-local.rules
.
Depending on whether you are using the libusb
or hidraw
implementations of hidapi
, use one of the following rules (having both doesn't hurt):
# ODROID Smart Power - HIDAPI/libusb
SUBSYSTEM=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="003f", GROUP="plugdev"
# ODROID Smart Power - HIDAPI/hidraw
KERNEL=="hidraw*", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="003f", GROUP="plugdev"
For the new permissions to take effect, the device must be remounted by the kernel - either disconnect and reconnect the device or reboot the system.
The user is responsible for initializing and finalizing the HIDAPI library using hid_init()
and hid_exit()
.
The following example skips those for brevity.
// get the handle
hosp_device* hosp = hosp_open();
if (hosp == NULL) {
perror("hosp_open");
return -errno;
}
// maybe ensure the OSP is started using hosp_request_status_write(...)/hosp_request_status_read(...)...
// ...now read data from it
unsigned int mV, mA, mW, mWh;
// we must inform the device of the kind of request we want to read
if (hosp_request_data_write(hosp)) {
perror("hosp_request_data_write");
} else {
for (i = 0; i < HOSP_READ_RETRIES; i++) {
// give the device a moment
usleep(10);
// now try to read
if ((ret = hosp_request_data_read(hosp, &mV, &mA, &mW, &mWh)) < 0) {
// some type of I/O failure
perror("hosp_request_data_read");
break;
} else if (!ret) {
// read was successful
printf("Millivolts: %u\nMilliamps: %u\nmilliwatts: %u\nMilliwatt-hours: %u\n", mV, mA, mW, mWh);
break;
}
// if we get here, the device responded but data was not ready yet, so maybe try again
}
if (i == HOSP_READ_RETRIES) {
// we exhausted our retries
errno = ENODATA;
perror("hosp_request_data_read");
}
}
// close the handle
if (hosp_close(hosp)) {
perror("hosp_close");
return -errno;
}
The following command-line utilities are also included. See their man pages for further usage instructions and examples.
hosp-enumerate
: Find and print ODROID Smart Power device pathshosp-get
: Get information from an ODROID Smart Powerhosp-poll
: Poll an ODROID Smart Power at regular intervalshosp-set
: Set an ODROID Smart Power ON/OFF and START/STOP status
Find this and related project sources at the energymon organization on GitHub.
This project originates at: https://github.com/energymon/hosp
Bug reports and pull requests for bug fixes and enhancements are welcome.