Reading Afvalwijzer in JSscripting or Jython

Is this script still working? because i see i need an api key. That is not available anymore.
MIJNAFVALWIJZER_APIKEY = “”

It does work, but I cannot provide the api key. Did you by any chance google the terms “afvalwijzer webservices appsinput” and looked at the URL of one of the first results? :wink:

Thank you. but the api key will stop working soon? When I read the topic on home-assistant they use a scraper.

The API key is still valid. I’ll try to make a scraping version when I find more time or once the API key is no longer valid (whatever comes first).

I added a javascript version of the rule because I no longer use Jython as my main rule engine.

1 Like

@ArdKuijpers I think your zipcode and housenumber is still in the JavaScript version.

1 Like

Actually, it is not mine (although not far away). I found it the code mentioned here: Idea: use python to directly generate rules files and I have since then used it to test my code.

Hi Ard,

I tried the script. Everytime the script runs it creates a new rule “afval ophaaldata updaten”.

How do i remove these rules if i don’t want to use the script anymore?
I can’t delete them through the ui because “Some of the selected rules are not modifiable because they have been provisioned by files”

EDIT: Found out they get deleted on a system reboot.

Thanks @ArdKuijpers wrote in the xmas break a js version as well, but not as extensive as yours…
Do you have a hint on this error?
EDIT: Seems I can prevent the error by removing the 2 actions.NotificationAction.sendBroadcastNotification(message); lines. Guess they are not known as I don’t have cloud notifications enabled.

note I chose the application/javascript;version=ECMAScript-2021 version… is that the right one or I should use the other one.

10:44:09.704 [DEBUG] [enhab.automation.script.afvalkalender] - Afval ophaaldata ophalen voor 4700ZZ-25
10:44:09.867 [DEBUG] [enhab.automation.script.afvalkalender] - Afvalwijzer URI: https://api.mijnafvalwijzer.nl/webservices/appsinput/?method=postcodecheck&street=&postcode=4700ZZ&huisnummer=25&toevoeging=&apikey=5ef443e778f41c4f75c69459eea6e6ae0c2d92de729aa0fc61653815fbd6a8ca&app_name=afvalwijzer&platform=phone&mobiletype=android&afvaldata=2022-01-10&version=58&langs=nl
10:44:10.542 [DEBUG] [enhab.automation.script.afvalkalender] - Ophaaldata verwerken voor papier: oud papier en Item AfvalData_papier on 2022-01-10T10:44:10.531+01:00[SYSTEM]
10:44:10.556 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'AfvalData_papier' changed from NULL to 2022-01-10T00:00:00.000+0100
10:44:10.557 [DEBUG] [org.openhab.automation.script.items  ] - Posted update 2022-01-10 to AfvalData_papier
10:44:10.559 [INFO ] [enhab.automation.script.afvalkalender] - Vandaag wordt het oud papier opgehaald.
10:44:10.564 [ERROR] [org.openhab.automation.script.rules  ] - Failed to execute rule Afval-ophaaldata-updaten-0afa0a3c-3c53-46cb-aa47-dc7982bbd6ae: TypeError: undefined has no such function "sendBroadcastNotification": TypeError: undefined has no such function "sendBroadcastNotification"
        at processPickupdates (<eval>:129)
        at execute (<eval>:88)
        at doExecute (webpack://openhab/./node_modules/openhab/rules/rules.js?:110)
10:44:10.566 [WARN ] [re.automation.internal.RuleEngineImpl] - Fail to execute action: 1
org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "sendBroadcastNotification"
        at <js>.processPickupdates(<eval>:129) ~[?:?]
        at <js>.execute(<eval>:88) ~[?:?]
        at <js>.doExecute(webpack://openhab/./node_modules/openhab/rules/rules.js?:110) ~[?:?]
        at org.graalvm.polyglot.Value.invokeMember(Value.java:934) ~[?:?]
        at com.oracle.truffle.host.adapters.SimpleRule$$Adapter.execute(Unknown Source) ~[?:?]
        at org.openhab.automation.jsscripting.internal.threading.ThreadsafeSimpleRuleDelegate.execute(ThreadsafeSimpleRuleDelegate.java:59) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRuleActionHandlerDelegate.execute(SimpleRuleActionHandlerDelegate.java:34) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.internal.delegates.SimpleActionHandlerDelegate.execute(SimpleActionHandlerDelegate.java:59) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1180) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1032) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1048) ~[?:?]
        at org.openhab.core.automation.rest.internal.RuleResource.runNow(RuleResource.java:327) ~[?:?]
        at jdk.internal.reflect.GeneratedMethodAccessor158.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217) ~[bundleFile:3.4.5]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[bundleFile:3.1.0]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:82) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.43.v20210629]
        at java.lang.Thread.run(Thread.java:829) [?:?]

