Skip to content

Commit

Permalink
Merge pull request #46 from tpanajott/devel
Browse files Browse the repository at this point in the history
Merge devel into main
  • Loading branch information
tpanajott authored Jun 30, 2023
2 parents 14485a4 + 385a924 commit bd06d7f
Show file tree
Hide file tree
Showing 70 changed files with 2,503 additions and 1,761 deletions.
Binary file modified HMI files/nspmanager.HMI
Binary file not shown.
Binary file modified HMI files/nspmanager.tft
Binary file not shown.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Logging from NSPanels are done over MQTT to the topic `nspanel/<panel name>/log`
|nspanel/panel_name/r1_state| 1 or 0 |Current relay 1 state, 1 or 0|
|nspanel/panel_name/r2_cmd| 1 or 0 |Control relay 2 state, 1 or 0|
|nspanel/panel_name/r2_state| 1 or 0 |Current relay 2 state, 1 or 0|
|nspanel/panel_name/temperature_state| temperature reading |Current temperature reading|

# Currently working (but might require more work)
* Integration with Home Assistant and OpenHAB
Expand Down
13 changes: 6 additions & 7 deletions docker/web/mqtt_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ def on_message(client, userdata, msg):
parts = msg.topic.split('/')
# Messages received was a status update (online/offline)
if parts[-1] == "log":
message_parts = msg.payload.decode('utf-8').split(':')
message_parts = msg.payload.decode('utf-8').split(';')
data = {
"type": "log",
"time": datetime.datetime.now().strftime("%H:%M:%S"),
"panel": parts[1],
"level": message_parts[0],
"message": ':'.join(message_parts[1:])
"mac": message_parts[0],
"level": message_parts[1],
"message": ':'.join(message_parts[2:])
}
mqtt_manager_libs.websocket_server.send_message(json.dumps(data))
elif parts[-1] == "status":
Expand All @@ -87,8 +88,7 @@ def on_message(client, userdata, msg):
"type": "status",
"payload": data
}
mqtt_manager_libs.websocket_server.send_message(
json.dumps(ws_data))
mqtt_manager_libs.websocket_server.send_message(json.dumps(ws_data))
elif parts[-1] == "status_report":
panel = parts[1]
data = json.loads(msg.payload.decode('utf-8'))
Expand All @@ -97,8 +97,7 @@ def on_message(client, userdata, msg):
"type": "status_report",
"payload": data
}
mqtt_manager_libs.websocket_server.send_message(
json.dumps(ws_data))
mqtt_manager_libs.websocket_server.send_message(json.dumps(ws_data))
elif msg.topic == "nspanel/mqttmanager/command":
data = json.loads(msg.payload.decode('utf-8'))
# Verify that the mac_origin is off a panel that is controlled by this instance
Expand Down
2 changes: 2 additions & 0 deletions docker/web/mqtt_manager_libs/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ def set_light_level(self, light_level: int):
logging.info(F"Sending kelvin update to OpenHAB for light {self.friendly_name}. Light was off previously.")
mqtt_manager_libs.openhab.set_entity_color_temp(self.openhab_item_color_temp, self.color_temp)
self.light_level = int(light_level)
self.last_mode_change = time.time()*1000
elif self.last_command_sent == "rgb":
logging.info(F"Sending light update to OpenHAB for light {self.friendly_name}. Sending RGB value: {light_level}")
if mqtt_manager_libs.openhab.set_entity_color_saturation(self.openhab_item_rgb, int(light_level), self.color_saturation, self.color_hue):
self.light_level = int(light_level)
self.last_mode_change = time.time()*1000
else:
logging.error("Unknown OpenHAB light state. Last command sent: " + self.last_command_sent)

Expand Down
13 changes: 9 additions & 4 deletions docker/web/mqtt_manager_libs/openhab.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
stop_keepalive = False
settings = {}

def millis():
return round(time() * 1000)


def init(settings_from_manager, mqtt_client_from_manager):
global openhab_url, openhab_token, settings, mqtt_client
Expand All @@ -38,7 +41,7 @@ def on_message(ws, message):
for light in mqtt_manager_libs.light_states.states.values():
try:
if light.type == "openhab":
current_time_ms = time()*1000
current_time_ms = millis()
if light.openhab_control_mode == "dimmer" and item == light.openhab_item_name:
light_level_pct = int(float(payload["value"]))
mqtt_client.publish(F"nspanel/entities/light/{light.id}/state_brightness_pct", light_level_pct, retain=True)
Expand All @@ -61,6 +64,7 @@ def on_message(ws, message):
mqtt_client.publish(F"nspanel/entities/light/{light.id}/state_kelvin", send_color_temp, retain=True)
light.color_temp = send_color_temp
light.last_command_sent = "color_temp"
light.last_mode_change = current_time_ms
return None
elif item == light.openhab_item_rgb and (current_time_ms >= light.last_mode_change + 1000 or light.last_command_sent == "rgb"):
#hue, sat, brightness = payload["value"]
Expand All @@ -74,9 +78,10 @@ def on_message(ws, message):
mqtt_client.publish(F"nspanel/entities/light/{light.id}/state_sat", light.color_saturation, retain=True)
mqtt_client.publish(F"nspanel/entities/light/{light.id}/state_brightness_pct", light.light_level, retain=True)
light.last_command_sent = "rgb"
light.last_mode_change = current_time_ms
return None

