com.geotab.model.entity.device.Device Maven / Gradle / Ivy
package com.geotab.model.entity.device;
import static com.geotab.util.Util.listOf;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.geotab.model.entity.NameEntityWithVersion;
import com.geotab.model.entity.customproperty.PropertyValue;
import com.geotab.model.entity.file.MediaFile;
import com.geotab.model.entity.group.CompanyGroup;
import com.geotab.model.entity.group.Group;
import com.geotab.model.entity.worktime.WorkTime;
import com.geotab.model.entity.worktime.WorkTimeStandardHours;
import com.geotab.model.serialization.serdes.DeviceDeserializer;
import com.geotab.model.serialization.serdes.EntityCollectionAsIdCollectionSerializer;
import com.geotab.util.ThirdPartyHelper;
import com.geotab.util.Util;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
/**
* A Device represents the physical tracking device installed in the vehicle. A device and vehicle is typically
* synonymous since the GO tracking device is installed in a vehicle. In the case where there is no device; this is
* represented by "NoDeviceId".
*/
@Getter @Setter
@NoArgsConstructor
@SuperBuilder
@JsonDeserialize(using = DeviceDeserializer.class)
public class Device extends NameEntityWithVersion {
public static final Float DEFAULT_MAX_NO_LOG_SECONDS = 200.0f;
public static final LocalDateTime MAX_DATE = LocalDateTime.of(2050, 1, 1, 0, 0, 0, 0);
public static final LocalDateTime MIN_DATE = LocalDateTime.of(1986, 1, 1, 0, 0, 0, 0);
/**
* The default serial number of historic devices.
*/
public static final String HISTORIC_SERIAL_NUMBER = "000-000-0000";
/**
* The minimum id value for devices that are archived.
*/
public static final int HISTORIC_MIN = 1000000;
/**
* The maximum id value for devices that are archived.
*/
public static final int HISTORIC_MAX = 10000000;
/**
* The default product Id for third-party devices.
*/
public static final int CUSTOM_DEVICE_PRODUCT_ID = 10000;
/**
* The default product Id for GoDrive mobile devices.
*/
public static final int GO_DRIVE_PRODUCT_ID = 256;
/**
* The default serial number prefix for GoDrive mobile devices.
*/
public static final String GO_DRIVE_PREFIX = "GD";
/**
* The default product Id for Go2 devices.
*/
public static final int GO2_PRODUCT_ID = 1;
/**
* The default serial number prefix for Go2 devices.
*/
public static final String GO2_PREFIX = "GT";
/**
* The default product Id for Go3 devices.
*/
public static final int GO3_PRODUCT_ID = 64;
/**
* The default serial number prefix for Go3 devices.
*/
public static final String GO3_PREFIX = "G3";
/**
* The default product Id for Go4 devices (pre Go4v3).
*/
public static final int GO4_PRODUCT_ID = 65;
/**
* The default serial number prefix for Go4 devices (pre Go4v3).
*/
public static final String GO4_PREFIX = "G4";
/**
* The default product Id for Go4v3 devices.
*/
public static final int GO4_V3_PRODUCT_ID = 81;
/**
* The default serial number prefix for Go4v3 devices.
*/
public static final String GO4_V3_PREFIX = "GV";
/**
* The default product Id for Go5 devices.
*/
public static final int GO5_PRODUCT_ID = 90;
/**
* The default serial number prefix for Go5 devices.
*/
public static final String GO5_PREFIX = "G5";
/**
* The default Product ID for Go6 devices.
*/
public static final int GO6_PRODUCT_ID = 101;
/**
* The default serial number prefix for Go6 devices.
*/
public static final String GO6_PREFIX = "G6";
/**
* The default Product ID for Go7 devices.
*/
public static final int GO7_PRODUCT_ID = 105;
/**
* The default serial number prefix for Go7 devices.
*/
public static final String GO7_PREFIX = "G7";
/**
* The default Product ID for Go8 devices.
*/
public static final int GO8_PRODUCT_ID = 114;
/**
* The default serial number prefix for Go8 devices.
*/
public static final String GO8_PREFIX = "G8";
/**
* The default Product ID for Go8 devices without a gps.
*/
public static final int GO8_PRODUCT_ID_NO_GPS = 116;
/**
* The default Product ID for Go9 devices.
*/
public static final int GO9_PRODUCT_ID = 120;
/**
* The default serial number prefix for Go9 devices.
*/
public static final String GO9_PREFIX = "G9";
/**
* The default Product ID for Go9b devices.
*/
public static final int GO9B_PRODUCT_ID = 124;
/**
* The default serial number prefix for Go9 devices.
*/
public static final String GO9B_PREFIX = "GA";
/**
* The default Product ID for Go9 devices.
*/
public static final int GO10_PRODUCT_ID = 124;
/**
* The default serial number prefix for Go10 devices.
*/
public static final String GO10_PREFIX = "GA";
/**
* The default serial number prefix for aptiv A1 devices.
*/
public static final String A1_PREFIX = "A1";
/**
* The default Product ID for A1 devices.
*/
public static final int A1_PRODUCT_ID = 255;
/**
* The default serial number prefix for A1 devices.
*/
public static final String U1_PREFIX = "U1";
/**
* The default Product ID for U1 devices.
*/
public static final int U1_PRODUCT_ID = 130;
/**
* The default serial number prefix for Go Anywhere (EOS Battery B1) devices.
*/
public static final String GO_ANYWHERE_PREFIX = "B1";
/**
* The default Product Id for Go Anywhere (EOS Battery B1) devices.
*/
public static final int GO_ANYWHERE_PRODUCT_ID = 131;
/**
* The default serial number prefix for A1 devices.
*/
public static final String S1_PREFIX = "S1";
/**
* The default Product Id for EOS Solar S1 devices.
*/
public static final int S1_PRODUCT_ID = 132;
/**
* The default Product ID for Go9 devices without a gps.
*/
public static final int GO9_PRODUCT_ID_NO_GPS = 121;
/**
* The maximum Product ID for Go devices.
*/
public static final int GO_MAX_PRODUCT_ID = 254;
/**
* The default Product ID for untracked assets.
*/
public static final int UNTRACKED_ASSET_PRODUCT_ID = -1;
/**
* The default Hardware Id for untracked assets.
*/
public static final int UNTRACKED_ASSET_HARDWARE_ID = -1;
public static final int OLD_GEOTAB_PRODUCT_ID = 0;
/**
* Prefix to product id mapping.
*/
public static final Map GO_PREFIX_TO_PRODUCT_ID_MAPPING =
Util.mapBuilder()
.put(GO2_PREFIX, GO2_PRODUCT_ID)
.put(GO3_PREFIX, GO3_PRODUCT_ID)
.put(GO4_PREFIX, GO4_PRODUCT_ID)
.put(GO4_V3_PREFIX, GO4_V3_PRODUCT_ID)
.put(GO5_PREFIX, GO5_PRODUCT_ID)
.put(GO6_PREFIX, GO6_PRODUCT_ID)
.put(GO7_PREFIX, GO7_PRODUCT_ID)
.put(GO8_PREFIX, GO8_PRODUCT_ID)
.put(GO9_PREFIX, GO9_PRODUCT_ID)
.put(GO9B_PREFIX, GO9B_PRODUCT_ID)
.put(GO10_PREFIX, GO10_PRODUCT_ID)
.put(GO_DRIVE_PREFIX, GO_DRIVE_PRODUCT_ID)
.put(A1_PREFIX, A1_PRODUCT_ID)
.put(U1_PREFIX, U1_PRODUCT_ID)
.build();
/**
* Specifies the GO or Custom {@link DeviceType}.
*/
protected DeviceType deviceType;
/**
* The product id. Each device is assigned a unique hardware product id.
*/
protected Integer productId;
/**
* The Serial Number of the device. Maximum length [12].
*/
protected String serialNumber;
/**
* The date that tells the system at what moment should it start checking the device status and warn if there is no
* new data. Used when a new device is just installed or the vehicle undergoes a lengthy service. Default [MinDate].
*/
protected LocalDateTime ignoreDownloadsUntil;
/**
* Gets or sets the expected time between downloads, i.e. how frequently the device is expected to produce new data.
* For passive devices this might range from 1 to a few days. For live devices this should be maximum 24h unless
* vehicles travel out of coverage frequently. This is used to check if the device is in good state.
*/
protected Duration timeToDownload;
/**
* The {@link WorkTime} rules to apply to the device. Default [{@link WorkTimeStandardHours}].
*/
protected WorkTime workTime;
/**
* The list of {@link Group}(s) the device belongs to.
*/
@JsonSerialize(converter = EntityCollectionAsIdCollectionSerializer.class)
protected List groups;
/**
* Geotab DevicePlan that has been purchased for this device.
*/
protected List devicePlans;
/**
* The {@link DevicePlanBillingInfo} that has been purchased for this device.
*/
protected List devicePlanBillingInfo;
/**
* The IANA time zone Id of the device used to determine local work times. This is typically the "home location" of
* the device. Default ["America/New_York"].
*/
protected String timeZoneId;
/**
* The minimum allowable value for maxSecondsBetweenLogs. Defaults to 0.0f.
*/
protected Float minSecondsBetweenLogs;
/**
* The maximum allowed time between logs when the ignition is on in seconds. When the value is exceeded, data is
* considered to be missing. Default [200].
*/
protected Float maxSecondsBetweenLogs;
/**
* The date the device is active from. Default [MIN_DATE].
*/
protected LocalDateTime activeFrom;
/**
* The date that the device is active to. Default [MAX_DATE].
*/
protected LocalDateTime activeTo;
/**
* Free text field where any user information can be stored and referenced for this entity.
*/
protected String comment;
/**
* The device features which have been enabled whether the feature is in use (e.g. HOS, Iridium). The DevicePlan
* property cannot be added/updated via the API.
*/
protected DeviceFlags deviceFlags;
/**
* The custom features for this device and their values.
*
* CustomFeatures property will be removed completely in a future version of the SDK.
* CustomFeatures property is only used by AutoHos, for which GoDevice#autoHos property was added. Backward
* compatibility for CustomFeatures is ensured: autoHos property takes precedence over customFeatures when both are
* set, otherwise customFeatures.
*/
protected Map customFeatures;
/**
* The set of dynamic, user created, custom properties.
*/
protected List customProperties;
/**
* The list of {@link MediaFile} for this asset.
*/
protected List mediaFiles;
/**
* Maps the given productId to a {@link DeviceType}.
*
* @param productId The device product Id.
* @return The {@link DeviceType}
*/
@SuppressWarnings("ConstantConditions")
public static DeviceType deviceTypeFromProductId(int productId) {
if (productId < 0) return DeviceType.NONE;
if (productId == 0) return DeviceType.OLD_GEOTAB;
if (productId <= 31 || productId >= 40 && productId <= 55) return DeviceType.GO2;
if (productId <= 39 || productId >= 56 && productId < GO4_PRODUCT_ID) return DeviceType.GO3;
if (productId >= GO4_PRODUCT_ID && productId < GO4_V3_PRODUCT_ID) return DeviceType.GO4;
if (productId >= GO4_V3_PRODUCT_ID && productId < GO5_PRODUCT_ID) return DeviceType.GO4V3;
if (productId >= GO5_PRODUCT_ID && productId < GO6_PRODUCT_ID) return DeviceType.GO5;
if (productId >= GO6_PRODUCT_ID && productId < GO7_PRODUCT_ID) return DeviceType.GO6;
if (productId >= GO7_PRODUCT_ID && productId < GO8_PRODUCT_ID) return DeviceType.GO7;
if (productId >= GO8_PRODUCT_ID && productId < GO9_PRODUCT_ID) return DeviceType.GO8;
if (productId >= GO9_PRODUCT_ID && productId < GO9B_PRODUCT_ID) return DeviceType.GO9;
if (productId >= GO9B_PRODUCT_ID && productId < GO10_PRODUCT_ID) return DeviceType.GO9B;
if (productId >= GO10_PRODUCT_ID && productId <= GO_MAX_PRODUCT_ID) return DeviceType.GO10;
if (productId == A1_PRODUCT_ID) return DeviceType.A1;
if (productId == U1_PRODUCT_ID) return DeviceType.U1;
if (productId == GO_DRIVE_PRODUCT_ID) return DeviceType.GO_DRIVE_DEVICE;
if (ThirdPartyHelper.isThirdPartyVehicleDevice(productId)) return DeviceType.CUSTOM_VEHICLE_DEVICE;
if (ThirdPartyHelper.isThirdPartyDevice(productId)) return DeviceType.CUSTOM_DEVICE;
return DeviceType.NONE;
}
/**
* Returns the product id from its serial number.
*
* @param serialNumber The serial number.
* @return Internal product Id for a serial number
*/
public static int productIdFromSerialNumber(String serialNumber) {
int productId = 0;
if (serialNumber.length() >= 2) {
String prefix = serialNumber.substring(0, 2);
if (GO_PREFIX_TO_PRODUCT_ID_MAPPING.containsKey(prefix)) {
return GO_PREFIX_TO_PRODUCT_ID_MAPPING.get(prefix);
} else {
return ThirdPartyHelper.getThirdPartyProductId(serialNumber);
}
}
return productId;
}
/**
* Returns the string prefix of the given product ID.
*
* @param productId Internal product Id for a serial number
* @return A serial number prefix.
*/
public static String prefixFromDeviceType(int productId) {
String prefix = deviceTypeFromProductId(productId).getPrefix();
if (!prefix.isEmpty()) return prefix;
return ThirdPartyHelper.THIRD_PARTY_DEVICE_TYPES.getOrDefault(productId, "");
}
/**
* Determine if a device is NoGps Device by its productId.
*
* @return true | false
*/
@JsonIgnore
public boolean isNoGpsDevice() {
return productId == GO8_PRODUCT_ID_NO_GPS || productId == GO9_PRODUCT_ID_NO_GPS;
}
/**
* Returns the correct type of device for the given serial number.
*
* @param serialNumber The serial number for the device. For example, GV-001-000-0000.
* @return An instance of {@link Device} object that corresponds to the serial number provided
*/
public static Device fromSerialNumber(String serialNumber) {
int productId = productIdFromSerialNumber(serialNumber);
Device device = fromProductId(productId);
device.serialNumber = serialNumber;
return device;
}
/**
* Set default values for the {@link Device} instance.
*/
public void populateDefaults() {
this.comment = Optional.ofNullable(this.comment).orElse("");
this.timeToDownload = Optional.ofNullable(this.timeToDownload).orElse(Duration.ofMillis(86400000L));
this.ignoreDownloadsUntil = Optional.ofNullable(this.ignoreDownloadsUntil).orElse(MIN_DATE);
this.timeZoneId = Optional.ofNullable(this.timeZoneId).orElse("America/New_York");
this.groups = Optional.ofNullable(this.groups).orElse(listOf(new CompanyGroup()));
this.maxSecondsBetweenLogs = Optional.ofNullable(this.maxSecondsBetweenLogs).orElse(DEFAULT_MAX_NO_LOG_SECONDS);
this.workTime = Optional.ofNullable(this.workTime).orElse(new WorkTimeStandardHours());
this.activeTo = MAX_DATE;
this.activeFrom = Optional.ofNullable(this.activeFrom).orElse(LocalDateTime.now(ZoneOffset.UTC));
}
/**
* Get the correct Device object from the given product Id.
*
* @param productId Product id.
* @return Device instance
*/
public static Device fromProductId(int productId) {
DeviceType deviceType = deviceTypeFromProductId(productId);
Device device = deviceType.newInstance();
device.productId = productId;
return device;
}
}