Struggled with the same…
I found that restarting the rulesupport will work as well…

openhab> bundle:list | grep RuleSupport
160 x Active    x  80 x 3.2.0                 x openHAB Core :: Bundles :: Automation Script RuleSupport
openhab> bundle:restart 160

I chose this version (2021) and it works well. Well…a sort of.
A first i’ll get this message:
Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.

Then a couple of seconds later the script executes without warnings.

The problem i encounter is that only items (after manually running the rule “afval ophaaldata updaten”):
AfvalData_volgendeDatum and
AfvalData_volgendeType

get updated. The other items don’t and keep their NULL value.

Thanks.

Recognise the issue.
For me that was solved by changing the afval type.
e.g. in the feed from api.mijnafvalwijzer.nl for my gemeente the type was plastic instead of pmd.
So changing the processPickupdates line to processPickupdates(pickupdates, 'plastic', 'plastic- en metaalafval en drinkkartons', ${itemPrefix}_pmd); fixed updating plastics.

Just use the url you see in the log manually in a browser and you see the types as per your gemeente

@ArdKuijpers you use icons like <garbage_papier> which are not standard openhab-classics ones.
do you have nice icons for this to share/recommend?

I figured it would be something like that.
Not as simple as your case but i managed to extract the JSON from afvalkalender and found the right naming for the afval type :slight_smile:

So for anybody using Cyclus NV change the processPickupdates lines to:

    processPickupdates(pickupdates, 'doos-karton-papier',           'oud papier',                              `${itemPrefix}_papier`);
    processPickupdates(pickupdates, 'appel-gft',                    'groente-, fruit- en tuinafval',           `${itemPrefix}_gft`);
    processPickupdates(pickupdates, 'zak-grijs-rest',               'restafval',                               `${itemPrefix}_restafval`);
    processPickupdates(pickupdates, 'petfles-blik-drankpak_pmd',    'plastic- en metaalafval en drinkkartons', `${itemPrefix}_pmd`);  
    processPickupdates(pickupdates, 'kerstboom-zonder-kruis',       'kerstbomen',                              `${itemPrefix}_kerstbomen`);

I removed the “klein chemisch afval” and added “kerstbomen”

