Порылся в коде, нашёл интересную фичу: когда биллинг обнаруживает ребут устройства (через uptime), то пытается вызвать метод onReboot обработчика управления устройством.
Добавил этот метод в свой обработчик:
Код:
/**
     * Метод вызывается автоматически биллингом при обнаружении ребута устройства.
     * Будем при этом сбрасывать все соединения, чтобы клиенты сразу могли начать подключаться, даже если у них установлено ограничение в 1 активную сессию
     */
    public String onReboot(InetDeviceManageEvent e) throws Exception {
        int count = 0;
        try(Connection con = Setup.getSetup().getDBConnection()) {
            InetConnectionDao connDao = new InetConnectionDao(con, e.getModuleId());
            int accountingRootDeviceId = InetUtils.getAccountingRootDeviceId(Setup.getSetup(), e.getModuleId(), e.getDeviceId());
            for (InetConnection connection : connDao.list(Collections.singleton(e.getDeviceId()), false)) {
                EventProcessor.getInstance().publish(new InetConnectionCommandEvent(e.getModuleId(), 0, accountingRootDeviceId, connection.getDeviceId(), connection.getServId(), connection
                        .getId(), "finish"));
                count++;
            }
            connDao.recycle();
        }
        return "Sessions finished: "+ count;
    }
Физически сессии не сбрасываются, только в биллинге.
Протестировал - всё ок работает.
Единственный нюанс - если метод uptime возвращает null, то это не считается ошибкой или ребутом, и время до следующего опроса увеличивается на +10минут (захардкожено в BG).
Т.е. в методе uptime при недоступности устройства и т.п. лучше явно кидать Exception - тогда биллинг начнёт опрашивать каждую минуту (или inet.manage.uptime.error), и как только аптайм появится и будет меньше предыдущего значения, то запустит onReboot.
Ps. Можно ещё усложнить логику и сбрасывать только сессии, которые стартовали раньше now()-uptime. Но так тоже ок: даже если сбросим свежую живую сессию в BG, то она поднимется из update.