Browse Source

mesh ui start

main
gsd 6 months ago
parent
commit
19debf4747
  1. 13
      pipboyMESH/mesh_server.py
  2. 3
      pipboyMESH/readme
  3. 3
      pipboyUI/angular.json
  4. 4
      pipboyUI/dist/pipboy-ui/index.html
  5. 1
      pipboyUI/dist/pipboy-ui/main.5af7ce4997d859e2.js
  6. 1
      pipboyUI/dist/pipboy-ui/main.dcb951af32c9d3b0.js
  7. 10
      pipboyUI/proxy.conf.json
  8. 5
      pipboyUI/src/app/app-routing.module.ts
  9. 5
      pipboyUI/src/app/app.module.ts
  10. 50
      pipboyUI/src/app/components/UpperHeaders/meshtastic-header.component.ts
  11. 6
      pipboyUI/src/app/components/upper-header.component.ts
  12. 101
      pipboyUI/src/app/services/MeshtasticService.ts
  13. 16
      pipboyWEB/nginx.conf
  14. 3
      pipboyWEB/update.sh

13
pipboyMESH/mesh_server.py

@ -80,7 +80,7 @@ class Servlet:
self.msh_state = AVAILABLE
self.lstChange["state"] = time()
await self.ws_update({"event": WS_EVENT_STATE, "data": self.msh_state})
await self.ws_update({"event": WS_EVENT_MYID, "data": self.device.my_node_id})
await self.ws_update({"event": WS_EVENT_MYID, "data": self.device.nid})
while True:
self.pulse = time()
@ -148,10 +148,15 @@ class Servlet:
try:
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_MYID, "data": self.device.nid})
#await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_MYNODE, "data": self.nodes.get(self.device.nid).__dict__ if self.device.nid in self.nodes else None})
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_CHANNEL, "data": [channel.__dict__ for channel in self.channels.values()]})
for channel in self.channels.values():
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_CHANNEL, "data": channel.__dict__})
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_STATE, "data": self.msh_state})
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_NODE, "data": [{"id": node.num, "name": str(node)} for node in self.nodes.values()]})
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_MESSAGE, "data": [message.__dict__ for message in self.message]})
for node in self.nodes.values():
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_NODE, "data": {"id": node.num, "name": str(node)}})
for message in self.message:
await websocket.send_json({"type":WS_TYPE_INIT, "event": WS_EVENT_MESSAGE, "data": message.__dict__})
except:
traceback.print_exc()
pass

3
pipboyMESH/readme

