Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fleet Management Integration, Teltonika Telematics Device Support #1147

Draft
wants to merge 132 commits into
base: master
Choose a base branch
from

Conversation

pankalog
Copy link
Member

@pankalog pankalog commented Oct 27, 2023

This is still missing tests, which I plan to implement this week.

The UI folder will be removed from the PR before merging, it is just useful for debugging purposes.

pankalog and others added 30 commits September 8, 2023 15:12
and either generates or updates an asset
depending on the IMEI of the device.
and either generates or updates an asset
depending on the IMEI of the device.

Currently reads Teltonika payloads,
finds the Asset using the IMEI, and
determines whether or not
a new Asset needs to be created
or an old one needs to be updated.
Creates asset when new IMEI is used,
Updates the asset if the IMEI has already
been used.
The method will parse the payload
coming from the device
to decode it into an attribute list.
The method will parse the payload
coming from the device
to decode it into an attribute list.
This asset helps with conciseness on code in the MQTT Handler, since we are aware that the required attributes exist and are complete.
Parses the JSON payload according to the screenshot on Teltonika forums, links the parameter IDs to their descriptions based on the Teltonika wiki, and dynamically inserts or updates an asset with the most recent data.

TODO:
- Proper Type definition for each attribute depending on the `Type` parameter in the Teltonika parameter ID forums

- Secure communication and provisioning of Teltonika Devices

- Automatically retrieve Teltonika device parameter information (preferrably from an official API)
When an asset marker is clicked, its history from midnight to the current time is displayed as lines and points. When deselected, the GeoJSON layers and sources are removed from the MapLibre map object.

TODO: Improve overall type-safety and robustness, improve UI line and point elements, implement configuration item to specifically allow the overlay to be visible.
Overlay is properly removed when another asset marker is selected, and when no asset is selected.
- Now does not require authentication for publishing to Teltonika topic (while Authentication is being worked on)

- Improved robustness and added more logging for when devices connect and publish.
- Since I have a device in my hands, I can test out the payload, and adjust the jackson parser.
- FMC003.json is not being included in the build, quick and dirty fix to get the parameters to be read accordingly.
- include FMC003.json in the build, quick and dirty fix to get the parameters to be read accordingly.
- Directory fixes and change string
- Fixed bug that only read the first attribute;
- Now logs the amount of Teltonika AVL parameters from file
- Fixed latitude and longitude regex to properly recognize all coordinates
- Fixed latitude and longitude regex to properly recognize all coordinates
- Select the Europe MBTILES file for deployment
- Correctly parse the coordinates sent by the device
- MQTT Handler updated to correctly parse data from real devices
- State.java now correctly parses the Type of each parameter
- State.java now correctly includes Attribute Metadata, based on TeltonikaParameter
- MQTT Handler now correctly handles updating and creating an Asset's Attributes using SEDA messages
- Bug when trying to render a Unit of Measurement that is not defined in the Constants file
- Support for sending messages to the Teltonika devices.
- Bug fixes and refactors
- Formatted the command to be of the appropriate format for the device
* New Nominatim client for better support
* Fixed formatting for Overview Analysis Type
Analysis types now more statically defined and easier to deal with. Functionality for multiple analysis types to come.
Reworked to include the ref's attribute's type, used for determining what types of analysis should be available, and for casting/display purposes.
Remove the connectedCallback() actions, as they were being triggered two times, once for the connectedCallback and once for firstUpdated. firstUpdated suffices, we just initialize everything later down the lifecycle of the LitElement
Remove a lot of console.logs and also updated UI element to explain the reasoning for the displayed error.
This fix now properly updates the attributes within AttributeActionEvent:detail, so that the attribute included is the actual one that is selected
EVEN IF you handle the exception, it still prints it, taking up ENORMOUS amounts of space in my log. Just destroys the great work I've done over months of printing ONE LINE per correctly parsed payload. Very happy to have taken the executive decision for this. Took some emotional strength, but I finally am committing the removal of this messy-for-my-logs piece of code.
Theoretically this should fix everything?
Comment on lines +33 to +37
org.openremote.manager.mqtt.level=FINE

# Processing time logging
#org.openremote.manager.asset.AssetProcessingService.level=FINE
#org.openremote.manager.asset.AssetStorageService.level=FINE
org.openremote.manager.asset.AssetProcessingService.level=WARNING
org.openremote.manager.asset.AssetStorageService.level=WARNING
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this is being changed in this PR...logging-dev is for development use and these levels were set to aid in tracing issues

