8 changed files with 286 additions and 26 deletions
@ -0,0 +1,171 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.firmware; |
|||
|
|||
import com.google.common.util.concurrent.FutureCallback; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; |
|||
import org.thingsboard.server.common.data.DataConstants; |
|||
import org.thingsboard.server.common.data.Device; |
|||
import org.thingsboard.server.common.data.DeviceProfile; |
|||
import org.thingsboard.server.common.data.Firmware; |
|||
import org.thingsboard.server.common.data.id.DeviceId; |
|||
import org.thingsboard.server.common.data.id.FirmwareId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.device.DeviceProfileService; |
|||
import org.thingsboard.server.dao.device.DeviceService; |
|||
import org.thingsboard.server.dao.firmware.FirmwareService; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
|
|||
import javax.annotation.Nullable; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
import java.util.function.Consumer; |
|||
|
|||
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM; |
|||
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_CHECKSUM_ALGORITHM; |
|||
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_SIZE; |
|||
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_TITLE; |
|||
import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_VERSION; |
|||
|
|||
@Slf4j |
|||
@Service |
|||
@TbCoreComponent |
|||
public class DefaultFirmwareStateService implements FirmwareStateService { |
|||
|
|||
private final FirmwareService firmwareService; |
|||
private final DeviceService deviceService; |
|||
private final DeviceProfileService deviceProfileService; |
|||
private final RuleEngineTelemetryService telemetryService; |
|||
|
|||
public DefaultFirmwareStateService(FirmwareService firmwareService, DeviceService deviceService, DeviceProfileService deviceProfileService, RuleEngineTelemetryService telemetryService) { |
|||
this.firmwareService = firmwareService; |
|||
this.deviceService = deviceService; |
|||
this.deviceProfileService = deviceProfileService; |
|||
this.telemetryService = telemetryService; |
|||
} |
|||
|
|||
@Override |
|||
public void update(Device device, boolean created) { |
|||
FirmwareId firmwareId = device.getFirmwareId(); |
|||
if (firmwareId == null) { |
|||
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); |
|||
firmwareId = deviceProfile.getFirmwareId(); |
|||
} |
|||
|
|||
if (firmwareId == null) { |
|||
if (!created) { |
|||
remove(device); |
|||
} |
|||
} else { |
|||
update(device, firmwareService.findFirmwareById(device.getTenantId(), firmwareId), System.currentTimeMillis()); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void update(DeviceProfile deviceProfile) { |
|||
TenantId tenantId = deviceProfile.getTenantId(); |
|||
|
|||
Consumer<Device> updateConsumer; |
|||
if (deviceProfile.getFirmwareId() != null) { |
|||
Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId()); |
|||
long ts = System.currentTimeMillis(); |
|||
updateConsumer = d -> update(d, firmware, ts); |
|||
} else { |
|||
updateConsumer = this::remove; |
|||
} |
|||
|
|||
PageLink pageLink = new PageLink(100); |
|||
PageData<Device> pageData; |
|||
do { |
|||
//TODO: create a query which will return devices without firmware
|
|||
pageData = deviceService.findDevicesByTenantIdAndType(tenantId, deviceProfile.getName(), pageLink); |
|||
|
|||
pageData.getData().stream().filter(d -> d.getFirmwareId() == null).forEach(updateConsumer); |
|||
|
|||
if (pageData.hasNext()) { |
|||
pageLink = pageLink.nextPageLink(); |
|||
} |
|||
} while (pageData.hasNext()); |
|||
} |
|||
|
|||
private void update(Device device, Firmware firmware, long ts) { |
|||
TenantId tenantId = device.getTenantId(); |
|||
DeviceId deviceId = device.getId(); |
|||
|
|||
List<TsKvEntry> telemetry = new ArrayList<>(); |
|||
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_TITLE, firmware.getTitle()))); |
|||
telemetry.add(new BasicTsKvEntry(ts, new StringDataEntry(DataConstants.TARGET_FIRMWARE_VERSION, firmware.getVersion()))); |
|||
|
|||
telemetryService.saveAndNotify(tenantId, deviceId, telemetry, new FutureCallback<>() { |
|||
@Override |
|||
public void onSuccess(@Nullable Void tmp) { |
|||
log.trace("[{}] Success save telemetry with target firmware for device!", deviceId); |
|||
} |
|||
|
|||
@Override |
|||
public void onFailure(Throwable t) { |
|||
log.error("[{}] Failed to save telemetry with target firmware for device!", deviceId, t); |
|||
} |
|||
}); |
|||
|
|||
List<AttributeKvEntry> attributes = new ArrayList<>(); |
|||
|
|||
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_TITLE, firmware.getTitle()))); |
|||
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_VERSION, firmware.getVersion()))); |
|||
|
|||
attributes.add(new BaseAttributeKvEntry(ts, new LongDataEntry(FIRMWARE_SIZE, (long) firmware.getData().array().length))); |
|||
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM_ALGORITHM, firmware.getChecksumAlgorithm()))); |
|||
attributes.add(new BaseAttributeKvEntry(ts, new StringDataEntry(DataConstants.FIRMWARE_CHECKSUM, firmware.getChecksum()))); |
|||
telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { |
|||
@Override |
|||
public void onSuccess(@Nullable Void tmp) { |
|||
log.trace("[{}] Success save attributes with target firmware!", deviceId); |
|||
} |
|||
|
|||
@Override |
|||
public void onFailure(Throwable t) { |
|||
log.error("[{}] Failed to save attributes with target firmware!", deviceId, t); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
private void remove(Device device) { |
|||
telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, |
|||
Arrays.asList(FIRMWARE_TITLE, FIRMWARE_VERSION, FIRMWARE_SIZE, FIRMWARE_CHECKSUM_ALGORITHM, FIRMWARE_CHECKSUM), |
|||
new FutureCallback<>() { |
|||
@Override |
|||
public void onSuccess(@Nullable Void tmp) { |
|||
log.trace("[{}] Success remove target firmware attributes!", device.getId()); |
|||
} |
|||
|
|||
@Override |
|||
public void onFailure(Throwable t) { |
|||
log.error("[{}] Failed to remove target firmware attributes!", device.getId(), t); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
/** |
|||
* Copyright © 2016-2021 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.firmware; |
|||
|
|||
import org.thingsboard.server.common.data.Device; |
|||
import org.thingsboard.server.common.data.DeviceProfile; |
|||
|
|||
public interface FirmwareStateService { |
|||
|
|||
void update(Device device, boolean created); |
|||
|
|||
void update(DeviceProfile deviceProfile); |
|||
|
|||
} |
|||
Loading…
Reference in new issue