Compare commits

..
Author SHA1 Message Date
k.renner faff22bebe Merge pull request 'feat(mqtt): register vitocal-can, the CAN gateway at the Vitocal' (#1593) from feat/vitocal-can-mqtt-account into main
Reviewed-on: #1593
2026-11-07 12:16:07 +00:00
claude-botandClaude Opus 5.5 7459aa9e59 feat(mqtt): register vitocal-can, the CAN gateway at the Vitocal
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
vitocal-can is a Waveshare ESP32-S3-RS485-CAN running boonkerz/open3e-esp32 on the
Vitocal 250-A's external CAN port. It takes over the open3e/# topics from
the heating-can stack on edge-1 (S28-28).

The controller pushes the password through the firmware's PUT /api/settings
over plain HTTP. The firmware sends its compiled-in DHCP hostname, so the
device is reachable as open3e.iot.renner.uno regardless of its configured
hostname. The controller egress gains that FQDN on port 80.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 12:52:31 +01:00
8 changed files with 98 additions and 31 deletions
+70
View File
@@ -0,0 +1,70 @@
---
# Configure VMs to use host time sync via kvm-clock
# Disables systemd-timesyncd to prevent NTP conflicts
#
# VMs get time from Proxmox host via kvm-clock paravirtualized clock
# This is more accurate and reliable than network NTP for VMs
- name: Configure VM time synchronization from host
hosts: all
become: yes
gather_facts: yes
tasks:
- name: Check if running as VM (not LXC)
stat:
path: /sys/devices/system/clocksource/clocksource0/current_clocksource
register: clocksource_file
- name: Get current clock source
slurp:
src: /sys/devices/system/clocksource/clocksource0/current_clocksource
register: clocksource
when: clocksource_file.stat.exists
- name: Display clock source
debug:
msg: "Clock source: {{ (clocksource.content | b64decode | trim) if clocksource_file.stat.exists else 'N/A (LXC)' }}"
- name: Check if systemd-timesyncd is installed
command: systemctl list-unit-files systemd-timesyncd.service
register: timesyncd_installed
check_mode: false
failed_when: false
changed_when: false
- name: Stop and disable systemd-timesyncd on VMs using kvm-clock
systemd:
name: systemd-timesyncd
state: stopped
enabled: no
when:
- clocksource_file.stat.exists
- clocksource.content is defined
- "'kvm-clock' in (clocksource.content | b64decode)"
- "'systemd-timesyncd.service' in timesyncd_installed.stdout"
- name: Mask systemd-timesyncd to prevent re-enabling
systemd:
name: systemd-timesyncd
masked: yes
when:
- clocksource_file.stat.exists
- clocksource.content is defined
- "'kvm-clock' in (clocksource.content | b64decode)"
- "'systemd-timesyncd.service' in timesyncd_installed.stdout"
- name: Verify time sync status
command: timedatectl show --property=NTPSynchronized
register: timesync_status
check_mode: false
changed_when: false
failed_when: false
- name: Display final status
debug:
msg: |
Host: {{ inventory_hostname }}
Type: {{ 'VM (kvm-clock)' if (clocksource_file.stat.exists and 'kvm-clock' in (clocksource.content | b64decode | default(''))) else 'LXC/Other' }}
Time sync: {{ timesync_status.stdout | default('unknown') }}
Note: VMs sync time from Proxmox host, LXCs inherit host time automatically
-1
View File
@@ -22,7 +22,6 @@
become: true
roles:
- common
- timesyncd
- docker-install
- netbird-proxy
- netbird-proxy-watchdog
-1
View File
@@ -16,6 +16,5 @@
become: true
roles:
- common
- timesyncd
- docker-install
- netbird-server
+11 -2
View File
@@ -54,9 +54,18 @@
# via plays/configure-ssh-ca.yml.
# -------------------------------------------------------
# 5. Time sync
# 5. Disable NTP on VMs/LXC (use host time)
# -------------------------------------------------------
# Moved to separate roles: timesyncd (internet VPS), chrony-ntp-server (edge).
- name: Stop and disable systemd-timesyncd on VMs/LXC
systemd:
name: systemd-timesyncd
state: stopped
enabled: no
masked: yes
when:
- ansible_facts['virtualization_role'] == 'guest'
- ansible_facts['virtualization_type'] in ['kvm', 'lxc']
ignore_errors: yes
# -------------------------------------------------------
# 6. Certificates
-26
View File
@@ -1,26 +0,0 @@
---
# Keep the system clock on NTP with systemd-timesyncd, on hosts that run no
# chrony. A KVM guest's clocksource does not steer wall-clock time; without an
# NTP client the clock drifts until JWT iat/exp checks fail.
- name: Install systemd-timesyncd
ansible.builtin.apt:
name: systemd-timesyncd
state: present
when: ansible_facts['os_family'] == 'Debian'
- name: Run systemd-timesyncd
ansible.builtin.systemd_service:
name: systemd-timesyncd
masked: false
enabled: true
state: started
- name: Wait for the clock to synchronize
ansible.builtin.command:
argv: [timedatectl, show, --property=NTPSynchronized, --value]
register: timesyncd_synchronized
changed_when: false
until: timesyncd_synchronized.stdout == "yes"
retries: 12
delay: 5
+2
View File
@@ -12,6 +12,8 @@
ansible.builtin.import_playbook: plays/configure-synology-python.yml
- name: Base system
ansible.builtin.import_playbook: plays/common.yml
- name: VM time sync
ansible.builtin.import_playbook: plays/configure-vm-time-sync.yml
- name: SSH user CA
ansible.builtin.import_playbook: plays/configure-ssh-ca.yml
@@ -66,6 +66,13 @@
auth: password
deliver: {esp32: "https://edge-2.iot.renner.uno:8443"}
acl: ["readwrite open3e/#"]
# vitocal-can: open3e-esp32 CAN gateway at the Vitocal 250-A (S28-28).
# The firmware registers its compiled-in DHCP name `open3e`, not its
# configured hostname.
- name: vitocal-can
auth: password
deliver: {esp32: "http://open3e.iot.renner.uno"}
acl: ["readwrite open3e/#"]
# Shellies (REN-1017): one password account per device, pushed by the
# controller through shelly-manager's per-device API. Name shelly-<id> =
# shelly-manager device id. ACL as the former shared user `shellies`
@@ -492,7 +492,7 @@ spec:
- port: "6638"
protocol: TCP
---
# mqtt-account-controller: credential delivery to edge-1 (deliver.esp32 in mqtt-accounts.yaml).
# mqtt-account-controller: credential delivery to deliver.esp32 targets in mqtt-accounts.yaml.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
@@ -524,6 +524,13 @@ spec:
- ports:
- port: "8443"
protocol: TCP
# vitocal-can (open3e-esp32), plain HTTP API.
- toFQDNs:
- matchName: "open3e.iot.renner.uno"
toPorts:
- ports:
- port: "80"
protocol: TCP
---
# whisper and speech-to-phrase: model downloads over HTTPS.
apiVersion: cilium.io/v2