Device Pavlok: added basic device files

This commit is contained in:
Daniel Dakhno 2024-04-22 22:36:28 +02:00
parent f186053dab
commit 4a73d2254a
4 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,42 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pavlok;
import androidx.annotation.NonNull;
import java.util.regex.Pattern;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.pavlok.PavlokSupport;
public class PavlokCoordinator extends AbstractBLEDeviceCoordinator {
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
}
@Override
protected Pattern getSupportedDeviceName() {
return Pattern.compile("^Pavlok-.*");
}
@Override
public String getManufacturer() {
return "Pavlok";
}
@NonNull
@Override
public Class<? extends DeviceSupport> getDeviceSupportClass() {
return PavlokSupport.class;
}
@Override
public int getDeviceNameResource() {
return R.string.devicetype_pavlok;
}
}

View File

@ -145,6 +145,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.Ear2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nothing.EarStickCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.nut.NutCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pavlok.PavlokCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.pinetime.PineTimeJFCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.qc35.QC35Coordinator;
@ -378,6 +379,7 @@ public enum DeviceType {
FEMOMETER_VINCA2(FemometerVinca2DeviceCoordinator.class),
PIXOO(PixooCoordinator.class),
SCANNABLE(ScannableDeviceCoordinator.class),
PAVLOK(PavlokCoordinator.class),
TEST(TestDeviceCoordinator.class);
private DeviceCoordinator coordinator;

View File

@ -0,0 +1,95 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.pavlok;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ReadAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.nut.NutSupport;
public class PavlokSupport extends AbstractBTLEDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(PavlokSupport.class);
private static final String ACTION_ZAP = "nodomain.freeyourgadget.gadgetbridge.devices.pavlok.ACTION_ZAP";
private static final UUID UUID_PAVLOK_SERVICE = UUID.fromString("156e1000-a300-4fea-897b-86f698d74461");
private static final UUID UUID_PAVLOK_CHARACTERISTIC_ZAP = UUID.fromString("00001003-0000-1000-8000-00805f9b34fb");
BroadcastReceiver zapReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int intensity = intent.getIntExtra("EXTRA_INTENSITY", 0);
if((intensity <= 0) || (intensity > 100)){
LOG.error("EXTRA_INTENSITY missing, <= 0 or > 100");
return;
}
sendZap(intensity);
}
};
private void sendZap(int intensity){
byte[] packet = new byte[]{(byte) 0x89, (byte) intensity};
new TransactionBuilder("send pavlok zap")
.write(getCharacteristic(UUID_PAVLOK_CHARACTERISTIC_ZAP), packet)
.queue(getQueue());
}
public PavlokSupport() {
super(LOG);
addSupportedService(GattService.UUID_SERVICE_BATTERY_SERVICE);
addSupportedService(UUID_PAVLOK_SERVICE);
}
@Override
public void dispose() {
getContext().unregisterReceiver(zapReceiver);
super.dispose();
}
@Override
public boolean useAutoConnect() {
return false;
}
@Override
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
getContext().registerReceiver(
zapReceiver,
new IntentFilter(ACTION_ZAP), Context.RECEIVER_EXPORTED
);
return builder
.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()))
.add(new ReadAction(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_BATTERY_LEVEL)))
.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if(characteristic.getUuid().equals(GattCharacteristic.UUID_CHARACTERISTIC_BATTERY_LEVEL)){
int level = (int) characteristic.getValue()[0];
getDevice().setBatteryLevel(level);
getDevice().sendDeviceUpdateIntent(getContext());
}
return super.onCharacteristicRead(gatt, characteristic, status);
}
}

View File

@ -2796,4 +2796,5 @@
<string name="pref_summary_bottom_navigation_bar_off">Switch between main screens only using horizontal swiping</string>
<string name="pref_dashboard_widget_today_upside_down_title">Midnight at bottom</string>
<string name="pref_dashboard_widget_today_upside_down_summary">In 24h mode, draw midnight at the bottom, midday at the top of the chart</string>
<string name="devicetype_pavlok">Pavlok shocker</string>
</resources>