Fuel drop/increase notifications

hypoclone a year ago

Hello wonderful people, I set up notifications for fuel drop/increase, these works fine, except the quantity of drop/increase is not included in the notification, how do I include this please, the setup includes a teltonika FMB with an omnicomm LLS4,

Anton Tananaev a year ago

Yeah, I don't think we include that information currently. You would probably have to update FuelEventHandler and then templates as well. Feel free to send a pull request if you implement it.

hypoclone a year ago

Thank you Anton
Please i have no knowledge of java and i don't want to post an embarrassing code in a PR, using chatgpt i was able to generate the below code for FuelEventHandler

/*
 * Copyright 2017 - 2024 Anton Tananaev (anton@traccar.org)
 *
 * 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.traccar.handler.events;

import jakarta.inject.Inject;
import org.traccar.config.Keys;
import org.traccar.helper.model.AttributeUtil;
import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
import org.traccar.session.cache.CacheManager;

import java.util.HashMap;
import java.util.Map;

public class FuelEventHandler extends BaseEventHandler {

    private final CacheManager cacheManager;

    @Inject
    public FuelEventHandler(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Override
    public void onPosition(Position position, Callback callback) {

        Device device = cacheManager.getObject(Device.class, position.getDeviceId());
        if (device == null) {
            return;
        }
        if (!PositionUtil.isLatest(cacheManager, position)) {
            return;
        }

        if (position.hasAttribute(Position.KEY_FUEL_LEVEL)) {
            Position lastPosition = cacheManager.getPosition(position.getDeviceId());
            if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) {
                double before = lastPosition.getDouble(Position.KEY_FUEL_LEVEL);
                double after = position.getDouble(Position.KEY_FUEL_LEVEL);
                double change = after - before;

                if (change > 0) {
                    double threshold = AttributeUtil.lookup(
                            cacheManager, Keys.EVENT_FUEL_INCREASE_THRESHOLD, position.getDeviceId());
                    if (threshold > 0 && change >= threshold) {
                        // Add before, after, and change to event attributes
                        Map<String, Object> attributes = new HashMap<>();
                        attributes.put("before", before);
                        attributes.put("after", after);
                        attributes.put("change", change);

                        Event event = new Event(Event.TYPE_DEVICE_FUEL_INCREASE, position);
                        event.setAttributes(attributes);
                        callback.eventDetected(event);
                    }
                } else if (change < 0) {
                    double threshold = AttributeUtil.lookup(
                            cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId());
                    if (threshold > 0 && Math.abs(change) >= threshold) {
                        // Add before, after, and change to event attributes
                        Map<String, Object> attributes = new HashMap<>();
                        attributes.put("before", before);
                        attributes.put("after", after);
                        attributes.put("change", change);

                        Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position);
                        event.setAttributes(attributes);
                        callback.eventDetected(event);
                    }
                }
            }
        }
    }

}

my next challenge was how to access the variables "before", "after" and "change" in the template
i made the below changes to the templates/full/deviceFuelDrop.vm file

#set($subject = "$device.name: fuel drop")
<!DOCTYPE html>
<html>
<body>
Device: $device.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
<br>
Quantity Before: $event.before<br>
Quantity After: $event.after<br>
Quantity Removed: $event.change<br>
<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>

I am not convinced i am doing the right thing, could you help review these before submitting as PR

Anton Tananaev a year ago

Seems roughly correct in Java code, but in the template you have to use attributes.

hypoclone a year ago

Thank you so much anton
Please will this suffice?

#set($subject = "$device.name: fuel drop")
<!DOCTYPE html>
<html>
<body>
Device: $device.name<br>
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)<br>
Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
<br>
Quantity Before: $!event.attributes.before<br>
Quantity After: $!event.attributes.after<br>
Quantity Removed: $!event.attributes.change<br><br>
<a href="$webUrl/settings/notifications?token=$token">Unsubscribe</a>
</body>
</html>
Anton Tananaev a year ago

Something like this. Have you tried it?

hypoclone a year ago

Thank you anton!
I am trying to implement this on a live server, but i keep getting the error below on he notification page

Screenshot 2024-12-19 153126.png

the system is version 6.5 i did a little modification to the web interface but i don't know where the "Description" column came from, all other instance(not version 6.5) don't have that column, traccar demos don't have it also
also all my existing notification disappeared

Screenshot 2024-12-19 153717.png

Anton Tananaev a year ago

Are you sure you used the 6.5 codebase and not master?

hypoclone a year ago

oh! so sorry, i was using the master

hypoclone a year ago

Thanks for the assistance anton, the setup seems to be working, below is a sample notification

Device: TestTruck2
Time: 2024-12-19 18:24:21
Quantity Before: 137.0
Quantity After: 112.0
Quantity Removed: 25.0
Point: address redacted

Unsubscribe

i will send a pull request