@ -1,3 +1,6 @@
Created on MiniMeshT (https://github.com/allanrbo/MiniMeshT)
need install fastapi uvicorn
python3 -m pip install --user --break-system-packages pyserial-asyncio
python3 -m pip install --user --break-system-packages uvicorn[standart] fastapi

3
pipboyUI/angular.json

@ -68,6 +68,9 @@
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"proxyConfig": "proxy.conf.json"
},
"configurations": {
"production": {
"browserTarget": "pipboyUI:build:production"

4
pipboyUI/dist/pipboy-ui/index.html

File diff suppressed because one or more lines are too long

1
pipboyUI/dist/pipboy-ui/main.5af7ce4997d859e2.js

File diff suppressed because one or more lines are too long

1
pipboyUI/dist/pipboy-ui/main.dcb951af32c9d3b0.js

File diff suppressed because one or more lines are too long

10
pipboyUI/proxy.conf.json

@ -0,0 +1,10 @@
{
"/mesh/api": {
"target": "http://127.0.0.1:8868/",
"secure": false
},
"/mesh/ws": {
"target": "http://127.0.0.1:8868/",
"secure": false,
"ws":true
}}

5
pipboyUI/src/app/app-routing.module.ts

@ -10,6 +10,7 @@ import {RadioHeaderComponent} from "./components/UpperHeaders/radio-header.compo
import {StatusLowerHeaderComponent} from "./components/LowerHeaders/Stats/status-lower-header.component";
import {InventoryAppsComponent} from "./components/LowerHeaders/Inventory/inventory-apps.component";
import {InventoryCustomComponent} from "./components/LowerHeaders/Inventory/inventory-custom.component";
import {MeshtasticHeaderComponent} from "./components/UpperHeaders/meshtastic-header.component";
const routes: Routes = [
{
@ -48,6 +49,10 @@ const routes: Routes = [
{
path: 'radio',
component: RadioHeaderComponent
},
{
path: 'mesh',
component: MeshtasticHeaderComponent
}
]
}

5
pipboyUI/src/app/app.module.ts

@ -22,6 +22,7 @@ import {WsService} from "./services/WsService";
import {IframeAppComponent} from "./components/apps/iframe-app.component";
import {RadioComponent} from "./components/LowerHeaders/Radio/radio.component";
import {KeyboardAppComponent} from "./components/apps/keyboard-app.component";
import {MeshtasticHeaderComponent} from "./components/UpperHeaders/meshtastic-header.component";
@NgModule({
declarations: [
@ -38,7 +39,9 @@ import {KeyboardAppComponent} from "./components/apps/keyboard-app.component";
ClockDialogApp,
IframeAppComponent,
RadioComponent,
KeyboardAppComponent
KeyboardAppComponent,
//
MeshtasticHeaderComponent
],
imports: [
BrowserModule,

50
pipboyUI/src/app/components/UpperHeaders/meshtastic-header.component.ts

@ -0,0 +1,50 @@
import {Component} from "@angular/core";
import {
AVAILABLE,
ERR,
MeshtasticService,
NOT_CONNECTED,
RECONNECT,
WAIT_CONFIG
} from "../../services/MeshtasticService";
@Component({
selector: "app-meshtastic-header",
template: `
<div style="display: flex; align-items: center; justify-content: flex-start; padding-left: 45px">
<p>MY</p>
<p>NODES</p>
<p *ngFor="let c of meshtastic.channels">{{c.name}}</p>
</div>
<div style="padding-top: 2.5%">
<!--<router-outlet></router-outlet>-->
</div>
<div class="footer">
<div style="display: flex; justify-content: space-between; height: 100%">
<div class="footer-text" style="width: 30%">
<span>{{getMeshState()}}</span>
</div>
<div class="footer-text" style="width: 49%">
<span>{{meshtastic.getMyMesh().name}}</span>
</div>
<div class="footer-text" style="width: 20%">
<span>{{meshtastic.nodes.length}} nodes</span>
</div>
</div>
</div>`
})
export class MeshtasticHeaderComponent {
constructor(public meshtastic: MeshtasticService) {
}
getMeshState(): string {
switch (this.meshtastic.state) {
case NOT_CONNECTED: return "Не подключен";
case WAIT_CONFIG: return "Ожидания конфигурации";
case AVAILABLE: return "Доступен";
case ERR: return "Ошибка модуля";
case RECONNECT: return "Переподключение";
default: return "Хуй знает";
}
}
}

6
pipboyUI/src/app/components/upper-header.component.ts

@ -7,6 +7,7 @@ import {MapHeaderComponent} from "./UpperHeaders/map-header.component";
import {RadioHeaderComponent} from "./UpperHeaders/radio-header.component";
import {AbsNavsHeaderComponent} from "./abstract/abs-navs-header.component";
import {IOService} from "../services/IOService";
import {MeshtasticHeaderComponent} from "./UpperHeaders/meshtastic-header.component";
@Component({
selector: "ui",
@ -32,9 +33,10 @@ export class UpperHeader extends AbsNavsHeaderComponent {
super.navs = [
{name: "stat", path: "stats", action: () => {}, component: StatsHeaderComponent.name},
{name: "inv", path: "inventory", action: () => {}, component: InvHeaderComponent.name},
{name: "data", path: "data", action: () => {}, component: DataHeaderComponent.name},
//{name: "data", path: "data", action: () => {}, component: DataHeaderComponent.name},
{name: "map", path: "map", action: () => {}, component: MapHeaderComponent.name},
{name: "radio", path: "radio", action: () => {}, component: RadioHeaderComponent.name}];
{name: "radio", path: "radio", action: () => {}, component: RadioHeaderComponent.name},
{name: "mesh", path: "mesh", action: () => {}, component: MeshtasticHeaderComponent.name}];
}

101
pipboyUI/src/app/services/MeshtasticService.ts

@ -0,0 +1,101 @@
import {Injectable} from "@angular/core";
import {WebSocketSubject} from "rxjs/internal/observable/dom/WebSocketSubject";
import {webSocket} from "rxjs/webSocket";
import {BehaviorSubject} from "rxjs";
export const WS_EVENT_CHANNEL = 0;
export const WS_EVENT_NODE = 1;
export const WS_EVENT_STATE = 2;
export const WS_EVENT_MESSAGE = 3;
export const WS_EVENT_MYID = 4;
export const WS_TYPE_INIT = 0;
export const WS_TYPE_NEW = 1;
export const WS_TYPE_FRONTEND = 2;
export const NOT_CONNECTED = 0;
export const WAIT_CONFIG = 1;
export const AVAILABLE = 2;
export const ERR = 3;
export const RECONNECT = 4;
interface MeshNodeShort {
id: number;
name: string;
}
interface MeshChannel {
index: number;
name: string;
}
@Injectable({
providedIn: 'root'
})
export class MeshtasticService {
private socket$?: WebSocketSubject<any>;
public channels: MeshChannel[] = [];
public nodes: MeshNodeShort[] = [];
public messages = new BehaviorSubject('{}')
public state: number = NOT_CONNECTED;
public meshId: number = 0;
constructor() {
this.connect();
}
public getMyMesh(): MeshNodeShort {
if (this.meshId == 0)
return {name: "Неизвестно", id: 0};
else {
let m: MeshNodeShort[] = this.nodes.filter(node => node.id == this.meshId);
// @ts-ignore
return m.length > 0 ? m.pop() : {name: "Неизвестно", id: 0};
}
}
private connect() {
this.socket$ = webSocket(`ws://${location.host}/mesh/ws`)
this.socket$.subscribe(
(parsed: {type: number, event: number, data: any}) => {
switch (parsed.event) {
case WS_EVENT_MYID: {
this.meshId = parsed.data;
break;
}
case WS_EVENT_NODE: {
const node: MeshNodeShort = parsed.data;
const s_node: MeshNodeShort[] = this.nodes.filter(n => n.id == node.id)
if (s_node.length == 0)
this.nodes.push(node)
else {
let idx = this.nodes.indexOf(s_node[0])
this.nodes[idx] = node
}
break;
}
case WS_EVENT_STATE: {
this.state = parsed.data;
break;
}
case WS_EVENT_CHANNEL: {
const channel: MeshChannel = parsed.data;
const s_channel: MeshChannel[] = this.channels.filter(ch => ch.index == channel.index);
if (s_channel.length == 0)
this.channels.push(channel)
else {
let idx = this.channels.indexOf(s_channel[0]);
this.channels[idx] = channel;
}
break;
}
}
},
(err) => {}
)
}
}

16
pipboyWEB/nginx.conf

@ -9,6 +9,22 @@ server {
try_files $uri $uri/ /index.html;
}
location /mesh/ws {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8868;
}
location /mesh/api/ {
proxy_pass http://127.0.0.1:8868;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Кэширование статических ресурсов
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|ttf)$ {
expires 1y;

3
pipboyWEB/update.sh

@ -1,3 +1,6 @@
#!/bin/bash
sudo systemctl stop nginx
sudo rm -rf /var/www/html
sudo cp -r /home/pipboy/Pipboy3Kmark4/pipboyUI/dist/pipboy-ui /var/www/html
sudo nginx -t
sudo systemctl start nginx
Loading…
Cancel
Save