diff --git a/ansible/playbooks/update_wmt_code.yml b/ansible/playbooks/update_wmt_code.yml index dfb8142..70af2c4 100644 --- a/ansible/playbooks/update_wmt_code.yml +++ b/ansible/playbooks/update_wmt_code.yml @@ -124,183 +124,12 @@ - name: Show data/ contents after update (should match before) debug: msg: "{{ data_files_after.stdout_lines }}" - - # ── 7. Restart WMT service ──────────────────────────────────────────── - - name: Restart WMT systemd service + + # ── 9. Reboot ───────────────────────────────────────────────────────── + - name: Reboot host to apply all changes become: true - systemd: - name: wmt - state: restarted - enabled: true - register: service_result - ignore_errors: true - - - name: Show service state - debug: - msg: "WMT service state: {{ service_result.status.ActiveState | default('unknown') }}" - when: service_result is not failed - - - name: Warn if service restart failed - debug: - msg: "WARNING: wmt service restart failed – the device may need a manual reboot." - when: service_result is failed - - vars: - wmt_dir: /home/pi/Desktop/WMT - tmp_zip: /tmp/wmt_update.zip - # Controller address – override on CLI with -e "server_url=http://..." - server_url: "http://{{ hostvars[inventory_hostname]['ansible_host'] | default(ansible_host) | regex_replace('\\d+\\.\\d+$', '10.76.157.1') }}" - - tasks: - - # ── 0. Resolve server URL ───────────────────────────────────────────── - # The monitoring server address is read from the device's own config.txt - # so we don't have to hard-code it here. - - name: Read server_host from WMT config.txt - shell: | - grep -E '^\s*server_host\s*=' {{ wmt_dir }}/data/config.txt 2>/dev/null \ - | head -1 | awk -F'=' '{print $2}' | tr -d ' \r\n' - register: cfg_server_host - changed_when: false - ignore_errors: true - - - name: Read server_port from WMT config.txt - shell: | - grep -E '^\s*server_port\s*=' {{ wmt_dir }}/data/config.txt 2>/dev/null \ - | head -1 | awk -F'=' '{print $2}' | tr -d ' \r\n' - register: cfg_server_port - changed_when: false - ignore_errors: true - - - name: Set monitoring server base URL - set_fact: - monitoring_base: "http://{{ cfg_server_host.stdout | default('rpi-ansible') }}:{{ cfg_server_port.stdout | default('5000') }}" - - - name: Show resolved server URL - debug: - msg: "Monitoring server: {{ monitoring_base }}" - - # ── 1. Check latest version on server ──────────────────────────────── - - name: Query latest WMT version from monitoring server - uri: - url: "{{ monitoring_base }}/api/wmt/client/version" - method: GET - return_content: true - timeout: 15 - register: version_response - ignore_errors: true - - - name: Show server version info - debug: - msg: "Server release: v{{ version_response.json.version | default('unknown') }} ({{ version_response.json.filename | default('n/a') }})" - when: version_response is not failed - - - name: Fail if server version endpoint unreachable - fail: - msg: "Cannot reach {{ monitoring_base }}/api/wmt/client/version – is the server running?" - when: version_response is failed - - # ── 2. Get current local version ───────────────────────────────────── - - name: Read first line of local app.py - shell: head -1 {{ wmt_dir }}/app.py 2>/dev/null || echo "unknown" - register: local_first_line - changed_when: false - - - name: Extract local version number - set_fact: - local_version: "{{ local_first_line.stdout | regex_search('version\\s+([\\d.]+)', '\\1') | first | default('0') }}" - - - name: Show local version - debug: - msg: "Local version: {{ local_version }} | Server version: {{ version_response.json.version }}" - - # ── 3. Ensure WMT directory exists ─────────────────────────────────── - - name: Ensure WMT directory exists - file: - path: "{{ wmt_dir }}" - state: directory - owner: pi - group: pi - mode: '0755' - - # ── 4. Download release zip ─────────────────────────────────────────── - - name: Download WMT release zip from monitoring server - get_url: - url: "{{ monitoring_base }}/api/wmt/client/download" - dest: "{{ tmp_zip }}" - force: true - timeout: 120 - mode: '0644' - - # ── 5. Back up current app.py ───────────────────────────────────────── - - name: Back up current app.py - copy: - src: "{{ wmt_dir }}/app.py" - dest: "{{ wmt_dir }}/app.py.bak.{{ local_version }}" - remote_src: true - owner: pi - group: pi - mode: preserve - ignore_errors: true - - # ── 6. Extract zip – skip data/ directory ───────────────────────────── - - name: Extract WMT release zip (preserving data/ directory) - shell: | - cd {{ wmt_dir }} - python3 - <<'EOF' - import zipfile, os, sys - zip_path = "{{ tmp_zip }}" - dest = "{{ wmt_dir }}" - skipped = 0 - extracted = 0 - with zipfile.ZipFile(zip_path, 'r') as zf: - for member in zf.infolist(): - p = member.filename.replace('\\', '/') - if p.startswith('data/') or p == 'data': - skipped += 1 - continue - zf.extract(member, dest) - extracted += 1 - print(f"Extracted {extracted} files, skipped {skipped} data/ entries") - EOF - register: extract_result - changed_when: true - - - name: Show extraction result - debug: - msg: "{{ extract_result.stdout }}" - - # ── 7. Fix ownership ────────────────────────────────────────────────── - - name: Set correct ownership on WMT directory - become: true - file: - path: "{{ wmt_dir }}" - owner: pi - group: pi - recurse: true - - # ── 8. Clean up temp zip ────────────────────────────────────────────── - - name: Remove temporary zip file - file: - path: "{{ tmp_zip }}" - state: absent - - # ── 9. Restart WMT service ──────────────────────────────────────────── - - name: Restart WMT systemd service - become: true - systemd: - name: wmt - state: restarted - enabled: true - register: service_result - ignore_errors: true - - - name: Show service restart result - debug: - msg: "Service state: {{ service_result.status.ActiveState | default('unknown') }}" - when: service_result is not failed - - - name: Warn if service restart failed - debug: - msg: "WARNING: wmt service restart failed – the device may need a manual reboot." - when: service_result is failed + reboot: + msg: "Rebooting after WMT code update " + reboot_timeout: 180 + pre_reboot_delay: 3 + post_reboot_delay: 15 \ No newline at end of file diff --git a/data/wmt_releases/latest.json b/data/wmt_releases/latest.json new file mode 100644 index 0000000..0e31deb --- /dev/null +++ b/data/wmt_releases/latest.json @@ -0,0 +1,6 @@ +{ + "version": "2.9", + "notes": "", + "uploaded_at": "2026-05-13T13:17:18", + "filename": "wmt_v2.9.zip" +} \ No newline at end of file diff --git a/data/wmt_releases/wmt_v2.9.zip b/data/wmt_releases/wmt_v2.9.zip new file mode 100644 index 0000000..bc7e64d Binary files /dev/null and b/data/wmt_releases/wmt_v2.9.zip differ diff --git a/templates/base.html b/templates/base.html index 39d5032..fc8627a 100644 --- a/templates/base.html +++ b/templates/base.html @@ -781,11 +781,73 @@ } body.dark-mode .nav-group-header:hover { - background-color: rgba(255,255,255,0.08); + background-color: rgba(255,255,255,0.07); } body.dark-mode .nav-group-header.open { - background-color: rgba(255,255,255,0.1); + background-color: rgba(255,255,255,0.09); + } + + /* ── Dark mode sidebar ── */ + body.dark-mode .sidebar { + background: linear-gradient(160deg, #0d0d0d 0%, #1a1a2e 50%, #16213e 100%); + box-shadow: 2px 0 16px rgba(0,0,0,0.6); + } + + body.dark-mode .sidebar .logo { + border-bottom-color: rgba(255,255,255,0.08); + } + + body.dark-mode .sidebar .logo small { + color: #7f8c9a; + } + + body.dark-mode .sidebar .nav-link { + color: #b0bec5; + } + + body.dark-mode .sidebar .nav-link:hover { + background-color: rgba(100,181,246,0.12); + color: #e0f0ff; + } + + body.dark-mode .sidebar .nav-link.active { + background-color: rgba(100,181,246,0.2); + color: #e0f0ff; + border-left: 3px solid #64b5f6; + padding-left: 12px; + } + + body.dark-mode .sidebar .nav-link i { + color: #64b5f6; + } + + body.dark-mode .sidebar .nav-link.active i { + color: #90caf9; + } + + body.dark-mode .sidebar .nav-link.admin-link { + color: #ef9a9a; + border-top-color: rgba(255,255,255,0.07); + } + + body.dark-mode .sidebar .nav-link.admin-link:hover { + background-color: rgba(239,154,154,0.15); + color: #ffcdd2; + } + + body.dark-mode .sidebar .nav-link.admin-link.active { + background-color: rgba(239,154,154,0.22); + color: #ffcdd2; + } + + body.dark-mode .sidebar .nav-link.admin-link i { + color: #ef9a9a; + } + + body.dark-mode .dark-mode-btn { + border-top-color: rgba(255,255,255,0.07); + color: #b0bec5; } {% block extra_css %}{% endblock %} diff --git a/we.txt b/we.txt new file mode 100644 index 0000000..d2b26eb --- /dev/null +++ b/we.txt @@ -0,0 +1 @@ +source venv/bin/activate && python3 main.py \ No newline at end of file