Compare commits
15 Commits
s-allius/i
...
s-allius/i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5623231aec | ||
|
|
c5f25b5728 | ||
|
|
0e99551064 | ||
|
|
5c2be5b0c7 | ||
|
|
c591bba8b1 | ||
|
|
73d7593505 | ||
|
|
ccf21d5355 | ||
|
|
62f1f63baf | ||
|
|
3293e6741f | ||
|
|
b79112b005 | ||
|
|
d2849e0e1e | ||
|
|
46ebfd9751 | ||
|
|
d7769599d2 | ||
|
|
d1b21abc4d | ||
|
|
f799bf9a17 |
@@ -7,13 +7,18 @@ from modbus import Modbus
|
|||||||
from messages import Message
|
from messages import Message
|
||||||
from cnf.config import Config
|
from cnf.config import Config
|
||||||
from singleton import Singleton
|
from singleton import Singleton
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
logger_mqtt = logging.getLogger('mqtt')
|
logger_mqtt = logging.getLogger('mqtt')
|
||||||
|
|
||||||
|
|
||||||
class Mqtt(metaclass=Singleton):
|
class Mqtt(metaclass=Singleton):
|
||||||
__client = None
|
__client: aiomqtt.Client = None
|
||||||
__cb_mqtt_is_up = None
|
__cb_mqtt_is_up = None
|
||||||
|
ctime = None
|
||||||
|
published: int = 0
|
||||||
|
received: int = 0
|
||||||
|
|
||||||
def __init__(self, cb_mqtt_is_up):
|
def __init__(self, cb_mqtt_is_up):
|
||||||
logger_mqtt.debug('MQTT: __init__')
|
logger_mqtt.debug('MQTT: __init__')
|
||||||
@@ -52,6 +57,7 @@ class Mqtt(metaclass=Singleton):
|
|||||||
| int | float | None = None) -> None:
|
| int | float | None = None) -> None:
|
||||||
if self.__client:
|
if self.__client:
|
||||||
await self.__client.publish(topic, payload)
|
await self.__client.publish(topic, payload)
|
||||||
|
self.published += 1
|
||||||
|
|
||||||
async def __loop(self) -> None:
|
async def __loop(self) -> None:
|
||||||
mqtt = Config.get('mqtt')
|
mqtt = Config.get('mqtt')
|
||||||
@@ -69,6 +75,9 @@ class Mqtt(metaclass=Singleton):
|
|||||||
try:
|
try:
|
||||||
async with self.__client:
|
async with self.__client:
|
||||||
logger_mqtt.info('MQTT broker connection established')
|
logger_mqtt.info('MQTT broker connection established')
|
||||||
|
self.ctime = datetime.now()
|
||||||
|
self.published = 0
|
||||||
|
self.received = 0
|
||||||
|
|
||||||
if self.__cb_mqtt_is_up:
|
if self.__cb_mqtt_is_up:
|
||||||
await self.__cb_mqtt_is_up()
|
await self.__cb_mqtt_is_up()
|
||||||
@@ -84,6 +93,8 @@ class Mqtt(metaclass=Singleton):
|
|||||||
await self.dispatch_msg(message)
|
await self.dispatch_msg(message)
|
||||||
|
|
||||||
except aiomqtt.MqttError:
|
except aiomqtt.MqttError:
|
||||||
|
self.ctime = None
|
||||||
|
|
||||||
if Config.is_default('mqtt'):
|
if Config.is_default('mqtt'):
|
||||||
logger_mqtt.info(
|
logger_mqtt.info(
|
||||||
"MQTT is unconfigured; Check your config.toml!")
|
"MQTT is unconfigured; Check your config.toml!")
|
||||||
@@ -101,11 +112,14 @@ class Mqtt(metaclass=Singleton):
|
|||||||
return
|
return
|
||||||
except Exception:
|
except Exception:
|
||||||
# self.inc_counter('SW_Exception') # fixme
|
# self.inc_counter('SW_Exception') # fixme
|
||||||
|
self.ctime = None
|
||||||
logger_mqtt.error(
|
logger_mqtt.error(
|
||||||
f"Exception:\n"
|
f"Exception:\n"
|
||||||
f"{traceback.format_exc()}")
|
f"{traceback.format_exc()}")
|
||||||
|
|
||||||
async def dispatch_msg(self, message):
|
async def dispatch_msg(self, message):
|
||||||
|
self.received += 1
|
||||||
|
|
||||||
if message.topic.matches(self.ha_status_topic):
|
if message.topic.matches(self.ha_status_topic):
|
||||||
status = message.payload.decode("UTF-8")
|
status = message.payload.decode("UTF-8")
|
||||||
logger_mqtt.info('Home-Assistant Status:'
|
logger_mqtt.info('Home-Assistant Status:'
|
||||||
|
|||||||
@@ -145,6 +145,10 @@ def main(): # pragma: no cover
|
|||||||
serv_name = os.getenv('SERVICE_NAME', 'proxy')
|
serv_name = os.getenv('SERVICE_NAME', 'proxy')
|
||||||
version = os.getenv('VERSION', 'unknown')
|
version = os.getenv('VERSION', 'unknown')
|
||||||
|
|
||||||
|
@app.context_processor
|
||||||
|
def utility_processor():
|
||||||
|
return dict(version=version)
|
||||||
|
|
||||||
setattr(logging.handlers, "log_path", args.log_path)
|
setattr(logging.handlers, "log_path", args.log_path)
|
||||||
setattr(logging.handlers, "log_backups", args.log_backups)
|
setattr(logging.handlers, "log_backups", args.log_backups)
|
||||||
os.makedirs(args.log_path, exist_ok=True)
|
os.makedirs(args.log_path, exist_ok=True)
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ def _get_row(inv: InverterBase):
|
|||||||
def get_table_data():
|
def get_table_data():
|
||||||
'''build the connection table'''
|
'''build the connection table'''
|
||||||
table = {
|
table = {
|
||||||
|
"headline": _('Connections'),
|
||||||
"col_classes": [
|
"col_classes": [
|
||||||
"w3-hide-small w3-hide-medium", "w3-hide-large",
|
"w3-hide-small w3-hide-medium", "w3-hide-large",
|
||||||
"",
|
"",
|
||||||
@@ -75,7 +76,7 @@ async def data_fetch():
|
|||||||
"proxy-cnt": f"<h3>{Infos.get_counter('ProxyMode_Cnt')}</h3>",
|
"proxy-cnt": f"<h3>{Infos.get_counter('ProxyMode_Cnt')}</h3>",
|
||||||
"emulation-cnt": f"<h3>{Infos.get_counter('EmuMode_Cnt')}</h3>",
|
"emulation-cnt": f"<h3>{Infos.get_counter('EmuMode_Cnt')}</h3>",
|
||||||
}
|
}
|
||||||
data["conn-table"] = await render_template('templ_conn_table.html.j2',
|
data["conn-table"] = await render_template('templ_table.html.j2',
|
||||||
table=get_table_data())
|
table=get_table_data())
|
||||||
|
|
||||||
data["notes-list"] = await render_template('templ_notes_list.html.j2')
|
data["notes-list"] = await render_template('templ_notes_list.html.j2')
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ async def file_fetch():
|
|||||||
data["file-list"] = await render_template('templ_log_files_list.html.j2',
|
data["file-list"] = await render_template('templ_log_files_list.html.j2',
|
||||||
dir_list=get_list_data())
|
dir_list=get_list_data())
|
||||||
|
|
||||||
data["notes-list"] = await render_template('templ_notes_list.html.j2')
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
58
app/src/web/mqtt_table.py
Normal file
58
app/src/web/mqtt_table.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
from inverter_base import InverterBase
|
||||||
|
from quart import render_template
|
||||||
|
from quart_babel import format_datetime, _
|
||||||
|
from mqtt import Mqtt
|
||||||
|
|
||||||
|
from . import web
|
||||||
|
|
||||||
|
|
||||||
|
def _get_row(inv: InverterBase):
|
||||||
|
'''build one row for the connection table'''
|
||||||
|
entity_prfx = inv.entity_prfx
|
||||||
|
inv_serial = inv.local.stream.inv_serial
|
||||||
|
node_id = inv.local.stream.node_id
|
||||||
|
sug_area = inv.local.stream.sug_area
|
||||||
|
|
||||||
|
row = []
|
||||||
|
row.append(inv_serial)
|
||||||
|
row.append(entity_prfx+node_id)
|
||||||
|
row.append(sug_area)
|
||||||
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
def get_table_data():
|
||||||
|
'''build the connection table'''
|
||||||
|
table = {
|
||||||
|
"headline": _('MQTT devices'),
|
||||||
|
"col_classes": [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
"thead": [[
|
||||||
|
_("Serial-No"),
|
||||||
|
_('Node-ID'),
|
||||||
|
_('HA-Area'),
|
||||||
|
]],
|
||||||
|
"tbody": []
|
||||||
|
}
|
||||||
|
for inverter in InverterBase:
|
||||||
|
table['tbody'].append(_get_row(inverter))
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
@web.route('/mqtt-fetch')
|
||||||
|
async def mqtt_fetch():
|
||||||
|
mqtt = Mqtt(None)
|
||||||
|
ctime = format_datetime(dt=mqtt.ctime, format='short')
|
||||||
|
data = {
|
||||||
|
"update-time": format_datetime(format="medium"),
|
||||||
|
"mqtt-ctime": f"<h3>{ctime}</h3>",
|
||||||
|
"mqtt-tx": f"<h3>{mqtt.published}</h3>",
|
||||||
|
"mqtt-rx": f"<h3>{mqtt.received}</h3>",
|
||||||
|
}
|
||||||
|
data["mqtt-table"] = await render_template('templ_table.html.j2',
|
||||||
|
table=get_table_data())
|
||||||
|
|
||||||
|
return data
|
||||||
@@ -11,9 +11,11 @@ async def index():
|
|||||||
fetch_url=url_for('.data_fetch'))
|
fetch_url=url_for('.data_fetch'))
|
||||||
|
|
||||||
|
|
||||||
@web.route('/page')
|
@web.route('/mqtt')
|
||||||
async def empty():
|
async def mqtt():
|
||||||
return await render_template('empty.html.j2')
|
return await render_template(
|
||||||
|
'page_mqtt.html.j2',
|
||||||
|
fetch_url=url_for('.mqtt_fetch'))
|
||||||
|
|
||||||
|
|
||||||
@web.route('/logging')
|
@web.route('/logging')
|
||||||
|
|||||||
@@ -41,12 +41,12 @@
|
|||||||
|
|
||||||
<!-- Sidebar/menu -->
|
<!-- Sidebar/menu -->
|
||||||
<nav class="w3-sidebar w3-collapse w3-white" style="z-index:3;width:250px;" id="mySidebar"><br>
|
<nav class="w3-sidebar w3-collapse w3-white" style="z-index:3;width:250px;" id="mySidebar"><br>
|
||||||
<div class="w3-container w3-row">
|
<div class="w3-container w3-cell-row">
|
||||||
<div class="w3-col s4">
|
<div class="w3-cell w3-cell-middle">
|
||||||
<img src="{{url_for('static', filename= 'images/favicon.svg') }}" alt="" class="w3-circle w3-margin-right" style="width:60px">
|
<img src="{{url_for('static', filename= 'images/favicon.svg') }}" alt="" class="w3-circle w3-margin-right" style="width:60px">
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-col s8 w3-bar">
|
<div class="w3-cell">
|
||||||
<h3>TSUN-Proxy</h3><br>
|
<span><b class="w3-xlarge">TSUN-Proxy</b><br>{{_('Version:')}} {{version}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<div class="w3-bar-block">
|
<div class="w3-bar-block">
|
||||||
<button href="#" class="w3-bar-item w3-button w3-padding-16 w3-hide-large w3-dark-grey w3-hover-black" onclick="w3_close()" title="close menu"><i class="fa fa-remove fa-fw"></i> Close Menu</button>
|
<button href="#" class="w3-bar-item w3-button w3-padding-16 w3-hide-large w3-dark-grey w3-hover-black" onclick="w3_close()" title="close menu"><i class="fa fa-remove fa-fw"></i> Close Menu</button>
|
||||||
<a href="{{ url_for('.index')}}" class="w3-bar-item w3-button w3-padding {% block menu1_class %}{% endblock %}"><i class="fa fa-network-wired fa-fw"></i> {{_('Connections')}}</a>
|
<a href="{{ url_for('.index')}}" class="w3-bar-item w3-button w3-padding {% block menu1_class %}{% endblock %}"><i class="fa fa-network-wired fa-fw"></i> {{_('Connections')}}</a>
|
||||||
<a href="{{ url_for('.empty')}}" class="w3-bar-item w3-button w3-padding {% block menu2_class %}{% endblock %}"><i class="fa fa-database fa-fw"></i> MQTT</a>
|
<a href="{{ url_for('.mqtt')}}" class="w3-bar-item w3-button w3-padding {% block menu2_class %}{% endblock %}"><i class="fa fa-database fa-fw"></i> MQTT</a>
|
||||||
<a href="{{ url_for('.logging')}}" class="w3-bar-item w3-button w3-padding {% block menu3_class %}{% endblock %}"><i class="fa fa-file-export fa-fw"></i> {{_('Log Files')}}</a>
|
<a href="{{ url_for('.logging')}}" class="w3-bar-item w3-button w3-padding {% block menu3_class %}{% endblock %}"><i class="fa fa-file-export fa-fw"></i> {{_('Log Files')}}</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{% extends 'base.html.j2' %}
|
|
||||||
|
|
||||||
{% block title %} TSUN Proxy - View {% endblock title%}
|
|
||||||
{% block menu2_class %}w3-blue{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
{% endblock content%}
|
|
||||||
|
|
||||||
{% block footer %}{% endblock footer %}
|
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="w3-row-padding w3-margin-bottom">
|
<div class="w3-row-padding w3-margin-bottom">
|
||||||
<div class="w3-quarter">
|
<div class="w3-quarter">
|
||||||
|
<div class="w3-card-4">
|
||||||
<div class="w3-container w3-indigo w3-padding-16">
|
<div class="w3-container w3-indigo w3-padding-16">
|
||||||
<div class="w3-left"><i class="fa fa-upload w3-xxxlarge fa-rotate-180"></i></div>
|
<div class="w3-left"><i class="fa fa-upload w3-xxxlarge fa-rotate-180"></i></div>
|
||||||
<div id = "server-cnt" class="w3-right">
|
<div id = "server-cnt" class="w3-right">
|
||||||
@@ -16,8 +17,10 @@
|
|||||||
<h4>{{_('Server Mode')}}</h4>
|
<h4>{{_('Server Mode')}}</h4>
|
||||||
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Established from device to proxy')}}</div>
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Established from device to proxy')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-quarter">
|
<div class="w3-quarter">
|
||||||
|
<div class="w3-card-4">
|
||||||
<div class="w3-container w3-purple w3-padding-16">
|
<div class="w3-container w3-purple w3-padding-16">
|
||||||
<div class="w3-left"><i class="fa fa-download w3-xxxlarge fa-rotate-180"></i></div>
|
<div class="w3-left"><i class="fa fa-download w3-xxxlarge fa-rotate-180"></i></div>
|
||||||
<div id = "client-cnt" class="w3-right">
|
<div id = "client-cnt" class="w3-right">
|
||||||
@@ -27,8 +30,10 @@
|
|||||||
<h4>{{_('Client Mode')}}</h4>
|
<h4>{{_('Client Mode')}}</h4>
|
||||||
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Established from proxy to device')}}</div>
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Established from proxy to device')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-quarter">
|
<div class="w3-quarter">
|
||||||
|
<div class="w3-card-4">
|
||||||
<div class="w3-container w3-orange w3-text-white w3-padding-16">
|
<div class="w3-container w3-orange w3-text-white w3-padding-16">
|
||||||
<div class="w3-left"><i class="fa fa-cloud w3-xxxlarge"></i></div>
|
<div class="w3-left"><i class="fa fa-cloud w3-xxxlarge"></i></div>
|
||||||
<div id = "proxy-cnt" class="w3-right">
|
<div id = "proxy-cnt" class="w3-right">
|
||||||
@@ -38,8 +43,10 @@
|
|||||||
<h4>{{_('Proxy Mode')}}</h4>
|
<h4>{{_('Proxy Mode')}}</h4>
|
||||||
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Forwarding data to cloud')}}</div>
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Forwarding data to cloud')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w3-quarter">
|
<div class="w3-quarter">
|
||||||
|
<div class="w3-card-4">
|
||||||
<div class="w3-container w3-teal w3-padding-16">
|
<div class="w3-container w3-teal w3-padding-16">
|
||||||
<div class="w3-left"><i class="fa fa-cloud-arrow-up-alt w3-xxxlarge"></i></div>
|
<div class="w3-left"><i class="fa fa-cloud-arrow-up-alt w3-xxxlarge"></i></div>
|
||||||
<div id = "emulation-cnt" class="w3-right">
|
<div id = "emulation-cnt" class="w3-right">
|
||||||
@@ -49,9 +56,12 @@
|
|||||||
<h4>{{_('Emu Mode')}}</h4>
|
<h4>{{_('Emu Mode')}}</h4>
|
||||||
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Emulation sends data to cloud')}}</div>
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Emulation sends data to cloud')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w3-container" id="notes-list"></div>
|
<div id="notes-list"></div>
|
||||||
<div class="w3-container" id="conn-table"></div>
|
<div id="conn-table"></div>
|
||||||
{% endblock content%}
|
{% endblock content%}
|
||||||
|
|
||||||
|
{% block footer %}{% endblock footer %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends 'base.html.j2' %}
|
{% extends 'base.html.j2' %}
|
||||||
|
|
||||||
{% block title %} TSUN Proxy - Downloads {% endblock title%}
|
{% block title %} TSUN Proxy - Log Files {% endblock title%}
|
||||||
{% block menu3_class %}w3-blue{% endblock %}
|
{% block menu3_class %}w3-blue{% endblock %}
|
||||||
{% block headline %}<i class="fa fa-file-export fa-fw"></i> {{_('Log Files')}}{% endblock headline %}
|
{% block headline %}<i class="fa fa-file-export fa-fw"></i> {{_('Log Files')}}{% endblock headline %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w3-container" id="file-list"></div>
|
<div id="file-list"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function deleteFile() {
|
function deleteFile() {
|
||||||
@@ -28,4 +28,3 @@
|
|||||||
{% endblock content%}
|
{% endblock content%}
|
||||||
|
|
||||||
{% block footer %}{% endblock footer %}
|
{% block footer %}{% endblock footer %}
|
||||||
|
|
||||||
|
|||||||
51
app/src/web/templates/page_mqtt.html.j2
Normal file
51
app/src/web/templates/page_mqtt.html.j2
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{% extends 'base.html.j2' %}
|
||||||
|
|
||||||
|
{% block title %} TSUN Proxy - MQTT Status {% endblock title%}
|
||||||
|
{% block menu2_class %}w3-blue{% endblock %}
|
||||||
|
{% block headline %}<i class="fa fa-database"></i> {{_('MQTT Overview')}}{% endblock headline %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="w3-row-padding w3-margin-bottom">
|
||||||
|
<div class="w3-third">
|
||||||
|
<div class="w3-card-4">
|
||||||
|
<div class="w3-container w3-indigo w3-padding-16">
|
||||||
|
<div class="w3-left"><i class="fa fa-link w3-xxxlarge"></i></div>
|
||||||
|
<div id = "mqtt-ctime" class="w3-right">
|
||||||
|
<h3>-</h3>
|
||||||
|
</div>
|
||||||
|
<div class="w3-clear"></div>
|
||||||
|
<h4>{{_('Connection Time')}}</h4>
|
||||||
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Time at which the connection was established')}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w3-third">
|
||||||
|
<div class="w3-card-4">
|
||||||
|
<div class="w3-container w3-purple w3-padding-16">
|
||||||
|
<div class="w3-left"><i class="fa fa-server w3-xxxlarge"></i></div>
|
||||||
|
<div id = "mqtt-tx" class="w3-right">
|
||||||
|
<h3>-</h3>
|
||||||
|
</div>
|
||||||
|
<div class="w3-clear"></div>
|
||||||
|
<h4>{{_('Published Topics')}}</h4>
|
||||||
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Number of published topics')}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w3-third">
|
||||||
|
<div class="w3-card-4">
|
||||||
|
<div class="w3-container w3-orange w3-text-white w3-padding-16">
|
||||||
|
<div class="w3-left"><i class="fa fa-user w3-xxxlarge"></i></div>
|
||||||
|
<div id = "mqtt-rx" class="w3-right">
|
||||||
|
<h3>-</h3>
|
||||||
|
</div>
|
||||||
|
<div class="w3-clear"></div>
|
||||||
|
<h4>{{_('Received Topics')}}</h4>
|
||||||
|
<div class="w3-hide-small w3-hide-medium" style="min-height:50px">{{_('Number of topics received')}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="mqtt-table"></div>
|
||||||
|
{% endblock content%}
|
||||||
|
|
||||||
|
{% block footer %}{% endblock footer %}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="w3-quarter w3-margin-bottom">
|
<div class="w3-quarter w3-margin-bottom">
|
||||||
|
|
||||||
<div class="w3-card-4">
|
<div class="w3-card-4">
|
||||||
<header class="w3-container w3-blue" style="min-height:80px">
|
<header class="w3-container w3-teal" style="min-height:80px">
|
||||||
<h4>{{file.name}}</h4>
|
<h4>{{file.name}}</h4>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<footer class="w3-blue">
|
<footer class="w3-teal">
|
||||||
<a href="{{ url_for('.send',file=file.name)}}" class="w3-button w3-hover-blue w3-hover-text-black"><i class="fa fa-file-download"></i> {{_('Download File')}}</a>
|
<a href="{{ url_for('.send',file=file.name)}}" class="w3-button w3-hover-teal w3-hover-text-black"><i class="fa fa-file-download"></i> {{_('Download File')}}</a>
|
||||||
<a class="w3-button w3-right w3-hover-blue w3-hover-text-black"
|
<a class="w3-button w3-right w3-hover-teal w3-hover-text-black"
|
||||||
onclick="document.getElementById('id03').innerHTML='{{file.name}}'; document.getElementById('id02').href='{{ url_for('.delete',file=file.name)}}'; document.getElementById('id01').style.display='block';"><i class="fa fa-trash"></i></a>
|
onclick="document.getElementById('id03').innerHTML='{{file.name}}'; document.getElementById('id02').href='{{ url_for('.delete',file=file.name)}}'; document.getElementById('id01').style.display='block';"><i class="fa fa-trash"></i></a>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,8 +12,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endmacro%}
|
{%- endmacro%}
|
||||||
|
|
||||||
<h5>{{_('Connections')}}</h5>
|
<div class="w3-container w3-margin-bottom">
|
||||||
<table class="w3-table w3-striped w3-bordered w3-border w3-hoverable w3-white">
|
<h5>{{table.headline}}</h5>
|
||||||
|
<div class="w3-card-4">
|
||||||
|
|
||||||
|
<table class="w3-table w3-bordered w3-hoverable w3-white">
|
||||||
{% if table.thead is defined%}
|
{% if table.thead is defined%}
|
||||||
<thead>
|
<thead>
|
||||||
{% for row in table.thead %}
|
{% for row in table.thead %}
|
||||||
@@ -35,3 +38,5 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -140,6 +140,7 @@ async def test_ha_reconnect(config_mqtt_conn):
|
|||||||
assert on_connect.is_set()
|
assert on_connect.is_set()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
assert m.received == 2
|
||||||
await m.close()
|
await m.close()
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from gen3plus.inverter_g3p import InverterG3P
|
|||||||
from test_inverter_g3p import FakeReader, FakeWriter, config_conn
|
from test_inverter_g3p import FakeReader, FakeWriter, config_conn
|
||||||
from cnf.config import Config
|
from cnf.config import Config
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
from proxy import Proxy
|
||||||
import os, errno
|
import os, errno
|
||||||
|
|
||||||
pytest_plugins = ('pytest_asyncio',)
|
pytest_plugins = ('pytest_asyncio',)
|
||||||
@@ -53,16 +54,16 @@ async def test_home(client):
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_page(client):
|
async def test_page(client):
|
||||||
"""Test the empty page route."""
|
"""Test the mqtt page route."""
|
||||||
response = await client.get('/page')
|
response = await client.get('/mqtt')
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.mimetype == 'text/html'
|
assert response.mimetype == 'text/html'
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_rel_page(client):
|
async def test_rel_page(client):
|
||||||
"""Test the empty page route."""
|
"""Test the mqtt route."""
|
||||||
web.build_relative_urls = True
|
web.build_relative_urls = True
|
||||||
response = await client.get('/page')
|
response = await client.get('/mqtt')
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.mimetype == 'text/html'
|
assert response.mimetype == 'text/html'
|
||||||
web.build_relative_urls = False
|
web.build_relative_urls = False
|
||||||
@@ -152,7 +153,7 @@ async def test_language_en(client):
|
|||||||
assert response.mimetype == 'text/html'
|
assert response.mimetype == 'text/html'
|
||||||
|
|
||||||
client.set_cookie('test', key='language', value='de')
|
client.set_cookie('test', key='language', value='de')
|
||||||
response = await client.get('/page')
|
response = await client.get('/mqtt')
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.mimetype == 'text/html'
|
assert response.mimetype == 'text/html'
|
||||||
|
|
||||||
@@ -174,6 +175,16 @@ async def test_language_unknown(client):
|
|||||||
assert response.mimetype == 'text/html'
|
assert response.mimetype == 'text/html'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_mqtt_fetch(client, create_inverter):
|
||||||
|
"""Test the mqtt-fetch route."""
|
||||||
|
_ = create_inverter
|
||||||
|
Proxy.class_init()
|
||||||
|
|
||||||
|
response = await client.get('/mqtt-fetch')
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_file_fetch(client, config_conn):
|
async def test_file_fetch(client, config_conn):
|
||||||
"""Test the data-fetch route."""
|
"""Test the data-fetch route."""
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: tsun-gen3-proxy 0.14.0\n"
|
"Project-Id-Version: tsun-gen3-proxy 0.14.0\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2025-05-02 17:00+0200\n"
|
"POT-Creation-Date: 2025-05-03 21:59+0200\n"
|
||||||
"PO-Revision-Date: 2025-04-18 16:24+0200\n"
|
"PO-Revision-Date: 2025-04-18 16:24+0200\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -19,34 +19,49 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.17.0\n"
|
"Generated-By: Babel 2.17.0\n"
|
||||||
|
|
||||||
#: src/web/conn_table.py:57
|
#: src/web/conn_table.py:51 src/web/templates/base.html.j2:58
|
||||||
|
msgid "Connections"
|
||||||
|
msgstr "Verbindungen"
|
||||||
|
|
||||||
|
#: src/web/conn_table.py:58
|
||||||
msgid "Device-IP:Port"
|
msgid "Device-IP:Port"
|
||||||
msgstr "Geräte-IP:Port"
|
msgstr "Geräte-IP:Port"
|
||||||
|
|
||||||
#: src/web/conn_table.py:57
|
#: src/web/conn_table.py:58
|
||||||
msgid "Device-IP"
|
msgid "Device-IP"
|
||||||
msgstr "Geräte-IP"
|
msgstr "Geräte-IP"
|
||||||
|
|
||||||
#: src/web/conn_table.py:58
|
#: src/web/conn_table.py:59 src/web/mqtt_table.py:33
|
||||||
msgid "Serial-No"
|
msgid "Serial-No"
|
||||||
msgstr "Seriennummer"
|
msgstr "Seriennummer"
|
||||||
|
|
||||||
#: src/web/conn_table.py:59
|
#: src/web/conn_table.py:60
|
||||||
msgid "Cloud-IP:Port"
|
msgid "Cloud-IP:Port"
|
||||||
msgstr "Cloud-IP:Port"
|
msgstr "Cloud-IP:Port"
|
||||||
|
|
||||||
#: src/web/conn_table.py:59
|
#: src/web/conn_table.py:60
|
||||||
msgid "Cloud-IP"
|
msgid "Cloud-IP"
|
||||||
msgstr "Cloud-IP"
|
msgstr "Cloud-IP"
|
||||||
|
|
||||||
|
#: src/web/mqtt_table.py:26
|
||||||
|
msgid "MQTT devices"
|
||||||
|
msgstr "MQTT Geräte"
|
||||||
|
|
||||||
|
#: src/web/mqtt_table.py:34
|
||||||
|
msgid "Node-ID"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/web/mqtt_table.py:35
|
||||||
|
msgid "HA-Area"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/web/templates/base.html.j2:37
|
#: src/web/templates/base.html.j2:37
|
||||||
msgid "Updated:"
|
msgid "Updated:"
|
||||||
msgstr "Aktualisiert:"
|
msgstr "Aktualisiert:"
|
||||||
|
|
||||||
#: src/web/templates/base.html.j2:58
|
#: src/web/templates/base.html.j2:49
|
||||||
#: src/web/templates/templ_conn_table.html.j2:15
|
msgid "Version:"
|
||||||
msgid "Connections"
|
msgstr ""
|
||||||
msgstr "Verbindungen"
|
|
||||||
|
|
||||||
#: src/web/templates/base.html.j2:60 src/web/templates/page_logging.html.j2:5
|
#: src/web/templates/base.html.j2:60 src/web/templates/page_logging.html.j2:5
|
||||||
msgid "Log Files"
|
msgid "Log Files"
|
||||||
@@ -56,35 +71,35 @@ msgstr "Log Dateien"
|
|||||||
msgid "Proxy Connection Overview"
|
msgid "Proxy Connection Overview"
|
||||||
msgstr "Proxy Verbindungen"
|
msgstr "Proxy Verbindungen"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:16
|
#: src/web/templates/page_index.html.j2:17
|
||||||
msgid "Server Mode"
|
msgid "Server Mode"
|
||||||
msgstr "Server Modus"
|
msgstr "Server Modus"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:17
|
#: src/web/templates/page_index.html.j2:18
|
||||||
msgid "Established from device to proxy"
|
msgid "Established from device to proxy"
|
||||||
msgstr "Vom Gerät zum Proxy aufgebaut"
|
msgstr "Vom Gerät zum Proxy aufgebaut"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:27
|
#: src/web/templates/page_index.html.j2:30
|
||||||
msgid "Client Mode"
|
msgid "Client Mode"
|
||||||
msgstr "Client Modus"
|
msgstr "Client Modus"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:28
|
#: src/web/templates/page_index.html.j2:31
|
||||||
msgid "Established from proxy to device"
|
msgid "Established from proxy to device"
|
||||||
msgstr "Vom Proxy zum Gerät aufgebaut"
|
msgstr "Vom Proxy zum Gerät aufgebaut"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:38
|
#: src/web/templates/page_index.html.j2:43
|
||||||
msgid "Proxy Mode"
|
msgid "Proxy Mode"
|
||||||
msgstr "Proxy Modus"
|
msgstr "Proxy Modus"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:39
|
#: src/web/templates/page_index.html.j2:44
|
||||||
msgid "Forwarding data to cloud"
|
msgid "Forwarding data to cloud"
|
||||||
msgstr "Weiterleitung in die Cloud"
|
msgstr "Weiterleitung in die Cloud"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:49
|
#: src/web/templates/page_index.html.j2:56
|
||||||
msgid "Emu Mode"
|
msgid "Emu Mode"
|
||||||
msgstr "Emu Modus"
|
msgstr "Emu Modus"
|
||||||
|
|
||||||
#: src/web/templates/page_index.html.j2:50
|
#: src/web/templates/page_index.html.j2:57
|
||||||
msgid "Emulation sends data to cloud"
|
msgid "Emulation sends data to cloud"
|
||||||
msgstr "Emulation sendet in die Cloud"
|
msgstr "Emulation sendet in die Cloud"
|
||||||
|
|
||||||
@@ -100,6 +115,34 @@ msgstr "File löschen"
|
|||||||
msgid "Abort"
|
msgid "Abort"
|
||||||
msgstr "Abbruch"
|
msgstr "Abbruch"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:5
|
||||||
|
msgid "MQTT Overview"
|
||||||
|
msgstr "MQTT Überblick"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:16
|
||||||
|
msgid "Connection Time"
|
||||||
|
msgstr "Verbindungszeit"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:17
|
||||||
|
msgid "Time at which the connection was established"
|
||||||
|
msgstr "Zeitpunkt des Verbindungsaufbaus"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:29
|
||||||
|
msgid "Published Topics"
|
||||||
|
msgstr "Gesendete Topics"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:30
|
||||||
|
msgid "Number of published topics"
|
||||||
|
msgstr "Anzahl der veröffentlichten Topics"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:42
|
||||||
|
msgid "Received Topics"
|
||||||
|
msgstr "Empfangene Topics"
|
||||||
|
|
||||||
|
#: src/web/templates/page_mqtt.html.j2:43
|
||||||
|
msgid "Number of topics received"
|
||||||
|
msgstr "Anzahl der empfangenen Topics"
|
||||||
|
|
||||||
#: src/web/templates/templ_log_files_list.html.j2:11
|
#: src/web/templates/templ_log_files_list.html.j2:11
|
||||||
msgid "Created"
|
msgid "Created"
|
||||||
msgstr "Erzeugt"
|
msgstr "Erzeugt"
|
||||||
@@ -116,3 +159,24 @@ msgstr "Größe"
|
|||||||
msgid "Download File"
|
msgid "Download File"
|
||||||
msgstr "Datei Download"
|
msgstr "Datei Download"
|
||||||
|
|
||||||
|
#~ msgid "MQTT Server"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "MQTT User"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "MQTT Connected"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Home Assistant Status"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "MQTT Publish Count"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "MQTT Reveiced Count"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "MQTT Connect Time"
|
||||||
|
#~ msgstr "MQTT Verbindungszeit"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user