Move from slow JSON to much quicker byte transfer

This commit is contained in:
Robert Marshall 2021-12-22 09:28:42 +00:00
parent 5615108b5d
commit 51f3c87c30
3 changed files with 84 additions and 27 deletions

View file

@ -28,7 +28,6 @@ android {
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

View file

@ -1,12 +1,14 @@
package uk.robware.vanlights;
public class Light {
public byte id;
public String name;
public boolean on;
public float brightness = 1;
public int timer;
public Light(String lightName) {
public Light(byte id, String lightName) {
this.id = id;
name=lightName;
}
}

View file

@ -12,8 +12,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import com.google.gson.Gson;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@ -21,13 +20,18 @@ import java.util.UUID;
public class LightsService extends Service {
private final IBinder binder = new LightsBinder();
private Map<String, Light> _lights= new HashMap<>();
private Map<Integer, Light> _lightsById= new HashMap<>();
private MainActivity _mainActivity;
public LightsService(){
_lights.put("seating", new Light("seating"));
_lights.put("kitchen", new Light("kitchen"));
_lights.put("bathroom", new Light("bathroom"));
_lights.put("awning", new Light("awning"));
_lights.put("seating", new Light((byte) 1, "seating"));
_lights.put("kitchen", new Light((byte) 2, "kitchen"));
_lights.put("bathroom", new Light((byte) 3, "bathroom"));
_lights.put("awning", new Light((byte) 4, "awning"));
for (Light light : _lights.values()) {
_lightsById.put(Integer.valueOf(light.id), light);
}
}
public class LightsBinder extends Binder {
@ -79,21 +83,34 @@ public class LightsService extends Service {
}
};
public int bytesToInt(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getInt();
}
public float bytesToFloat(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getFloat();
}
private void readControllerData(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
if (value.length == 0)
return;
String jsonString = new String(value);
Gson json = new Gson();
Light[] lights = new Light[0];
lights = json.fromJson(jsonString, lights.getClass());
for (Light light : lights) {
_lights.put(light.name, light);
}
if (_mainActivity!=null)
_mainActivity.dataReadCallback(_lights);
// byte[] value = characteristic.getValue();
// if (value.length == 0)
// return;
//
// for (int i=0; i<value.length;i+=10){
// Light light=_lightsById.get(Integer.valueOf(value[i]));
// light.on=value[i+1]==1;
// light.brightness=bytesToFloat(new byte[]{value[i+2],value[i+3],value[i+4],value[i+5]});
// light.timer=bytesToInt(new byte[]{value[i+6],value[i+7],value[i+8],value[i+9]});
// }
//
// if (_mainActivity!=null)
// _mainActivity.dataReadCallback(_lights);
}
public void registerUI(MainActivity mainActivity){
@ -109,10 +126,49 @@ public class LightsService extends Service {
_gatt.disconnect();
}
public byte[] intToBytes(int x) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.putInt(x);
return buffer.array();
}
public byte[] floatToBytes(float x) {
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.putFloat(x);
return buffer.array();
}
private byte[] getLightDataAsBytes() {
byte[] data=new byte[10 * _lights.size()];
int dataIndex=0;
for (Light light : _lights.values()) {
data[dataIndex]= light.id;
data[dataIndex+1]= (byte) (light.on?1:0);
int brightnessByteIndex=0;
byte[] brightnessToBytes = intToBytes((int) (light.brightness*100));
for (byte brightnessByte: brightnessToBytes) {
data[dataIndex + 2 + brightnessByteIndex] = brightnessByte;
brightnessByteIndex++;
}
int timerByteIndex=0;
byte[] timerToBytes = intToBytes(light.timer);
for (byte timerByte: timerToBytes) {
data[dataIndex + 6 + timerByteIndex] = timerByte;
timerByteIndex++;
}
dataIndex+=10;
}
return data;
}
public boolean sendUpdate() {
Gson json=new Gson();
String value = json.toJson(_lights.values());
return write(value);
byte[] data=getLightDataAsBytes();
return write(data);
}
public void updateState(String name, boolean state) {
@ -131,11 +187,11 @@ public class LightsService extends Service {
light.timer=totalSeconds;
}
private boolean write(String value){
private boolean write(byte[] value){
if (_characteristic==null || _gatt==null)
return false;
_characteristic.setValue(value);
_gatt.writeCharacteristic(_characteristic);
return true;
}
}
}