logging.info(F"Got state update event for light not managed by NSPanelManager. Topic: " + json_msg["topic"])
else:
logging.info(F"Got state update event for light not managed by NSPanelManager. Message: {message}")
except Exception as e:
traceback.print_exc()

Expand Down Expand Up @@ -156,7 +161,7 @@ def set_entity_brightness(openhab_item_name: str, openhab_control_mode: str, lig
# Format OpenHAB state update
if light_level > 0:
onoff = "ON"
if light_level <= 0:
elif light_level <= 0:
onoff = "OFF"

msg = {
Expand Down
Binary file modified docker/web/nspanelmanager/data_file.bin
Binary file not shown.
Binary file modified docker/web/nspanelmanager/firmware.bin
Binary file not shown.
Binary file modified docker/web/nspanelmanager/gui.tft
Binary file not shown.
9 changes: 8 additions & 1 deletion docker/web/nspanelmanager/web/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def get_mqtt_manager_config(request):
"openhab_color_temp_channel_name", "")
return_json["openhab_rgb_channel_name"] = get_setting_with_default("openhab_rgb_channel_name", "")
return_json["clock_us_style"] = get_setting_with_default("clock_us_style", False)
return_json["use_farenheit"] = get_setting_with_default("use_farenheit", False)

return_json["lights"] = {}
for light in Light.objects.all():
Expand Down Expand Up @@ -159,9 +160,11 @@ def register_nspanel(request):
"""Update the already existing NSPanel OR create a new one"""
data = json.loads(request.body)
new_panel = NSPanel.objects.filter(mac_address=data['mac_address']).first()
panel_already_exists = True

if not new_panel:
new_panel = NSPanel()
panel_already_exists = False

new_panel.friendly_name = data['friendly_name']
new_panel.mac_address = data['mac_address']
Expand All @@ -178,7 +181,8 @@ def register_nspanel(request):

# Save the update/Create new panel
new_panel.save()
restart_mqtt_manager()
if not panel_already_exists:
restart_mqtt_manager()
return HttpResponse('OK', status=200)


Expand Down Expand Up @@ -207,6 +211,7 @@ def get_nspanel_config(request):
base["clock_us_style"] = get_setting_with_default("clock_us_style", False)
base["screensaver_activation_timeout"] = get_setting_with_default("screensaver_activation_timeout", 30000)
base["button1_mode"] = nspanel.button1_mode
base["use_farenheit"] = get_setting_with_default("use_farenheit", False)
if nspanel.button1_detached_mode_light:
base["button1_detached_light"] = nspanel.button1_detached_mode_light.id
else:
Expand Down Expand Up @@ -278,8 +283,10 @@ def set_panel_status(request, panel_mac: str):
nspanel = nspanels.first()
# We got a match
json_payload = json.loads(request.body.decode('utf-8'))
print(json_payload);
nspanel.wifi_rssi = int(json_payload["rssi"])
nspanel.heap_used_pct = int(json_payload["heap_used_pct"])
nspanel.temperature = round(json_payload["temperature"], 2)
nspanel.save()
return HttpResponse("", status=200)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.1.7 on 2023-06-23 22:43

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('web', '0031_lightstate_color_temperature'),
]

