fangtang.md
17.4 KB
方糖相关文档
标签(空格分隔): work
1.智能模块
1.1 门锁蓝牙控制模块
门锁使用的desman的方案,基于蓝牙4.0,官方app是小滴管家。通过其提供的android sdk(greenbluetoothlelib.jar),可以实现开关的控制。sdk中通过蓝牙模块的mac(蓝牙名以IDLOCK_开头) 地址区分不同的门锁.在启动GREENBluetoothLeService时,其'onCreate'代码中有重启ble相关操作GREENBluetoothLeService.restartBleDevice(),故会导致蓝牙遥控器短暂失效。
主要使用流程概述如下
- 注册启动相关服务
java //androidmanifest <service android:name="com.bluetoothle.GREENBluetoothLeService" android:enabled="true"/> //activity onCreate startService(new Intent(this, GREENBluetoothLeService.class));- 发送开锁命令,其中mac地址会根据实际布置进行绑定 ```java private BLEBroadcastReceiver bleBroadcastReceiver = new BLEBroadcastReceiver(); bleBroadcastReceiver.setResponseObj(new GREENCITYBLEProtocolFactory.GREENCITYBleDataWritten() {
@Override
public void writeSuccess() {
bleBroadcastReceiver.setResponseObj(null);
Toast.makeText(MainActivity.this, "开门成功", Toast.LENGTH_SHORT).show();
BLEOpenRecord bleOpenRecord = new BLEOpenRecord();
bleOpenRecord.setLockmac("DC:F6:70:C1:AA:D6");
bleOpenRecord.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(new Date()));
Intent intent = new Intent();
intent.setAction(GREENBluetoothLeService.ACTION_OPEN_SUCCESS);
intent.putExtra("openrecord", bleOpenRecord);
sendBroadcast(intent);
}
@Override
public void writeFailure(String error) {
bleBroadcastReceiver.setResponseObj(null);
Toast.makeText(MainActivity.this, "开门失败," + error, Toast.LENGTH_SHORT).show();
}
});
GREENBLE.send(this, "DC:F6:70:C1:AA:D6", openCMD.getBytes());
## 1.2 智能灯光
智能灯光使用的是大豆的方案,基于蓝牙4.0,官方app是dadouLight。使用时需要`add mess`,基出厂的默认配置均为`mesh name:telink_zz,pwd:123`,配置成功后,调用相关方法可以通过mesh name寻找当前范围内是否有相关智能灯存在,若存在会登录,成功后即可控制。踢除后灯光成功登录后灯光下显示的是3F:99,此时`mesh name `应为`out_of_mesh`
**注意:在重设置`mesh name`时,在设置mesh页面将`mesh name` 填入`factory name`,保存后,一定要等所连灯消失后再去点`network scanning`,否则很大的可能会设置失败,失败后需要将,`mesh name `改回去再改一次**
主要使用流程概述如下
> * 注册application主要用于初始化`Mesh`启动灯光相关服务
```java
public class FangTangApplication extends TelinkApplication {
private Mesh mesh;
@Override
public void onCreate() {
super.onCreate();
AdvanceStrategy.setDefault(new MySampleAdvanceStrategy());
}
@Override
public void doInit() {
super.doInit();
if (FileSystem.exists(Mesh.MESH_FILE_NAME)) {
this.mesh = (Mesh) FileSystem.readAsObject(Mesh.MESH_FILE_NAME);
}
Log.d("SMCService", "doInit");
//启动LightService
this.startLightService(TelinkLightService.class);
}
public Mesh getMesh() {
return this.mesh;
}
public void setMesh(Mesh mesh) {
this.mesh = mesh;
}
public boolean isEmptyMesh() {
return this.mesh == null;
}
}
- 声名服务继承于
LightService,启动LightAdapter```java public final class TelinkLightService extends LightService { private static TelinkLightService mThis; public static TelinkLightService Instance() { return mThis; }
@Override
public IBinder onBind(Intent intent) {
..... }
@Override
public void onCreate() {
super.onCreate();
mThis = this;
if (this.mAdapter == null)
this.mAdapter = new LightAdapter();
this.mAdapter.start(this);
}
public class LocalBinder extends Binder {
public TelinkLightService getService() {
return TelinkLightService.this;
}
}
}
> * 启动蓝牙
```java
if (!LeBluetooth.getInstance().isEnabled()) {
LeBluetooth.getInstance().enable(getApplicationContext());
Log.d(TAG, "开启蓝牙,体验智能灯!");
}
- 自动连接
```java if (TelinkLightService.Instance() != null) { Log.d(TAG, "connect not null"); if (TelinkLightService.Instance().getMode() != LightAdapter.MODE_AUTO_CONNECT_MESH) { Lights.getInstance().clear(); if (mApplication.isEmptyMesh()) return; Mesh mesh = mApplication.getMesh(); //自动重连参数 LeAutoConnectParameters connectParams = Parameters.createAutoConnectParameters(); connectParams.setMeshName(mesh.name); connectParams.setPassword(mesh.password); connectParams.autoEnableNotification(true); //自动重连 TelinkLightService.Instance().autoConnect(connectParams); } else { Log.d(TAG, "connect null"); }
//刷新Notify参数
LeRefreshNotifyParameters refreshNotifyParams = Parameters.createRefreshNotifyParameters();
refreshNotifyParams.setRefreshRepeatCount(2);
refreshNotifyParams.setRefreshInterval(2000);
//开启自动刷新Notify
TelinkLightService.Instance().autoRefreshNotify(refreshNotifyParams);
}
> * 监听扫描成功。其sdk基于event bus通知消息,实现接口`EventListener<String> `重写方法`public void performed(Event<String> event)`即可,其中涉及到的一些具体逻辑处理方法可参见代码
```java
@Override
public void performed(Event<String> event) {
switch (event.getType()) {
case NotificationEvent.ONLINE_STATUS:
onOnlineStatusNotify((NotificationEvent) event);
break;
case DeviceEvent.STATUS_CHANGED:
onDeviceStatusChanged((DeviceEvent) event);
break;
case MeshEvent.OFFLINE:
onMeshOffline((MeshEvent) event);
break;
case MeshEvent.ERROR:
onMeshError((MeshEvent) event);
break;
case ServiceEvent.SERVICE_CONNECTED:
onServiceConnected((ServiceEvent) event);
break;
case ServiceEvent.SERVICE_DISCONNECTED:
onServiceDisconnected((ServiceEvent) event);
break;
}
}
- 基本控制方法,开关及亮度色温控制,其中传递不同的
address可以控制不同的灯,0xFFFF表示当前mesh中所有的灯,如代码中注释了的addr = 0x8003;表示组为0x8003的所有灯。
private void open() {
byte opcode = (byte) 0xD0;
int address = 0xFFFF;
byte[] params = new byte[]{0x01, 0x00, 0x00};
if (TelinkLightService.Instance().sendCommandNoResponse(opcode, address, params)) {
Log.d("aidl","open all success");
}
}
private void close() {
byte opcode = (byte) 0xD0;
int address = 0xFFFF;
byte[] params = new byte[]{0x00, 0x00, 0x00};
if (TelinkLightService.Instance().sendCommandNoResponse(opcode, address, params)) {
Log.d("aidl","open all success");
}
}
private void setBrightness(int value) {
int addr = 0xFFFF;
//change group brightness or color temperature
//addr = 0x8003;
byte opcode;
byte[] params;
opcode = (byte) 0xD2;
params = new byte[]{(byte) value};
TelinkLightService.Instance().sendCommandNoResponse(opcode, addr, params, true);
}
private void setTemperature{
int addr = 0xFFFF;
//change group brightness or color temperature
//addr = 0x8003;
byte opcode;
byte[] params;
opcode = (byte) 0xE2;
params = new byte[]{0x05, (byte) value};
TelinkLightService.Instance().sendCommandNoResponse(opcode, addr, params, true);
}
- 对亮度色温渐变处理时需要添加额外逻辑
1.3 智能开关
智能开关使用的思唯奇的方案,基于网络,现使用是通过投影控制,只使用了局域网相关功能,没有调试公网功能,其控制主机hub可连接2.4G网络,不支持5G网络。官方app为homelf,可在其官网下载http://www.adroplat.com/homelf/app/android/download/homelf.apk。 使用流程,先添加主机(hub),若是没有配置过的主机需要先联结其自带的wifi homelf才能发现主机,并设置相应控制密码(官方app是自己算出一个随机字符串设置),若是已配置过的直接在其所在2.4G wifi下添加发现即可。添加开关的步骤是,当开关面板全关时长按其中一路到所有路闪烁,后点添加按钮,成功后会有相关提示。 集成sdk相关函数介绍
public class Device implements Serializable, Cloneable {
private static final long serialVersionUID = -1055014034866886590L;
private static Device instance;
private Device() {
}
public static Device getInstance() {
if (null == instance) {
instance = new Device();
}
Device hub;
try {
hub = (Device) instance.clone();
} catch (CloneNotSupportedException e) {
hub = new Device();
}
return hub;
}
/**
* 控制ID
*/
private long ControllerId;
/**
* 命令类型
*/
private int CmdType;
/**
* 错误码
*/
private byte ErrorCode;
/**
* 设备IP
*/
private byte[] DeviceIp;
/**
* 设备端口
*/
private int DevicePort;
/**
* 设备公网IP
*/
private byte[] MappedIp;
/**
* 设备公网端口
*/
private int MappedPort;
/**
* 设备号
*/
private byte[] DeviceNum;
/**
* 设备口令
*/
private byte[] DeviceKey;
/**
* 是否是广域网控制
*/
private boolean IsWan;
/**
* 子设备
*/
private ArrayList<SubDevice> SubDevices;
public long getControllerId() {
return ControllerId;
}
public void setControllerId(long controllerId) {
ControllerId = controllerId;
}
public int getCmdType() {
return CmdType;
}
public void setCmdType(int cmdType) {
CmdType = cmdType;
}
public byte getErrorCode() {
return ErrorCode;
}
public void setErrorCode(byte errorCode) {
ErrorCode = errorCode;
}
public byte[] getDeviceIp() {
return DeviceIp;
}
public String getStringDeviceIp() {
String strIp = "null";
if (null != DeviceIp) {
char point = '.';
StringBuilder builder = new StringBuilder();
for (byte b : DeviceIp) {
builder.append((b & GlobalVar.MAX_BYTE)).append(point);
}
builder.deleteCharAt(builder.length() - 1);
strIp = builder.toString();
}
return strIp;
}
public void setDeviceIp(byte[] deviceIp) {
DeviceIp = deviceIp;
}
public int getDevicePort() {
return DevicePort;
}
public void setDevicePort(int devicePort) {
DevicePort = devicePort;
}
public byte[] getMappedIp() {
return MappedIp;
}
public void setMappedIp(byte[] mappedIp) {
MappedIp = mappedIp;
}
public int getMappedPort() {
return MappedPort;
}
public void setMappedPort(int mappedPort) {
MappedPort = mappedPort;
}
public byte[] getDeviceNum() {
return DeviceNum;
}
//添加 转化成16进制显示 17.03.23
public String getStringDeviceNum() {
String strIp = "null";
if (null != DeviceNum) {
char point = ':';
StringBuilder builder = new StringBuilder();
for (byte b : DeviceNum) {
builder.append(decimal2hex(b & GlobalVar.MAX_BYTE)).append(point);
}
builder.deleteCharAt(builder.length() - 1);
strIp = builder.toString();
}
return strIp;
}
// precondition: d is a nonnegative integer
public static String decimal2hex(int d) {
String digits = "0123456789ABCDEF";
if (d <= 0) return "00";
int base = 16; // flexible to change in any base under 16
String hex = "";
while (d > 0) {
int digit = d % base; // rightmost digit
hex = digits.charAt(digit) + hex; // string concatenation
d = d / base;
}
return hex;
}
public void setDeviceNum(byte[] deviceNum) {
DeviceNum = deviceNum;
}
public byte[] getDeviceKey() {
return DeviceKey;
}
public String getDeviceStrKey() {
String strKey = "";
try {
strKey = new String(DeviceKey, GlobalVar.CHARSET_UTF8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return strKey;
}
public void setDeviceKey(byte[] deviceKey) {
DeviceKey = deviceKey;
}
public boolean isWan() {
return IsWan;
}
public void setWan(boolean wan) {
IsWan = wan;
}
public ArrayList<SubDevice> getSubDevices() {
return SubDevices;
}
public void setSubDevices(ArrayList<SubDevice> subDevices) {
this.SubDevices = subDevices;
}
/**
* DeviceNum转换成long
*
* @return
*/
public long getLongDeviceNum() {
return ByteUtils.macArrayToLong(DeviceNum);
}
/**
* DeviceKey转换成long
*
* @return
*/
public long getLongDeviceKey() {
return ByteUtils.macArrayToLong(DeviceKey);
}
/**
* MappedIp转换成int
*
* @return
*/
public int getIntMappedIp() {
return ByteUtils.byteArrayToInt(MappedIp);
}
/**
* DeviceIp转换成int
*
* @return
*/
public int getIntDeviceIp() {
return ByteUtils.byteArrayToInt(DeviceIp);
}
}
public class SubDevice implements Cloneable {
private static SubDevice instance;
private SubDevice() {
}
public static SubDevice getInstance() {
if (null == instance) {
instance = new SubDevice();
}
SubDevice subDevice = null;
try {
subDevice = (SubDevice) instance.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
if (null == subDevice) {
subDevice = new SubDevice();
}
return subDevice;
}
private long SubDeviceNum;
private int SubDeviceType;
private int SubDeviceStatus;
private int SubDeviceOnlineStatus;
private int SubDeviceBit;
public long getSubDeviceNum() {
return SubDeviceNum;
}
public void setSubDeviceNum(long subDeviceNum) {
SubDeviceNum = subDeviceNum;
}
public int getSubDeviceType() {
return SubDeviceType;
}
public void setSubDeviceType(int subDeviceType) {
SubDeviceType = subDeviceType;
}
public int getSubDeviceStatus() {
return SubDeviceStatus;
}
public void setSubDeviceStatus(int subDeviceStatus) {
SubDeviceStatus = subDeviceStatus;
}
public int getSubDeviceOnlineStatus() {
return SubDeviceOnlineStatus;
}
public void setSubDeviceOnlineStatus(int subDeviceOnlineStatus) {
SubDeviceOnlineStatus = subDeviceOnlineStatus;
}
public int getSubDeviceBit() {
return SubDeviceBit;
}
public void setSubDeviceBit(int subDeviceBit) {
SubDeviceBit = subDeviceBit;
}
}
- 启动sdk(调用
FistJni.getInstance().startSdk())后会自动调用FistJni中的FistListener方法.调用'FistJni.getInstance().searchLocalDevice()'可扫描当前网络中所有主机信息,若有相关信息返回,fistListerner中会执行case FistProtocol.CommondType.CMD_TYPE_SEARCH_RESPONS,之后可心根据需求做相应的处理。public void query(final String jsonDevice):jsonDevice是主机的json字符串,获取当前主机所有了子设备(开关),FistProtocol.CommondType.CMD_TYPE_QUERY_RESPONSEpublic void normalC(final String jsonDevice):控制开关。获取需要控制的subdevice设置相应的状态(1开,0关),将其单独添加到所属的Device中后转化成json串,调用相关方法发送指令 。FistProtocol.CommondType.CMD_TYPE_CONTROL_DONE_RESPONSE FistProtocol.CommondType.CMD_TYPE_CONTROL_RESPONSE FistProtocol.CommondType.CMD_TYPE_CONTROLpublic void delSub(final String jsonDevice):删除相关开关,使用方法如上类似FistProtocol.CommondType.CMD_TYPE_ADD_RESPONSEstartAdd(String hubJson),stopAdd(String hubJson):添加删除开关,使用hub的信息。如上长按闪烁后添加,结束后调任stop,以免影响主机正常工作。modifyPwd(String hubJson,String pwd):设置hub的控制密码getlinkRouter(String hubJson,String ssid,String pwd):配置路由器信息。