• Modbus-Rtu 2 Channel 7-24V Relay Module

    install modbus command line tool

    pip3 install modbus_cli

    setup udev rules for usb QinHeng Electronics CH340 serial converter

    #cat /etc/udev/rules.d/98-usb-serial.rules
    KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", OWNER="hass", GROUP="users", MODE="0660", SYMLINK+="rs485"

    relay control

    # 1
    # on 
    modbus   -b 9600   -s 2  -v   /dev/rs485  c@0=1
    # off
    modbus   -b 9600   -s 2  -v   /dev/rs485  c@0=0
    # status
    modbus -b 9600 -s 2  -v /dev/rs485  c@0/8B | egrep -o '\[.*\]' | tr -d '[,]' | cut -f1 -d' '
    # 2
    # on 
    modbus   -b 9600   -s 2  -v   /dev/rs485  c@1=1
    # off
    modbus   -b 9600   -s 2  -v   /dev/rs485  c@1=0
    # status
    modbus -b 9600 -s 2  -v /dev/rs485  c@0/8B | egrep -o '\[.*\]' | tr -d '[,]' | cut -f2 -d' '
  • write data to influxdb with curl

    systemd unit file

    # /etc/systemd/system/influx-send.service
    [Unit]
    Description=send data to influx 
    After=syslog.target network.target
    [Service]
    Type=simple
    ExecStart=/usr/local/sys/influx/influx-send.sh
    [Install]
    WantedBy=multi-user.target

    shell script /usr/local/sys/influx/influx-send.sh

    #!/bin/bash
    while true; do
    find /var/spool/emeter -type f -exec sh -c "curl -o /dev/null -w \"%{http_code}\" --user 'username':'password' -sS -X POST http://192.168.110.16:8086/write?db=emeter -d @{} | grep -q  204 && rm  {}" \;
    sleep 60
    done

    sample data from /var/spool/emeter/*

    voltage,stand=diesel-new,phase=A value=218 1699828098942885595
  • get data from sinotimer meter

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    import libscrc
    import serial
    import sys
    import struct
    def str_to_bytes(data):
        return [hex(ord(c)) for c in data]
    port=sys.argv[1]
    addr=sys.argv[2]
    def get_value(data,port,addr):
        crc16 = libscrc.modbus(data)
        crc16_str = '0x{:04x}'.format(crc16)
        data.append(int(crc16_str[2:][2:4],16))
        data.append(int(crc16_str[2:][0:2],16))
        ser = serial.Serial(port,9600,timeout=0.1,bytesize=8,stopbits=1,parity='N',writeTimeout=0)
        ser.write(data)
        line = ser.read(100)
        ret = (''.join('{:02x}'.format(ord(x)) for x in line))
        val = struct.unpack('>f',line[3:7])[0]
        return "%.3f" % val
        ser.close()
    data = bytearray(b'\x00\x04\x00\x00\x00\x02')
    data[0]=int(addr)
    voltage = get_value(data,port,addr)
    data = bytearray(b'\x00\x04\x00\x08\x00\x02')
    data[0]=int(addr)
    current = get_value(data,port,addr)
    data = bytearray(b'\x00\x04\x00\x12\x00\x02')
    data[0]=int(addr)
    power = get_value(data,port,addr)
    data = bytearray(b'\x00\x04\x01\x00\x00\x02')
    data[0]=int(addr)
    power_total = get_value(data,port,addr)
    print("U="+voltage+" I="+current+" P="+power+" W="+power_total+"|U="+voltage+";; I="+current+";; P="+power+";; "+"W="+power_total+";; ")
  • nginx selecting the backend by header

    in http block

        upstream backend13 {
        # sticky - link backend by cookies
        # must build nginx with  --add-module=/usr/local/src/nginx-goodies-nginx-sticky-module-ng
        sticky;
        server 127.0.0.1:6001;
        server 127.0.0.1:6002;
        server 127.0.0.1:6003;
        }
        upstream backend47 {
        sticky;
        server 127.0.0.1:6004;
        server 127.0.0.1:6005;
        server 127.0.0.1:6006;
        server 127.0.0.1:6007;
        }
        map $http_x_backend $backend {
        default backend13;
        13      backend13;
        47      backend47;
        }

    in server block

            location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_pass http://$backend;
            }

    in backend server block

        set_real_ip_from  127.0.0.1/32;
        real_ip_header    X-Forwarded-For;

    testing

    curl -c curl_cookie -b curl_cookie -sS  --header "X-Backend: 13" http://192.168.0.65/
  • php-fpm and apparmor

    got error when access php-fpm backend

    curl http://192.168.0.65/index.php
    Access denied.

    /var/log/nginx/error.log

    2023/09/10 16:55:16 [error] 8597#8597: *35 FastCGI sent in stderr: "Unable to open primary script: /srv/www/htdocs/6001/index.php (Permission denied)" while reading response header from upstream, client: 192.168.0.57, server: , request: "GET /index.php HTTP/1.0", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.0.65"

    check file permission from user nginx

    su - nginx -s /bin/bash
    nginx@zei0mucu:~> cat /srv/www/htdocs/index.php 
    <?php
    echo $_SERVER['REMOTE_ADDR']
    ?>

    all is ok, but

    /var/log/audit/audit.log

    type=AVC msg=audit(1694354225.344:6659): apparmor="DENIED" operation="open" profile="php-fpm" name="/srv/www/htdocs/6001/index.php" pid=32709 comm="php-fpm" requested_mask="r" denied_mask="r" fsuid=484 ouid=484

    edit apparmor profile

    vim  /etc/apparmor.d/php-fpm

    add rule for /srv/www/htdocs (store of php files)

     # the main log file
      /var/log/php*-fpm.log rw,
      # web server files
      /srv/www/htdocs/** r,
      # we need to be able to create all sockets
      @{run}/php{,-fpm}/php*-fpm.pid rw,
      @{run}/php*-fpm.pid rw,
      @{run}/php{,-fpm}/php*-fpm.sock rwlk,

    restart apparmor

    systemctl restart apparmor