operations = [
migrations.AddField(
model_name='nspanel',
name='temperature',
field=models.FloatField(default=0),
),
]
1 change: 1 addition & 0 deletions docker/web/nspanelmanager/web/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class NSPanel(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
wifi_rssi = models.IntegerField(default=0)
heap_used_pct = models.IntegerField(default=0)
temperature = models.FloatField(default=0)
online_state = models.BooleanField(default=False)
button1_mode = models.IntegerField(default=0)
button1_detached_mode_light = models.ForeignKey("Light", on_delete=models.SET_NULL, blank=True, null=True, related_name="+")
Expand Down
2 changes: 1 addition & 1 deletion docker/web/nspanelmanager/web/static/edit_nspanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function connect_to_websocket() {

webSocket.onmessage = (event) => {
data = JSON.parse(event.data);
if(data.type == "log") {
if(data.type == "log" && data.mac == $('#nspanel_mac').text()) {
var add_html = "<tr><td>";
add_html += data.time;
add_html += "</td><td>";
Expand Down
29 changes: 27 additions & 2 deletions docker/web/nspanelmanager/web/static/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function connect_to_websocket() {

webSocket.onmessage = (event) => {
data = JSON.parse(event.data);
console.log(data);
if(data.type == "status") {
let mac_selector = data.payload.mac;
mac_selector = mac_selector.replaceAll(":", "\\:");
Expand All @@ -23,7 +24,7 @@ function connect_to_websocket() {
// Got a state update for a panel that does not exist in this page, reload to show it if it has registered
setTimeout(function() {
location.reload();
}, 5000);
}, 2000);
}

if(data.payload.state == "online") {
Expand All @@ -37,6 +38,10 @@ function connect_to_websocket() {
let mac_selector = data.payload.mac;
mac_selector = mac_selector.replaceAll(":", "\\:");
$("#heap_used_" + mac_selector).text(data.payload.heap_used_pct + "%");
var temperature_unit = $("#temperature_" + mac_selector).text().slice(-2);
$("#temperature_" + mac_selector).text(Math.round(data.payload.temperature*100)/100 + " " + temperature_unit);


var new_rssi_classes = "";
if(data.payload.rssi <= -90) {
new_rssi_classes = "mdi mdi-wifi-strength-1-alert";
Expand Down Expand Up @@ -83,10 +88,30 @@ function connect_to_websocket() {
console.log("Websocket closed, trying in 1 second");
setTimeout(function() {
connect_to_websocket();
// location.reload();
}, 1000);
};
}

$(document).ready(function() {
connect_to_websocket();
});

$("#firmware_upload_file_input").change(function (){
var fileName = $(this).val().replace("C:\\fakepath\\", "");
$("#firmware_upload_file_name").html(fileName);
});


$("#data_upload_file_input").change(function (){
var fileName = $(this).val().replace("C:\\fakepath\\", "");
$("#data_upload_file_name").html(fileName);
});


$("#tft_upload_file_input").change(function (){
var fileName = $(this).val().replace("C:\\fakepath\\", "");
$("#tft_upload_file_name").html(fileName);
});
});


1 change: 1 addition & 0 deletions docker/web/nspanelmanager/web/templates/edit_nspanel.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

{% block content %}
<h2 class="title is-4" id="nspanel_name">{{ panel.friendly_name }} settings</h2>
<h2 class="subtitle is-6">MAC: <span id="nspanel_mac">{{ panel.mac_address }}</span></h2>
<form method="POST" action="{% url 'save_panel_settings' panel_id=panel.id %}">
{% csrf_token %}
<div class="field">
Expand Down
6 changes: 4 additions & 2 deletions docker/web/nspanelmanager/web/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ <h2 class="title is-4">Panels</h2>
<th>Room</th>
<th>IP Address</th>
<th>Status</th>
<th><span class="mdi mdi-wifi"></span></th>
<th><span class="mdi mdi-wifi" title="WiFi signal strength"></span></th>
<th><span class="mdi mdi-memory" title="Memory used"></span></i></th>
<th><span class="mdi mdi-thermometer" title="Temperature"></span></i></th>
<th>Version</th>
<th>Actions</th>
</tr>
Expand Down Expand Up @@ -53,6 +54,7 @@ <h2 class="title is-4">Panels</h2>
{% endif %}
</td>
<td id="heap_used_{{ nspanel.mac_address }}">{{ nspanel.heap_used_pct }}%</td>
<td id="temperature_{{ nspanel.mac_address }}">{{ nspanel.temperature }} {{ temperature_unit }}</td>
<td>{{ nspanel.version }}</td>
<td>
<a type="button" class="button is-primary is-small"
Expand All @@ -68,4 +70,4 @@ <h2 class="title is-4">Panels</h2>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% endblock %}
35 changes: 19 additions & 16 deletions docker/web/nspanelmanager/web/templates/modals.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@
<button type="button" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="file">
<div class="file has-name">
<label class="file-label">
<input class="file-input" type="file" name="firmware" accept=".bin">
<input class="file-input" type="file" name="firmware" accept=".bin" id="firmware_upload_file_input">
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="mdi mdi-upload mr-1"></span>
<span class="file-label">
Choose a file…
</span>
</span>
</label>
<span class="file-name" id="firmware_upload_file_name">
- No file selected -
</span>
</div>
</section>
<footer class="modal-card-foot">
Expand All @@ -65,18 +66,19 @@
<button type="button" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="file">
<div class="file has-name">
<label class="file-label">
<input class="file-input" type="file" name="data_file" accept=".bin">
<input class="file-input" type="file" name="data_file" accept=".bin" id="data_upload_file_input">
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="mdi mdi-upload mr-1"></span>
<span class="file-label">
Choose a file…
</span>
</span>
</label>
<span class="file-name" id="data_upload_file_name">
- No file selected -
</span>
</div>
</section>
<footer class="modal-card-foot">
Expand All @@ -97,18 +99,19 @@
<button type="button" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="file">
<div class="file has-name">
<label class="file-label">
<input class="file-input" type="file" name="tft_file" accept=".tft">
<input class="file-input" type="file" name="tft_file" accept=".tft" id="tft_upload_file_input">
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="mdi mdi-upload mr-1"></span>
<span class="file-label">
Choose a file…
</span>
</span>
</label>
<span class="file-name" id="tft_upload_file_name">
- No file selected -
</span>
</div>
</section>
<footer class="modal-card-foot">
Expand Down Expand Up @@ -204,4 +207,4 @@
</div>
</nav>
</div>
</div>
</div>
Loading

0 comments on commit bd06d7f

Please sign in to comment.