all working i think

This commit is contained in:
2025-07-28 06:21:45 -07:00
parent b740ba9991
commit 211930cde3
30 changed files with 900 additions and 117 deletions

80
archive/gsysctl.yaml Normal file
View File

@ -0,0 +1,80 @@
---
###############################################
# Prepare for docker container
# https://github.com/shakg/g-systemctl
###############################################
- name: set docker folder variable
set_fact:
docker_root: "/opt/cosmos/gsc"
# clear folder first
- name: gsc - delete old folder
shell: "rm -R {{ docker_root }}"
# Create docker Folder
- name: g-systemctl - create docker_root folder
file:
path: "{{ docker_root }}"
state: directory
mode: '0755'
owner: root
group: root
- name: g-systemctl - clone the git
git:
repo: "https://github.com/shakg/g-systemctl"
dest: "{{ docker_root }}"
###############################################
# Start docker container
###############################################
- name: Replace golang version number
ansible.builtin.replace:
path: "{{ docker_root }}/backend/Dockerfile"
regexp: '^FROM golang:.*-alpine as development'
replace: 'FROM golang:1.24-alpine as development'
# Replace g-systemctl docker-compose file
- name: g-systemctl - replace docker-compose
copy:
dest: "{{ docker_root }}/docker-compose.yaml"
content: |
version: '3.8'
services:
frontend:
container_name: gsc-frontend
network_mode: bridge
restart: always
build:
context: ./frontend
target: production
ports:
- "80:80"
backend:
container_name: gsc-backend
network_mode: bridge
restart: always
build:
context: ./backend
target: production
ports:
- "8080:8080"
privileged: true
- name: "g-systemctl - build and run containers"
shell: "docker-compose -f {{ docker_root }}/docker-compose.yaml up -d"
register: local_index_output
- debug: |
msg="{{ local_index_output.stdout_lines }}"
msg="{{ local_index_output.stderr_lines }}"
...

39
archive/index.php.old Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Call Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p id="time"></p>
<p id="apiData"></p>
<div id="content">
<!-- The data will be displayed here -->
Loading...
</div>
<script>
// JavaScript to fetch and display API data every second
function fetchData() {
fetch('http://172.17.0.1:5000/status')
.then(response => response.json())
.then(data => {
// Display the fetched data in the div with id 'content'
document.getElementById('content').innerHTML = JSON.stringify(data, null, 2);
})
.catch(error => console.error('Error:', error));
}
// Fetch data on page load
fetchData();
// Set an interval to fetch data every second
setInterval(fetchData, 1000);
</script>
</body>
</html>

58
archive/js_site/app.js Normal file
View File

@ -0,0 +1,58 @@
document.addEventListener('DOMContentLoaded', function () {
// Initially set button state to "Loading..."
updateButtonState("Loading...");
// Set an interval to check the API every second
setInterval(checkAPIStatus, 1000); // 1000 ms = 1 second
});
// Function to update the button text based on the API state
function updateButtonState(status) {
const button = document.getElementById('statusButton');
if (status === "active") {
button.innerHTML = "Stop Service";
button.style.backgroundColor = "#FF6347"; // Red for stopping
button.onclick = stopService;
} else if (status === "inactive") {
button.innerHTML = "Start Service";
button.style.backgroundColor = "#32CD32"; // Green for starting
button.onclick = startService;
} else if (status === "failed") {
button.innerHTML = "Service Failed!";
button.style.backgroundColor = "#FF6347"; // Red for failed
button.onclick = null;
}else {
button.innerHTML = "Unknown";
button.style.backgroundColor = "#808080"; // Gray for error
button.onclick = null;
}
}
// Simulate API call and handle response
function checkAPIStatus() {
// Replace with your actual API endpoint
fetch('http://172.17.0.1:5000/status')
.then(response => response.json())
.then(data => {
const apiStatus = data.Status;
updateButtonState(apiStatus);
})
.catch(error => {
console.error('Error fetching API status:', error);
updateButtonState('error');
});
}
// Function to start the service (this would make the API call to start it)
function startService() {
console.log('Starting service...');
// You can call an API to start the service here
}
// Function to stop the service (this would make the API call to stop it)
function stopService() {
console.log('Stopping service...');
// You can call an API to stop the service here
}

