all working i think
This commit is contained in:
80
archive/gsysctl.yaml
Normal file
80
archive/gsysctl.yaml
Normal 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
39
archive/index.php.old
Normal 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
58
archive/js_site/app.js
Normal 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
19
archive/js_site/index.php
Normal 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
26
archive/js_site/style.css
Normal 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);
|
||||||
|
}
|
||||||
@ -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: ""
|
||||||
|
|
||||||
...
|
...
|
||||||
85
files/service_control_api/app.py
Normal file
85
files/service_control_api/app.py
Normal 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)
|
||||||
|
|
||||||
203
files/service_control_api/website/index.php
Normal file
203
files/service_control_api/website/index.php
Normal 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>
|
||||||
|
|
||||||
|
|
||||||
80
files/service_control_api/website/styles.css
Normal file
80
files/service_control_api/website/styles.css
Normal 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
35
tasks/chrome.yaml
Normal 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 }}"
|
||||||
|
...
|
||||||
@ -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
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -6,29 +6,36 @@
|
|||||||
# 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
|
|
||||||
block:
|
|
||||||
|
|
||||||
- name: Chrome Kiosk - user stop service
|
- name: Chrome Kiosk - user stop service
|
||||||
command: "systemctl --user -M cosmos@ stop {{ service_name }}.service"
|
command: "systemctl --user -M cosmos@ stop {{ item.service_name }}.service"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Chrome Kiosk - Kill chrome if running otherwise
|
# - name: Chrome Kiosk - Kill chrome if running otherwise
|
||||||
command: pkill chrome
|
# command: pkill chrome
|
||||||
ignore_errors: true
|
# ignore_errors: true
|
||||||
|
|
||||||
- name: Chrome Kiosk - Copy chrome service file
|
- name: Chrome Kiosk - Copy chrome service file
|
||||||
template:
|
template:
|
||||||
src: chrome-app.service.j2
|
src: chrome-app.service.j2
|
||||||
dest: "/home/cosmos/.config/systemd/user/{{ service_name }}.service"
|
dest: "/home/cosmos/.config/systemd/user/{{ item.service_name }}.service"
|
||||||
owner: cosmos
|
owner: cosmos
|
||||||
group: cosmos
|
group: cosmos
|
||||||
mode: 0600
|
mode: 0600
|
||||||
@ -38,13 +45,9 @@
|
|||||||
register: user_daemon_reload
|
register: user_daemon_reload
|
||||||
|
|
||||||
- name: Chrome Kiosk - user enable service
|
- name: Chrome Kiosk - user enable service
|
||||||
command: "systemctl --user -M cosmos@ enable {{ service_name }}.service"
|
command: "systemctl --user -M cosmos@ enable {{ item.service_name }}.service"
|
||||||
|
|
||||||
- name: Chrome Kiosk - user start service
|
- name: Chrome Kiosk - user start service
|
||||||
command: "systemctl --user -M cosmos@ start {{ service_name }}.service"
|
command: "systemctl --user -M cosmos@ start {{ item.service_name }}.service"
|
||||||
|
|
||||||
loop: "{{ timelapse_script_templates }}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
@ -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
|
||||||
|
|
||||||
...
|
...
|
||||||
@ -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
135
tasks/service_control.yaml
Normal 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 }}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
...
|
||||||
@ -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 }}"
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
15
templates/service_control.service.j2
Normal file
15
templates/service_control.service.j2
Normal 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
|
||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user