Do you use the rule in a file or in the UI? My guess is you used the UI, right?. The script in the OP is meant to be used as a file-based rule in …/automation/js/. If you use this in the UI, the rules.JSRule({...}); creates a new rule every time. So for the UI, please use the version below. It works on my system:

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: >
        {
          const logger = log('afvalkalender');

          // const MijnAfvalWijzerConfig = {
          //     huisnummer: "41",
          //     toevoeging: '',
          //     postcode: "3825AL",
          //     apikey: "<voer-hier-de-apikey-in>"
          // };

          const AfvalkalenderConfig = {  
              huisnummer: "17",
              postcode: "5581BG",
              afvalkalenderUri: 'https://afvalkalender.waalre.nl'
          };

          //const CONFIG = MijnAfvalWijzerConfig;
          const CONFIG = AfvalkalenderConfig;
          CONFIG.itemPrefix = "AfvalKalender";

          const { postcode, huisnummer, toevoeging } = CONFIG;
          itemPrefix = CONFIG.itemPrefix ?? "AfvalData";

          class pickupDate {
              constructor(date, type) {
                  this.date = date;
                  this.type = type;
              }
          }

          function processPickupdates(dates, afvalType, afvalTypeDescription, item, now = undefined) {
              if (!pickupdates || pickupdates.length == 0)
                  return;
              const afvalTypeDates = dates.filter(d => d.type == afvalType).map(d => d.date);
              if (afvalTypeDates.length == 0)
                  return;
              if (now == undefined)
                  now = time.ZonedDateTime.now();
              logger.debug(`Ophaaldata verwerken voor ${afvalType}: ${afvalTypeDescription} en Item ${item} on ${now}`);
              if (items.getItem(item, true) == null) {
                  logger.warn(`Kan ophaaldata niet verwerken want Item ${item} bestaat niet`);
                  return;
              }
              const today = now.toLocalDate();
              const tomorrow = today.plusDays(1);
              let pickupDate = afvalTypeDates.find(d => !d.isBefore(today));
              if (pickupDate == undefined)
                  pickupDate = afvalTypeDates.at(-1);

              items.getItem(item).postUpdate(pickupDate.format(time.DateTimeFormatter.ISO_LOCAL_DATE));
              const currentTime = now.toLocalTime();
              if (today.isEqual(pickupDate) && currentTime.hour() <= 12) {
                  message = `Vandaag wordt het ${afvalTypeDescription} opgehaald.`;
                  logger.info(message);
                  actions.NotificationAction.sendBroadcastNotification(message);
              }
              else if (tomorrow.isEqual(pickupDate) && currentTime.hour() > 12) {
                  message = `Morgen wordt het ${afvalTypeDescription} opgehaald.`;
                  logger.info(message);
                  actions.NotificationAction.sendBroadcastNotification(message);
              }
          }

          function setNextDateAndType(dates, nextDateItem, nextTypeItem, now=undefined)
          {
              if (items.getItem(nextDateItem, true) == null) {
                  logger.warn(`Kan volgende ophaaldatum niet verwerken want Item ${nextDateItem} bestaat niet`);
                  return;
              }
              if (items.getItem(nextTypeItem, true) == null) {
                  logger.warn(`Kan volgende ophaaldatum niet verwerken want Item ${nextTypeItem} bestaat niet`);
                  return;
              }

              now = now ?? time.ZonedDateTime.now();
              const today = now.toLocalDate();
              const sortedDates = dates.sort((d1, d2) => d1.date.compareTo(d2.date));
              let nextDate = sortedDates.find(d => !d.date.isBefore(today));
              if (nextDate == undefined)
                  nextDate = sortedDates.at(-1);
              items.getItem(nextDateItem).postUpdate(nextDate.date.format(time.DateTimeFormatter.ISO_LOCAL_DATE));
              items.getItem(nextTypeItem).postUpdate(nextDate.type);    
          }

          function getJSONResponse(uri)
          {
              const result = actions.HTTP.sendHttpGetRequest(uri);
              if (!result)
              {
                  logger.warn(`Geen respons gekregen van ${uri}`);
                  return undefined;
              }
              try {
                  return JSON.parse(result);
              }
              catch (error)
              {
                  logger.warn(`Kon respons van ${uri} niet naar JSON omzetten: ${error}`);
                  return undefined;
              }
          }

          /** 
           * Gets pickup dates from different garbage collectors from mijnafvalwijzer.
           */
          function getPickupdatesMijnafvalwijzer(postcode, huisnummer, toevoeging, apikey) {
              const dateFormatter = time.DateTimeFormatter.ofPattern('yyyy-MM-dd');
              const today = time.ZonedDateTime.now().format(dateFormatter);
              const uri = `https://api.mijnafvalwijzer.nl/webservices/appsinput/?method=postcodecheck&street=&postcode=${postcode}&huisnummer=${huisnummer}&toevoeging=${toevoeging}&apikey=${apikey}&app_name=afvalwijzer&platform=phone&mobiletype=android&afvaldata=${today}&version=58&langs=nl`;
              logger.debug(`Afvalwijzer URI: ${uri}`); 
              try {
                  const response = getJSONResponse(uri);
                  const ophaaldagen = response.ophaaldagen;
                  if (ophaaldagen.response !== 'OK')
                  {
                      logger.warn(`Ongeldige respons bij het downloaden van ophaaldata van ${uri}: ${pickupdates.error}`);
                      return undefined;
                  }
                  pickupdates = [];
                  return ophaaldagen.data.map(d => new pickupDate(time.LocalDate.parse(d.date, dateFormatter), d.type));
              }
              catch (error)
              {
                  logger.warn(`Kon ophaaldata niet destileren uit respons van ${uri}: ${error}`);
                  return undefined;
              }    
          }

          /**
           * Gets pickup dates from different garbage collectors from afvalkalender
           */

          function getPickupdatesAfvalkalender(postcode, huisnummer, afvalkalenderUri) {
              const uriAddress=`${afvalkalenderUri}/rest/adressen/${postcode}-${huisnummer}`;
              const responseAddress = getJSONResponse(uriAddress);
              if (!responseAddress) {
                  logger.warn(`Kon adresgegevens niet downloaden van ${uriAddress}`);
                  return undefined;
              }
              const bagId = responseAddress[0].bagId;
              const uriPickupdates=`${afvalkalenderUri}/rest/adressen/${bagId}/afvalstromen`;
              const responsePickupdates = getJSONResponse(uriPickupdates);
              if (!responsePickupdates)
              {
                  logger.warn(`Kon ophaaldata niet downloaden van ${uriPickupdates}`);
                  return undefined;
              }
              pickupdates = [];
              return responsePickupdates
                  .filter(d => d.icon && d.ophaaldatum)
                  .map(d =>  new pickupDate(time.LocalDate.parse(d.ophaaldatum,time.DateTimeFormatter.ofPattern('yyyy-MM-dd')), d.icon === "rest" ? "restafval" : d.icon));
          }

          logger.info(`Afval ophaaldata ophalen voor ${postcode}-${huisnummer}${toevoeging}`);
          if ('afvalkalenderUri' in CONFIG && CONFIG.afvalkalenderUri)
              pickupdates = getPickupdatesAfvalkalender(postcode, huisnummer, CONFIG.afvalkalenderUri);
          else
              pickupdates = getPickupdatesMijnafvalwijzer(postcode, huisnummer, toevoeging, CONFIG.apikey);

          if (pickupdates && pickupdates.length != 0) {
            processPickupdates(pickupdates, 'papier',    'oud papier',                              `${itemPrefix}_papier`);
            processPickupdates(pickupdates, 'gft',       'groente-, fruit- en tuinafval',           `${itemPrefix}_gft`);
            processPickupdates(pickupdates, 'restafval', 'restafval',                               `${itemPrefix}_restafval`);
            processPickupdates(pickupdates, 'pmd',       'plastic- en metaalafval en drinkkartons', `${itemPrefix}_pmd`);
            processPickupdates(pickupdates, 'kca',       'klein chemisch afval',                    `${itemPrefix}_kca`);

            setNextDateAndType(pickupdates, `${itemPrefix}_volgendeDatum`, `${itemPrefix}_volgendeType`);
            logger.info(`Afvalophaaldata bijgewerkt voor ${postcode}-${huisnummer}${toevoeging}`);
          } else {
            logger.warn(`Kon ophaaldata niet downloaden voor ${postcode}-${huisnummer}${toevoeging}`);
          }
        }
    type: script.ScriptAction