19
archive/js_site/index.php Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Status Button</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app">
<button id="statusButton" onclick="handleButtonClick()">Loading...</button>
</div>
<?php
$status = file_get_contents("http://172.17.0.1:5000/status");
echo $status;
?>
<script src="app.js"></script>
</body>
</html>

26
archive/js_site/style.css Normal file
View File

@ -0,0 +1,26 @@
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f4f4f9;
}
#app {
text-align: center;
}
button {
padding: 15px 30px;
font-size: 18px;
cursor: pointer;
border: none;
border-radius: 5px;
transition: background-color 0.3s ease;
}
button:active {
transform: scale(0.98);
}

View File

@ -1,30 +1,58 @@
--- ---
packages: main_packages:
- gpsd
- gpsd-clients
- bc
- ffmpeg
- imagemagick
- ustreamer
- ffmpeg - ffmpeg
- ethtool - ethtool
- python3 - python3
- python3-venv - python3-venv
- pip - pip
- python-is-python3 - python-is-python3
- dbus-user-session
- apache2 - apache2
- php - php
autologin_packages:
- kde-plasma-desktop - kde-plasma-desktop
- clinfo - clinfo
- mesa-utils - mesa-utils
- vulkan-tools - vulkan-tools
- wayland-utils - wayland-utils
- xscreensaver - xscreensaver
- dbus-user-session
# chrome kiosk variables # chrome kiosk variables
kiosk_service_templates: kiosk_service_templates:
- chrome_resolution: "720,405" - chrome_resolution: "720,405"
chrome_website: "http://127.0.0.1:7123/stream" chrome_website: "http://127.0.0.1:7123/stream"
service_name: chrome_webcam service_name: chrome_webcam
- chrome_resolution: "720,595" extra_service_configs: |
chrome_website: "http://127.0.0.1:3000" After=ustreamer.service
Wants=ustreamer.service
user_data_dir: "/opt/chrome/one"
extra_chrome_configs: |
--user-data-dir=/opt/chrome/one \
- chrome_resolution: "720,550"
chrome_website: "http://127.0.0.1:8081"
service_name: chrome_timelapse_control service_name: chrome_timelapse_control
extra_service_configs: ""
user_data_dir: "/opt/chrome/two"
extra_chrome_configs: |
--window-position="0,410" \
--user-data-dir="/opt/chrome/two" \
create_data_dir: true
# timelapse scripts for templating
timelapse_script_templates:
- src: timelapse_service.sh.j2
dest: "{{ working_folder }}/timelapse_service.sh"
- src: create_timelapse.sh.j2
dest: "{{ working_folder }}/create_timelapse.sh"
# this will be the parent folder where the photos will be stored # this will be the parent folder where the photos will be stored
@ -38,11 +66,15 @@ working_folder: "/opt/carputer/timelapse"
# other folder variables # other folder variables
gps_service_directory: "/opt/cosmos/gps_service" gps_service_directory: "/opt/cosmos/gps_service"
photo_refresh_folder: "/opt/cosmos/photo_refresh" photo_refresh_folder: "/opt/cosmos/photo_refresh"
service_control_folder: "/opt/cosmos/timelapse_service_control"
# ustreamer variables # ustreamer variables
video_device: "/dev/video0" video_device: "/dev/video0"
resolution: "1920x1080" resolution: "1920x1080"
ustreamer_port: "7123" ustreamer_port: "7123"
# other rando vars
cpu_architecture: "amd64"
extra_volumes: ""
... ...

View File

@ -0,0 +1,85 @@
import subprocess
import requests
from lxml import html
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
def start_service():
command = "systemctl start timelapse.service"
try:
# Run the command using subprocess.run()
process = subprocess.Popen(command, shell=True)
except subprocess.CalledProcessError as e:
return {"Error": e.strip('\n')}
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
try:
# Run the command using subprocess.run()
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
return {"Message": result.stdout.strip('\n')}
except subprocess.CalledProcessError as e:
return {"Error": e.strip('\n')}
def stop_service():
command = "systemctl stop timelapse.service"
try:
# Run the command using subprocess.run()
process = subprocess.Popen(command, shell=True)
except subprocess.CalledProcessError as e:
return {"Error": e.strip('\n')}
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
try:
# Run the command using subprocess.run()
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
return {"Message": result.stdout.strip('\n')}
except subprocess.CalledProcessError as e:
return {"Error": e.strip('\n')}
def service_status():
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
try:
# Run the command using subprocess.run()
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2 | cut -d ' ' -f 2"
status = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
return {"Message": result.stdout.strip('\n'), "Status": status.stdout.strip('\n')}
except subprocess.CalledProcessError as e:
return {"Error": e.strip('\n')}
@app.route('/start', methods=['GET'])
def start():
try:
return jsonify(start_service())
except ValueError as e:
print(e)
return jsonify({'error': e}), 400
@app.route('/stop', methods=['GET'])
def stop():
try:
return jsonify(stop_service())
except ValueError as e:
print(e)
return jsonify({'error': e}), 400
@app.route('/status', methods=['GET'])
def status():
try:
return jsonify(service_status())
except ValueError as e:
print(e)
return jsonify({'error': e}), 400
@app.route('/test', methods=['GET'])
def test():
return jsonify({'message': 'Hello there'})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)

View File

@ -0,0 +1,203 @@
<?php
# set default values
$status = "Unchecked";
$message = "No attempt made yet.";
$button_text = "Pending";
$button_active = false;
$button_recent = false;
$button_action = "";
$button_result = "";
$http_host = $_SERVER['HTTP_HOST'];
$debug_string = "";
if (isset($_GET['action'])) {
$debug_string = $debug_string."GET called, ".$_GET['action']."<br>";
$button_recent = true;
$button_result = runAPI($_GET['action']);
$debug_string = $debug_string."Button Result: ".$button_result."<br>";
sleep(1);
}
function runAPI($submitted_status) {
if(!isset($debug_string)){
$debug_string = "";
}
$debug_string = $debug_string."runAPI called, ".$submitted_status."<br>";
switch ($submitted_status) {
case "stop":
$apiUrl = "http://172.17.0.1:5000/stop";
break;
case "start":
$apiUrl = "http://172.17.0.1:5000/start";
break;
default:
$apiUrl = "http://172.17.0.1:5000/status";
break;
}
// API URL
$debug_string = $debug_string."After switch, apiUrl is ".$apiUrl."<br>";
// Use file_get_contents or cURL to fetch the API data
$response = file_get_contents($apiUrl);
if ($response === FALSE) {
$debug_string = $debug_string."Response ERROR!!<br>";
return "error"; // API error
}
// Decode the JSON response (assuming the API returns JSON)
$data = json_decode($response, true);
$debug_string = $debug_string."Data from API call: ".$data['Message']."<br>";
// Assuming the API returns a single word result (like "success", "failure", etc.)
return isset($data['Status']) ? $data['Status'] : 'unknown';
}
// Check if the button was clicked via AJAX request
// if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// $button_recent = true;
// $status_at_submit = $_POST['status'];
// echo "Set when clicked, second in code - ".$status_at_submit."<br>";
// // Get the API result
// $apiResult = runAPI($status_at_submit);
// // Return the result as a JSON response
// echo json_encode(['status' => $apiResult]);
// exit;
// }
// URL of the external API
$apiUrl = "http://172.17.0.1:5000/status";
// Use file_get_contents to fetch data from the API
$response = file_get_contents($apiUrl);
// Check if the request was successful
if ($response === FALSE) {
$data = "Failed to fetch data.";
}
else {
// Decode the JSON response (assuming the API returns JSON)
$data = json_decode($response, true);
// If you want to display specific data, adjust this part
// For example, if the API returns a 'message' key, display it
if (isset($data['Message'])) {
$message = $data['Message'];
} else {
$message = "No message found in the response.";
}
if (isset($data['Status'])) {
$status = $data['Status'];
} else {
$status = "None";
}
}
switch ($status) {
case "active":
$button_text = "Stop Service";
$button_active = true;
break;
case "inactive":
$button_text = "Start Service";
$button_active = true;
break;
case "failed":
$button_text = "Start Service - Warning";
$button_active = true;
break;
case "deactivating":
$button_text = "Service Stopping...";
$button_active = false;
break;
default:
$button_text = "Error, No Status";
$button_active = false;
$status="unknown";
break;
}
if($button_active && !$button_recent){
$action = "";
if($status == "active"){
$action = "stop";
}
else if($status == "inactive"){
$action = "start";
}
else if($status == "failed"){
$action = "start";
}
$button_action = ' onclick="location.href=\'/?action='.$action.'\'" ';
}
if($button_recent){
/*
$delay = 5; // Number of seconds before redirection
echo "You will be redirected in $delay seconds.";
header("Refresh: $delay; url=https://example.com");
exit();
*/
header("Location: http://".$http_host);
exit(); // Always include exit() after headers are sent
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Data Display</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="button-container">
<button <?php echo $button_action; ?> class="<?php echo $status; ?>" id="phpButton"<?php if(!$button_active || $button_recent) {echo " disabled";} ?>>
<?php echo $button_text; ?>
</button>
<p>
</div>
<p>
<div class="api-data">
<!-- PHP will inject the data here -->
<?php
echo "Full Message:<br>".htmlspecialchars($message)."<p>Current Date:<br>".date("F j, Y, g:i:s a")."<p>";
?>
</div>
</div>
<script>
// When the button is clicked, send an AJAX request to fetch new data
document.getElementById('phpButton').addEventListener('click', function() {
// Disable button to avoid multiple clicks
this.disabled = true;
this.innerText = 'Loading...';
// Make an AJAX request
fetch('index.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
'status': '<?php echo $status; ?>'
},
body: 'action=fetch_data' // Trigger the PHP function via POST
})
});
</script>
<script>
// Automatically refresh the page every second
setTimeout(function() {
location.reload();
}, <?php if($button_recent){ echo "5000"; } else{ echo "1000"; } ?>); // Refresh interval (1000 ms = 1 second)
</script>
</body>
</html>

