Fixed Typo in HMI/README.md

Updated to NsPanelTs.ts to support new FW
Updated README.md
This commit is contained in:
britzelpuf
2022-03-19 23:26:57 +01:00
parent 48b6347ba7
commit e35a252e65
3 changed files with 235 additions and 79 deletions

View File

@@ -95,7 +95,7 @@ The following message can be used to update the content on the cardEntities Page
`,text,sensor.entityName,3,17299,Temperature,content` `,text,sensor.entityName,3,17299,Temperature,content`
`button,button.entityName,3,17299,bt-name,bt-text` `,button,button.entityName,3,17299,bt-name,bt-text`
`,switch,switch.entityName,4,17299,Switch1,0` `,switch,switch.entityName,4,17299,Switch1,0`

View File

@@ -27,21 +27,84 @@ type Config = {
dateFormat: string, dateFormat: string,
weatherEntity: string | null, weatherEntity: string | null,
temperatureUnit: string, temperatureUnit: string,
batEntity: string, leftEntity: string,
pvEntity: string, leftEntityIcon: number,
pages: (PageThermo | PageEntities)[] leftEntityText: string,
leftEntityUnitText: string | null,
rightEntity: string,
rightEntityIcon: number,
rightEntityText: string,
rightEntityUnitText: string | null,
pages: (PageThermo | PageEntities)[],
button1Page: (PageThermo | PageEntities | null),
button2Page: (PageThermo | PageEntities | null),
} }
var subscriptions: any = {}; var subscriptions: any = {};
var pageId = 0; var pageId = 0;
var page1: PageEntities =
{
"type": "cardEntities",
"heading": "Haus",
"items": [
"alias.0.Rolladen_Eltern",
"alias.0.Erker",
"alias.0.Küche",
"alias.0.Wand"
]
};
var page2: PageEntities =
{
"type": "cardEntities",
"heading": "Strom",
"items": [
"alias.0.Netz",
"alias.0.Hausverbrauch",
"alias.0.Pv",
"alias.0.Batterie"
]
};
var button1Page: PageEntities =
{
"type": "cardEntities",
"heading": "Knopf1",
"items": [
"alias.0.Schlafen",
"alias.0.Stern",
"delete",
"delete"
]
};
var button2Page: PageEntities =
{
"type": "cardEntities",
"heading": "Knopf2",
"items": [
"delete",
"delete",
"alias.0.Schlafen",
"alias.0.Stern"
]
};
var config: Config = { var config: Config = {
panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT", panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT",
panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend", panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend",
batEntity: "alias.0.Batterie.ACTUAL", leftEntity: "alias.0.Batterie.ACTUAL",
pvEntity: "alias.0.Pv.ACTUAL", leftEntityIcon: 34,
leftEntityText: "Batterie",
leftEntityUnitText: "%",
rightEntity: "alias.0.Pv.ACTUAL",
rightEntityIcon: 32,
rightEntityText: "PV",
rightEntityUnitText: "W",
timeoutScreensaver: 15, timeoutScreensaver: 15,
dimmode: 8, dimmode: 8,
locale: "de_DE", locale: "de_DE",
@@ -50,33 +113,16 @@ var config: Config = {
weatherEntity: "alias.0.Wetter", weatherEntity: "alias.0.Wetter",
temperatureUnit: "°C", temperatureUnit: "°C",
pages: [ pages: [page1, page2,
{
"type": "cardEntities",
"heading": "Haus",
"items": [
"alias.0.Rolladen_Eltern",
"alias.0.Erker",
"alias.0.Küche",
"alias.0.Wand"
]
},
{
"type": "cardEntities",
"heading": "Strom",
"items": [
"alias.0.Netz",
"alias.0.Hausverbrauch",
"alias.0.Pv",
"alias.0.Batterie"
]
},
{ {
"type": "cardThermo", "type": "cardThermo",
"heading": "Thermostat", "heading": "Thermostat",
"item": "alias.0.WzNsPanel" "item": "alias.0.WzNsPanel"
} }
] ],
button1Page: button1Page,
button2Page: button2Page
}; };
schedule("* * * * *", function () { schedule("* * * * *", function () {
@@ -86,10 +132,20 @@ schedule("0 * * * *", function () {
SendDate(); SendDate();
}); });
on([config.pvEntity, config.batEntity], function () { // Only monitor the extra nodes if one or both are present
HandleScreensaverUpdate(); var updateArray: string[] = [];
}) if (config.rightEntity !== null && existsState(config.rightEntity)) {
updateArray.push(config.rightEntity)
}
if (config.leftEntity !== null && existsState(config.leftEntity)) {
updateArray.push(config.leftEntity)
}
if (updateArray.length > 0) {
on(updateArray, function () {
HandleScreensaverUpdate();
})
}
on({ id: config.panelRecvTopic }, function (obj) { on({ id: config.panelRecvTopic }, function (obj) {
if (obj.state.val.startsWith('\{"CustomRecv":')) { if (obj.state.val.startsWith('\{"CustomRecv":')) {
var json = JSON.parse(obj.state.val); var json = JSON.parse(obj.state.val);
@@ -123,15 +179,11 @@ function HandleMessage(typ: string, method: string, page: number, words: Array<s
if (method == 'pageOpen' || method == 'startup') { if (method == 'pageOpen' || method == 'startup') {
UnsubscribeWatcher(); UnsubscribeWatcher();
var retMsgs: Array<Payload> = [];
if (config.pages[pageId].type == "cardEntities") {
retMsgs = GenerateEntitiesPage(pageId, <PageEntities>config.pages[pageId])
} else if (config.pages[pageId].type == "cardThermo") {
retMsgs = GenerateThermoPage(pageId, <PageThermo>config.pages[pageId])
}
if (method == 'startup') if (method == 'startup')
HandleStartupProcess(); HandleStartupProcess();
SendToPanel(retMsgs)
GeneratePage(config.pages[pageId]);
} }
if (method == 'buttonPress' || method == "tempUpd") { if (method == 'buttonPress' || method == "tempUpd") {
@@ -141,6 +193,43 @@ function HandleMessage(typ: string, method: string, page: number, words: Array<s
if (method == 'screensaverOpen') { if (method == 'screensaverOpen') {
HandleScreensaver() HandleScreensaver()
} }
if (method == 'button1' || method == 'button2') {
HandleHardwareButton(method);
}
}
}
function GeneratePage(page: Page): void {
var retMsgs: Array<Payload> = [];
if (page.type == "cardEntities") {
retMsgs = GenerateEntitiesPage(<PageEntities>config.pages[pageId])
} else if (page.type == "cardThermo") {
retMsgs = GenerateThermoPage(pageId, <PageThermo>config.pages[pageId])
}
SendToPanel(retMsgs)
}
function HandleHardwareButton(method: string): void {
let page: (PageThermo | PageEntities);
if (config.button1Page !== null && method == "button1") {
page = config.button1Page;
}
else if (config.button2Page !== null && method == "button2") {
page = config.button2Page;
}
else {
return;
}
SendToPanel({ payload: "wake" });
switch (page.type) {
case "cardEntities":
SendToPanel(GenerateEntitiesPage(page));
break;
case "cardThermo":
SendToPanel(GenerateThermoPage(0, page));
break;
} }
} }
@@ -178,22 +267,23 @@ function SendTime(): void {
SendToPanel(<Payload>{ payload: "time," + hr + ":" + min }); SendToPanel(<Payload>{ payload: "time," + hr + ":" + min });
} }
function GenerateEntitiesPage(pageNum: number, page: PageEntities): Payload[] { function GenerateEntitiesPage(page: PageEntities): Payload[] {
var out_msgs: Array<Payload> = []; var out_msgs: Array<Payload> = [];
out_msgs = [{ payload: "pageType,cardEntities" }, { payload: "entityUpdHeading," + config.pages[pageNum].heading }] out_msgs = [{ payload: "pageType,cardEntities" }, { payload: "entityUpdHeading," + page.heading }]
let pageData = "entityUpd";
page.items.forEach(function (id, i) { page.items.forEach(function (id, i) {
out_msgs.push(CreateEntity(id, i + 1)); pageData += CreateEntity(id, i + 1);
}) })
out_msgs.push({ payload: pageData });
return out_msgs return out_msgs
} }
function CreateEntity(id: string, placeId: number): Payload { function CreateEntity(id: string, placeId: number): string {
var type = "delete" var type = "delete"
var iconId = 0 var iconId = 0
var name = "FriendlyName" var name = "FriendlyName"
if (id == "delete") { if (id == "delete") {
return { payload: "entityUpd," + placeId + "," + type }; return ",delete,,,,"
} }
// ioBroker // ioBroker
@@ -217,7 +307,7 @@ function CreateEntity(id: string, placeId: number): Payload {
var optVal = "0" var optVal = "0"
if (val === true || val === "true") if (val === true || val === "true")
optVal = "1" optVal = "1"
return { payload: "entityUpd," + placeId + "," + type + "," + id + "," + iconId + "," + name + "," + optVal } return "," + type + "," + id + "," + iconId + "," + "17299," + name + "," + optVal
case "dimmer": case "dimmer":
type = "light" type = "light"
@@ -233,12 +323,12 @@ function CreateEntity(id: string, placeId: number): Payload {
} }
if (val === true || val === "true") if (val === true || val === "true")
optVal = "1" optVal = "1"
return { payload: "entityUpd," + placeId + "," + type + "," + id + "," + iconId + "," + name + "," + optVal } return "," + type + "," + id + "," + iconId + "," + "17299," + name + "," + optVal
case "blind": case "blind":
type = "shutter" type = "shutter"
iconId = 0 iconId = 0
return { payload: "entityUpd," + placeId + "," + type + "," + id + "," + iconId + "," + name } return "," + type + "," + id + "," + iconId + "," + "17299," + name + ","
case "info": case "info":
case "value.temperature": case "value.temperature":
@@ -261,19 +351,21 @@ function CreateEntity(id: string, placeId: number): Payload {
else { else {
optVal += GetUnitOfMeasurement(id + ".ACTUAL"); optVal += GetUnitOfMeasurement(id + ".ACTUAL");
} }
return { payload: "entityUpd," + placeId + "," + type + "," + id + "," + iconId + "," + name + "," + optVal }; return "," + type + "," + id + "," + iconId + "," + "17299," + name + "," + optVal;
case "button": case "button":
type = "button"; type = "button";
iconId = 3; iconId = 3;
var optVal = "PRESS"; var optVal = "PRESS";
return { payload: "entityUpd," + placeId + "," + type + "," + id + "," + iconId + "," + name + "," + optVal }; return "," + type + "," + id + "," + iconId + "," + "17299," + name + "," + optVal;
default: default:
break return ",delete,,,,"
} }
} }
return { payload: "entityUpd," + placeId + "," + type };
return ",delete,,,,"
} }
function RegisterEntityWatcher(id: string, entityId: string, placeId: number): void { function RegisterEntityWatcher(id: string, entityId: string, placeId: number): void {
@@ -281,7 +373,7 @@ function RegisterEntityWatcher(id: string, entityId: string, placeId: number): v
return; return;
} }
subscriptions[id] = (on({ id: id, change: 'any' }, function (data) { subscriptions[id] = (on({ id: id, change: 'any' }, function (data) {
SendToPanel(CreateEntity(entityId, placeId)); GeneratePage(config.pages[pageId]);
})) }))
} }
@@ -392,6 +484,7 @@ function GenerateDetailPage(type: string, entityId: string): Payload[] {
if (existsObject(id)) { if (existsObject(id)) {
var o = getObject(id) var o = getObject(id)
var val = null; var val = null;
let icon = 1;
if (type == "popupLight") { if (type == "popupLight") {
let switchVal = "0" let switchVal = "0"
if (o.common.role == "light") { if (o.common.role == "light") {
@@ -406,8 +499,8 @@ function GenerateDetailPage(type: string, entityId: string): Payload[] {
if (val) if (val)
switchVal = "1" switchVal = "1"
out_msgs.push({ payload: "entityUpdateDetail," + switchVal + ",disable,disable,disable" }) out_msgs.push({ payload: "entityUpdateDetail," + icon + "," + "17299," + switchVal + ",disable,disable,disable" })
} }
if (o.common.role == "dimmer") { if (o.common.role == "dimmer") {
@@ -433,7 +526,7 @@ function GenerateDetailPage(type: string, entityId: string): Payload[] {
//if (attr_support_color.includes("color_temp")) //if (attr_support_color.includes("color_temp"))
// colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100)) // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100))
out_msgs.push({ payload: "entityUpdateDetail," + switchVal + "," + brightness + "," + colortemp }) out_msgs.push({ payload: "entityUpdateDetail," + icon + "," + "17299," + switchVal + "," + brightness + "," + colortemp })
} }
} }
@@ -469,12 +562,37 @@ function HandleScreensaverUpdate(): void {
if (config.weatherEntity != null && existsObject(config.weatherEntity)) { if (config.weatherEntity != null && existsObject(config.weatherEntity)) {
var icon = getState(config.weatherEntity + ".ICON").val; var icon = getState(config.weatherEntity + ".ICON").val;
let temperature: string = getState(config.weatherEntity + ".TEMP").val; let temperature: string =
existsState(config.weatherEntity + ".ACTUAL") ? getState(config.weatherEntity + ".ACTUAL").val :
existsState(config.weatherEntity + ".TEMP") ? getState(config.weatherEntity + ".TEMP").val: "null";
let humidity = getState(config.weatherEntity + ".HUMIDITY").val; let humidity = getState(config.weatherEntity + ".HUMIDITY").val;
let u1 = getState(config.batEntity).val;
let u2 = getState(config.pvEntity).val;
SendToPanel(<Payload>{ payload: "weatherUpdate,?" + GetAccuWeatherIcon(parseInt(icon)) + "?" + temperature.toString() + " " + config.temperatureUnit + "?26?" + humidity + " %?Batterie?34?" + u1 + "%?PV?32?" + u2 + "W" })
let payloadString =
"weatherUpdate,?" + GetAccuWeatherIcon(parseInt(icon)) + "?"
+ temperature + " " + config.temperatureUnit + "?26?"
+ humidity + " %?" ;
if(existsState(config.leftEntity))
{
let u1 = getState(config.leftEntity).val;
payloadString += config.leftEntityText + "?" + config.leftEntityIcon + "?" + u1 + " " + config.leftEntityUnitText + "?";
}
else
{
payloadString += "???";
}
if(existsState(config.rightEntity))
{
let u2 = getState(config.rightEntity).val;
payloadString += config.rightEntityText + "?" + config.rightEntityIcon + "?" + u2 + " " + config.rightEntityUnitText;
}
else
{
payloadString += "??";
}
SendToPanel(<Payload>{ payload: payloadString});
} }
} }

View File

@@ -24,8 +24,13 @@ You can find this in the device raw settings.
## Installation ## Installation
- Import this script into the ioBroker javascript instance and choose Typescript. - Import this script into the ioBroker javascript instance and choose Typescript.
- Make sure the version of the adapter is not to old.
- Find the config variable and update to your needs. - Find the config variable and update to your needs.
- The format strings are not used right now. - The format strings are not used right now.
- Make sure your device is connected with the mqtt instance. I didn't get it working with the sonoff adapter, but I didn't tried it too long.
- Create a state with a mqtt client or create one per hand. The mqtt adapter will not create the state CustomSend
- you only need to send a dummy message to cmnd/<yourPanel>/CustomSend
- then the state will be created
## Update the screensaver string ## Update the screensaver string
The screensaver string which is send to the display looks something like this: The screensaver string which is send to the display looks something like this:
@@ -37,21 +42,16 @@ See the icons currently usable in the following table:
[Icon Table](../HMI#icons-ids) [Icon Table](../HMI#icons-ids)
You can change the string in this function: You can change the string and devices in the config object.
## Buttons
If you like you can add special pages for the buttons, but there is a problem currently which will open the last page again. But if you press the button again, the correct page will open.
First you need to add this rule to Tasmota:
``` ```
function HandleScreensaverUpdate(): void { Rule2 on Button1#state do Publish tele/%topic%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish tele/%topic%/RESULT {"CustomRecv":"event,button2"} endon
if (config.weatherEntity != null && existsObject(config.weatherEntity)) { Rule2
var icon = getState(config.weatherEntity + ".ICON").val;
let temperature: string = getState(config.weatherEntity + ".TEMP").val;
let humidity = getState(config.weatherEntity + ".HUMIDITY").val;
let u1 = getState(config.batEntity).val;
let u2 = getState(config.pvEntity).val;
SendToPanel(<Payload>{ payload: "weatherUpdate,?" + GetAccuWeatherIcon(parseInt(icon)) + "?" + temperature.toString() + " " + config.temperatureUnit + "?26?" + humidity + " %?Batterie?4?" + u1 + "%?PV?23?" + u2 + "W" })
}
}
``` ```
## The config element in the script which needs to be configured ## The config element in the script which needs to be configured
@@ -59,11 +59,14 @@ function HandleScreensaverUpdate(): void {
var config: Config = { var config: Config = {
panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT", // This is the object where the panel send the data to. panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT", // This is the object where the panel send the data to.
panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend", // This is the object where data is send to the panel. panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend", // This is the object where data is send to the panel.
batEntity: "alias.0.Batterie.ACTUAL", // This is a state which can be used to display the battery state. leftEntity: "alias.0.Batterie.ACTUAL", // This is a state will be displayed on the left side.
pvEntity: "alias.0.Pv.ACTUAL", // This is a state which can be used to display the current solar yield. leftEntityIcon: 34, // This is a icon which will be displayed on the left side.
// Both values are send via the HandleScreensaverUpdate() function, you need to update this string to your needs. leftEntityText: "Batterie", // The label for the left side.
// Currently the icons are hardcoded. leftEntityUnitText: "%", // The unit which will be appendon the left side.
rightEntity: "alias.0.Pv.ACTUAL", // The same but for the right side.
rightEntityIcon: 32,
rightEntityText: "PV",
rightEntityUnitText: "W",
timeoutScreensaver: 15, // Timeout for screensaver timeoutScreensaver: 15, // Timeout for screensaver
dimmode: 8, // Display dim dimmode: 8, // Display dim
locale: "de_DE", // not used right now locale: "de_DE", // not used right now
@@ -100,7 +103,42 @@ var config: Config = {
"heading": "Thermostat", "heading": "Thermostat",
"item": "alias.0.WzNsPanel" // Needs to be a thermostat in the device panel "item": "alias.0.WzNsPanel" // Needs to be a thermostat in the device panel
} }
],
button1Page: button1Page, // A cardEntities, cardThermo or nothing. This will be opened when pressing button1
button2Page: button2Page // you guess it
};
```
If you want you can create dedicated objects, so you don't need to declare them again. Then you can use tehm in the pages array and button pages.
```
var button1Page: PageEntities =
{
"type": "cardEntities",
"heading": "Knopf1",
"items": [
"alias.0.Schlafen",
"alias.0.Stern",
"delete",
"delete"
] ]
}; };
``` ```
Pages array can look like this:
```
pages: [
button1Page,
{
"type": "cardEntities",
"heading": "Strom",
"items": [
"alias.0.Netz",
"alias.0.Hausverbrauch",
"alias.0.Pv",
"alias.0.Batterie"
]
}]
```