Right, it is EMCASCript-2021. And you are probably right about the notifications. I use them to get notifications in my phone app. You can either remove this or substitute these with other notifications (e.g. telegram)

Some icons:
garbage_restafval garbage_gft garbage_kca garbage_papier garbage_pmd

And a widget:

component: oh-list-card
config:
  footer: '="Volgende: " + items.AfvalData_volgendeType.state
    +    (dayjs(items.AfvalData_volgendeDatum.state).diff(dayjs().startOf("day"),     "days")
    == 0 ? " vandaag" :
    dayjs(items.AfvalData_volgendeDatum.state).diff(dayjs().startOf("day"),     "days")
    == 1 ? " morgen" : " over " +
    dayjs(items.AfvalData_volgendeDatum.state).diff(dayjs().startOf("day"),     "days")
    + " dagen")'
  title: Afvalkalender
slots:
  default:
    - component: oh-label-item
      config:
        icon: oh:garbage_gft
        item: AfvalData_gft
        title: Groente, Fruit en Tuin
    - component: oh-label-item
      config:
        icon: oh:garbage_papier
        item: AfvalData_papier
        title: Papier
    - component: oh-label-item
      config:
        icon: oh:garbage_restafval
        item: AfvalData_restafval
        title: Restafval

Ah, good find. I didn’t know these were different for the various Afvalkalenders.