@@ -216,7 +216,7 @@ public static <T> Optional<T> parse(String jsonString, Type type) {
try {
return Optional.of(JSON.readValue(jsonString, JSON.constructType(type)));
} catch (Exception e) {
LOG.log(Level.WARNING, "Failed to parse JSON", e);
// LOG.log(Level.WARNING, "Failed to parse JSON", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't merge this

Comment on lines +406 to +427
this._assets.filter((asset) => {
if (!asset.attributes) {
return false;
}
const attr = asset.attributes[WellknownAttributes.LOCATION] as Attribute<GeoJSONPoint>;
return !attr.meta || !attr.meta.hasOwnProperty(WellknownMetaItems.SHOWONDASHBOARD) || !!Util.getMetaValue(WellknownMetaItems.SHOWONDASHBOARD, attr);
})
.sort((a, b) => {
if (a.attributes[WellknownAttributes.LOCATION].value && b.attributes[WellknownAttributes.LOCATION].value) {
return b.attributes[WellknownAttributes.LOCATION].value.coordinates[1] - a.attributes[WellknownAttributes.LOCATION].value.coordinates[1];
} else {
return;
}
})
.map(asset => {
return html`
<or-map-marker-asset
?active="${this._currentAsset && this._currentAsset.id === asset.id}"
.asset="${asset}"
.config="${this.config.markers}"></or-map-marker-asset>
`;
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reformatting here makes it difficult to follow what has actually changed...we do need to enforce some linting and coding standards though

<or-map-location-history-overlay .assetId="${this._currentAsset?.id}" .map="${this._map}" ></or-map-location-history-overlay>
${currentAssetSelected ? html`
<or-map-asset-card .config="${this.config?.card}" .assetId="${this._currentAsset.id}"
.markerconfig="${this.config?.markers}" .map="${this._map}"></or-map-asset-card>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This newly added map property doesn't appear to be used

<!--
<or-map-location-history-markers .assetId="${this._currentAsset?.id}" .map="${this._map}"></or-map-location-history-markers>
-->
<or-map-location-history-overlay .assetId="${this._currentAsset?.id}" .map="${this._map}" ></or-map-location-history-overlay>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this location history is to be integrated into the generic manager app then it will need to be configurable

Comment on lines +747 to +751
type: "all",
fromTimestamp: this._startOfPeriod,
toTimestamp: this._endOfPeriod,
amountOfPoints: 20,
} as AssetDatapointLTTBQuery
} as AssetDatapointAllQuery
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To additionally comment on this; we're intentionally using LTTB in the or-attribute-card here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks but is it a change that makes sense for everything or just this fleet management application? If it doesn't make sense in general then it needs to be configurable on the map config

@@ -193,7 +193,7 @@ export class AttributesPanel extends LitElement {
}

protected async loadAssets(): Promise<Asset[]> {
if(this.attributeRefs.filter(ar => !this.getLoadedAsset(ar)).length > 0) {
if(true) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove or fix

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just update the forward/reverse geocoder functions in mapwidget rather than this, as it doesn't add enough functionality to warrant the copy paste and source code isn't maintained. We should definitely default to nominatim openstreetmap API though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a way of being able to plugin custom widgets at runtime from a custom project

Comment on lines +914 to +916
public async getGeoJsonFeature(query: {query: string}){
// let gc: MaplibreGeocoder. = this._geocoder;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not work? Can it be fixed or removed or at least commented out with reason

Comment on lines +917 to +922
public async getAddress(query: {lat: number, lon: number}){
// let gc: MaplibreGeocoder. = this._geocoder;
return this._reverseGeocode(query);
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe should be exposed from the or-map so no dependency on the map for geocoding

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be a pluggable mechanism from a custom project

Comment on lines +72 to +73
const popup = new maplibregl.Popup().setText(
'Construction on the Washington Monument began in 1848.'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup required

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this as a marker type but needs to be configurable at the map level.

Can this marker not extend the OrMapMarkerAsset or even just add this functionality to that marker.

History duration to retrieve in map config (if set then uses this marker instead of asset marker)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not clear to me why this is needed rather than encapsulating everything in the history marker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants