nocin.eu

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

[Home Assistant] Person card with step counter

I recently enhanced the person cards on my dashboard to display some mobile phone sensor data (check here). In addition, I now also added the daily steps by using the Steps sensor of my mobile phone in combination with a utility helper sensor, which counts the daily steps, as the mobile Steps sensor is an increasing counter without daily reset. This is how it looks now:

To include the daily steps, you first have to enable the Steps sensor in the Home Assistant Companion App on your mobile phone.

Next, create a utility sensor which uses the Steps sensor as Input and daily resets the counted steps.

The utility sensor history should look like this after a few days:

Now we can add the utility sensor to the dashboard. As I’m using the vertical-stack-in-card, I simply had to add a new horizontal-stack to the person card to get a new line, and include a mushroom-chips-card which displays the steps.

  - type: horizontal-stack
    cards:
      - type: custom:mushroom-chips-card
        alignment: center
        card_mod:
          style: |
            ha-card {
                --chip-font-size: 0.32em;
                --chip-icon-size: 0.5em;
                --chip-border-width: 0;
                --chip-box-shadow: none;
                --chip-background: none;
                --chip-border: none;
                --chip-spacing: none;
                --chip-font-weight: bold;
            }
        chips:
          - type: template
            entity: sensor.daily_steps_mi8
            content: "{{ states('sensor.daily_steps_mi8')}} steps today"
            tap_action:
              action: more-info

I noticed, that the Steps sensor sometimes does not count steps, and it helps to have some separate steps counter app running on the phone like Paseo.

[HR] OM – Besetzungsplan (Struktur)

Da ich nur selten mit dem OM arbeite, vergessen ich immer wieder, wie man das OM “umdreht”, wenn man eine Person ausgewählt hat. Also die Anzeige von P – S – O umkehrt auf O – S – P.
Dabei ist es total einfach! Die Org. Einheit markieren und links oben in der Toolbar auf den Dropdown Button (Springen) gehen und Besetzungsplan (Struktur) auswählen und man erhält die gewünschte Ansicht.

[Android] Upgrading LineageOS 20.0 to 21.0 on my Xiaomi Mi 8 (dipper)

Install the Android Debug Bridge (ADB)

https://wiki.lineageos.org/adb_fastboot_guide.html
https://github.com/M0Rf30/android-udev-rules#installation

# check if device is found
adb devices
# reboot into sideload modus
adb reboot sideload

Or manually boot into recovery, holding Volume Up + Power when the phone is off. Navigate to AdvancedADB Sideload.


Update MIUI Firmware

Following the docs, I first had to check the Firmware version. V12.0.3.0.QEAMIXM was required, and I already had it installed.
If you’re on an older version, download the right MIUI Firmware for your device from https://xiaomifirmwareupdater.com/firmware/dipper/.
Flash the new Firmware via TWRP or via ADB sideload.

adb sideload fw_dipper_miui_MI8Global_V12.0.3.0.QEAMIXM_7619340f8c_10.0.zip

Flash latest recovery

Since I follow the LineageOS subreddit, I have already seen posts with problems with the latest update. Check here: https://www.reddit.com/r/LineageOS/comments/1fxlmtq/regular_ota_update_20241005_on_xiaomi_mi8_dipper/
There it is recommended to flash the latest recovery to prevent any issues. Although this is step 1 in the upgrade guide, I skipped updating the recovery the last years, because I was using TWRP instead of the LineageOS recovery. But to be on the safe side, this time I flashed the LineageOS recovery (which meant loosing/removing TWRP). To flash the recovery, you must first boot into fastboot by using adb or Volume Down + Power when the phone is off, like it is described here.

# boot into fastboot
adb -d reboot bootloader
# flash recovery
fastboot flash recovery lineage-21.0-20241208-microG-dipper-recovery.img

Download and flash new LineageOS image

I’m using the LineageOS fork LineageOS for microG. Download it from here: https://download.lineage.microg.org/dipper/ (MI 8 = dipper)
The upgrade steps are the same as for the official rom: https://wiki.lineageos.org/devices/dipper/upgrade. As I’ve already flashed the latest recovery, I only had to flash the new LineageOS image.

# reboot again into recovery
adb reboot sideload
# flash again new image
adb sideload lineage-21.0-20241208-microG-dipper.zip

[HR] A1-Meldeverfahren

Übersicht

Gute Zusammenfassung: https://www.iprocon.de/abbildung-des-a1-meldeverfahrens-in-sap-hcm/

2682093 – Informationen zur Umsetzung des A1-Meldeverfahrens im SAP-System (siehe auch das PDF im Hinweis)

2730927 – A1-Verfahren: Hilfestellung zum Customizing

2833850 – A1-Verfahren: Archivierung der A1-Bescheinigung und Erweiterung für das BAdI HRPAYDE_A1_EMAIL

2841779 – A1-Verfahren: ESS-Szenario (Web-Dynpro ABAP) (Paket PAOC_ESS_A1_DE)

Die Datenerfassung der Antragsdaten erfolgt im Infotyp: 0700 (Elektronischer Datenaustausch)
Subtypen:

  • DXA1 (A1: Antrag Entsendebescheinigung)
  • DXAV (A1: Antrag Ausnahmevereinbarung)

Reports zur Erstellung der Meldungen und der Meldedateien:

  • Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Abrechnungszusatz → A1-Meldeverfahren → Ausgangsmeldungen

Reports zur Verarbeitung der Eingangsmeldungen:

  • Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Abrechnungszusatz → A1-Meldeverfahren → Eingangsmeldungen

Behördenkommunikation (B2A): Transaktion PB2A

  • Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Behördenkommunikation (B2A) → B2A-Manager

Hilfreiche Entwicklungsobjekte

Paket: P01S

Reports:

Klassen:

Für mich hilfreich waren folgenden Klassen:

  • CL_HRPAYDE_A1_NOTIF (Klasse für A1-Meldungen)
  • CL_HRPAYDE_A1_NOTIF_DISPLAYER (ALV-Ausgabe für A1-Meldungen)
  • CL_HRPAYDE_A1_ALV_EVNT_HANDLER (Ereignisbehandler für A1-spezifische Ereignisse)

PDFs der A1-Meldungen von Datenbank lesen

*&---------------------------------------------------------------------*
*& Tabellen A1-Meldeverfahren:
*& P01A1_STAT    - A1-Verfahren: Verwaltungstabelle
*& P01A1_RAWDATA - A1-Verfahren: Rohdaten einer Meldung
*&---------------------------------------------------------------------*

GET peras.

  SELECT * INTO TABLE @DATA(lt_p01a1_stat) FROM p01a1_stat
    WHERE pernr  = @pernr-pernr
      AND mdtyp  = '2'
      AND status = '23'
      AND mzbeg <= @pn-endda
      AND mzbeg >= @pn-begda.

  LOOP AT lt_p01a1_stat INTO DATA(ls_p01a1_stat).

    SELECT SINGLE * INTO @DATA(ls_p01a1_rawdata) FROM p01a1_rawdata
      WHERE guid = @ls_p01a1_stat-guid
        AND lfdnr = ( SELECT MAX( lfdnr ) FROM p01a1_rawdata WHERE guid = @ls_p01a1_stat-guid ). "höchste lfdnr nehmen

    DATA(pdf_xstring) = ls_p01a1_rawdata-rawdata.

  ENDLOOP.

[Home Assistant] Combine Adaptive Lightning, motion activated light and lights turned on by sunset

In my home, I have some motion activated lights, for example in the kitchen. During daytime, the kitchen light should simply be turned on and off by the motion sensor. But when the sun sets, I like to turn on most of the lights in the house to 1% brightness, so that you never walk into a completely dark room. In this case, the motion sensor should not turn the kitchen light on and off, but instead should increase the brightness and afterward go back to the previous state of 1% brightness. And with “increase the brightness”, I don’t mean a fix value, but instead it should set the right brightness provided by the Adaptive Lightning integration. When it’s late, and the sleep mode is tuned on for the house, the kitchen light of course should be turned off, and when it is turned on, it should respect the configured sleep values from Adaptive Lightning settings.

Most things turned out to be quite easy by using Scenes to store the current light state and of course by using the great Adaptive Lightning features. But my automation had one important gap. When someone was is the kitchen, means kitchen light was turned on by the motion sensor, and we had sunset in this exact moment, it would always turn down the brightness to 1%, because the automation which turns on all lights to 1% brightness when the sun sets got triggered. Also, when the person left the kitchen, the previous stored scene was loaded, which was created before sunset, means it turned off the kitchen light, instead of the now required 1% brightness. This was of course really confusing for people in the kitchen…

I needed a way, to only activate the 1% sunset brightness, when no one is currently in the kitchen. The solution was a wait_template which checks if currently a motion automation is running in the kitchen. I could have also used the wait check on motion sensor directly, but I wanted to be able to use timeouts in my automation, which can be longer than the actual motion detection.

The important snippet is this one, which checks if no automation is currently running:

{{ is_state_attr('automation.bewegungsmelder_kuche', 'current', 0) }}

And this is the whole part I have added to my sunset automation (and also for the sleep automation similarly) for every room, which has a motion activated light:

sequence:
  - wait_template: "{{ is_state_attr('automation.bewegungsmelder_kuche', 'current', 0) }}"
    continue_on_timeout: true
  - action: adaptive_lighting.set_manual_control
    metadata: {}
    data:
      manual_control: true
      lights:
        - light.kueche
  - action: light.turn_on
    metadata: {}
    data:
      brightness_pct: 1
      kelvin: 2000
    target:
      entity_id: light.kueche
enabled: true

It simply waits until the motion sensor automation is done, then turns on the manual_control flag in Adaptive Lightning, so it does not adjust the light automatically, as it should stay at 1%, and finally turns on the light with 1% brightness. The only drawback is, that there is a millisecond where the light is turned off by the motion automation and until this wait_template fires and turns the light back on to 1% brightness. But as in this case no one should be in the room anymore, I can live with that.

And this is my motion sensor automation for the kitchen:

alias: Bewegungsmelder Küche
description: ""
mode: single
triggers:
  - entity_id:
      - binary_sensor.0xb4e3f9fffeb689d4_occupancy
    to: "on"
    trigger: state
conditions: []
actions:
  - data:
      scene_id: zustand_kueche_alt
      snapshot_entities:
        - light.kueche
    action: scene.create
  - action: adaptive_lighting.set_manual_control
    metadata: {}
    data:
      manual_control: false
      lights:
        - light.kueche
  - target:
      entity_id:
        - light.kueche
    data:
      transition: 5
    action: light.turn_on
    enabled: true
  - wait_for_trigger:
      - entity_id:
          - binary_sensor.0xb4e3f9fffeb689d4_occupancy
        to: "off"
        for:
          hours: 0
          minutes: 0
          seconds: 10
        trigger: state
  - target:
      entity_id: scene.zustand_kueche_alt
    data:
      transition: 5
    action: scene.turn_on

Before turning on the kitchen light, it stores the current state in a scene, then always disables the manual_control flag (in case the sunset automation turned it on), so that when in the next step the light is turned on, it automatically adjusts the brightness to the right value. When no motion is detected for 10 seconds, it restores the previous scene.

[ABAP] Read attendance/absence quotas

DATA pernr TYPE pernr_d VALUE 1.

DATA(time_accounts) = cl_hcmfab_att_abs_bl_apis=>get_instance( )->read_time_accounts( iv_pernr = pernr
                                                                                      iv_begda = sy-datum
                                                                                      iv_endda = sy-datum ). "iv_endda is never used!

cl_demo_output=>display( time_accounts ).

Although there is an obligatory iv_endda parameter, it is never used inside of method read_time_accounts. Instead, there is some logic which checks for a T77S0 Parameter, and it will use either highdate or begda as endda value.

IMO, it would have made sense to mark iv_endda as optional, so it would be downward compatible and the parameter could be omitted on newer releases. Now it is a bit misleading.

[ABAP] REDUCE as an alternative to line_exists for the use of other comparison operators such as >, <, >=, <=, CS, CN

By using line_exists you can check if a line exists or not exists, but it is not possible to use other comparison operators. A workaround can be REDUCE in that case.

In the following snippet, we want to check if there is a flight that costs more than $1000,

SELECT * FROM sflight INTO TABLE @DATA(flights).

* Check if flight with price > 1000 exist
IF REDUCE abap_bool( INIT price_gt_1000 = abap_false
                     FOR  line IN flights WHERE ( price > 1000 )
                     NEXT price_gt_1000 = abap_true ) EQ abap_true.
  " flight with price > 1000 exists
ENDIF.