1 Like

I created a script in the UI. All seems to work fine now.
Manually runnig the script creates the rule which will trigger the script twice a day.
Running the rule executes the script but does NOT add another rule.
So that should be fine then right?

And i if move the script into a file ( most of my openhab config is file based) what should be the file extension? .js ?

File based rules should be located in you configuration folder in the subdirrectory ./automation/js so e.g. /openhab/conf/automation/js/. Files should use the extension .js. Then the rules are automatically created and updated when you change them.

1 Like

Executing this script in the UI gives me this. Can you see why?

2022-01-10 19:38:46.950 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:

org.graalvm.polyglot.PolyglotException: SyntaxError: <eval>:5:10 Expected ; but found :

  - inputs: {}

          ^

<eval>:9:14 Expected an operand but found >

      script: >

              ^

	at org.graalvm.polyglot.Context.eval(Context.java:379) ~[?:?]

	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]

	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]

	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]

	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:51) ~[?:?]

	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWithInvocable.java:69) ~[?:?]

	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:51) ~[?:?]

	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWithInvocable.java:69) ~[?:?]

	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:62) ~[?:?]

	at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]

	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:59) ~[?:?]

	at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1180) ~[?:?]

	at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1032) ~[?:?]

	at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1048) ~[?:?]

	at org.openhab.core.automation.rest.internal.RuleResource.runNow(RuleResource.java:327) ~[?:?]

	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]

	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]

	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]

	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]

	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]

	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]

	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]

	at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]

	at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]

	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]

	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217) ~[bundleFile:3.4.5]

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[bundleFile:3.1.0]

	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]

	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.43.v20210629]

	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[bundleFile:?]

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434) ~[bundleFile:9.4.43.v20210629]

	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.43.v20210629]

	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:82) ~[bundleFile:?]

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388) ~[bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.43.v20210629]

	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.43.v20210629]

	at java.lang.Thread.run(Thread.java:829) [?:?]

2022-01-10 19:38:46.985 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Afval_Cyclus' failed: org.graalvm.polyglot.PolyglotException: SyntaxError: <eval>:5:10 Expected ; but found :

  - inputs: null

          ^

<eval>:9:14 Expected an operand but found >

      script: >

              ^


Did you switch to the code view first and then pasted the code?

That way you can enter a rule together with the conditions. If you just want the rule itself paste only the script part between (the part between script: > and type: script.ScriptAction

Thanks for your help. Seems to be working now.
All i had to change was this line:
CONFIG.itemPrefix = “AfvalKalender”;
to this
//CONFIG.itemPrefix = “AfvalKalender”;

Otherwise i had to change the items naming from prefix : AfvalData to AfvalKalender.