View File

@ -0,0 +1,80 @@
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #2c3e50; /* Dark background color */
color: #bdc3c7; /* Dimmer text color */
zoom: 1.5
}
.container {
max-width: 500px;
margin: 0 auto;
margin-top: 20px;
padding: 20px;
background-color: #34495e; /* Darker background for container */
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); /* Slightly darker shadow */
}
.api-data {
font-size: 1.4rem;
color: #bdc3c7; /* Dimmer text color */
}
.loading {
font-size: 1.2rem;
background-color: #34495e; /* Darker background for container-wide */
}
.status-button {
padding: 10px 20px;
font-size: 1.5rem;
border: none;
cursor: pointer;
margin-top: 20px;
border-radius: 5px;
}
.button-container {
display: flex;
justify-content: center; /* This centers the button horizontally */
}
button {
background: radial-gradient(circle, #ff7e5f 0%, #feb47b 100%);
border: none;
color: white;
font-size: 30px;
padding: 25px 50px;
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
border-radius: 30px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
}
button:hover {
transform: scale(1.05);
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.inactive {
background-color: #0b660e;
background: radial-gradient(circle, #0b660e 0%, #2b922f 100%);
color: #bdc3c7; /* Dimmer text color */
}
.active {
background-color: #a5150b;
background: radial-gradient(circle, #a5150b 0%, #d6382d 100%);
color: #bdc3c7; /* Dimmer text color */
}
.failed {
background-color: #671281;
background: radial-gradient(circle, #671281 0%, #8423a1 100%);
color: #bdc3c7; /* Dimmer text color */
}
.deactivating {
background-color: #003699;
background: radial-gradient(circle, #003699 0%, #337aff 100%);
color: #bdc3c7; /* Dimmer text color */
}
.unknown {
background-color: #ec701e;
background: radial-gradient(circle, #c9580d 0%, #ec701e 100%);
color: #bdc3c7; /* Dimmer text color */
}

35
tasks/chrome.yaml Normal file
View File

@ -0,0 +1,35 @@
---
###############################################
# Install Chrome
- name: Chrome - Chrome - Check if installed
command: dpkg -l google-chrome-stable
register: chrome_installed
ignore_errors: true
- name: Chrome - Chrome - Set chrome_present variable
set_fact:
chrome_present: "{{ chrome_installed.rc == 0 }}"
- name: Chrome - Install Chrome
include_tasks: /var/jenkins_home/ansible/roles/install_apps/tasks/chrome.yaml
when: not chrome_present | bool
- name: Chrome - Create User Service Folder
file:
path: /home/cosmos/.config/systemd/user
state: directory
owner: cosmos
group: cosmos
mode: '0700'
- name: Chrome - clear user cache
shell: "rm -R /home/cosmos/.config/google-chrome"
###############################################
# Configure Kiosks
- name: Set up Chrome Kiosk Services
include_tasks: kiosk.yaml
loop: "{{ kiosk_service_templates }}"
...

View File

@ -8,7 +8,7 @@
apt: apt:
name: "{{ item }}" name: "{{ item }}"
state: present state: present
loop: "{{ packages }}" loop: "{{ autologin_packages }}"
# Set sddm as def # Set sddm as def
- name: prereqs - enable sddm in xdm - name: prereqs - enable sddm in xdm
@ -32,21 +32,6 @@
dest: /etc/sddm.conf dest: /etc/sddm.conf
mode: 0644 mode: 0644
###############################################
# Install Chrome
- name: prereqs - Chrome - Check if installed
command: dpkg -l google-chrome-stable
register: chrome_installed
ignore_errors: true
- name: prereqs - Chrome - Set chrome_present variable
set_fact:
chrome_present: "{{ chrome_installed.rc == 0 }}"
- name: prereqs - Install Chrome
include_tasks: /var/jenkins_home/ansible/roles/install_apps/tasks/chrome.yaml
when: not chrome_present | bool
############################################### ###############################################
# Apply Profile # Apply Profile
# Create Cosmos user folder # Create Cosmos user folder
@ -61,7 +46,7 @@
# Extract profile # Extract profile
- name: prereqs - extract cosmos user profile - name: prereqs - extract cosmos user profile
unarchive: unarchive:
src: /var/jenkins_home/ansible-files/lldp_scan/cosmos.tar.gz src: /var/jenkins_home/ansible-files/profile/cosmos.tar.gz
dest: /home dest: /home
owner: cosmos owner: cosmos
group: cosmos group: cosmos

View File

@ -9,16 +9,6 @@
owner: root owner: root
group: root group: root
# install packages
- name: gps_service - Install Packages
apt:
name:
- gpsd
- gpsd-clients
state: present
register: apt_result
ignore_errors: true
- name: gps_service - Enable and start gpsd system service - name: gps_service - Enable and start gpsd system service
become: true become: true
systemd: systemd:

View File

@ -6,45 +6,48 @@
# so i can make a list of variables again # so i can make a list of variables again
############################################### ###############################################
- name: Chrome Kiosk - Create User Service Folder - name: Chrome Kiosk - display info
debug:
msg:
- "Chrome Kiosk Configuring"
- "Kiosk Service Name: {{ item.service_name }}"
- "Chrome Website: {{ item.chrome_website }}"
- "Chrome App Resolution: {{ item.chrome_resolution }}"
# Create user data dir Folder
- name: timelapse - create working folder
when: create_data_dir | bool
file: file:
path: /home/cosmos/.config/systemd/user path: "{{ item.user_data_dir }}"
state: directory state: directory
mode: '0755'
owner: cosmos owner: cosmos
group: cosmos group: cosmos
mode: '0700'
- name: configure kiosks - name: Chrome Kiosk - user stop service
block: command: "systemctl --user -M cosmos@ stop {{ item.service_name }}.service"
ignore_errors: true
- name: Chrome Kiosk - user stop service # - name: Chrome Kiosk - Kill chrome if running otherwise
command: "systemctl --user -M cosmos@ stop {{ service_name }}.service" # command: pkill chrome
ignore_errors: true # ignore_errors: true
- name: Chrome Kiosk - Kill chrome if running otherwise - name: Chrome Kiosk - Copy chrome service file
command: pkill chrome template:
ignore_errors: true src: chrome-app.service.j2
dest: "/home/cosmos/.config/systemd/user/{{ item.service_name }}.service"
owner: cosmos
group: cosmos
mode: 0600
- name: Chrome Kiosk - Copy chrome service file - name: Chrome Kiosk - user daemon reload
template: command: "systemctl --user -M cosmos@ daemon-reload"
src: chrome-app.service.j2 register: user_daemon_reload
dest: "/home/cosmos/.config/systemd/user/{{ service_name }}.service"
owner: cosmos
group: cosmos
mode: 0600
- name: Chrome Kiosk - user daemon reload - name: Chrome Kiosk - user enable service
command: "systemctl --user -M cosmos@ daemon-reload" command: "systemctl --user -M cosmos@ enable {{ item.service_name }}.service"
register: user_daemon_reload
- name: Chrome Kiosk - user enable service
command: "systemctl --user -M cosmos@ enable {{ service_name }}.service"
- name: Chrome Kiosk - user start service
command: "systemctl --user -M cosmos@ start {{ service_name }}.service"
loop: "{{ timelapse_script_templates }}"
- name: Chrome Kiosk - user start service
command: "systemctl --user -M cosmos@ start {{ item.service_name }}.service"
... ...

View File

@ -4,24 +4,41 @@
# Playbook for configuring GOLE as Road Trip Carputer # Playbook for configuring GOLE as Road Trip Carputer
########################################################### ###########################################################
# Steps: # Steps:
### Packages
### uStreamer ### uStreamer
### GPS Service
### Timelapse Service ### Timelapse Service
### Sharing Page ### Photo Refresh Page
### Cosmos Autologin ### Cosmos Autologin
### Top Cam Feed Kiosk ### Top Cam Feed Kiosk
### Bottom Service Control Panel ### Bottom Service Control Panel
#- name: Install ustreamer
# include_tasks: ustreamer.yaml
#
#- name: Install gps_service
# include_tasks: gps_service.yaml
#
#- name: install timelapse service
# include_tasks: timelapse.yaml
#
#- name: Install photo refresh site
# include_tasks: photo_refresh.yaml
- name: Install Packages
apt:
name: "{{ item }}"
state: present
loop: "{{ main_packages }}"
- name: Install ustreamer
include_tasks: ustreamer.yaml
- name: Install gps_service
include_tasks: gps_service.yaml
- name: install timelapse service
include_tasks: timelapse.yaml
- name: Install photo refresh site
include_tasks: photo_refresh.yaml
- name: Install cosmos autologin user
include_tasks: cosmos_autologin.yaml
- name: Install timelapse service control
include_tasks: service_control.yaml
- name: Set up Chrome Kiosk Services
include_tasks: chrome.yaml
... ...

View File

@ -36,6 +36,12 @@
- name: start photo_refresh - name: start photo_refresh
block: block:
- name: set container_name
set_fact:
container_name: "photo_refresh"
container_http_port: "8080"
extra_volumes: |
- {{ working_folder }}/small_thumbs:/var/www/html/capture
- name: photo_refresh - template config - name: photo_refresh - template config
template: template:

135
tasks/service_control.yaml Normal file
View File

@ -0,0 +1,135 @@
---
###############################################
# This will be a big one, gonne need the API
# for service interaction, as well as the
# web server code
###############################################
###############################################
# This part sets up python serice control api
###############################################
- name: service control api
when: false
block:
# Stop service
- name: service_control api - stop service api
systemd:
name: service_control.service
state: stopped
ignore_errors: yes
# Create API Folder
- name: service_control api - create api folder
file:
path: "{{ service_control_folder }}"
state: directory
mode: '0755'
# Copy API Code
- name: service_control api - copy api code
copy:
src: service_control_api/app.py
dest: "{{ service_control_folder }}/app.py"
mode: 0644
# Create service_control api service
- name: service_control api - create requirement file
copy:
dest: "{{ service_control_folder }}/requirements.txt"
content: |
Flask==2.1.0
pytz
requests
lxml
Werkzeug==2.0
mode: 0644
# build venv
- name: service_control api - build venv
pip:
virtualenv: "{{ service_control_folder }}/venv"
requirements: "{{ service_control_folder }}/requirements.txt"
virtualenv_command: python3 -m venv
state: present
# Create service_control api service
- name: service_control api - create service file
# vars:
template:
src: service_control.service.j2
dest: /etc/systemd/system/service_control.service
mode: 0644
# daemon reload
- name: service_control api - daemon reload
systemd:
daemon_reload: yes
# Enable and start
- name: service_control api - enable and start service api
systemd:
name: service_control.service
state: started
enabled: yes
###############################################
# This part sets up serice control website
###############################################
- name: service control web interface
when: true
block:
- name: set docker folder variable
set_fact:
service_control_web_folder: "{{ service_control_folder }}/web"
# Create docker Folder
- name: service_control_website - create service_control_web_folder folder
file:
path: "{{ service_control_web_folder }}"
state: directory
mode: '0755'
owner: root
group: root
- name: service_control_website - copy files for docker container
copy:
src: "service_control_api/website/"
dest: "{{ service_control_web_folder }}/html"
mode: 0755
owner: root
group: root
###############################################
# Start photo_refresh
###############################################
- name: start service_control_website
block:
- name: set container_name
set_fact:
container_name: "service_control_website"
container_http_port: "8081"
- name: service_control_website - template config
template:
src: docker-compose-php.yaml.j2
dest: "{{ service_control_web_folder }}/docker-compose.yaml"
mode: 0644
- name: "service_control_website - Start container at 0.0.0.0:{{ container_http_port }}"
shell: "docker-compose -f {{ service_control_web_folder }}/docker-compose.yaml up -d"
register: local_index_output
- debug: |
msg="{{ local_index_output.stdout_lines }}"
msg="{{ local_index_output.stderr_lines }}"
...

View File

@ -1,16 +1,5 @@
--- ---
# install packages
- name: photo_refresh - Install Packages
apt:
name:
- bc
- ffmpeg
- imagemagick
state: present
register: apt_result
ignore_errors: true
# Create working Folder # Create working Folder
- name: timelapse - create working folder - name: timelapse - create working folder
file: file:
@ -18,17 +7,6 @@
state: directory state: directory
mode: '0755' mode: '0755'
- name: timelapse - set template vars
set_fact:
# timelapse related scripts
timelapse_script_templates:
- src: timelapse_service.sh.j2
dest: "{{ working_folder }}/timelapse_service.sh"
- src: record_snapshots.sh.j2
dest: "{{ working_folder }}/record_snapshots.sh"
- src: create_timelapse.sh.j2
dest: "{{ working_folder }}/create_timelapse.sh"
- name: timelapse - template scripts - name: timelapse - template scripts
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"

View File

@ -1,13 +1,5 @@
--- ---
- name: ustreamer - Install Packages
apt:
name:
- ustreamer
state: present
register: apt_result
ignore_errors: true
- name: ustreamer - Create user - name: ustreamer - Create user
user: user:
name: "ustreamer" name: "ustreamer"

View File

@ -1,8 +1,8 @@
[Unit] [Unit]
Description=Chrome Description=Chrome
After=lldp_api.service
After=sddm.service After=sddm.service
[Service] [Service]
Restart=always Restart=always
RestartSec=3s RestartSec=3s
@ -13,8 +13,12 @@ ExecStart=/usr/bin/google-chrome \
--no-first-run \ --no-first-run \
--ignore-ssl-errors \ --ignore-ssl-errors \
--disable-usb-keyboard-detect \ --disable-usb-keyboard-detect \
--window-size={{ chrome_resolution }}' --window-size="{{ item.chrome_resolution }}" \
--app="{{ chrome_website }}" --app="{{ item.chrome_website }}" \
{{ item.extra_chrome_configs}}
{{ item.extra_service_configs }}
[Install] [Install]
WantedBy=graphical-session.target WantedBy=graphical-session.target

View File

@ -1,10 +1,9 @@
#!/bin/bash #!/bin/bash
# end the loop # end the loop
rm $WORKING_DIR/run rm $RUN_FILE
sleep 5 rm $WORKING_DIR/*temp*.jpg
# create timelapse # create timelapse
/bin/ffmpeg -r 30 -pattern_type glob -i "$WORKING_DIR/*.jpg" \ /bin/ffmpeg -r 30 -pattern_type glob -i "$WORKING_DIR/*.jpg" -vf "scale=1920x1080" -vcodec libx264 /$WORKING_DIR/00-timelapse.mp4 &
-vf "scale=1920x1080" -vcodec libx264 /$WORKING_DIR/00-timelapse.mp4

View File

@ -1,12 +1,12 @@
services: services:
photo_refresh: {{ container_name }}:
container_name: photo_refresh container_name: {{ container_name }}
image: php:8.0-apache image: php:8.0-apache
ports: ports:
- 8080:80 - {{ container_http_port }}:80
volumes: volumes:
- ./html:/var/www/html/ - ./html:/var/www/html/
- {{ working_folder }}/small_thumbs:/var/www/html/capture {{ extra_volumes }}
network_mode: bridge network_mode: bridge
restart: always restart: always

View File

@ -0,0 +1,15 @@
[Unit]
Description=Timelapse Service Control API
After=network.target
[Service]
User=root
Group=root
WorkingDirectory={{ service_control_folder }}
ExecStartPre=/bin/sleep 5
ExecStart={{ service_control_folder }}/venv/bin/python {{ service_control_folder }}/app.py
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
trap "source {{ working_folder }}/create_timelapse.sh &" SIGINT SIGTERM trap "source {{ working_folder }}/create_timelapse.sh" SIGINT SIGTERM
# initialize all the variables # initialize all the variables
# basic things # basic things
@ -12,6 +12,7 @@ CITY=$(echo $WHERES_GALI | jq .city)
STATE=$(echo $WHERES_GALI | jq .state) STATE=$(echo $WHERES_GALI | jq .state)
ZIPCODE=$(echo $WHERES_GALI | jq .postcode) ZIPCODE=$(echo $WHERES_GALI | jq .postcode)
DISPLAY_NAME=$(echo $WHERES_GALI | jq .display_name) DISPLAY_NAME=$(echo $WHERES_GALI | jq .display_name)
RUN_FILE={{ working_folder }}/run
# Generate Status Report # Generate Status Report
mkdir -p $WORKING_DIR mkdir -p $WORKING_DIR
@ -28,8 +29,9 @@ echo "/bin/ffmpeg -r 30 -pattern_type glob -i "$WORKING_DIR/*.jpg" \\" >> {{ wo
echo "-vf "scale=1920x1080" -vcodec libx264 /$WORKING_DIR/00-timelapse.mp4" >> {{ working_folder }}/generate_timelapses.sh echo "-vf "scale=1920x1080" -vcodec libx264 /$WORKING_DIR/00-timelapse.mp4" >> {{ working_folder }}/generate_timelapses.sh
# capture time # capture time
touch $RUN_FILE
i=1 i=1
while [ $i ] while [ -e $RUN_FILE ]
do do
FILENAME=$(printf "img-%05d" "$i") FILENAME=$(printf "img-%05d" "$i")
# old API based latlon # old API based latlon