Merge branch 'master' into dockerbuildtest
# Conflicts: # contrib/docker/Dockerfile.arm32v5 # contrib/docker/Dockerfile.arm32v7 # make_debian.sh
This commit is contained in:
+21
-1
@@ -1,12 +1,32 @@
|
||||
# 21.3 (tbd)
|
||||
# 21.3 (2021-11-07)
|
||||
|
||||
## Bug Fixes
|
||||
* fix for escaping double quote in CSV format
|
||||
* adjusted helper shell scripts and Munin plugin to newer netcat
|
||||
* fix for weekday in BDA data type (for sending only)
|
||||
* fix some compiler warnings
|
||||
* fix non-unique message keys in HTTP JSON output with "full" query parameter
|
||||
* fix for message after debian install
|
||||
* fix for replacing already existing message definitions
|
||||
* fix missing length in CSV dump for some data types
|
||||
* fix some missing data type lengths in "grab decode" result
|
||||
* fix for injecting several messages via command line args
|
||||
|
||||
## Features
|
||||
* added DTM and BDZ data types
|
||||
* added "-n" argument to "hex" and "direct" commands for automatically determining message length from input
|
||||
* added level/pollprio/condition/field flags and field result type as well as list of types to HTTP JSON output
|
||||
* added message dump from commandline in JSON format
|
||||
* added support for newer MQTT broker versions
|
||||
* added some PIC calibration data to "ebuspicloader" verbose output
|
||||
* added support for upcoming adapter 3 firmware enhancements
|
||||
* added config override path
|
||||
* added support for adding message definition, retrieving data types and raw messages, and decode data types from raw values to HTTP port
|
||||
* added "--mqttverbose" option
|
||||
* added verbose option to "info" command
|
||||
|
||||
## Breaking Changes
|
||||
* remove support for Debian 8 Jessie in docker
|
||||
|
||||
|
||||
# 21.2 (2021-02-08)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Contributor: Milan Knizek <knizek volny cz>
|
||||
# Usage: makepkg
|
||||
pkgname=ebusd
|
||||
pkgver=21.2
|
||||
pkgver=21.3
|
||||
pkgrel=1
|
||||
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Usage: makepkg -p PKGBUILD.git
|
||||
pkgname=ebusd-git
|
||||
_gitname=ebusd
|
||||
pkgver=21.2
|
||||
pkgver=21.3
|
||||
pkgrel=1
|
||||
pkgdesc="ebusd, the daemon for communication with eBUS heating systems."
|
||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
||||
|
||||
+20
-10
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
|
||||
FROM debian:bullseye as build
|
||||
FROM $BASE_IMAGE as build
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
@@ -9,25 +10,34 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH amd64
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
ADD . /build
|
||||
RUN ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
FROM $BASE_IMAGE-slim as image
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH amd64
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
ARG EBUSD_IMAGE
|
||||
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||
|
||||
@@ -39,6 +49,6 @@ RUN dpkg -i ebusd.deb \
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
COPY --from=build /build/contrib/docker/docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm32v5/debian:jessie as build
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ADD . /build
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm32v5
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN ./make_debian.sh --host `gcc -dumpmachine`
|
||||
|
||||
|
||||
|
||||
FROM arm32v5/debian:jessie-slim
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm32v5
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-arm-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY --from=build /build/contrib/docker/docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,42 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm32v7/debian:jessie as build
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
ADD . /build
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm32v7
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
FROM arm32v7/debian:jessie-slim
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm32v7
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-arm-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY --from=build /build/contrib/docker/docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm64v8/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm64v8
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM arm64v8/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm64v8
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-aarch64-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM i386/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-i386-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH i386
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM i386/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-i386-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH i386
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}-devel"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-i386-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,5 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
|
||||
FROM debian:bullseye as build
|
||||
FROM $BASE_IMAGE as build
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
@@ -9,29 +10,38 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH amd64
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
ADD . /build
|
||||
RUN ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
FROM $BASE_IMAGE-slim as image
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH amd64
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
ARG EBUSD_IMAGE
|
||||
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
ADD https://github.com/john30/ebusd/releases/download/v${EBUSD_VERSION}/ebusd-${EBUSD_VERSION}_${TARGETARCH}${TARGETVARIANT}-${EBUSD_IMAGE}_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
@@ -39,6 +49,6 @@ RUN dpkg -i ebusd.deb \
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
COPY contrib/docker/docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm32v5/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm32v5
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM arm32v5/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm32v5
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-arm-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm32v7/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm32v7
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM arm32v7/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm32v7
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-arm-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM arm64v8/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH arm64v8
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM arm64v8/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-aarch64-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH arm64v8
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-aarch64-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM multiarch/qemu-user-static as qemu
|
||||
FROM i386/debian:bullseye as build
|
||||
COPY --from=qemu /usr/bin/qemu-i386-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
autoconf automake g++ make git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH i386
|
||||
ENV EBUSD_VERSION 21.2
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& ./make_debian.sh
|
||||
|
||||
|
||||
|
||||
|
||||
FROM i386/debian:bullseye-slim
|
||||
COPY --from=qemu /usr/bin/qemu-i386-static /usr/bin/
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION 21.2
|
||||
ENV EBUSD_ARCH i386
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb /usr/bin/qemu-i386-static
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
@@ -1,6 +1,7 @@
|
||||
%QEMU_FROM_LINE%
|
||||
FROM %BASE_IMAGE% as build
|
||||
%QEMU_FROM_COPY%
|
||||
ARG BASE_IMAGE
|
||||
|
||||
FROM $BASE_IMAGE as build
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libmosquitto-dev libstdc++6 libc6 libgcc1 \
|
||||
curl \
|
||||
@@ -9,36 +10,45 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV EBUSD_ARCH %EBUSD_ARCH%
|
||||
ENV EBUSD_VERSION %EBUSD_VERSION%
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
|
||||
RUN git clone https://github.com/john30/ebusd.git /build \
|
||||
&& %EBUSD_MAKE%
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
ADD . /build
|
||||
RUN %EBUSD_MAKE%
|
||||
|
||||
%EBUSD_UPLOAD_LINES%
|
||||
|
||||
|
||||
FROM %BASE_IMAGE%-slim
|
||||
%QEMU_FROM_COPY%
|
||||
FROM $BASE_IMAGE-slim as image
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
logrotate libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
libmosquitto1 libstdc++6 libc6 libgcc1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
LABEL maintainer "ebusd@ebusd.eu"
|
||||
|
||||
ENV EBUSD_VERSION %EBUSD_VERSION%
|
||||
ENV EBUSD_ARCH %EBUSD_ARCH%
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
ARG EBUSD_VERSION
|
||||
ARG EBUSD_IMAGE
|
||||
|
||||
ENV EBUSD_ARCH $TARGETARCH$TARGETVARIANT
|
||||
ENV EBUSD_VERSION $EBUSD_VERSION
|
||||
|
||||
LABEL version "${EBUSD_VERSION}-${EBUSD_ARCH}%EBUSD_VERSION_VARIANT%"
|
||||
|
||||
COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb
|
||||
%EBUSD_COPYDEB%
|
||||
|
||||
RUN dpkg -i ebusd.deb \
|
||||
&& ebusd -V \
|
||||
&& rm -f ebusd.deb%EXTRA_RM%
|
||||
&& rm -f ebusd.deb
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
COPY docker-entrypoint.sh /
|
||||
%EBUSD_COPYENTRY%
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["-f", "--scanconfig"]
|
||||
|
||||
@@ -2,8 +2,8 @@ ebusd Docker image
|
||||
==================
|
||||
|
||||
An [ebusd](https://github.com/john30/ebusd/) Docker image is available on the
|
||||
[Docker Hub](https://hub.docker.com/r/john30/ebusd/) and comes with the latest German
|
||||
[configuration files](https://github.com/john30/ebusd-configuration/).
|
||||
[Docker Hub](https://hub.docker.com/r/john30/ebusd/) and is able to download the latest released German
|
||||
[configuration files](https://github.com/john30/ebusd-configuration/) from a dedicated webservice.
|
||||
|
||||
It allows you to run ebusd without actually installing (or even building) it on your system.
|
||||
You might even be able to run it on a non-Linux operating system, which is at least known to
|
||||
@@ -18,12 +18,11 @@ To download the latest release image from the hub, use the following command:
|
||||
The image is able to run on any of the following architectures and the right image will be picked automatically:
|
||||
* amd64
|
||||
* i386
|
||||
* arm32v5
|
||||
* arm32v7
|
||||
* arm64v8
|
||||
|
||||
In addition to the default "latest" tag, a development set of images is available with "devel" tag. This is built
|
||||
automatically with every commit to the git repository. Run the following command to use it:
|
||||
Due to changes of docker hub policies, the development set of images with "devel" tag are currently not automatically
|
||||
built with every commit to the git repository. Run the following command to use it:
|
||||
|
||||
> docker pull john30/ebusd:devel
|
||||
|
||||
@@ -54,9 +53,9 @@ Using a network device
|
||||
|
||||
When using a network device, the "--device" argument to docker can be omitted, but the device information has to be
|
||||
passed on to ebusd:
|
||||
> docker run --rm -it -p 8888 john30/ebusd -f --scanconfig -d udp:192.168.178.123:10000 --latency=80
|
||||
> docker run --rm -it -p 8888 john30/ebusd -f --scanconfig -d 192.168.178.123:10000 --latency=20
|
||||
|
||||
Note: the "-f" and "--scanconfig" arguments are only passed to ebusd if it is called without any additional arguments.
|
||||
Note: the default "-f" and "--scanconfig" arguments are only passed to ebusd if it is called without any additional arguments.
|
||||
So when passing further arguments, these two usually need to be added as well.
|
||||
|
||||
|
||||
|
||||
+52
-17
@@ -1,20 +1,55 @@
|
||||
#!/bin/bash
|
||||
archs='amd64 i386 arm32v5 arm32v7 arm64v8'
|
||||
images='stretch buster bullseye'
|
||||
UPLOAD_URL='http://'`hostname`'/ebusdreleaseupload.php'
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "usage: $0 [release|UPLOADHOST]"
|
||||
echo " without arguments: build and push devel docker images"
|
||||
echo " release: build and push release docker images from latest release binaries"
|
||||
echo " UPLOADHOST: build Debian release packages (with and without MQTT) and upload them to UPLOADHOST"
|
||||
exit 1
|
||||
fi
|
||||
archs=linux/amd64,linux/386,linux/arm/v7,linux/arm64
|
||||
if [[ -z "$1" ]] || [[ "x$1" == "xrelease" ]]; then
|
||||
UPLOAD_URL=
|
||||
else
|
||||
UPLOAD_URL="http://$1/ebusdreleaseupload.php"
|
||||
fi
|
||||
UPLOAD_CREDENTIALS='anonymous:build'
|
||||
for image in $images; do
|
||||
dir=$image
|
||||
mkdir -p $dir
|
||||
BASE_IMAGE=debian:$image ./update.sh $dir/
|
||||
for arch in $archs; do
|
||||
if [ "$arch" != "amd64" ]; then
|
||||
suffix=".$arch"
|
||||
else
|
||||
suffix=''
|
||||
fi
|
||||
docker build $@ --target build --build-arg "UPLOAD_URL=$UPLOAD_URL" --build-arg "UPLOAD_CREDENTIALS=$UPLOAD_CREDENTIALS" --build-arg "UPLOAD_OS=$image" -f $dir/Dockerfile$suffix .
|
||||
done
|
||||
rm -rf $dir
|
||||
done
|
||||
version=`cat ../../VERSION`
|
||||
source='../..'
|
||||
images='bullseye'
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
namesuffix=''
|
||||
target=image
|
||||
outputFmt='-o type=docker,type=registry'
|
||||
tagsuffix=':devel'
|
||||
elif [[ "x$1" = "xrelease" ]]; then
|
||||
archs=linux/amd64
|
||||
namesuffix='.release'
|
||||
target=image
|
||||
outputFmt='-o type=docker,type=registry'
|
||||
tagsuffix=":v$version"
|
||||
else
|
||||
namesuffix='.build'
|
||||
target=build
|
||||
images='bullseye buster stretch'
|
||||
outputFmt=-q
|
||||
tagsuffix=":v$version-prep"
|
||||
fi
|
||||
|
||||
for image in $images; do
|
||||
output=$(echo "$outputFmt"|sed -e "s#%IMAGE%#$image#g")
|
||||
docker buildx build \
|
||||
--target $target \
|
||||
--progress pain \
|
||||
--platform $archs \
|
||||
-f Dockerfile${namesuffix} \
|
||||
--build-arg "BASE_IMAGE=debian:$image" \
|
||||
--build-arg "EBUSD_VERSION=$version" \
|
||||
--build-arg "EBUSD_IMAGE=$image" \
|
||||
--build-arg "UPLOAD_URL=$UPLOAD_URL" \
|
||||
--build-arg "UPLOAD_CREDENTIALS=$UPLOAD_CREDENTIALS" \
|
||||
--build-arg "UPLOAD_OS=$image" \
|
||||
-t ebusd$tagsuffix \
|
||||
$output \
|
||||
$source
|
||||
done
|
||||
|
||||
+20
-46
@@ -1,63 +1,37 @@
|
||||
#!/bin/bash
|
||||
DEFAULT_IMAGE=debian:bullseye
|
||||
EBUSD_VERSION=`cat ../../VERSION`
|
||||
|
||||
archs='amd64 i386 arm32v5:arm arm32v7:arm arm64v8:aarch64'
|
||||
|
||||
function replaceTemplate () {
|
||||
prefix=
|
||||
suffix=
|
||||
qemu_from_line=
|
||||
qemu_from_copy=
|
||||
extra_rm=
|
||||
if [ "$arch" != "amd64" ]; then
|
||||
qemu="${arch##*:}"
|
||||
arch="${arch%%:*}"
|
||||
prefix="$arch/"
|
||||
suffix=".$arch"
|
||||
qemu_from_line="FROM multiarch/qemu-user-static as qemu"
|
||||
qemu_from_copy="COPY --from=qemu /usr/bin/qemu-$qemu-static /usr/bin/"
|
||||
extra_rm=" /usr/bin/qemu-$qemu-static"
|
||||
fi
|
||||
file="${dir}Dockerfile${namesuffix}${suffix}"
|
||||
file="Dockerfile${namesuffix}"
|
||||
sed \
|
||||
-e "s#%QEMU_FROM_LINE%#${qemu_from_line}#g" \
|
||||
-e "s#%BASE_IMAGE%#${prefix}${BASE_IMAGE:-$DEFAULT_IMAGE}#g" \
|
||||
-e "s#%QEMU_FROM_COPY%#${qemu_from_copy}#g" \
|
||||
-e "s#%EBUSD_MAKE%#${make}#g" \
|
||||
-e "s#%EBUSD_VERSION%#${EBUSD_VERSION}#g" \
|
||||
-e "s#%EBUSD_VERSION_VARIANT%#${version_variant}#g" \
|
||||
-e "s#%EBUSD_ARCH%#${arch}#g" \
|
||||
-e "s#%EXTRA_RM%#${extra_rm}#g" \
|
||||
-e "s#%EBUSD_UPLOAD_LINES%#${upload_lines}#g" \
|
||||
-e "s#%EBUSD_COPYDEB%#${copydeb}#g" \
|
||||
-e "s#%EBUSD_COPYENTRY%#${copyentry}#g" \
|
||||
Dockerfile.template > "$file"
|
||||
echo "updated $file"
|
||||
}
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
# devel updates
|
||||
version_variant='-devel'
|
||||
make='./make_debian.sh'
|
||||
dir=''
|
||||
upload_line=''
|
||||
namesuffix=''
|
||||
for arch in $archs; do
|
||||
replaceTemplate
|
||||
done
|
||||
fi
|
||||
# devel update
|
||||
version_variant='-devel'
|
||||
make='./make_debian.sh'
|
||||
upload_lines=''
|
||||
copydeb='COPY --from=build /build/ebusd-*_mqtt1.deb ebusd.deb'
|
||||
copyentry='COPY --from=build /build/contrib/docker/docker-entrypoint.sh /'
|
||||
namesuffix=''
|
||||
replaceTemplate
|
||||
|
||||
# release updates
|
||||
# release update
|
||||
version_variant=''
|
||||
dir="$1"
|
||||
copydeb="ADD https://github.com/john30/ebusd/releases/download/v\${EBUSD_VERSION}/ebusd-\${EBUSD_VERSION}_\${TARGETARCH}\${TARGETVARIANT}-\${EBUSD_IMAGE}_mqtt1.deb ebusd.deb"
|
||||
copyentry='COPY contrib/docker/docker-entrypoint.sh /'
|
||||
namesuffix='.release'
|
||||
replaceTemplate
|
||||
|
||||
if [[ -n "$1" ]]; then
|
||||
# build releases update
|
||||
make='./make_all.sh'
|
||||
upload_lines='ARG UPLOAD_URL\nARG UPLOAD_CREDENTIALS\nARG UPLOAD_OS\nRUN if [ -n "\$UPLOAD_URL" ] \&\& [ -n "\$UPLOAD_CREDENTIALS" ]; then for img in ebusd-*.deb; do echo -n "upload \$img: "; curl -fs -u "\$UPLOAD_CREDENTIALS" -X POST --data-binary "@\$img" -H "Content-Type: application/octet-stream" "\$UPLOAD_URL/\$img?a=\$EBUSD_ARCH\&o=\$UPLOAD_OS\&v=\$EBUSD_VERSION" || echo "failed"; done; fi'
|
||||
namesuffix=''
|
||||
else
|
||||
make='./make_debian.sh'
|
||||
namesuffix='.release'
|
||||
fi
|
||||
for arch in $archs; do
|
||||
namesuffix='.build'
|
||||
replaceTemplate
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
+287
-302
@@ -10,86 +10,19 @@ paths:
|
||||
get:
|
||||
summary: Get all messages of all circuits.
|
||||
parameters:
|
||||
- name: since
|
||||
in: query
|
||||
description: limit to messages that have changed since the specified UTC seconds.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: poll
|
||||
in: query
|
||||
description: set the poll priority of matching message(s) to prio.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: verbose
|
||||
in: query
|
||||
description: include comments and field units.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: indexed
|
||||
in: query
|
||||
description: always return field indexes instead of names.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: numeric
|
||||
in: query
|
||||
description: return numeric values of value list entries.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: valuename
|
||||
in: query
|
||||
description: include value and name for named values.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: full
|
||||
in: query
|
||||
description: include all available attributes.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: required
|
||||
in: query
|
||||
description: retrieve the data from the bus if not yet cached.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: write
|
||||
in: query
|
||||
description: retrieve write messages in addition to read/poll messages.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: raw
|
||||
in: query
|
||||
description: include raw master/slave data.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: def
|
||||
in: query
|
||||
description: include message and field definition.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: user
|
||||
in: query
|
||||
description: authenticate with user name.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- name: secret
|
||||
in: query
|
||||
description: authenticate with user secret.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- $ref: '#/components/parameters/sinceQuery'
|
||||
- $ref: '#/components/parameters/pollQuery'
|
||||
- $ref: '#/components/parameters/verboseQuery'
|
||||
- $ref: '#/components/parameters/indexedQuery'
|
||||
- $ref: '#/components/parameters/numericQuery'
|
||||
- $ref: '#/components/parameters/valuenameQuery'
|
||||
- $ref: '#/components/parameters/fullQuery'
|
||||
- $ref: '#/components/parameters/requiredQuery'
|
||||
- $ref: '#/components/parameters/writeQuery'
|
||||
- $ref: '#/components/parameters/rawQuery'
|
||||
- $ref: '#/components/parameters/defQuery'
|
||||
- $ref: '#/components/parameters/userQuery'
|
||||
- $ref: '#/components/parameters/secretQuery'
|
||||
responses:
|
||||
200:
|
||||
description: Success.
|
||||
@@ -118,92 +51,20 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: since
|
||||
in: query
|
||||
description: limit to messages that have changed since the specified UTC seconds.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: poll
|
||||
in: query
|
||||
description: set the poll priority of matching message(s) to prio.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: exact
|
||||
in: query
|
||||
description: exact search for circuit/message name.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: verbose
|
||||
in: query
|
||||
description: include comments and field units.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: indexed
|
||||
in: query
|
||||
description: always return field indexes instead of names.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: numeric
|
||||
in: query
|
||||
description: return numeric values of value list entries.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: valuename
|
||||
in: query
|
||||
description: include value and name for named values.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: full
|
||||
in: query
|
||||
description: include all available attributes.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: required
|
||||
in: query
|
||||
description: retrieve the data from the bus if not yet cached.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: write
|
||||
in: query
|
||||
description: retrieve write messages in addition to read/poll messages.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: raw
|
||||
in: query
|
||||
description: include raw master/slave data.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: def
|
||||
in: query
|
||||
description: include message and field definition.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: user
|
||||
in: query
|
||||
description: authenticate with user name.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- name: secret
|
||||
in: query
|
||||
description: authenticate with user secret.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- $ref: '#/components/parameters/sinceQuery'
|
||||
- $ref: '#/components/parameters/pollQuery'
|
||||
- $ref: '#/components/parameters/exactQuery'
|
||||
- $ref: '#/components/parameters/verboseQuery'
|
||||
- $ref: '#/components/parameters/indexedQuery'
|
||||
- $ref: '#/components/parameters/numericQuery'
|
||||
- $ref: '#/components/parameters/valuenameQuery'
|
||||
- $ref: '#/components/parameters/fullQuery'
|
||||
- $ref: '#/components/parameters/requiredQuery'
|
||||
- $ref: '#/components/parameters/writeQuery'
|
||||
- $ref: '#/components/parameters/rawQuery'
|
||||
- $ref: '#/components/parameters/defQuery'
|
||||
- $ref: '#/components/parameters/userQuery'
|
||||
- $ref: '#/components/parameters/secretQuery'
|
||||
responses:
|
||||
200:
|
||||
description: Success.
|
||||
@@ -237,92 +98,21 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: since
|
||||
in: query
|
||||
description: limit to messages that have changed since the specified UTC seconds.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: poll
|
||||
in: query
|
||||
description: set the poll priority of matching message(s) to prio.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
minimum: 0
|
||||
type: integer
|
||||
- name: exact
|
||||
in: query
|
||||
description: exact search for circuit/message name.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: verbose
|
||||
in: query
|
||||
description: include comments and field units.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: indexed
|
||||
in: query
|
||||
description: always return field indexes instead of names.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: numeric
|
||||
in: query
|
||||
description: return numeric values of value list entries.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: valuename
|
||||
in: query
|
||||
description: include value and name for named values.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: full
|
||||
in: query
|
||||
description: include all available attributes.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: required
|
||||
in: query
|
||||
description: retrieve the data from the bus if not yet cached.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: write
|
||||
in: query
|
||||
description: retrieve write messages in addition to read/poll messages.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: raw
|
||||
in: query
|
||||
description: include raw master/slave data.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: def
|
||||
in: query
|
||||
description: include message and field definition.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: boolean
|
||||
- name: user
|
||||
in: query
|
||||
description: authenticate with user name.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- name: secret
|
||||
in: query
|
||||
description: authenticate with user secret.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
- $ref: '#/components/parameters/sinceQuery'
|
||||
- $ref: '#/components/parameters/pollQuery'
|
||||
- $ref: '#/components/parameters/exactQuery'
|
||||
- $ref: '#/components/parameters/verboseQuery'
|
||||
- $ref: '#/components/parameters/indexedQuery'
|
||||
- $ref: '#/components/parameters/numericQuery'
|
||||
- $ref: '#/components/parameters/valuenameQuery'
|
||||
- $ref: '#/components/parameters/fullQuery'
|
||||
- $ref: '#/components/parameters/requiredQuery'
|
||||
- $ref: '#/components/parameters/writeQuery'
|
||||
- $ref: '#/components/parameters/rawQuery'
|
||||
- $ref: '#/components/parameters/defQuery'
|
||||
- $ref: '#/components/parameters/defineQuery'
|
||||
- $ref: '#/components/parameters/userQuery'
|
||||
- $ref: '#/components/parameters/secretQuery'
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
@@ -333,6 +123,66 @@ paths:
|
||||
500:
|
||||
description: Circuit or message not found.
|
||||
content: { }
|
||||
/datatypes:
|
||||
get:
|
||||
summary: Get all known field data types.
|
||||
responses:
|
||||
200:
|
||||
description: Success.
|
||||
content:
|
||||
application/json;charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DataTypes'
|
||||
400:
|
||||
description: Invalid request parameters.
|
||||
content: { }
|
||||
403:
|
||||
description: User not authorized.
|
||||
content: { }
|
||||
404:
|
||||
description: Circuit or message not found.
|
||||
content: { }
|
||||
500:
|
||||
description: General error.
|
||||
content: { }
|
||||
/raw:
|
||||
get:
|
||||
summary: Retrieve raw data from grabbed and/or decoded messages.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/sinceQuery'
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json;charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RawMessages'
|
||||
/decode:
|
||||
get:
|
||||
summary: Decode raw data with the specified field defintion.
|
||||
parameters:
|
||||
- name: def
|
||||
in: query
|
||||
description: the field definition (starting with type).
|
||||
allowEmptyValue: false
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: raw
|
||||
in: query
|
||||
description: the raw symbols to decode as hex sequence.
|
||||
required: true
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^([0-9a-f][0-9a-f])+$'
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json;charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/FieldValue'
|
||||
/{file}:
|
||||
get:
|
||||
summary: Retrieve a particular file.
|
||||
@@ -391,36 +241,36 @@ paths:
|
||||
500:
|
||||
description: General error.
|
||||
content: { }
|
||||
head:
|
||||
summary: Retrieve headers for a certain file.
|
||||
parameters:
|
||||
- name: file
|
||||
in: path
|
||||
description: the file to retrieve.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json;charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Data'
|
||||
400:
|
||||
description: Circuit or message not found.
|
||||
content: { }
|
||||
# head:
|
||||
# summary: Retrieve headers for a certain file.
|
||||
# parameters:
|
||||
# - name: file
|
||||
# in: path
|
||||
# description: the file to retrieve.
|
||||
# required: true
|
||||
# schema:
|
||||
# type: string
|
||||
# responses:
|
||||
# 200:
|
||||
# description: Success
|
||||
# content:
|
||||
# application/json;charset=utf-8:
|
||||
# schema:
|
||||
# $ref: '#/components/schemas/Data'
|
||||
# 400:
|
||||
# description: Circuit or message not found.
|
||||
# content: { }
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Global:
|
||||
required:
|
||||
- lastup
|
||||
- version
|
||||
- signal
|
||||
- reconnects
|
||||
- masters
|
||||
- messages
|
||||
- reconnects
|
||||
- signal
|
||||
- version
|
||||
- lastup
|
||||
type: object
|
||||
properties:
|
||||
version:
|
||||
@@ -433,6 +283,12 @@ components:
|
||||
description: the result of update check ("OK" or string describing available
|
||||
updates).
|
||||
example: revision 1234abd available, 5 newer configuration files available
|
||||
user:
|
||||
type: string
|
||||
description: logged in user name.
|
||||
access:
|
||||
type: string
|
||||
description: access level(s) of the logged in user.
|
||||
signal:
|
||||
type: boolean
|
||||
description: whether signal is available.
|
||||
@@ -447,6 +303,26 @@ components:
|
||||
type: integer
|
||||
description: the maximum symbol rate on the bus seen since start.
|
||||
example: 167
|
||||
minarbitrationmicros:
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: the minimum arbitration delay in microseconds.
|
||||
example: 4231
|
||||
maxarbitrationmicros:
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: the maximum arbitration delay in microseconds.
|
||||
example: 4892
|
||||
minsymbollatency:
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: the minimum symbol latency in milliseconds.
|
||||
example: 4
|
||||
maxsymbollatency:
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: the maximum symbol latency in milliseconds.
|
||||
example: 9
|
||||
qq:
|
||||
maximum: 255
|
||||
minimum: 0
|
||||
@@ -487,14 +363,15 @@ components:
|
||||
example: 8
|
||||
messages:
|
||||
type: object
|
||||
description: the messages with the unique key per circuit.
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/Message'
|
||||
Message:
|
||||
required:
|
||||
- lastup
|
||||
- name
|
||||
- passive
|
||||
- write
|
||||
- lastup
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
@@ -506,6 +383,16 @@ components:
|
||||
write:
|
||||
type: boolean
|
||||
description: true for a write message, false for a read message.
|
||||
level:
|
||||
type: string
|
||||
description: the access level for the message (only with full).
|
||||
pollprios:
|
||||
description: the poll priority of the message (only with full).
|
||||
type: integer
|
||||
minimum: 0
|
||||
condition:
|
||||
type: string
|
||||
description: the condition string in case of a conditional message (only with full).
|
||||
lastup:
|
||||
minimum: 0
|
||||
type: integer
|
||||
@@ -515,7 +402,7 @@ components:
|
||||
maximum: 255
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: limited source master address (only with def).
|
||||
description: limited source master address (only with def or data).
|
||||
example: 49
|
||||
zz:
|
||||
maximum: 255
|
||||
@@ -535,30 +422,34 @@ components:
|
||||
type: string
|
||||
description: the message comment (only with verbose).
|
||||
master:
|
||||
type: array
|
||||
$ref: '#/components/schemas/Symbols'
|
||||
description: the last seen master data bytes (only with raw and if available).
|
||||
items:
|
||||
maximum: 255
|
||||
minimum: 0
|
||||
type: integer
|
||||
slave:
|
||||
type: array
|
||||
$ref: '#/components/schemas/Symbols'
|
||||
description: the last seen slave data bytes (only with raw and if available).
|
||||
items:
|
||||
maximum: 255
|
||||
minimum: 0
|
||||
type: integer
|
||||
fields:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/Field'
|
||||
description: the decoded fields the message is composed of (only if available).
|
||||
decodeerror:
|
||||
type: string
|
||||
description: set to the error message instead of fields in case of a decoding error.
|
||||
fielddefs:
|
||||
type: array
|
||||
description: the field definitions the message is composed of (only with
|
||||
def).
|
||||
items:
|
||||
$ref: '#/components/schemas/FieldDef'
|
||||
Symbols:
|
||||
description: master or slave data bytes.
|
||||
type: array
|
||||
minItems: 1
|
||||
maximum: 32
|
||||
items:
|
||||
maximum: 255
|
||||
minimum: 0
|
||||
type: integer
|
||||
Field:
|
||||
type: object
|
||||
properties:
|
||||
@@ -566,7 +457,7 @@ components:
|
||||
type: string
|
||||
description: the field name.
|
||||
value:
|
||||
type: object
|
||||
$ref: '#/components/schemas/FieldValue'
|
||||
description: the field value.
|
||||
unit:
|
||||
type: string
|
||||
@@ -574,13 +465,19 @@ components:
|
||||
comment:
|
||||
type: string
|
||||
description: the field comment (only with verbose).
|
||||
FieldValue:
|
||||
description: the field value.
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
nullable: true
|
||||
FieldDef:
|
||||
required:
|
||||
- isbits
|
||||
- length
|
||||
- name
|
||||
- slave
|
||||
- type
|
||||
- isbits
|
||||
- length
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
@@ -601,7 +498,8 @@ components:
|
||||
when isbits is true).
|
||||
divisor:
|
||||
type: number
|
||||
description: the extra divisor applied to the raw value (only if applicable).
|
||||
description: the divisor for numeric types (only if applicable, positive
|
||||
for divisor, negative for reciprocal i.e. 1/-divisor).
|
||||
value:
|
||||
type: string
|
||||
description: the constant value (only if applicable).
|
||||
@@ -621,6 +519,54 @@ components:
|
||||
comment:
|
||||
type: string
|
||||
description: the field comment.
|
||||
DataType:
|
||||
description: a known field data type.
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
description: the type name.
|
||||
example: UCH
|
||||
isbits:
|
||||
type: boolean
|
||||
description: true when the length is in bits.
|
||||
isadjustable:
|
||||
type: boolean
|
||||
description: whether the length is adjustable.
|
||||
isignored:
|
||||
type: boolean
|
||||
description: whether the result is ignored.
|
||||
length:
|
||||
type: number
|
||||
minimum: -1
|
||||
maximum: 31
|
||||
description: the field length in bytes (-1 for remainder, number
|
||||
of bits when isbits is true).
|
||||
result:
|
||||
enum:
|
||||
- void
|
||||
- string
|
||||
- number
|
||||
- date
|
||||
- time
|
||||
- datetime
|
||||
description: the result type.
|
||||
divisor:
|
||||
type: number
|
||||
description: the divisor for numeric types (only if applicable, positive
|
||||
for divisor, negative for reciprocal i.e. 1/-divisor).
|
||||
precision:
|
||||
type: number
|
||||
description: the precision (number of fraction digits) when divisor is >1.
|
||||
required:
|
||||
- type
|
||||
- isbits
|
||||
- length
|
||||
DataTypes:
|
||||
type: array
|
||||
description: the known field data types.
|
||||
items:
|
||||
$ref: '#/components/schemas/DataType'
|
||||
Data:
|
||||
required:
|
||||
- global
|
||||
@@ -630,6 +576,38 @@ components:
|
||||
$ref: '#/components/schemas/Global'
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/Circuit'
|
||||
RawMessage:
|
||||
type: object
|
||||
description: raw message seen on the bus.
|
||||
properties:
|
||||
master:
|
||||
$ref: '#/components/schemas/Symbols'
|
||||
description: the last seen master data bytes (only with raw and if available).
|
||||
slave:
|
||||
$ref: '#/components/schemas/Symbols'
|
||||
description: the last seen slave data bytes (only with raw and if available).
|
||||
lastup:
|
||||
minimum: 0
|
||||
type: integer
|
||||
description: the time in UTC seconds of the last update of the message (0
|
||||
for never).
|
||||
count:
|
||||
type: number
|
||||
description: number of times the master part was seen.
|
||||
circuit:
|
||||
type: string
|
||||
description: name of the circuit in case of an already associated message definition.
|
||||
name:
|
||||
type: string
|
||||
description: name of the message in case of an already associated message definition.
|
||||
required:
|
||||
- master
|
||||
- count
|
||||
RawMessages:
|
||||
type: array
|
||||
description: raw messages seen on the bus.
|
||||
items:
|
||||
$ref: '#/components/schemas/RawMessage'
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Invalid request parameters.
|
||||
@@ -676,72 +654,80 @@ components:
|
||||
name: exact
|
||||
in: query
|
||||
description: exact search for circuit/message name.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
verboseQuery:
|
||||
name: verbose
|
||||
in: query
|
||||
description: include comments and field units.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
indexedQuery:
|
||||
name: indexed
|
||||
in: query
|
||||
description: always return field indexes instead of names.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
numericQuery:
|
||||
name: numeric
|
||||
in: query
|
||||
description: return numeric values of value list entries.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
valuenameQuery:
|
||||
name: valuename
|
||||
in: query
|
||||
description: include value and name for named values.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
fullQuery:
|
||||
name: full
|
||||
in: query
|
||||
description: include all available attributes.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
requiredQuery:
|
||||
name: required
|
||||
in: query
|
||||
description: retrieve the data from the bus if not yet cached.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
writeQuery:
|
||||
name: write
|
||||
in: query
|
||||
description: retrieve write messages in addition to read/poll messages.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
rawQuery:
|
||||
name: raw
|
||||
in: query
|
||||
description: include raw master/slave data.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
defQuery:
|
||||
name: def
|
||||
in: query
|
||||
description: include message and field definition.
|
||||
allowEmptyValue: false
|
||||
allowEmptyValue: true
|
||||
schema:
|
||||
type: boolean
|
||||
defineQuery:
|
||||
name: define
|
||||
in: query
|
||||
description: update/replace a message definition.
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
description: message definition in CSV format.
|
||||
userQuery:
|
||||
name: user
|
||||
in: query
|
||||
@@ -756,4 +742,3 @@ components:
|
||||
allowEmptyValue: false
|
||||
schema:
|
||||
type: string
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@ echo "ebusd=${version},${revision}" > versions.txt
|
||||
echo "ebusd=${version},${revision}" > oldversions.txt
|
||||
files=`find config/ -type f -or -type l`
|
||||
../../src/lib/ebus/test/test_filereader $files|sed -e 's#^config/##' -e 's#^\([^ ]*\) #\1=#' -e 's# #,#g'|sort >> versions.txt
|
||||
./oldtest_filereader $files|sed -e 's#^config/##' -e 's#^\([^ ]*\) #\1=#' -e 's# #,#g'|sort >> oldversions.txt
|
||||
#./oldtest_filereader $files|sed -e 's#^config/##' -e 's#^\([^ ]*\) #\1=#' -e 's# #,#g'|sort >> oldversions.txt
|
||||
|
||||
+17
-15
@@ -15,8 +15,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pwd
|
||||
ls -la
|
||||
keepbuilddir=
|
||||
if [ "x$1" = "x--keepbuilddir" ]; then
|
||||
keepbuilddir=1
|
||||
@@ -80,16 +78,21 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "*************"
|
||||
echo " test"
|
||||
echo "*************"
|
||||
echo
|
||||
testdie() {
|
||||
echo "test failed"
|
||||
exit 1
|
||||
}
|
||||
(cd src/lib/ebus/test && make test_data >/dev/null && ./test_data) || testdie
|
||||
if [ -n "$RUNTEST" ]; then
|
||||
echo
|
||||
echo "*************"
|
||||
echo " test"
|
||||
echo "*************"
|
||||
echo
|
||||
testdie() {
|
||||
echo "test failed"
|
||||
exit 1
|
||||
}
|
||||
($RELEASE/usr/bin/ebusd -f -c src/lib/ebus/test -d /dev/null --checkconfig -i 10fe0900040000803e/ | egrep "received update-read broadcast test QQ=10: 0\.25$") || testdie
|
||||
if [ "$RUNTEST" == "full" ]; then
|
||||
(cd src/lib/ebus/test && make >/dev/null && ./test_filereader && ./test_data && ./test_message && ./test_symbol) || testdie
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "*************"
|
||||
@@ -97,7 +100,6 @@ echo " pack"
|
||||
echo "*************"
|
||||
echo
|
||||
mkdir -p $RELEASE/DEBIAN $RELEASE/etc/default $RELEASE/etc/logrotate.d || exit 1
|
||||
rm $RELEASE/usr/bin/ebusfeed
|
||||
mkdir -p $RELEASE/lib/systemd/system || exit 1
|
||||
cp contrib/debian/systemd/ebusd.service $RELEASE/lib/systemd/system/ebusd.service || exit 1
|
||||
mkdir -p $RELEASE/etc/init.d || exit 1
|
||||
@@ -114,13 +116,13 @@ Architecture: $ARCH
|
||||
Maintainer: John Baier <ebusd@ebusd.eu>
|
||||
Homepage: https://github.com/john30/ebusd
|
||||
Bugs: https://github.com/john30/ebusd/issues
|
||||
Depends: logrotate, libstdc++6 (>= 4.8.1), libc6, libgcc1$extralibs
|
||||
Depends: libstdc++6 (>= 4.8.1), libc6, libgcc1$extralibs
|
||||
Recommends: logrotate
|
||||
Description: eBUS daemon.
|
||||
ebusd is a daemon for handling communication with eBUS devices connected to a
|
||||
2-wire bus system.
|
||||
EOF
|
||||
cat <<EOF > $RELEASE/DEBIAN/dirs
|
||||
/etc/ebusd
|
||||
/etc/default
|
||||
/etc/init.d
|
||||
/etc/logrotate.d
|
||||
|
||||
+78
-47
@@ -253,65 +253,87 @@ bool decodeType(const DataType* type, const SymbolString& input, size_t length,
|
||||
return !first;
|
||||
}
|
||||
|
||||
bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, bool decode, ostringstream* output,
|
||||
bool isDirectMode) const {
|
||||
bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, OutputFormat outputFormat,
|
||||
ostringstream* output, bool isDirectMode) const {
|
||||
Message* message = messages->find(m_lastMaster);
|
||||
if (unknown && message) {
|
||||
return false;
|
||||
}
|
||||
if (!first) {
|
||||
*output << endl;
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ",";
|
||||
} else {
|
||||
*output << endl;
|
||||
}
|
||||
}
|
||||
symbol_t dstAddress = m_lastMaster[1];
|
||||
*output << m_lastMaster.getStr();
|
||||
if (dstAddress != BROADCAST && !isMaster(dstAddress)) {
|
||||
*output << (isDirectMode ? " " : " / ") << m_lastSlave.getStr();
|
||||
}
|
||||
if (!isDirectMode) {
|
||||
*output << " = " << m_count;
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << "\n{";
|
||||
if (m_lastMaster.dumpJson(false, output)) {
|
||||
*output << ", ";
|
||||
if (dstAddress != BROADCAST && !isMaster(dstAddress) && m_lastSlave.dumpJson(false, output)) {
|
||||
*output << ", ";
|
||||
}
|
||||
}
|
||||
*output << "\"count\": " << static_cast<unsigned>(m_count);
|
||||
*output << ", \"lastup\": " << setw(0) << dec << m_lastTime;
|
||||
if (message) {
|
||||
*output << ": " << message->getCircuit() << " " << message->getName();
|
||||
*output << ", \"circuit\": \"" << message->getCircuit() << "\""
|
||||
<< ", \"name\": \"" << message->getName() << "\"";
|
||||
}
|
||||
*output << "}";
|
||||
} else {
|
||||
*output << m_lastMaster.getStr();
|
||||
if (dstAddress != BROADCAST && !isMaster(dstAddress)) {
|
||||
*output << (isDirectMode ? " " : " / ") << m_lastSlave.getStr();
|
||||
}
|
||||
if (!isDirectMode) {
|
||||
*output << " = " << m_count;
|
||||
if (message) {
|
||||
*output << ": " << message->getCircuit() << " " << message->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decode) {
|
||||
DataTypeList *types = DataTypeList::getInstance();
|
||||
if (!types) {
|
||||
return true;
|
||||
if (!(outputFormat & OF_DEFINITION) || (outputFormat & OF_JSON)) {
|
||||
return true;
|
||||
}
|
||||
DataTypeList *types = DataTypeList::getInstance();
|
||||
if (!types) {
|
||||
return true;
|
||||
}
|
||||
bool master = isMaster(dstAddress) || dstAddress == BROADCAST || m_lastSlave.getDataSize() <= 0;
|
||||
size_t remain = master ? m_lastMaster.getDataSize() : m_lastSlave.getDataSize();
|
||||
if (remain == 0) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& it : *types) {
|
||||
const DataType* baseType = it.second;
|
||||
if ((baseType->getBitCount() % 8) != 0 || baseType->isIgnored() || baseType->hasFlag(DUP)) { // skip bit and ignored types
|
||||
continue;
|
||||
}
|
||||
bool master = isMaster(dstAddress) || dstAddress == BROADCAST || m_lastSlave.getDataSize() <= 0;
|
||||
size_t remain = master ? m_lastMaster.getDataSize() : m_lastSlave.getDataSize();
|
||||
if (remain == 0) {
|
||||
return true;
|
||||
size_t maxLength = baseType->getBitCount()/8;
|
||||
bool firstOnly = maxLength >= 8;
|
||||
if (maxLength > remain) {
|
||||
maxLength = remain;
|
||||
}
|
||||
for (const auto& it : *types) {
|
||||
const DataType* baseType = it.second;
|
||||
if ((baseType->getBitCount() % 8) != 0 || baseType->isIgnored()) { // skip bit and ignored types
|
||||
continue;
|
||||
}
|
||||
size_t maxLength = baseType->getBitCount()/8;
|
||||
bool firstOnly = maxLength >= 8;
|
||||
if (maxLength > remain) {
|
||||
maxLength = remain;
|
||||
}
|
||||
if (baseType->isAdjustableLength()) {
|
||||
for (size_t length = maxLength; length >= 1; length--) {
|
||||
const DataType* type = types->get(baseType->getId(), length);
|
||||
bool decoded;
|
||||
if (master) {
|
||||
decoded = decodeType(type, m_lastMaster, length, remain-length, firstOnly, output);
|
||||
} else {
|
||||
decoded = decodeType(type, m_lastSlave, length, remain-length, firstOnly, output);
|
||||
}
|
||||
if (decoded && firstOnly) {
|
||||
break; // only a single offset with maximum length when adjustable maximum size is at least 8 bytes
|
||||
}
|
||||
}
|
||||
} else if (maxLength > 0) {
|
||||
if (baseType->isAdjustableLength()) {
|
||||
for (size_t length = maxLength; length >= 1; length--) {
|
||||
const DataType* type = types->get(baseType->getId(), length);
|
||||
bool decoded;
|
||||
if (master) {
|
||||
decodeType(baseType, m_lastMaster, maxLength, remain-maxLength, false, output);
|
||||
decoded = decodeType(type, m_lastMaster, length, remain-length, firstOnly, output);
|
||||
} else {
|
||||
decodeType(baseType, m_lastSlave, maxLength, remain-maxLength, false, output);
|
||||
decoded = decodeType(type, m_lastSlave, length, remain-length, firstOnly, output);
|
||||
}
|
||||
if (decoded && firstOnly) {
|
||||
break; // only a single offset with maximum length when adjustable maximum size is at least 8 bytes
|
||||
}
|
||||
}
|
||||
} else if (maxLength > 0) {
|
||||
if (master) {
|
||||
decodeType(baseType, m_lastMaster, maxLength, remain-maxLength, false, output);
|
||||
} else {
|
||||
decodeType(baseType, m_lastSlave, maxLength, remain-maxLength, false, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,6 +447,14 @@ void BusHandler::run() {
|
||||
} while (isRunning());
|
||||
}
|
||||
|
||||
#ifndef FALLTHROUGH
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#define FALLTHROUGH [[fallthrough]];
|
||||
#else
|
||||
#define FALLTHROUGH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
result_t BusHandler::handleSymbol() {
|
||||
unsigned int timeout = SYN_TIMEOUT;
|
||||
symbol_t sendSymbol = ESC;
|
||||
@@ -438,6 +468,7 @@ result_t BusHandler::handleSymbol() {
|
||||
|
||||
case bs_skip:
|
||||
timeout = SYN_TIMEOUT;
|
||||
FALLTHROUGH
|
||||
case bs_ready:
|
||||
if (m_currentRequest != nullptr) {
|
||||
setState(bs_ready, RESULT_ERR_TIMEOUT); // just to be sure an old BusRequest is cleaned up
|
||||
@@ -1601,10 +1632,10 @@ bool BusHandler::enableGrab(bool enable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void BusHandler::formatGrabResult(bool unknown, bool decode, ostringstream* output, bool isDirectMode,
|
||||
void BusHandler::formatGrabResult(bool unknown, OutputFormat outputFormat, ostringstream* output, bool isDirectMode,
|
||||
time_t since, time_t until) const {
|
||||
if (!m_grabMessages) {
|
||||
if (!isDirectMode) {
|
||||
if (!isDirectMode && !(outputFormat & OF_JSON)) {
|
||||
*output << "grab disabled";
|
||||
}
|
||||
return;
|
||||
@@ -1615,7 +1646,7 @@ void BusHandler::formatGrabResult(bool unknown, bool decode, ostringstream* outp
|
||||
|| (until > 0 && it.second.getLastTime() >= until)) {
|
||||
continue;
|
||||
}
|
||||
if (it.second.dump(unknown, m_messages, first, decode, output, isDirectMode)) {
|
||||
if (it.second.dump(unknown, m_messages, first, outputFormat, output, isDirectMode)) {
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,12 +334,12 @@ class GrabbedMessage {
|
||||
* @param unknown whether to dump only if this message is unknown.
|
||||
* @param messages the @a MessageMap instance for resolving known @a Message instances.
|
||||
* @param first whether this is the first message to be added to the output.
|
||||
* @param decode whether to add decoding hints.
|
||||
* @param outputFormat the @a OutputFormat options to use.
|
||||
* @param output the @a ostringstream to format the messages to.
|
||||
* @param isDirectMode true for direct mode, false for grab command.
|
||||
* @return whether the message was added to the output.
|
||||
*/
|
||||
bool dump(bool unknown, MessageMap* messages, bool first, bool decode, ostringstream* output,
|
||||
bool dump(bool unknown, MessageMap* messages, bool first, OutputFormat outputFormat, ostringstream* output,
|
||||
bool isDirectMode = false) const;
|
||||
|
||||
|
||||
@@ -538,13 +538,13 @@ class BusHandler : public WaitThread {
|
||||
/**
|
||||
* Format the grabbed messages to the @a ostringstream.
|
||||
* @param unknown whether to dump only unknown messages.
|
||||
* @param decode whether to add decoding hints.
|
||||
* @param outputFormat the @a OutputFormat options to use.
|
||||
* @param output the @a ostringstream to format the messages to.
|
||||
* @param isDirectMode true for direct mode, false for grab command.
|
||||
* @param since the start time from which to add received messages (inclusive), or 0 for all.
|
||||
* @param until the end time to which to add received messages (exclusive), or 0 for all.
|
||||
*/
|
||||
void formatGrabResult(bool unknown, bool decode, ostringstream* output, bool isDirectMode = false,
|
||||
void formatGrabResult(bool unknown, OutputFormat outputFormat, ostringstream* output, bool isDirectMode = false,
|
||||
time_t since = 0, time_t until = 0) const;
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1388,10 +1388,10 @@ int main(int argc, char* argv[]) {
|
||||
s_mainLoop = new MainLoop(opt, device, s_messageMap);
|
||||
if (opt.injectMessages) {
|
||||
BusHandler* busHandler = s_mainLoop->getBusHandler();
|
||||
MasterSymbolString master;
|
||||
SlaveSymbolString slave;
|
||||
while (arg_index < argc) {
|
||||
// add each passed message
|
||||
MasterSymbolString master;
|
||||
SlaveSymbolString slave;
|
||||
if (!parseMessage(argv[arg_index++], false, &master, &slave)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+148
-20
@@ -434,14 +434,14 @@ void MainLoop::run() {
|
||||
}
|
||||
if (settings.listenWithUnknown || settings.listenOnlyUnknown) {
|
||||
if (m_busHandler->isGrabEnabled()) {
|
||||
m_busHandler->formatGrabResult(true, false, &ostream, true, since, now);
|
||||
m_busHandler->formatGrabResult(true, OF_NONE, &ostream, true, since, now);
|
||||
} else {
|
||||
m_busHandler->enableGrab(true); // needed for listening to all messages
|
||||
}
|
||||
}
|
||||
} else if (settings.mode == cm_direct) {
|
||||
if (m_busHandler->isGrabEnabled()) {
|
||||
m_busHandler->formatGrabResult(false, false, &ostream, true, since, now);
|
||||
m_busHandler->formatGrabResult(false, OF_NONE, &ostream, true, since, now);
|
||||
}
|
||||
}
|
||||
// send result to client
|
||||
@@ -607,7 +607,7 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
|
||||
if (cmd == "G" || cmd == "GRAB") {
|
||||
return executeGrab(args, ostream);
|
||||
}
|
||||
if (cmd == "DEFINE") {
|
||||
if (cmd == "DEF" || cmd == "DEFINE") {
|
||||
if (m_newlyDefinedMessages) {
|
||||
return executeDefine(args, ostream);
|
||||
}
|
||||
@@ -921,8 +921,6 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
||||
Message* message;
|
||||
result_t ret;
|
||||
if (newDefinition) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
string errorDescription;
|
||||
istringstream defstr("#\n" + args[argPos]); // ensure first line is not used for determining col names
|
||||
m_newlyDefinedMessages->clear();
|
||||
@@ -1256,7 +1254,7 @@ result_t MainLoop::parseHexAndSend(const vector<string>& args, size_t& argPos, b
|
||||
result_t MainLoop::executeHex(const vector<string>& args, ostringstream* ostream) {
|
||||
size_t argPos = 1;
|
||||
result_t ret = parseHexAndSend(args, argPos, false, ostream);
|
||||
if (argPos == args.size()) {
|
||||
if (argPos != 0 && argPos == args.size()) {
|
||||
return ret;
|
||||
}
|
||||
*ostream << "usage: hex [-s QQ] ZZPBSBNN[DD]*\n"
|
||||
@@ -1641,7 +1639,7 @@ result_t MainLoop::executeGrab(const vector<string>& args, ostringstream* ostrea
|
||||
}
|
||||
}
|
||||
if (!invalid) {
|
||||
m_busHandler->formatGrabResult(onlyUnknown, decode, ostream);
|
||||
m_busHandler->formatGrabResult(onlyUnknown, decode ? OF_DEFINITION : OF_NONE, ostream);
|
||||
return RESULT_OK;
|
||||
}
|
||||
}
|
||||
@@ -1677,7 +1675,7 @@ result_t MainLoop::executeDefine(const vector<string>& args, ostringstream* ostr
|
||||
time(&now);
|
||||
string errorDescription;
|
||||
istringstream defstr("#\n" + args[argPos]); // ensure first line is not used for determining col names
|
||||
return m_messages->readFromStream(&defstr, "temporary", now, true, nullptr, &errorDescription, replace);
|
||||
return m_messages->readFromStream(&defstr, "tcp", now, true, nullptr, &errorDescription, replace);
|
||||
}
|
||||
|
||||
|
||||
@@ -1902,19 +1900,30 @@ result_t MainLoop::executeReload(const vector<string>& args, ostringstream* ostr
|
||||
}
|
||||
|
||||
result_t MainLoop::executeInfo(const vector<string>& args, const string& user, ostringstream* ostream) {
|
||||
if (args.size() == 0) {
|
||||
*ostream << "usage: info\n"
|
||||
" Report information about the daemon, the configuration, and seen devices.";
|
||||
bool verbose = args.size() == 2 && args[1] == "verbose";
|
||||
if (args.size() != 1 && !verbose) {
|
||||
*ostream << "usage: info [verbose]\n"
|
||||
" Report information about the daemon, configuration, seen participants, and the device.";
|
||||
return RESULT_OK;
|
||||
}
|
||||
*ostream << "version: " << PACKAGE_STRING "." REVISION "\n";
|
||||
if (!m_updateCheck.empty()) {
|
||||
*ostream << "update check: " << m_updateCheck << "\n";
|
||||
}
|
||||
string info = m_device->getEnhancedInfos();
|
||||
if (!info.empty()) {
|
||||
*ostream << "device: " << info << "\n";
|
||||
*ostream << "device: " << m_device->getName();
|
||||
if (m_device->isEnhancedProto()) {
|
||||
*ostream << ", enhanced";
|
||||
}
|
||||
if (m_device->isReadOnly()) {
|
||||
*ostream << ", readonly";
|
||||
}
|
||||
if (verbose) {
|
||||
string info = m_device->getEnhancedInfos();
|
||||
if (!info.empty()) {
|
||||
*ostream << ", " << info;
|
||||
}
|
||||
}
|
||||
*ostream << "\n";
|
||||
if (!user.empty()) {
|
||||
*ostream << "user: " << user << "\n";
|
||||
}
|
||||
@@ -1962,8 +1971,8 @@ result_t MainLoop::executeHelp(ostringstream* ostream) {
|
||||
*ostream << "usage:\n"
|
||||
" read|r Read value(s): read [-f] [-m SECONDS] [-s QQ] [-d ZZ] [-c CIRCUIT] [-p PRIO] [-v|-V] [-n|-N]"
|
||||
" [-i VALUE[;VALUE]*] NAME [FIELD[.N]]\n"
|
||||
" Read by new defintion: read [-f] [-m SECONDS] [-s QQ] [-d ZZ] [-v|-V] [-n|-N] (if enabled)"
|
||||
" [-i VALUE[;VALUE]*] -def DEFINITION\n"
|
||||
" Read by new defintion: read [-f] [-m SECONDS] [-s QQ] [-d ZZ] [-v|-V] [-n|-N]"
|
||||
" [-i VALUE[;VALUE]*] -def DEFINITION (if enabled)\n"
|
||||
" Read hex message: read [-f] [-m SECONDS] [-s QQ] [-c CIRCUIT] -h ZZPBSBNN[DD]*\n"
|
||||
" write|w Write value(s): write [-s QQ] [-d ZZ] -c CIRCUIT NAME [VALUE[;VALUE]*]\n"
|
||||
" Write by new def.: write [-s QQ] [-d ZZ] -def DEFINITION [VALUE[;VALUE]*] (if enabled)\n"
|
||||
@@ -1975,7 +1984,7 @@ result_t MainLoop::executeHelp(ostringstream* ostream) {
|
||||
" listen|l Listen for updates: listen [-v|-V] [-n|-N] [-u|-U] [stop]\n"
|
||||
" direct Enter direct mode\n"
|
||||
" state|s Report bus state\n"
|
||||
" info|i Report information about the daemon, the configuration, and seen devices.\n"
|
||||
" info|i Report information about the daemon, configuration, seen participants, and the device.\n"
|
||||
" grab|g Grab messages: grab [stop]\n"
|
||||
" Report the messages: grab result [all]\n"
|
||||
" define Define new message: define [-r] DEFINITION\n"
|
||||
@@ -2002,9 +2011,6 @@ bool parseBoolQuery(const string& value) {
|
||||
}
|
||||
|
||||
result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostringstream* ostream) {
|
||||
bool required = false, full = false, withWrite = false, raw = false;
|
||||
bool withDefinition = false;
|
||||
OutputFormat verbosity = OF_NAMES;
|
||||
time_t maxAge = -1;
|
||||
size_t argPos = 1;
|
||||
string uri = args[argPos++];
|
||||
@@ -2019,6 +2025,10 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
circuit = uri.substr(6, pos - 6);
|
||||
name = uri.substr(pos + 1);
|
||||
}
|
||||
bool required = false, full = false, withWrite = false, raw = false;
|
||||
bool withDefinition = false;
|
||||
string newDefinition;
|
||||
OutputFormat verbosity = OF_NAMES;
|
||||
time_t since = 0;
|
||||
size_t pollPriority = 0;
|
||||
bool exact = false;
|
||||
@@ -2072,6 +2082,18 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
raw = parseBoolQuery(value);
|
||||
} else if (qname == "def") {
|
||||
withDefinition = parseBoolQuery(value);
|
||||
} else if (qname == "define") {
|
||||
if (!m_newlyDefinedMessages || circuit.empty() || name.empty() || value.empty()) {
|
||||
ret = RESULT_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
size_t comma = value.find(',');
|
||||
if (comma == string::npos || comma == 0
|
||||
|| value.find(circuit+","+name+",") != comma+1) { // ensure same circuit+name
|
||||
ret = RESULT_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
newDefinition = value;
|
||||
} else if (qname == "user") {
|
||||
user = value;
|
||||
} else if (qname == "secret") {
|
||||
@@ -2091,6 +2113,11 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
time_t now;
|
||||
time(&now);
|
||||
time_t maxLastUp = 0;
|
||||
if (ret == RESULT_OK && !newDefinition.empty()) {
|
||||
string errorDescription;
|
||||
istringstream defstr("#\n" + newDefinition); // ensure first line is not used for determining col names
|
||||
ret = m_messages->readFromStream(&defstr, "http", now, true, nullptr, &errorDescription, true);
|
||||
}
|
||||
if (ret == RESULT_OK) {
|
||||
bool first = true;
|
||||
verbosity |= OF_JSON | (full ? OF_ALL_ATTRS : OF_NONE) | (withDefinition ? OF_DEFINITION : OF_NONE);
|
||||
@@ -2192,6 +2219,107 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
return formatHttpResult(ret, type, ostream);
|
||||
} // request for "/data..."
|
||||
|
||||
if (uri == "/datatypes") {
|
||||
*ostream << "[";
|
||||
OutputFormat verbosity = OF_NAMES|OF_JSON|OF_ALL_ATTRS;
|
||||
DataTypeList::getInstance()->dump(verbosity, true, ostream);
|
||||
*ostream << "\n]";
|
||||
type = 6;
|
||||
*connected = false;
|
||||
return formatHttpResult(ret, type, ostream);
|
||||
}
|
||||
|
||||
if (uri == "/raw") {
|
||||
time_t since = 0, until = 0;
|
||||
bool onlyUnknown = false;
|
||||
if (args.size() > argPos) {
|
||||
string query = args[argPos];
|
||||
istringstream stream(query);
|
||||
string token;
|
||||
while (getline(stream, token, '&')) {
|
||||
size_t pos = token.find('=');
|
||||
string qname, value;
|
||||
if (pos != string::npos) {
|
||||
qname = token.substr(0, pos);
|
||||
value = token.substr(pos + 1);
|
||||
} else {
|
||||
qname = token;
|
||||
}
|
||||
if (qname == "since") {
|
||||
since = parseInt(value.c_str(), 10, 0, 0xffffffff, &ret);
|
||||
} else if (qname == "unknown") {
|
||||
onlyUnknown = parseBoolQuery(value);
|
||||
}
|
||||
if (ret != RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == RESULT_OK) {
|
||||
*ostream << "[";
|
||||
if (since > 0) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
until = now-1;
|
||||
}
|
||||
m_busHandler->formatGrabResult(onlyUnknown, OF_JSON, ostream, false, since, until);
|
||||
*ostream << "\n]";
|
||||
type = 6;
|
||||
}
|
||||
*connected = false;
|
||||
return formatHttpResult(ret, type, ostream);
|
||||
}
|
||||
|
||||
if (uri == "/decode") {
|
||||
string def;
|
||||
string raw;
|
||||
if (args.size() > argPos) {
|
||||
string query = args[argPos];
|
||||
istringstream stream(query);
|
||||
string token;
|
||||
while (getline(stream, token, '&')) {
|
||||
size_t pos = token.find('=');
|
||||
string qname, value;
|
||||
if (pos != string::npos) {
|
||||
qname = token.substr(0, pos);
|
||||
value = token.substr(pos + 1);
|
||||
} else {
|
||||
qname = token;
|
||||
}
|
||||
if (qname == "def") {
|
||||
def = value;
|
||||
} else if (qname == "raw") {
|
||||
raw = value;
|
||||
}
|
||||
if (ret != RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == RESULT_OK) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
istringstream defstr("#\n" + def); // ensure first line is not used for determining col names
|
||||
string errorDescription;
|
||||
DataFieldTemplates* templates = getTemplates("*");
|
||||
LoadableDataFieldSet fields("", templates);
|
||||
ret = fields.readFromStream(&defstr, "temporary", now, true, nullptr, &errorDescription);
|
||||
if (ret == RESULT_OK) {
|
||||
const SingleDataField* field = fields[0];
|
||||
SlaveSymbolString slave;
|
||||
slave.push_back(0); // dummy length
|
||||
ret = slave.parseHex(raw);
|
||||
if (ret == RESULT_OK) {
|
||||
slave.adjustHeader();
|
||||
ret = field->read(slave, 0, false, nullptr, 0, OF_JSON|OF_SHORT, 0, ostream);
|
||||
}
|
||||
}
|
||||
type = 6;
|
||||
}
|
||||
*connected = false;
|
||||
return formatHttpResult(ret, type, ostream);
|
||||
}
|
||||
|
||||
if (uri.length() < 1 || uri[0] != '/' || uri.find("//") != string::npos || uri.find("..") != string::npos) {
|
||||
ret = RESULT_ERR_INVALID_ARG;
|
||||
} else {
|
||||
|
||||
@@ -46,6 +46,7 @@ using std::dec;
|
||||
#define O_KEYF (O_CERT+1)
|
||||
#define O_KEPA (O_KEYF+1)
|
||||
#define O_INSE (O_KEPA+1)
|
||||
#define O_VERB (O_INSE+1)
|
||||
|
||||
/** the definition of the MQTT arguments. */
|
||||
static const struct argp_option g_mqtt_argp_options[] = {
|
||||
@@ -60,6 +61,7 @@ static const struct argp_option g_mqtt_argp_options[] = {
|
||||
"Use MQTT TOPIC (prefix before /%circuit/%name or complete format) [ebusd]", 0 },
|
||||
{"mqttretain", O_RETA, nullptr, 0, "Retain all topics instead of only selected global ones", 0 },
|
||||
{"mqttjson", O_JSON, nullptr, 0, "Publish in JSON format instead of strings", 0 },
|
||||
{"mqttverbose", O_VERB, nullptr, 0, "Publish all available attributes", 0 },
|
||||
#if (LIBMOSQUITTO_VERSION_NUMBER >= 1003001)
|
||||
{"mqttlog", O_LOGL, nullptr, 0, "Log library events", 0 },
|
||||
#endif
|
||||
@@ -75,7 +77,7 @@ static const struct argp_option g_mqtt_argp_options[] = {
|
||||
{"mqttcert", O_CERT, "CERTFILE", 0, "Use CERTFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkey", O_KEYF, "KEYFILE", 0, "Use KEYFILE for MQTT TLS client certificate (no default)", 0 },
|
||||
{"mqttkeypass", O_KEPA, "PASSWORD", 0, "Use PASSWORD for the encrypted KEYFILE (no default)", 0 },
|
||||
{"mqttinsecure", O_INSE, nullptr, 0, "Allow insecure TLS connection (e.g. using a self signed certificate)", 0 },
|
||||
{"mqttinsecure", O_INSE, nullptr, 0, "Allow insecure TLS connection (e.g. using a self signed certificate)", 0 },
|
||||
#endif
|
||||
|
||||
{nullptr, 0, nullptr, 0, nullptr, 0 },
|
||||
@@ -189,6 +191,10 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
|
||||
g_publishFormat |= OF_JSON|OF_NAMES;
|
||||
break;
|
||||
|
||||
case O_VERB: // --mqttverbose
|
||||
g_publishFormat |= OF_NAMES|OF_UNITS|OF_COMMENTS|OF_ALL_ATTRS;
|
||||
break;
|
||||
|
||||
#if (LIBMOSQUITTO_VERSION_NUMBER >= 1003001)
|
||||
case O_LOGL:
|
||||
g_logFromLib = true;
|
||||
@@ -909,7 +915,7 @@ void MqttHandler::publishMessage(const Message* message, ostringstream* updates,
|
||||
publishTopic(getTopic(message), updates->str());
|
||||
return;
|
||||
}
|
||||
if (json) {
|
||||
if (json && !(outputFormat & OF_ALL_ATTRS)) {
|
||||
outputFormat |= OF_SHORT;
|
||||
}
|
||||
for (size_t index = 0; index < message->getFieldCount(); index++) {
|
||||
|
||||
+76
-31
@@ -45,7 +45,12 @@ using std::endl;
|
||||
bool DataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << "\"type\": \"" << m_id << "\", \"isbits\": "
|
||||
<< (getBitCount() < 8 ? "true" : "false") << ", \"length\": ";
|
||||
<< (getBitCount() < 8 ? "true" : "false");
|
||||
if (outputFormat & OF_ALL_ATTRS) {
|
||||
*output << ", \"isadjustable\": " << (isAdjustableLength() ? "true" : "false");
|
||||
*output << ", \"isignored\": " << (isIgnored() ? "true" : "false");
|
||||
}
|
||||
*output << ", \"length\": ";
|
||||
if (isAdjustableLength() && length == REMAIN_LEN) {
|
||||
*output << "-1";
|
||||
} else {
|
||||
@@ -54,10 +59,11 @@ bool DataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor
|
||||
} else {
|
||||
*output << m_id;
|
||||
if (isAdjustableLength()) {
|
||||
*output << LENGTH_SEPARATOR;
|
||||
if (length == REMAIN_LEN) {
|
||||
*output << ":*";
|
||||
*output << "*";
|
||||
} else {
|
||||
*output << ":" << static_cast<unsigned>(length);
|
||||
*output << static_cast<unsigned>(length);
|
||||
}
|
||||
}
|
||||
if (appendDivisor) {
|
||||
@@ -68,6 +74,14 @@ bool DataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor
|
||||
}
|
||||
|
||||
|
||||
bool StringDataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const {
|
||||
DataType::dump(outputFormat, length, appendDivisor, output);
|
||||
if ((outputFormat & OF_JSON) && (outputFormat & OF_ALL_ATTRS)) {
|
||||
*output << ", \"result\": \"" << (isIgnored() ? "void" : "string") << "\"";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
result_t StringDataType::readRawValue(size_t, size_t, const SymbolString&, unsigned int*) const {
|
||||
return RESULT_EMPTY;
|
||||
}
|
||||
@@ -203,6 +217,14 @@ result_t StringDataType::writeSymbols(size_t offset, size_t length, istringstrea
|
||||
}
|
||||
|
||||
|
||||
bool DateTimeDataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const {
|
||||
DataType::dump(outputFormat, length, appendDivisor, output);
|
||||
if ((outputFormat & OF_JSON) && (outputFormat & OF_ALL_ATTRS)) {
|
||||
*output << ", \"result\": \"" << (hasDate() ? hasTime() ? "datetime" : "date" : "time") << "\"";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
result_t DateTimeDataType::readRawValue(size_t, size_t, const SymbolString&, unsigned int*) const {
|
||||
return RESULT_EMPTY;
|
||||
}
|
||||
@@ -572,25 +594,32 @@ bool NumberDataType::dump(OutputFormat outputFormat, size_t length, bool appendD
|
||||
} else {
|
||||
DataType::dump(outputFormat, length, appendDivisor, output);
|
||||
}
|
||||
if ((outputFormat & OF_JSON) && (outputFormat & OF_ALL_ATTRS)) {
|
||||
*output << ", \"result\": \"number\"";
|
||||
}
|
||||
if (!appendDivisor) {
|
||||
return false;
|
||||
}
|
||||
bool ret = false;
|
||||
if (m_baseType) {
|
||||
if (m_baseType->m_divisor != m_divisor) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"divisor\": ";
|
||||
}
|
||||
*output << (m_divisor / m_baseType->m_divisor);
|
||||
return true;
|
||||
ret = true;
|
||||
}
|
||||
} else if (m_divisor != 1) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"divisor\": ";
|
||||
}
|
||||
*output << m_divisor;
|
||||
return true;
|
||||
ret = true;
|
||||
}
|
||||
return false;
|
||||
if (ret && (outputFormat & OF_JSON) && (outputFormat & OF_ALL_ATTRS)) {
|
||||
*output << ", \"precision\": " << static_cast<unsigned>(getPrecision());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
result_t NumberDataType::derive(int divisor, size_t bitCount, const NumberDataType** derived) const {
|
||||
@@ -985,16 +1014,18 @@ DataTypeList::DataTypeList() {
|
||||
// date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99,
|
||||
// WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff)
|
||||
add(new DateTimeDataType("BDA", 32, BCD, 0xff, true, false, 0));
|
||||
add(new DateTimeDataType("BDA:4", 32, BCD|DUP, 0xff, true, false, 0));
|
||||
// date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99, replacement 0xff)
|
||||
add(new DateTimeDataType("BDA", 24, BCD, 0xff, true, false, 0));
|
||||
add(new DateTimeDataType("BDA:3", 24, BCD, 0xff, true, false, 0));
|
||||
// date with zero-based weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WZ,0x00 - 0x31,0x12,WZ,0x99,
|
||||
// WZ is zero-based weekday Mon=0x00 - Sun=0x06, replacement 0xff)
|
||||
add(new DateTimeDataType("BDZ", 32, BCD|SPE, 0xff, true, false, 0));
|
||||
// date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63,
|
||||
// WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff)
|
||||
add(new DateTimeDataType("HDA", 32, 0, 0xff, true, false, 0));
|
||||
add(new DateTimeDataType("HDA:4", 32, DUP, 0xff, true, false, 0));
|
||||
// date, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x1f,0x0c,0x63, replacement 0xff)
|
||||
add(new DateTimeDataType("HDA", 24, 0, 0xff, true, false, 0));
|
||||
add(new DateTimeDataType("HDA:3", 24, 0, 0xff, true, false, 0));
|
||||
// date, days since 01.01.1900, 01.01.1900 - 06.06.2079 (0x00,0x00 - 0xff,0xff)
|
||||
add(new DateTimeDataType("DAY", 16, 0, 0xff, true, false, 0));
|
||||
// date+time in minutes since 01.01.2009, 01.01.2009 - 31.12.2099 (0x00,0x00,0x00,0x00 - 0x02,0xda,0x4e,0x1f)
|
||||
@@ -1022,13 +1053,15 @@ DataTypeList::DataTypeList() {
|
||||
add(new NumberDataType("BDY", 8, DAY, 0x07, 0, 6, 1)); // weekday, "Mon" - "Sun" (0x00 - 0x06) [eBUS type]
|
||||
add(new NumberDataType("HDY", 8, DAY, 0x00, 1, 7, 1)); // weekday, "Mon" - "Sun" (0x01 - 0x07) [Vaillant type]
|
||||
add(new NumberDataType("BCD", 8, BCD, 0xff, 0, 99, 1)); // unsigned decimal in BCD, 0 - 99
|
||||
add(new NumberDataType("BCD", 16, BCD, 0xffff, 0, 9999, 1)); // unsigned decimal in BCD, 0 - 9999
|
||||
add(new NumberDataType("BCD", 24, BCD, 0xffffff, 0, 999999, 1)); // unsigned decimal in BCD, 0 - 999999
|
||||
add(new NumberDataType("BCD", 32, BCD, 0xffffffff, 0, 99999999, 1)); // unsigned decimal in BCD, 0 - 99999999
|
||||
add(new NumberDataType("BCD:1", 8, BCD|DUP, 0xff, 0, 99, 1)); // unsigned decimal in BCD, 0 - 99
|
||||
add(new NumberDataType("BCD:2", 16, BCD, 0xffff, 0, 9999, 1)); // unsigned decimal in BCD, 0 - 9999
|
||||
add(new NumberDataType("BCD:3", 24, BCD, 0xffffff, 0, 999999, 1)); // unsigned decimal in BCD, 0 - 999999
|
||||
add(new NumberDataType("BCD:4", 32, BCD, 0xffffffff, 0, 99999999, 1)); // unsigned decimal in BCD, 0 - 99999999
|
||||
add(new NumberDataType("HCD", 32, HCD|BCD|REQ, 0, 0, 99999999, 1)); // unsigned decimal in HCD, 0 - 99999999
|
||||
add(new NumberDataType("HCD", 8, HCD|BCD|REQ, 0, 0, 99, 1)); // unsigned decimal in HCD, 0 - 99
|
||||
add(new NumberDataType("HCD", 16, HCD|BCD|REQ, 0, 0, 9999, 1)); // unsigned decimal in HCD, 0 - 9999
|
||||
add(new NumberDataType("HCD", 24, HCD|BCD|REQ, 0, 0, 999999, 1)); // unsigned decimal in HCD, 0 - 999999
|
||||
add(new NumberDataType("HCD:4", 32, HCD|BCD|REQ|DUP, 0, 0, 99999999, 1)); // unsigned decimal in HCD, 0 - 99999999
|
||||
add(new NumberDataType("HCD:1", 8, HCD|BCD|REQ, 0, 0, 99, 1)); // unsigned decimal in HCD, 0 - 99
|
||||
add(new NumberDataType("HCD:2", 16, HCD|BCD|REQ, 0, 0, 9999, 1)); // unsigned decimal in HCD, 0 - 9999
|
||||
add(new NumberDataType("HCD:3", 24, HCD|BCD|REQ, 0, 0, 999999, 1)); // unsigned decimal in HCD, 0 - 999999
|
||||
add(new NumberDataType("SCH", 8, SIG, 0x80, 0x81, 0x7f, 1)); // signed integer, -127 - +127
|
||||
add(new NumberDataType("D1B", 8, SIG, 0x80, 0x81, 0x7f, 1)); // signed integer, -127 - +127
|
||||
// unsigned number (fraction 1/2), 0 - 100 (0x00 - 0xc8, replacement 0xff)
|
||||
@@ -1076,36 +1109,48 @@ DataTypeList::DataTypeList() {
|
||||
add(new NumberDataType("BI4", 4, ADJ|REQ, 0, 4, 1)); // bit 4 (up to 4 bits until bit 7)
|
||||
add(new NumberDataType("BI5", 3, ADJ|REQ, 0, 5, 1)); // bit 5 (up to 3 bits until bit 7)
|
||||
add(new NumberDataType("BI6", 2, ADJ|REQ, 0, 6, 1)); // bit 6 (up to 2 bits until bit 7)
|
||||
add(new NumberDataType("BI7", 1, ADJ|REQ, 0, 7, 1)); // bit 7
|
||||
add(new NumberDataType("BI7", 1, REQ, 0, 7, 1)); // bit 7
|
||||
}
|
||||
|
||||
DataTypeList* DataTypeList::getInstance() {
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
void DataTypeList::dump(OutputFormat outputFormat, bool appendDivisor, ostream* output) const {
|
||||
bool json = outputFormat & OF_JSON;
|
||||
string sep = "\n";
|
||||
for (const auto &it: m_typesById) {
|
||||
const DataType *dataType = it.second;
|
||||
if (dataType->hasFlag(DUP)) {
|
||||
continue;
|
||||
}
|
||||
if (json) {
|
||||
*output << sep << " {";
|
||||
}
|
||||
if ((dataType->getBitCount() % 8) != 0) {
|
||||
dataType->dump(outputFormat, dataType->getBitCount(), appendDivisor, output);
|
||||
} else {
|
||||
dataType->dump(outputFormat, dataType->getBitCount() / 8, appendDivisor, output);
|
||||
}
|
||||
if (json) {
|
||||
*output << "}";
|
||||
sep = ",\n";
|
||||
} else {
|
||||
*output << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataTypeList::clear() {
|
||||
for (auto& it : m_cleanupTypes) {
|
||||
delete it;
|
||||
}
|
||||
m_cleanupTypes.clear();
|
||||
m_typesByIdLength.clear();
|
||||
m_typesById.clear();
|
||||
}
|
||||
|
||||
result_t DataTypeList::add(const DataType* dataType) {
|
||||
if (!dataType->isAdjustableLength()) {
|
||||
ostringstream str;
|
||||
size_t bitCount = dataType->getBitCount();
|
||||
str << dataType->getId() << LENGTH_SEPARATOR << static_cast<unsigned>(bitCount >= 8?bitCount/8:bitCount);
|
||||
if (m_typesByIdLength.find(str.str()) != m_typesByIdLength.end()) {
|
||||
return RESULT_ERR_DUPLICATE_NAME; // duplicate key
|
||||
}
|
||||
m_typesByIdLength[str.str()] = dataType;
|
||||
if (m_typesById.find(dataType->getId()) != m_typesById.end()) {
|
||||
m_cleanupTypes.push_back(dataType);
|
||||
return RESULT_OK; // only store first one as default
|
||||
}
|
||||
} else if (m_typesById.find(dataType->getId()) != m_typesById.end()) {
|
||||
if (m_typesById.find(dataType->getId()) != m_typesById.end()) {
|
||||
return RESULT_ERR_DUPLICATE_NAME; // duplicate key
|
||||
}
|
||||
m_typesById[dataType->getId()] = dataType;
|
||||
@@ -1117,8 +1162,8 @@ const DataType* DataTypeList::get(const string& id, size_t length) const {
|
||||
if (length > 0) {
|
||||
ostringstream str;
|
||||
str << id << LENGTH_SEPARATOR << static_cast<unsigned>(length);
|
||||
auto it = m_typesByIdLength.find(str.str());
|
||||
if (it != m_typesByIdLength.end()) {
|
||||
auto it = m_typesById.find(str.str());
|
||||
if (it != m_typesById.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-10
@@ -178,9 +178,8 @@ enum PartType {
|
||||
/** bit flag for @a DataType: special marker for certain types. */
|
||||
#define SPE 0x800
|
||||
|
||||
/** bit flag for @a DataType: marker for a constant value. */
|
||||
#define CON 0x1000
|
||||
|
||||
/** bit flag for @a DataType: stored duplicate for backwards compatibility, not to be traversed in lists any more. */
|
||||
#define DUP 0x1000
|
||||
|
||||
/**
|
||||
* Base class for all kinds of data types.
|
||||
@@ -326,6 +325,9 @@ class StringDataType : public DataType {
|
||||
*/
|
||||
virtual ~StringDataType() {}
|
||||
|
||||
// @copydoc
|
||||
bool dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const override;
|
||||
|
||||
// @copydoc
|
||||
result_t readRawValue(size_t offset, size_t length, const SymbolString& input,
|
||||
unsigned int* value) const override;
|
||||
@@ -370,6 +372,9 @@ class DateTimeDataType : public DataType {
|
||||
*/
|
||||
virtual ~DateTimeDataType() {}
|
||||
|
||||
// @copydoc
|
||||
bool dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const override;
|
||||
|
||||
/**
|
||||
* @return true if date part is present.
|
||||
*/
|
||||
@@ -429,7 +434,7 @@ class NumberDataType : public DataType {
|
||||
NumberDataType(const string& id, size_t bitCount, uint16_t flags, unsigned int replacement,
|
||||
unsigned int minValue, unsigned int maxValue, int divisor,
|
||||
const NumberDataType* baseType = nullptr)
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(minValue), m_maxValue(maxValue), m_divisor(divisor),
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(minValue), m_maxValue(maxValue), m_divisor(divisor==0 ? 1 : divisor),
|
||||
m_precision(calcPrecision(divisor)), m_firstBit(0), m_baseType(baseType) {}
|
||||
|
||||
/**
|
||||
@@ -444,7 +449,7 @@ class NumberDataType : public DataType {
|
||||
*/
|
||||
NumberDataType(const string& id, size_t bitCount, uint16_t flags, unsigned int replacement,
|
||||
int16_t firstBit, int divisor, const NumberDataType* baseType = nullptr)
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(0), m_maxValue((1 << bitCount)-1), m_divisor(divisor),
|
||||
: DataType(id, bitCount, flags|NUM, replacement), m_minValue(0), m_maxValue((1 << bitCount)-1), m_divisor(divisor==0 ? 1 : divisor),
|
||||
m_precision(0), m_firstBit(firstBit), m_baseType(baseType) {}
|
||||
|
||||
/**
|
||||
@@ -570,6 +575,14 @@ class DataTypeList {
|
||||
*/
|
||||
static DataTypeList* getInstance();
|
||||
|
||||
/**
|
||||
* Dump the type list optionally including the divisor to the output.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param appendDivisor whether to append the divisor (if available).
|
||||
* @param output the @a ostream to dump to.
|
||||
*/
|
||||
void dump(OutputFormat outputFormat, bool appendDivisor, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Removes all @a DataType instances.
|
||||
*/
|
||||
@@ -611,12 +624,9 @@ class DataTypeList {
|
||||
map<string, const DataType*>::const_iterator end() const { return m_typesById.end(); }
|
||||
|
||||
private:
|
||||
/** the known @a DataType instances by ID only. */
|
||||
map<string, const DataType*> m_typesById;
|
||||
|
||||
/** the known @a DataType instances by ID and length (i.e. "ID:BITS").
|
||||
/** the known @a DataType instances by ID (e.g. "ID:BITS" or just "ID").
|
||||
* Note: adjustable length types are stored by ID only. */
|
||||
map<string, const DataType*> m_typesByIdLength;
|
||||
map<string, const DataType*> m_typesById;
|
||||
|
||||
/** the @a DataType instances to cleanup. */
|
||||
list<const DataType*> m_cleanupTypes;
|
||||
|
||||
+11
-25
@@ -935,20 +935,6 @@ void Message::dumpField(const string& fieldName, bool withConditions, OutputForm
|
||||
dumpAttribute(false, outputFormat, fieldName, output);
|
||||
}
|
||||
|
||||
void addData(const SymbolString& data, ostringstream* output) {
|
||||
if (data.size() == 0) {
|
||||
return;
|
||||
}
|
||||
*output << ",\n \"" << (data.isMaster() ? "master" : "slave") << "\": [";
|
||||
for (size_t pos = 0; pos < data.size(); pos++) {
|
||||
if (pos > 0) {
|
||||
*output << ", ";
|
||||
}
|
||||
*output << dec << static_cast<unsigned>(data[pos]);
|
||||
}
|
||||
*output << "]";
|
||||
}
|
||||
|
||||
void Message::decodeJson(bool leadingSeparator, bool appendDirectionCondition, bool withData, bool addRaw,
|
||||
OutputFormat outputFormat, ostringstream* output) const {
|
||||
outputFormat |= OF_JSON;
|
||||
@@ -1005,8 +991,8 @@ void Message::decodeJson(bool leadingSeparator, bool appendDirectionCondition, b
|
||||
appendAttributes(outputFormat, output);
|
||||
if (hasData) {
|
||||
if (addRaw) {
|
||||
addData(m_lastMasterData, output);
|
||||
addData(m_lastSlaveData, output);
|
||||
m_lastMasterData.dumpJson(true, output);
|
||||
m_lastSlaveData.dumpJson(true, output);
|
||||
*output << dec;
|
||||
}
|
||||
size_t pos = (size_t)output->tellp();
|
||||
@@ -1884,27 +1870,27 @@ void MessageMap::remove(Message* message) {
|
||||
const auto keyIt = m_messagesByKey.find(key);
|
||||
bool deleted = false;
|
||||
if (keyIt != m_messagesByKey.end()) {
|
||||
vector<Message*> messages = keyIt->second;
|
||||
for (auto it = messages.begin(); it != messages.end(); ) {
|
||||
vector<Message*>* messages = &keyIt->second;
|
||||
for (auto it = messages->begin(); it != messages->end(); ) {
|
||||
Message* other = *it;
|
||||
if (other == message) {
|
||||
if (!deleted) {
|
||||
deleted = true;
|
||||
delete(other);
|
||||
}
|
||||
messages.erase(it);
|
||||
it = messages->erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (messages.empty()) {
|
||||
if (messages->empty()) {
|
||||
m_messagesByKey.erase(keyIt);
|
||||
}
|
||||
}
|
||||
bool storedByName = false;
|
||||
for (auto nameIt = m_messagesByName.begin(); nameIt != m_messagesByName.end(); ) {
|
||||
vector<Message*> messages = nameIt->second;
|
||||
for (auto it = messages.begin(); it != messages.end(); ) {
|
||||
vector<Message*>* messages = &nameIt->second;
|
||||
for (auto it = messages->begin(); it != messages->end(); ) {
|
||||
Message* other = *it;
|
||||
if (other == message) {
|
||||
storedByName = true;
|
||||
@@ -1912,13 +1898,13 @@ void MessageMap::remove(Message* message) {
|
||||
deleted = true;
|
||||
delete(other);
|
||||
}
|
||||
messages.erase(it);
|
||||
it = messages->erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (messages.empty()) {
|
||||
m_messagesByName.erase(nameIt);
|
||||
if (messages->empty()) {
|
||||
nameIt = m_messagesByName.erase(nameIt);
|
||||
} else {
|
||||
++nameIt;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,11 @@ class Message : public AttributedItem {
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Message() { if (m_deleteData) { delete m_data; } }
|
||||
virtual ~Message() {
|
||||
if (m_deleteData) {
|
||||
delete m_data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the key for the ID.
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace ebusd {
|
||||
using std::ostringstream;
|
||||
using std::nouppercase;
|
||||
using std::setw;
|
||||
using std::dec;
|
||||
using std::hex;
|
||||
using std::setfill;
|
||||
|
||||
@@ -157,6 +158,24 @@ const string SymbolString::getStr(size_t skipFirstSymbols) const {
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
bool SymbolString::dumpJson(bool withSeparator, ostringstream* output) const {
|
||||
if (size() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (withSeparator) {
|
||||
*output << ",\n ";
|
||||
}
|
||||
*output << "\"" << (isMaster() ? "master" : "slave") << "\": [";
|
||||
for (size_t pos = 0; pos < size(); pos++) {
|
||||
if (pos > 0) {
|
||||
*output << ", ";
|
||||
}
|
||||
*output << dec << static_cast<unsigned>(m_data[pos]);
|
||||
}
|
||||
*output << "]";
|
||||
return true;
|
||||
}
|
||||
|
||||
symbol_t SymbolString::calcCrc() const {
|
||||
symbol_t crc = 0;
|
||||
for (size_t i = 0; i < m_data.size(); i++) {
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace ebusd {
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ostringstream;
|
||||
|
||||
/** the base type for symbols sent to/from the eBUS. */
|
||||
typedef unsigned char symbol_t;
|
||||
@@ -158,6 +159,14 @@ class SymbolString {
|
||||
*/
|
||||
const string getStr(size_t skipFirstSymbols = 0) const;
|
||||
|
||||
/**
|
||||
* Dump the data in JSON format to the output.
|
||||
* @param withSeparator true to prepend the field separator.
|
||||
* @param output the @a ostringstream to format the messages to.
|
||||
* @return true if something was written to the output.
|
||||
*/
|
||||
bool dumpJson(bool withSeparator, ostringstream* output) const;
|
||||
|
||||
/**
|
||||
* Return a reference to the symbol at the specified index.
|
||||
* @param index the index of the symbol to return.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#
|
||||
b,broadcast,test,,,fe,0900,,,,EXP
|
||||
|
@@ -154,22 +154,22 @@ int main() {
|
||||
{"w,ehp,multi,,,,,01:8;02:2;03,longname,,STR:15", "ABCDEFGHIJKLMNO", "ff08b5090a0e014142434445464748;ff08b509040e02494a;ff08b509070e034b4c4d4e4f", "00;00;00", "dC" },
|
||||
{"w,ehp,multi,,,,,01:8;02:2;0304,longname,,STR:15", "ABCDEFGHIJKLMNO", "ff08b5090a0e014142434445464748;ff08b509040e02494a;ff08b509070e034b4c4d4e4f", "00;00;00", "cC" },
|
||||
{"r,ehp,scan,chained scan,,08,B509,24:9;25;26;27,,,IGN,,,,id4,,STR:28", "21074500100027790000000000N8", "ff08b5090124;ff08b5090125;ff08b5090126;ff08b5090127", "09003231303734353030;09313030303237373930;09303030303030303030;024E38", "dC" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B61", "ff08b509030d6900", "03138040", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B60", "ff08b509030d6900", "0313ffbf", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B61", "ff08b509030d6900", "03137fff", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B60", "ff08b509030d6900", "03137fbf", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B61;B71", "ff08b509030d6a00", "0213ff", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B60;B71", "ff08b509030d6a00", "0213bf", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B61;B70", "ff08b509030d6a00", "02137f", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B60;B70", "ff08b509030d6a00", "02133f", "d" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B61", "ff08b509060e6900138040", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B60", "ff08b509060e6900138000", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B61", "ff08b509060e6900130040", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7:1,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B60", "ff08b509060e6900130000", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B61;B71", "ff08b509050e6a0013c0", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B60;B71", "ff08b509050e6a001380", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B61;B70", "ff08b509050e6a001340", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7:1,0=B70;1=B71", "1.9;B60;B70", "ff08b509050e6a001300", "00", "di" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B61", "ff08b509030d6900", "03138040", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B60", "ff08b509030d6900", "0313ffbf", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B61", "ff08b509030d6900", "03137fff", "d" },
|
||||
{"r,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B60", "ff08b509030d6900", "03137fbf", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B61;B71", "ff08b509030d6a00", "0213ff", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B60;B71", "ff08b509030d6a00", "0213bf", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B61;B70", "ff08b509030d6a00", "02137f", "d" },
|
||||
{"r,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B60;B70", "ff08b509030d6a00", "02133f", "d" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B61", "ff08b509060e6900138040", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B71;B60", "ff08b509060e6900138000", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B61", "ff08b509060e6900130040", "00", "di" },
|
||||
{"w,,x,,,,,6900,,,UCH,10,bar,,Bit7,,BI7,0=B70;1=B71,,,Bit6,,BI6:1,0=B60;1=B61", "1.9;B70;B60", "ff08b509060e6900130000", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B61;B71", "ff08b509050e6a0013c0", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B60;B71", "ff08b509050e6a001380", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B61;B70", "ff08b509050e6a001340", "00", "di" },
|
||||
{"w,,x,,,,,6a00,,,UCH,10,bar,,Bit6,,BI6:1,0=B60;1=B61,,,Bit7,,BI7,0=B70;1=B71", "1.9;B60;B70", "ff08b509050e6a001300", "00", "di" },
|
||||
{"w,,x,,,,,,,,IGN:1,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:1,,,,,,IGN:1,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;1;1;0;0;0", "ff08b509050e00070000", "00", "di" },
|
||||
{"w,,x,,,,,,,,IGN:1,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:1,,,,,,IGN:1,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;0;0;0;0;1", "ff08b509050e00010004", "00", "di" },
|
||||
{"w,,x,,,,,,,,IGN:1,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:1,,,,,,IGN:1,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "0;0;1;0;1;1", "ff08b509050e00040006", "00", "di" },
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
set(ebusctl_SOURCES ebusctl.cpp)
|
||||
set(ebusfeed_SOURCES ebusfeed.cpp)
|
||||
set(ebuspicloader_SOURCES ebuspicloader.cpp intelhex/intelhexclass.cpp)
|
||||
|
||||
if(HAVE_CONTRIB)
|
||||
set(ebusfeed_LIBS ${ebusfeed_LIBS} ebuscontrib)
|
||||
endif(HAVE_CONTRIB)
|
||||
|
||||
include_directories(../lib/ebus)
|
||||
include_directories(../lib/utils)
|
||||
include_directories(intelhex)
|
||||
|
||||
add_executable(ebusctl ${ebusctl_SOURCES})
|
||||
add_executable(ebusfeed ${ebusfeed_SOURCES})
|
||||
add_executable(ebuspicloader ${ebuspicloader_SOURCES})
|
||||
target_link_libraries(ebusctl utils ebus ${LIB_ARGP} ${ebusctl_LIBS})
|
||||
target_link_libraries(ebusfeed ebus ${LIB_ARGP} ${ebusfeed_LIBS})
|
||||
target_link_libraries(ebuspicloader ${LIB_ARGP})
|
||||
|
||||
install(TARGETS ebusctl ebuspicloader EXPORT ebusd DESTINATION usr/bin)
|
||||
|
||||
@@ -2,22 +2,13 @@ AM_CXXFLAGS = -I$(top_srcdir)/src \
|
||||
-isystem$(top_srcdir)
|
||||
|
||||
bin_PROGRAMS = ebusctl \
|
||||
ebusfeed \
|
||||
ebuspicloader
|
||||
|
||||
ebusctl_SOURCES = ebusctl.cpp
|
||||
ebusctl_LDADD = ../lib/utils/libutils.a
|
||||
|
||||
ebusfeed_SOURCES = ebusfeed.cpp
|
||||
ebusfeed_LDADD = ../lib/utils/libutils.a \
|
||||
../lib/ebus/libebus.a
|
||||
|
||||
ebuspicloader_SOURCES = ebuspicloader.cpp intelhex/intelhexclass.cpp
|
||||
|
||||
if CONTRIB
|
||||
ebusfeed_LDADD += ../lib/ebus/contrib/libebuscontrib.a
|
||||
endif
|
||||
|
||||
distclean-local:
|
||||
-rm -f Makefile.in
|
||||
-rm -rf .libs
|
||||
|
||||
@@ -63,15 +63,6 @@ EOF
|
||||
./src/ebusd/ebusd -c contrib/etc/ebusd --checkconfig >/dev/null
|
||||
rm -f contrib/etc/ebusd/bad.csv
|
||||
echo > dump
|
||||
./src/tools/ebusfeed -d tcp:127.0.0.1:8876 -t 10000 dump >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -d tcp:127.0.0.1:99999 dump >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -d udp:127.0.0.1:8876 -t 10000 dump >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -d udp:127.0.0.1:8876 -t 10000 nonexistdump >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -d "" >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -t 1 >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed "" >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed 1 2 >/dev/null 2>/dev/null
|
||||
./src/tools/ebusfeed -x >/dev/null 2>/dev/null
|
||||
./src/tools/ebusctl -s testserver -p 100000 >/dev/null 2>/dev/null
|
||||
./src/tools/ebusctl -s "" >/dev/null 2>/dev/null
|
||||
./src/tools/ebusctl -p "" >/dev/null 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user