[SOLVED] Trying to implement ThingActions into binding

I’am trying to implement ThingActions into the Onkyo binding, but I’m always getting an error that the action is not found:

Rule ‘Test Switch’: ‘sendRawCommand’ is not a member of ‘org.eclipse.smarthome.core.thing.binding.ThingActions’; line 6, column 9, length 35

Here is the code of my implementation:

/**
 * Copyright (c) 2010-2019 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.openhab.binding.onkyo.internal.automation.modules;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.binding.ThingActions;
import org.eclipse.smarthome.core.thing.binding.ThingActionsScope;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.openhab.binding.onkyo.internal.eiscp.EiscpCommand;
import org.openhab.binding.onkyo.internal.handler.OnkyoHandler;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.RuleAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Some automation actions to be used with a {@link OnkyoThingActionsService}
 *
 * @author David Masshardt - initial contribution
 *
 */
@ThingActionsScope(name = "onkyo")
@NonNullByDefault
public class OnkyoThingActionsService implements ThingActions {

    private final Logger logger = LoggerFactory.getLogger(OnkyoThingActionsService.class);

    private @Nullable OnkyoHandler handler;

    @RuleAction(label = "Onkyo sendRawCommand", description = "Action that sends raw command to the receiver")
    public void sendRawCommand(@ActionInput(name = "rawCommand") @Nullable String rawCommand) {
        logger.debug("sendRawCommand called with raw command: {}", rawCommand);
    }

    @Override
    public void setThingHandler(@Nullable ThingHandler handler) {
        if (handler instanceof OnkyoHandler) {
            this.handler = (OnkyoHandler) handler;
        }
    }

    @Override
    public @Nullable ThingHandler getThingHandler() {
        return this.handler;
    }

}

I’ve also added the getServices method to the binding handler:

@Override
    public Collection<Class<? extends ThingHandlerService>> getServices() {
        return Collections.singletonList(OnkyoThingActionsService.class);
    }

And this is my test rule:

rule "Test Switch"
    when
        Item SW_Test changed
    then
        val onkyoActions = getActions("onkyo","onkyo:TX-NR818:93b02aca-832a-cab9-6a23-ca0983b98a33")
        onkyoActions.sendRawCommand("Test")
    end

What am I doing wrong? I copied most of the code from the MQTT binding and there the method call works.

2 Likes

Thanks for the quick help, it is working now!

It’s so cool that more and more bindings are picking this up. As soon as we officially release the new rule engine, there will be plenty of actions it looks like.

What do I need to change to get this to work? I am trying to get my LG WEB OS binding to send remote navigation commands like “HOME”, “UP”, “DOWN”, etc.

Here is my code so far and I keep getting “Actions not found, check thing ID” errors.

rule "Home"
when Item HomeDummy changed
then
    val actions = getActions("lgwebos","lgwebos:WebOSTV:088e58e6-d74c-4aae-bfaa-1e46281b1d85")
    if(null === actions) {
        logInfo("actions", "Actions not found, check thing ID")
        return
    }
                
    actions.sendButton("HOME")
end

Thanks!

Without have a view of what you changed in the lg webos binding I can’t know why it doesn’t work for you, so can you post a link to you github repo?

1 Like

I have the same problem with my action. Here is my code:

/**
 * Copyright (c) 2010-2020 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.openhab.binding.satel.action;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.binding.ThingActions;
import org.eclipse.smarthome.core.thing.binding.ThingActionsScope;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.openhab.binding.satel.internal.handler.SatelEventLogHandler;
import org.openhab.core.automation.annotation.RuleAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Automation action handler service for reading Satel event log.
 *
 * @author Krzysztof Goworek - Initial contribution
 * @see SatelEventLogHandler
 */
@ThingActionsScope(name = "satel")
@NonNullByDefault
public class SatelEventLogActions implements ThingActions {

    @Override
    public void activate() {
        logger.info("satel actions activated");
    }

    @Override
    public void deactivate() {
        logger.info("satel actions deactivated");
    }

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private @Nullable SatelEventLogHandler handler;

    @Override
    public void setThingHandler(@Nullable ThingHandler handler) {
        this.handler = (SatelEventLogHandler) handler;
    }

    @Override
    public @Nullable ThingHandler getThingHandler() {
        return handler;
    }

    @RuleAction(label = "actionLabel", description = "actionDesc")
    public void testAction() {
        logger.info("satel.testAction called");
    }

    public static void testAction(@Nullable ThingActions actions) {
        if (actions instanceof SatelEventLogActions) {
            ((SatelEventLogActions) actions).testAction();
        } else {
            throw new IllegalArgumentException("Instance is not a SatelEventLogActions class.");
        }
    }

}

The service is being activated, but the only action testAction is not visible, despite the fact there is already also static method for DSL engine.
Here is my action:

rule "Send event log new"
when
    Item Satel_DumpEventLog changed to ON
then
    createTimer(now.plusSeconds(2), [|
        Satel_DumpEventLog.postUpdate(OFF)
    ])
    val actions = getActions("satel","satel:event-log:home:1")
    logInfo("EventLog", "Actions: " + actions)
    if (null === actions) {
        logInfo("EventLog", "Actions not found, check thing ID")
        return
    }
    actions.testAction()
end

Here is the log:

2020-04-03 20:22:38.414 [INFO ] [ng.satel.action.SatelEventLogActions] - satel actions activated
2020-04-03 20:23:16.020 [INFO ] [ipse.smarthome.model.script.EventLog] - Actions: org.openhab.binding.satel.action.SatelEventLogActions@46217aa9
2020-04-03 20:23:16.036 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Send event log new': 'testAction' is not a member of 'org.eclipse.smarthome.core.thing.binding.ThingActions'; line 92, column 2, length 20

Am I missing something obvious?

Does your handler have a getServices method?

    @Override
    public Collection<Class<? extends ThingHandlerService>> getServices() {
        return Collections.singletonList(SatelEventLogActions.class);
    }

Also be mindful of this bug, which can be very annoying, especially during development.

2 Likes

That was it. After restart works like a charm. Thanks!