8 个版本

新版本 0.1.7 2024年7月29日
0.1.6 2023年12月12日
0.1.5 2023年4月18日
0.1.4 2022年5月24日

#468网络编程 中排名

Download history 134/week @ 2024-07-29

每月 134 次下载

MIT 许可证

185KB
4.5K SLoC

rscp

Crate Docs License Coverage

这个库是一个基于 Rust 的 E3/DC RSCP 连接器。

  • 避免使用双重命名和包装
  • 实现了不进行类型包装的原生类型解析

由于没有已知的需求,因此忽略了 Tag 字段中的响应位。

此库处于早期阶段。

用法

存在多个用户级别(NO_AUTH => USER ... => ADMIN => E3DC_ROOT)。对于大多数情况,NO_AUTH 和 USER 级别的访问就足够了。因此,在向您的 E3DC 系统发送请求之前,我们首先需要进行身份验证。

向 RSCP 系统发送的每个请求都包含一个 rscp::Frame(容器)和多个 rscp::Item,后者包含标签和数据。

登录和第一个数据包

RSCP_KEY 是您在 S10 屏幕上的“设置”=>“个性化”=>“用户资料”+>“local.user”中定义的密码
RSCP_USER 是您的 S10 门户中的用户名(即电子邮件地址)
RSCP_PASSWORD 是您的 S10 门户中的密码

use rscp::GetItem;

let mut c = rscp::Client::new("RSCP_KEY", "RSCP_USER".to_string(), "RSCP_PASSWORD".to_string());
match c.connect("energy.storage.local", None) {
    Ok(_) => (),
    Err(err) => {
        panic!("Unable to connect: {:?}", err);
    }
}

let mut info_frame = rscp::Frame::new();
info_frame.push_item(rscp::Item { tag: rscp::tags::INFO::SERIAL_NUMBER.into(), data: None } );
info_frame.push_item(rscp::Item { tag: rscp::tags::INFO::MAC_ADDRESS.into(), data: None } );
info_frame.push_item(rscp::Item { tag: rscp::tags::INFO::SW_RELEASE.into(), data: None } );

match c.send_receive_frame(&info_frame) {
    Ok(result_frame) => {
        println!("{}", result_frame.get_item_data::<String>(rscp::tags::INFO::SERIAL_NUMBER.into()).unwrap());
    },
    Err(err) => {
        warn!("Unable send: {:?}", err);
    }
}

c.disconnect().unwrap();

组成电池信息请求

类似于官方 rscp 调用请求电池信息的示例,我们也可以定义一个容器请求。BAT::DATA 标签定义了后续的标签应该被评估以接收有关电池的一些数据。

let mut battery_info_frame = Frame::new();
battery_info_frame.push_item(rscp::Item::new(rscp::tags::BAT::DATA.into(),
    vec![
        rscp::Item { tag: rscp::tags::BAT::INDEX.into(), data: Some(Box::new(0)), },
        rscp::Item { tag: rscp::tags::BAT::RSOC.into(), data: None },
        rscp::Item { tag: rscp::tags::BAT::MODULE_VOLTAGE.into(), data: None },
        rscp::Item { tag: rscp::tags::BAT::CURRENT.into(), data: None },
        rscp::Item { tag: rscp::tags::BAT::STATUS_CODE.into(), data: None },
        rscp::Item { tag: rscp::tags::BAT::ERROR_CODE.into(), data: None },
    ]));

match 中的预期输出 println!("结果: {:?}", result_frame.items.get_item(DATA.into()));

Result: Ok(Item 
{ tag: "BAT_DATA", data: [
    Item { tag: "BAT_INDEX", data: 0 }, 
    Item { tag: "BAT_RSOC", data: 38.218014 }, 
    Item { tag: "BAT_MODULE_VOLTAGE", data: 51.7 }, 
    Item { tag: "BAT_CURRENT", data: 108.9 }, 
    Item { tag: "BAT_STATUS_CODE", data: 0 }, 
    Item { tag: "BAT_ERROR_CODE", data: 0 }
] })

标签与标签

请小心使用您在请求中使用的标签,因为某些标签设置值而不是获取值。官方示例应用程序文档和 Excel 表格提供了区分这些标签所需的信息。

本项目中标签的结构与标签文档相似,但并不一定与官方示例应用中的标签相同。例如,这个官方标签:#define TAG_BAT_INDEX 0x03040001 对应于项目标签

rscp::tags::BAT::INDEX

  • BAT = 0x03,
  • INDEX = 0x040001,

其优势在于标签名称的重用,因此代码的可读性也得到了提升。

项目标签 示例应用标签
PVI::DATA = 0x040000, TAG_PVI_DATA = 0x02840000
BAT::DATA = 0x040000, TAG_BAT_INDEX = 0x03840000
DCDC::DATA = 0x040000, TAG_DCDC_REQ_DATA = 0x04040000
... ...

依赖项

~1.5MB
~26K SLoC