Merge with master
This commit is contained in:
		
						commit
						193b37e292
					
				@ -259,17 +259,16 @@ public class ThingsboardInstallService {
 | 
			
		||||
                        case "3.5.1":
 | 
			
		||||
                            log.info("Upgrading ThingsBoard from version 3.5.1 to 3.5.2 ...");
 | 
			
		||||
                            databaseEntitiesUpgradeService.upgradeDatabase("3.5.1");
 | 
			
		||||
                            entityDatabaseSchemaService.createOrUpdateViewsAndFunctions();
 | 
			
		||||
                            entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry);
 | 
			
		||||
                            log.info("Updating system data...");
 | 
			
		||||
                            systemDataLoaderService.updateSystemWidgets();
 | 
			
		||||
                            installScripts.loadSystemLwm2mResources();
 | 
			
		||||
                            //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache
 | 
			
		||||
                            break;
 | 
			
		||||
                        //TODO update CacheCleanupService on the next version upgrade
 | 
			
		||||
                        default:
 | 
			
		||||
                            throw new RuntimeException("Unable to upgrade ThingsBoard, unsupported fromVersion: " + upgradeFromVersion);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    entityDatabaseSchemaService.createOrUpdateViewsAndFunctions();
 | 
			
		||||
                    entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry);
 | 
			
		||||
                    log.info("Updating system data...");
 | 
			
		||||
                    systemDataLoaderService.updateSystemWidgets();
 | 
			
		||||
                    installScripts.loadSystemLwm2mResources();
 | 
			
		||||
                }
 | 
			
		||||
                log.info("Upgrade finished successfully!");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,8 @@ public class DefaultCacheCleanupService implements CacheCleanupService {
 | 
			
		||||
                break;
 | 
			
		||||
            case "3.4.4":
 | 
			
		||||
                log.info("Clearing cache to upgrade from version 3.4.4 to 3.5.0");
 | 
			
		||||
                clearCacheByName("deviceProfiles");
 | 
			
		||||
                clearAll();
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                //Do nothing, since cache cleanup is optional.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -348,7 +348,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public AlarmApiCallResult clearAlarm(TenantId tenantId, AlarmId id, long clearTs, JsonNode details) {
 | 
			
		||||
        return toAlarmApiResult(alarmRepository.clearAlarm(tenantId.getId(), id.getId(), clearTs, getDetailsAsString(details)));
 | 
			
		||||
        return toAlarmApiResult(alarmRepository.clearAlarm(tenantId.getId(), id.getId(), clearTs, details != null ? getDetailsAsString(details) : null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -226,7 +226,11 @@ BEGIN
 | 
			
		||||
    END IF;
 | 
			
		||||
    IF NOT(existing.cleared) THEN
 | 
			
		||||
        cleared = TRUE;
 | 
			
		||||
        UPDATE alarm a SET cleared = true, clear_ts = a_ts, additional_info = a_details WHERE a.id = a_id AND a.tenant_id = t_id;
 | 
			
		||||
        IF a_details IS NULL THEN
 | 
			
		||||
            UPDATE alarm a SET cleared = true, clear_ts = a_ts WHERE a.id = a_id AND a.tenant_id = t_id;
 | 
			
		||||
        ELSE
 | 
			
		||||
            UPDATE alarm a SET cleared = true, clear_ts = a_ts, additional_info = a_details WHERE a.id = a_id AND a.tenant_id = t_id;
 | 
			
		||||
        END IF;
 | 
			
		||||
    END IF;
 | 
			
		||||
    SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id;
 | 
			
		||||
    RETURN json_build_object('success', true, 'cleared', cleared, 'alarm', row_to_json(result))::text;
 | 
			
		||||
 | 
			
		||||
@ -202,7 +202,34 @@ public class JpaAlarmDaoTest extends AbstractJpaDaoTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testClearAlarmProcedure() {
 | 
			
		||||
        UUID tenantId = UUID.randomUUID();
 | 
			
		||||
        ;
 | 
			
		||||
        UUID originator1Id = UUID.fromString("d4b68f41-3e96-11e7-a884-898080180d6b");
 | 
			
		||||
        UUID alarm1Id = UUID.fromString("d4b68f43-3e96-11e7-a884-898080180d6b");
 | 
			
		||||
        Alarm alarm = saveAlarm(alarm1Id, tenantId, originator1Id, "TEST_ALARM");
 | 
			
		||||
        long clearTs = System.currentTimeMillis();
 | 
			
		||||
        var details = JacksonUtil.newObjectNode().put("test", 123);
 | 
			
		||||
        AlarmApiCallResult result = alarmDao.clearAlarm(alarm.getTenantId(), alarm.getId(), clearTs, details);
 | 
			
		||||
        AlarmInfo afterSave = alarmDao.findAlarmInfoById(alarm.getTenantId(), alarm.getUuidId());
 | 
			
		||||
        assertNotNull(result);
 | 
			
		||||
        assertTrue(result.isSuccessful());
 | 
			
		||||
        assertTrue(result.isCleared());
 | 
			
		||||
        assertNotNull(result.getAlarm());
 | 
			
		||||
        assertEquals(afterSave, result.getAlarm());
 | 
			
		||||
        assertEquals(clearTs, result.getAlarm().getClearTs());
 | 
			
		||||
        assertTrue(result.getAlarm().isCleared());
 | 
			
		||||
        assertEquals(details, result.getAlarm().getDetails());
 | 
			
		||||
        result = alarmDao.clearAlarm(alarm.getTenantId(), alarm.getId(), clearTs + 1, JacksonUtil.newObjectNode());
 | 
			
		||||
        assertNotNull(result);
 | 
			
		||||
        assertNotNull(result.getAlarm());
 | 
			
		||||
        assertEquals(afterSave, result.getAlarm());
 | 
			
		||||
        assertTrue(result.isSuccessful());
 | 
			
		||||
        assertFalse(result.isCleared());
 | 
			
		||||
        assertEquals(clearTs, result.getAlarm().getClearTs());
 | 
			
		||||
        assertTrue(result.getAlarm().isCleared());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testClearAlarmWithoutDetailsProcedure() {
 | 
			
		||||
        UUID tenantId = UUID.randomUUID();
 | 
			
		||||
        UUID originator1Id = UUID.fromString("d4b68f41-3e96-11e7-a884-898080180d6b");
 | 
			
		||||
        UUID alarm1Id = UUID.fromString("d4b68f43-3e96-11e7-a884-898080180d6b");
 | 
			
		||||
        Alarm alarm = saveAlarm(alarm1Id, tenantId, originator1Id, "TEST_ALARM");
 | 
			
		||||
@ -216,6 +243,7 @@ public class JpaAlarmDaoTest extends AbstractJpaDaoTest {
 | 
			
		||||
        assertEquals(afterSave, result.getAlarm());
 | 
			
		||||
        assertEquals(clearTs, result.getAlarm().getClearTs());
 | 
			
		||||
        assertTrue(result.getAlarm().isCleared());
 | 
			
		||||
        assertEquals(alarm.getDetails(), result.getAlarm().getDetails());
 | 
			
		||||
        result = alarmDao.clearAlarm(alarm.getTenantId(), alarm.getId(), clearTs + 1, JacksonUtil.newObjectNode());
 | 
			
		||||
        assertNotNull(result);
 | 
			
		||||
        assertNotNull(result.getAlarm());
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,13 @@ import { Observable, of } from 'rxjs';
 | 
			
		||||
import { Polyline } from './polyline';
 | 
			
		||||
import { Polygon } from './polygon';
 | 
			
		||||
import { Circle } from './circle';
 | 
			
		||||
import { createTooltip, entitiesParseName, isCutPolygon, isJSON } from '@home/components/widget/lib/maps/maps-utils';
 | 
			
		||||
import {
 | 
			
		||||
  createTooltip,
 | 
			
		||||
  entitiesParseName,
 | 
			
		||||
  isCutPolygon,
 | 
			
		||||
  isJSON,
 | 
			
		||||
  isValidLatLng
 | 
			
		||||
} from '@home/components/widget/lib/maps/maps-utils';
 | 
			
		||||
import { checkLngLat, createLoadingDiv } from '@home/components/widget/lib/maps/common-maps-utils';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import {
 | 
			
		||||
@ -148,7 +154,8 @@ export default abstract class LeafletMap {
 | 
			
		||||
            if (isDefinedAndNotNull(markerColor) && tinycolor(markerColor).isValid()) {
 | 
			
		||||
              const parsedColor = tinycolor(markerColor);
 | 
			
		||||
              return L.divIcon({
 | 
			
		||||
                html: `<div style="background-color: ${parsedColor.setAlpha(0.4).toRgbString()};" class="marker-cluster tb-cluster-marker-element">` +
 | 
			
		||||
                html: `<div style="background-color: ${parsedColor.setAlpha(0.4).toRgbString()};" ` +
 | 
			
		||||
                  `class="marker-cluster tb-cluster-marker-element">` +
 | 
			
		||||
                  `<div style="background-color: ${parsedColor.setAlpha(0.9).toRgbString()};"><span>` + childCount + '</span></div></div>',
 | 
			
		||||
                iconSize: new L.Point(40, 40),
 | 
			
		||||
                className: 'tb-cluster-marker-container'
 | 
			
		||||
@ -378,7 +385,8 @@ export default abstract class LeafletMap {
 | 
			
		||||
            });
 | 
			
		||||
          },
 | 
			
		||||
        });
 | 
			
		||||
        this.map.pm.Toolbar.changeControlOrder(['tbMarker', 'tbRectangle', 'tbPolygon', 'tbCircle', 'editMode', 'dragMode', 'tbCut', 'removalMode', 'rotateMode']);
 | 
			
		||||
        this.map.pm.Toolbar.changeControlOrder(['tbMarker', 'tbRectangle', 'tbPolygon', 'tbCircle',
 | 
			
		||||
          'editMode', 'dragMode', 'tbCut', 'removalMode', 'rotateMode']);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.map.pm.setLang('en', this.translateService.instant('widgets.maps'), 'en');
 | 
			
		||||
@ -643,19 +651,19 @@ export default abstract class LeafletMap {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extractPosition(data: FormattedData): {x: number, y: number} {
 | 
			
		||||
    extractPosition(data: FormattedData): {x: number; y: number} {
 | 
			
		||||
      if (!data) {
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
      const lat = data[this.options.latKeyName];
 | 
			
		||||
      const lng = data[this.options.lngKeyName];
 | 
			
		||||
      if (!isDefinedAndNotNull(lat) || isString(lat) || isNaN(lat) || !isDefinedAndNotNull(lng) || isString(lng) || isNaN(lng)) {
 | 
			
		||||
      if (!isValidLatLng(lat, lng)) {
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
      return {x: lat, y: lng};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    positionToLatLng(position: {x: number, y: number}): L.LatLng {
 | 
			
		||||
    positionToLatLng(position: {x: number; y: number}): L.LatLng {
 | 
			
		||||
      return L.latLng(position.x, position.y) as L.LatLng;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -936,7 +944,7 @@ export default abstract class LeafletMap {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        this.saveLocation(data, this.convertToCustomFormat(e.target._latlng)).subscribe();
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private createMarker(key: string, data: FormattedData, dataSources: FormattedData[], settings: Partial<WidgetMarkersSettings>,
 | 
			
		||||
                         updateBounds = true, callback?, snappable = false): Marker {
 | 
			
		||||
@ -1141,7 +1149,7 @@ export default abstract class LeafletMap {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.saveLocation(data, this.convertPolygonToCustomFormat(coordinates)).subscribe(() => {});
 | 
			
		||||
  }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: Partial<WidgetPolygonSettings>,
 | 
			
		||||
                  updateBounds = true, snappable = false) {
 | 
			
		||||
@ -1218,7 +1226,7 @@ export default abstract class LeafletMap {
 | 
			
		||||
      const center = e.layer.getLatLng();
 | 
			
		||||
      const radius = e.layer.getRadius();
 | 
			
		||||
      this.saveLocation(data, this.convertCircleToCustomFormat(center, radius)).subscribe(() => {});
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    updateCircle(circlesData: FormattedData[], updateBounds = true) {
 | 
			
		||||
      const toDelete = new Set(Array.from(this.circles.keys()));
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@ import {
 | 
			
		||||
  ShowTooltipAction, WidgetToolipSettings
 | 
			
		||||
} from './map-models';
 | 
			
		||||
import { Datasource, FormattedData } from '@app/shared/models/widget.models';
 | 
			
		||||
import { fillDataPattern, processDataPattern, safeExecute } from '@core/utils';
 | 
			
		||||
import { fillDataPattern, isDefinedAndNotNull, isString, processDataPattern, safeExecute } from '@core/utils';
 | 
			
		||||
import { parseWithTranslation } from '@home/components/widget/lib/maps/common-maps-utils';
 | 
			
		||||
 | 
			
		||||
export function createTooltip(target: L.Layer,
 | 
			
		||||
@ -110,3 +110,16 @@ export function entitiesParseName(entities: FormattedData[], labelSettings: labe
 | 
			
		||||
  }
 | 
			
		||||
  return entities;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const isValidLatitude = (latitude: any): boolean =>
 | 
			
		||||
  isDefinedAndNotNull(latitude) &&
 | 
			
		||||
  !isString(latitude) &&
 | 
			
		||||
  !isNaN(latitude) && isFinite(latitude) && Math.abs(latitude) <= 90;
 | 
			
		||||
 | 
			
		||||
export const isValidLongitude = (longitude: any): boolean =>
 | 
			
		||||
  isDefinedAndNotNull(longitude) &&
 | 
			
		||||
  !isString(longitude) &&
 | 
			
		||||
  !isNaN(longitude) && isFinite(longitude) && Math.abs(longitude) <= 180;
 | 
			
		||||
 | 
			
		||||
export const isValidLatLng = (latitude: any, longitude: any): boolean =>
 | 
			
		||||
  isValidLatitude(latitude) && isValidLongitude(longitude);
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,7 @@ export class ValueInputComponent implements OnInit, ControlValueAccessor {
 | 
			
		||||
        if (res) {
 | 
			
		||||
          this.modelValue = res;
 | 
			
		||||
          this.inputForm.control.patchValue({value: this.modelValue});
 | 
			
		||||
          this.updateView();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user