chore(ansible): remove the Shelly NTP play #1501

Merged
k.renner merged 1 commits from remove-shelly-ntp-play into main 2026-10-27 21:45:27 +00:00
3 changed files with 1 additions and 194 deletions
-67
View File
@@ -1,67 +0,0 @@
#!/usr/bin/env python3
"""
Discover Shelly devices on the network via HTTP API
Returns JSON array of discovered devices
"""
import sys
import json
import ipaddress
import concurrent.futures
import urllib.request
import urllib.error
def check_shelly(ip):
"""Check if IP is a Shelly device and return info"""
try:
url = f"http://{ip}/shelly"
req = urllib.request.Request(url, headers={'User-Agent': 'Ansible-Shelly-Discovery'})
with urllib.request.urlopen(req, timeout=2) as response:
data = json.loads(response.read().decode())
# Gen1 devices don't have 'gen' field, default to 1
gen = data.get('gen', 1)
if gen is None:
gen = 1
return {
'ip': str(ip),
'type': data.get('type', 'unknown'),
'mac': data.get('mac', ''),
'gen': gen,
'name': data.get('name', data.get('id', str(ip))),
'fw_id': data.get('fw_id', data.get('fw', 'unknown'))
}
except (urllib.error.URLError, urllib.error.HTTPError, OSError, json.JSONDecodeError):
return None
except Exception:
return None
def main():
if len(sys.argv) < 2:
print("Usage: discover_shelly.py <network1> [network2] ...")
print("Example: discover_shelly.py 10.2.30.0/24 10.2.20.0/24")
sys.exit(1)
networks = sys.argv[1:]
devices = []
# Collect all IPs to scan
all_ips = []
for network in networks:
try:
all_ips.extend(ipaddress.IPv4Network(network).hosts())
except ValueError as e:
print(f"Invalid network: {network} - {e}", file=sys.stderr)
continue
# Scan in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
results = executor.map(check_shelly, all_ips)
for result in results:
if result:
devices.append(result)
# Output JSON
print(json.dumps(devices, indent=2))
if __name__ == "__main__":
main()
-125
View File
@@ -1,125 +0,0 @@
---
# Configure NTP server on all Shelly devices
# Discovers Shelly devices via network scan and configures them to use local NTP server
#
# Usage:
# ansible-playbook plays/configure-shelly-ntp.yml
# ansible-playbook plays/configure-shelly-ntp.yml -e "shelly_ntp_server=10.2.40.4"
# ansible-playbook plays/configure-shelly-ntp.yml -e "shelly_networks=10.2.30.0/24,10.2.20.0/24"
- name: Configure Shelly NTP Settings
hosts: localhost
connection: local
gather_facts: no
vars:
shelly_ntp_server: "ntp.renner.uno"
shelly_networks: "10.2.30.0/24 10.2.20.0/24"
shelly_timeout: 5
tasks:
- name: Discover Shelly devices on network
script: "{{ playbook_dir }}/../files/discover_shelly.py {{ shelly_networks }}"
args:
executable: python3
register: discovered_devices
changed_when: false
- name: Parse discovered devices
set_fact:
shelly_devices: "{{ discovered_devices.stdout | from_json }}"
- name: Display discovered Shelly devices
debug:
msg: "Found {{ shelly_devices | length }} Shelly devices"
- name: Show device list
debug:
msg: "{{ item.name }} ({{ item.type }}) - {{ item.ip }} - Gen{{ item.gen }}"
loop: "{{ shelly_devices }}"
when: shelly_devices | length > 0
- name: Configure NTP on Gen1 devices
uri:
url: "http://{{ item.ip }}/settings?sntp_server={{ shelly_ntp_server }}"
method: GET
timeout: "{{ shelly_timeout }}"
return_content: yes
loop: "{{ shelly_devices | selectattr('gen', 'equalto', 1) | list }}"
register: gen1_results
ignore_errors: yes
when: shelly_devices | length > 0
- name: Configure NTP on Gen2+ devices
uri:
url: "http://{{ item.ip }}/rpc/Sys.SetConfig"
method: POST
body_format: json
body:
config:
sntp:
server: "{{ shelly_ntp_server }}"
timeout: "{{ shelly_timeout }}"
return_content: yes
loop: "{{ shelly_devices | selectattr('gen', 'greaterthan', 1) | list }}"
register: gen2_results
ignore_errors: yes
when: shelly_devices | length > 0
- name: Verify Gen1 NTP configuration
uri:
url: "http://{{ item.ip }}/settings"
method: GET
timeout: "{{ shelly_timeout }}"
return_content: yes
loop: "{{ shelly_devices | selectattr('gen', 'equalto', 1) | list }}"
register: gen1_verify
ignore_errors: yes
when: shelly_devices | length > 0
- name: Verify Gen2+ NTP configuration
uri:
url: "http://{{ item.ip }}/rpc/Sys.GetConfig"
method: GET
timeout: "{{ shelly_timeout }}"
return_content: yes
loop: "{{ shelly_devices | selectattr('gen', 'greaterthan', 1) | list }}"
register: gen2_verify
ignore_errors: yes
when: shelly_devices | length > 0
- name: Summary - Gen1 devices configured
debug:
msg: "{{ item.item.name }} ({{ item.item.ip }}): NTP={{ item.json.sntp.server | default('unknown') }}"
loop: "{{ gen1_verify.results | default([]) }}"
when:
- gen1_verify is defined
- gen1_verify.results is defined
- item.json is defined
- item.json.sntp is defined
loop_control:
label: "{{ item.item.name | default(item.item.ip) }}"
- name: Summary - Gen2+ devices configured
debug:
msg: "{{ item.item.name }} ({{ item.item.ip }}): NTP={{ item.json.sntp.server | default('unknown') }}"
loop: "{{ gen2_verify.results | default([]) }}"
when:
- gen2_verify is defined
- gen2_verify.results is defined
- item.json is defined
- item.json.sntp is defined
loop_control:
label: "{{ item.item.name | default(item.item.ip) }}"
- name: Final summary
debug:
msg: |
==========================================
Shelly NTP Configuration Complete
==========================================
Total devices found: {{ shelly_devices | length }}
Gen1 devices: {{ shelly_devices | selectattr('gen', 'equalto', 1) | list | length }}
Gen2+ devices: {{ shelly_devices | selectattr('gen', 'greaterthan', 1) | list | length }}
NTP Server: {{ shelly_ntp_server }}
==========================================
+1 -2
View File
@@ -6,8 +6,7 @@
# ansible-playbook site.yml
#
# One-off actions are not state and stay separate: plays/update-os.yml,
# plays/update-dist-upgrade.yml, plays/rotate-netbird-secrets.yml,
# plays/configure-shelly-ntp.yml (devices outside the inventory).
# plays/update-dist-upgrade.yml, plays/rotate-netbird-secrets.yml.
- name: Base system
ansible.builtin.import_playbook: plays/common.yml