Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[ABAP] Filter table using VALUE FOR

DATA(lt_result) = VALUE z_type( FOR line IN lt_table
                                WHERE ( value IN lr_values )
                                ( field = ls_line-value ) ).

[ABAP] Selection Screen Tabbed Block

SELECTION-SCREEN BEGIN OF BLOCK bl4 WITH FRAME TITLE TEXT-t01.
SELECTION-SCREEN BEGIN OF TABBED BLOCK tbl FOR 10 LINES.
SELECTION-SCREEN TAB (15) tbl_tab1 USER-COMMAND tab1 DEFAULT SCREEN 1001.
SELECTION-SCREEN TAB (15) tbl_tab2 USER-COMMAND tab2 DEFAULT SCREEN 1002.
SELECTION-SCREEN TAB (15) tbl_tab3 USER-COMMAND tab3 DEFAULT SCREEN 1003.
SELECTION-SCREEN END OF BLOCK tbl.
SELECTION-SCREEN END OF BLOCK bl4.

* Subscreen 1001 Tab1
SELECTION-SCREEN BEGIN OF SCREEN 1001 AS SUBSCREEN.
PARAMETERS p_bool1 TYPE abap_bool AS CHECKBOX.
SELECTION-SCREEN END OF SCREEN 1001.

* Subscreen 1002 Tab2
SELECTION-SCREEN BEGIN OF SCREEN 1002 AS SUBSCREEN.
PARAMETERS p_btp1 TYPE flag RADIOBUTTON GROUP rbg DEFAULT 'X'.
PARAMETERS p_btp2 TYPE flag RADIOBUTTON GROUP rbg.
PARAMETERS p_btp3 TYPE flag RADIOBUTTON GROUP rbg.
SELECTION-SCREEN END OF SCREEN 1002.

* Subscreen 1003 Tab3
SELECTION-SCREEN BEGIN OF SCREEN 1003 AS SUBSCREEN.
PARAMETERS p_bool2 TYPE flag AS CHECKBOX.
SELECTION-SCREEN END OF SCREEN 1003.

INITIALIZATION.

  " provide tab names
  tbl_tab1 = 'Tab1'.
  tbl_tab2 = 'Tab2'.
  tbl_tab3 = 'Tab3'.

  " set active tab (activetab value must be in uppercase)
  tbl-activetab = 'TAB2'.
  tbl-dynnr     = 1002.
  tbl-prog      = sy-repid.

AT SELECTION-SCREEN.

  " click on tabstrip event
  CASE sy-ucomm.
    WHEN 'TAB1'.
      MESSAGE 'TAB1' TYPE 'S'.
    WHEN 'TAB2'.
      MESSAGE 'TAB2' TYPE 'S'.
    WHEN 'TAB3'.
      MESSAGE 'TAB3' TYPE 'S'.
  ENDCASE.

[CAP] min and max functions

Since there is nothing in the official CAP documentation about min and max functions, I figured out the following syntax:

    const result1 = await cds.run(`SELECT *, MAX(seqNr) FROM ${myTable} LIMIT 1`) //returns array

    const result2 = await SELECT.one.from(myTable, [`MAX(seqNr)`]).columns('*') //returns object 

    const result3 = await SELECT.one.from(myTable).columns('MAX(seqNr)') //returns object containing only the max counter value

[Proxmox] Upgrade 7.4 to 8.0 – Failed to run lxc.hook.pre-start for container

After updating my Proxmox Server to PVE8.0, suddenly two lxc containers did not start anymore.

root@pve:~# pct start 192
run_buffer: 322 Script exited with status 2
lxc_init: 844 Failed to run lxc.hook.pre-start for container "192"
__lxc_start: 2027 Failed to initialize container "192"
startup for container '192' failed

I tried to view the error.log but couldn’t find any helpful information.

lxc-start -lDEBUG -o error.log -F -n 192

When googling, I stumbled across this reddit post. Although the issue was a bit different, I tried the recommended steps. The first command, directly led me to the right direction…

root@pve:~# pct mount 192
mounting container failed
directory '/mnt/nfs/data/folder' does not exist

For whatever reason, after restarting proxmox it did not mount the nfs shares properly on the host. And of course, after this hint, I noticed that both containers were trying to mount some of these folders, which were actually nfs shares from my NAS. A simple mount -a on the host fixed it immediately. Besides of this little problem, everything went well with the proxmox upgrade!

[Home Assistant] Conbee II Firmware Update

The firmware update is done in just a few minutes. Connect the Conbee II to your PC, install the deCONZ software, download the latest firmware and use the command line tool to flash it.

Guide: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Update-deCONZ-manually#update-in-ubuntu-or-debian

deCONZ: http://deconz.dresden-elektronik.de/ubuntu/stable/

Firmware: http://deconz.dresden-elektronik.de/deconz-firmware/

[Home Assistant] Ikea Traefdri Reset Script / Pairing mode

Handy script, to put Ikea Bulbs into pairing mode by using a Zigbee Switch: https://community.home-assistant.io/t/handy-script-to-reset-ikea-tradfri-bulb/435622

Just go to Settings -> Automations -> Scripts and paste the following YAML script:

alias: Reset IKEA bulb with Switch
sequence:
  - repeat:
      count: "5"
      sequence:
        - service: switch.turn_off
          data: {}
          target:
            entity_id: "{{ smart_plug }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: 900
        - service: switch.turn_on
          data: {}
          target:
            entity_id: "{{ smart_plug }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: 500
variables:
  smart_plug: switch.REPLACE_SWITCH_NAME
mode: single

Now just insert your light bulb with a light socket into the plug and run the script.

To use the script with other bulbs, just adjust the counter and seconds to your needs, e.g. like here for Ledvance bulbs:

alias: Reset Ledvance Gardenpole with Switch
sequence:
  - repeat:
      count: "5"
      sequence:
        - service: switch.turn_off
          data: {}
          target:
            entity_id: "{{ smart_plug }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 5
            milliseconds: 0
        - service: switch.turn_on
          data: {}
          target:
            entity_id: "{{ smart_plug }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 5
            milliseconds: 0
variables:
  smart_plug: switch.REPLACE_SWITCH_NAME
mode: single

[ABAP] Display Table data as HTML

REPORT z_table_to_html.

TRY.

    SELECT * FROM sflight INTO TABLE @DATA(flights) UP TO 100 ROWS.

    cl_demo_output=>write_data( flights ).

    DATA(lv_html) = cl_demo_output=>get( ).

    cl_abap_browser=>show_html( title       = 'Flights'
                                html_string = lv_html
                                container   = cl_gui_container=>default_screen ).

    " force cl_gui_container=>default_screen
    WRITE: space.

  CATCH cx_root INTO DATA(e).
    WRITE: / e->get_text( ).
ENDTRY.