@ -0,0 +1,9 @@
|
||||
/.idea
|
||||
/node_modules
|
||||
.git
|
||||
admin/i18n/flat.txt
|
||||
admin/i18n/*/flat.txt
|
||||
test/Ananas64.exe
|
||||
iob_npm.done
|
||||
tmp
|
||||
package-lock.json
|
@ -0,0 +1,12 @@
|
||||
gulpfile.js
|
||||
tasks
|
||||
node_modules
|
||||
.idea
|
||||
.git
|
||||
/node_modules
|
||||
test
|
||||
.travis.yml
|
||||
appveyor.yml
|
||||
admin/i18n
|
||||
iob_npm.done
|
||||
package-lock.json
|
@ -0,0 +1,24 @@
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
language: node_js
|
||||
node_js:
|
||||
- '4'
|
||||
- '6'
|
||||
- '8'
|
||||
- '10'
|
||||
before_install:
|
||||
- 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CC=clang++; export CXX=clang++; export CXXFLAGS=-std=c++11; fi'
|
||||
- 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-4.8; fi'
|
||||
before_script:
|
||||
- export NPMVERSION=$(echo "$($(which npm) -v)"|cut -c1)
|
||||
- 'if [[ $NPMVERSION == 5 ]]; then npm install -g npm@5; fi'
|
||||
- npm -v
|
||||
- npm install winston@2.3.1
|
||||
- 'npm install https://github.com/yunkong2/yunkong2.js-controller/tarball/master --production'
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Bluefox <dogafox@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"General": "基本",
|
||||
"Inputs": "离散输入",
|
||||
"Do not align addresses to word:": "Do not align addresses to 16 bits:",
|
||||
"Coils": "线圈",
|
||||
"Input Registers": "输入寄存器",
|
||||
"Holding Registers": "保持寄存器",
|
||||
"PLC Connection:": "PLC 连接:",
|
||||
"PLC IP Address:": "PLC IP Address:",
|
||||
"PLC Rack:": "PLC Rack:",
|
||||
"PLC Slot:": "PLC Slot:",
|
||||
"Round Real to:": "Round real to:",
|
||||
"Poll delay:": "Poll delay:",
|
||||
"deviceId": "Slave ID",
|
||||
"Reconnect time:": "Reconnect time:",
|
||||
"Pulse time:": "Pulse time:",
|
||||
"Import symbols file:": "Import symbols file:",
|
||||
"Import DB file:": "Import DB file:",
|
||||
"Load Symbols": "Load symbols",
|
||||
"Add DB": "Add DB",
|
||||
"Toggle poll": "切换 poll",
|
||||
"Toggle RW": "切换 RW",
|
||||
"Toggle WP": "切换 WP",
|
||||
"Address": "地址",
|
||||
"Name": "名称",
|
||||
"Description": "说明",
|
||||
"Type": "类型",
|
||||
"Unit": "单位",
|
||||
"poll": "poll",
|
||||
"RW": "RW",
|
||||
"CW": "CW",
|
||||
"WP": "WP",
|
||||
"Role": "规则",
|
||||
"Room": "场景",
|
||||
"registers": "寄存器",
|
||||
"Device ID:": "Modbus站 ID:",
|
||||
"RTU over TCP": "RTU over TCP",
|
||||
"Data bits:": "数据位:",
|
||||
"Stop bits:": "停止位:",
|
||||
"Parity:": "Parity:",
|
||||
"Read timeout:": "Read timeout:",
|
||||
"Multi device IDs:": "Multi device IDs:",
|
||||
"Use aliases as address:": "Use aliases:",
|
||||
"Max read request length:": "Max read request length:",
|
||||
"Enable polling of data point": "Enable polling of data point",
|
||||
"Write access allowed": "Write access allowed",
|
||||
"Write pulses (true=>false edge)": "Write pulses (true=>false edge)",
|
||||
"Connection parameters:": "连接参数",
|
||||
"Partner IP Address:": "IP Address:",
|
||||
"Port:": "端口:",
|
||||
"Type:": "类型:",
|
||||
"Master": "主机",
|
||||
"Slave": "从机",
|
||||
"Are you sure?": "你确定吗?",
|
||||
"Start address:": "开始地址:",
|
||||
"Text copied to clipboard. Click to close the window": "文本已经复制到剪贴板",
|
||||
"Export": "导出",
|
||||
"Import": "导入",
|
||||
"Close": "关闭",
|
||||
"Export to CSV": "导出成 CSV文件",
|
||||
"Import from CSV": "从 CSV文件导入",
|
||||
"Delete all entries": "删除所有的点位数据",
|
||||
"Length": "长度",
|
||||
"All entries will be deleted. Are you sure?": "所有的点位数据都将被删除,你确定吗?",
|
||||
"Factor": "Factor",
|
||||
"Offset": "偏移",
|
||||
"Cyclic write": "Cyclic write",
|
||||
"TCP/Serial RTU:": "TCP/Serial RTU:",
|
||||
"TCP": "TCP",
|
||||
"Serial": "串口",
|
||||
"Baud rate:": "波特率:",
|
||||
"Use direct addresses by aliases:": "Use direct addresses by aliases:",
|
||||
"Select port": "端口"
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"General": "General",
|
||||
"Inputs": "Discrete Inputs",
|
||||
"Do not align addresses to word:": "Do not align addresses to 16 bits:",
|
||||
"Coils": "Coils",
|
||||
"Input Registers": "Input Registers",
|
||||
"Holding Registers": "Holding Registers",
|
||||
"PLC Connection:": "PLC Connection:",
|
||||
"PLC IP Address:": "PLC IP Address:",
|
||||
"PLC Rack:": "PLC Rack:",
|
||||
"PLC Slot:": "PLC Slot:",
|
||||
"Round Real to:": "Round real to:",
|
||||
"Poll delay:": "Poll delay:",
|
||||
"deviceId": "Slave ID",
|
||||
"Reconnect time:": "Reconnect time:",
|
||||
"Pulse time:": "Pulse time:",
|
||||
"Import symbols file:": "Import symbols file:",
|
||||
"Import DB file:": "Import DB file:",
|
||||
"Load Symbols": "Load symbols",
|
||||
"Add DB": "Add DB",
|
||||
"Toggle poll": "Toggle poll",
|
||||
"Toggle RW": "Toggle RW",
|
||||
"Toggle WP": "Toggle WP",
|
||||
"Address": "Address",
|
||||
"Name": "Name",
|
||||
"Description": "Description",
|
||||
"Type": "Type",
|
||||
"Unit": "Unit",
|
||||
"poll": "poll",
|
||||
"RW": "RW",
|
||||
"CW": "CW",
|
||||
"WP": "WP",
|
||||
"Role": "Role",
|
||||
"Room": "Room",
|
||||
"registers": "registers",
|
||||
"Device ID:": "Device ID:",
|
||||
"RTU over TCP": "RTU over TCP",
|
||||
"Data bits:": "Data bits:",
|
||||
"Stop bits:": "Stop bits:",
|
||||
"Parity:": "Parity:",
|
||||
"Read timeout:": "Read timeout:",
|
||||
"Multi device IDs:": "Multi device IDs:",
|
||||
"Use aliases as address:": "Use aliases:",
|
||||
"Max read request length:": "Max read request length:",
|
||||
"Enable polling of data point": "Enable polling of data point",
|
||||
"Write access allowed": "Write access allowed",
|
||||
"Write pulses (true=>false edge)": "Write pulses (true=>false edge)",
|
||||
"Connection parameters:": "Connection parameters:",
|
||||
"Partner IP Address:": "Partner IP Address:",
|
||||
"Port:": "Port:",
|
||||
"Type:": "Type:",
|
||||
"Master": "Master",
|
||||
"Slave": "Slave",
|
||||
"Are you sure?": "Are you sure?",
|
||||
"Start address:": "Start address:",
|
||||
"Text copied to clipboard. Click to close the window": "Text copied to clipboard. Click to close the window",
|
||||
"Export": "Export",
|
||||
"Import": "Import",
|
||||
"Close": "Close",
|
||||
"Export to CSV": "Export to CSV",
|
||||
"Import from CSV": "Import from CSV",
|
||||
"Delete all entries": "Delete all entries",
|
||||
"Length": "Length",
|
||||
"All entries will be deleted. Are you sure?": "All entries will be deleted. Are you sure?",
|
||||
"Factor": "Factor",
|
||||
"Offset": "Offset",
|
||||
"Cyclic write": "Cyclic write",
|
||||
"TCP/Serial RTU:": "TCP/Serial RTU:",
|
||||
"TCP": "TCP",
|
||||
"Serial": "Serial",
|
||||
"Baud rate:": "Baud rate:",
|
||||
"Use direct addresses by aliases:": "Use direct addresses by aliases:",
|
||||
"Select port": "Select port"
|
||||
}
|
After Width: | Height: | Size: 67 KiB |
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* jsGrid v1.0.1 (http://js-grid.com)
|
||||
* (c) 2015 Artem Tabalin
|
||||
* Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
.jsgrid {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.jsgrid, .jsgrid *, .jsgrid *:before, .jsgrid *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.jsgrid input,
|
||||
.jsgrid textarea,
|
||||
.jsgrid select {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.jsgrid-grid-header {
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.jsgrid-grid-body {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.jsgrid-table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.jsgrid-table td {
|
||||
padding: 0.5em 0.5em;
|
||||
}
|
||||
|
||||
.jsgrid-table td,
|
||||
.jsgrid-table th {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.jsgrid-align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.jsgrid-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jsgrid-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.jsgrid-header-row > th {
|
||||
padding: .5em .5em;
|
||||
}
|
||||
|
||||
.jsgrid-filter-row input,
|
||||
.jsgrid-filter-row textarea,
|
||||
.jsgrid-filter-row select,
|
||||
.jsgrid-edit-row input,
|
||||
.jsgrid-edit-row textarea,
|
||||
.jsgrid-edit-row select,
|
||||
.jsgrid-insert-row input,
|
||||
.jsgrid-insert-row textarea,
|
||||
.jsgrid-insert-row select {
|
||||
width: 90%;
|
||||
padding: .3em .5em;
|
||||
}
|
||||
|
||||
.jsgrid-filter-row input[type='checkbox'],
|
||||
.jsgrid-edit-row input[type='checkbox'],
|
||||
.jsgrid-insert-row input[type='checkbox'] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.jsgrid-header-row > th,
|
||||
.jsgrid-filter-row > td,
|
||||
.jsgrid-insert-row > td,
|
||||
.jsgrid-edit-row > td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jsgrid-selected-row td {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jsgrid-nodata-row td {
|
||||
padding: .5em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jsgrid-header-sort {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jsgrid-pager {
|
||||
padding: .5em 0;
|
||||
}
|
||||
|
||||
.jsgrid-pager-nav-button {
|
||||
padding: .2em .6em;
|
||||
}
|
||||
|
||||
.jsgrid-pager-page {
|
||||
padding: .2em .6em;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* jsGrid v1.0.1 (http://js-grid.com)
|
||||
* (c) 2015 Artem Tabalin
|
||||
* Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
.jsgrid{position:relative;overflow:hidden;font-size:1em}.jsgrid,.jsgrid *,.jsgrid :after,.jsgrid :before{box-sizing:border-box}.jsgrid input,.jsgrid select,.jsgrid textarea{font-size:1em}.jsgrid-grid-header{overflow-x:hidden;overflow-y:hidden;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.jsgrid-grid-body{overflow-x:hidden;overflow-y:scroll;-webkit-overflow-scrolling:touch}.jsgrid-table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0}.jsgrid-table td{padding:.5em}.jsgrid-table td,.jsgrid-table th{box-sizing:border-box}.jsgrid-align-left{text-align:left}.jsgrid-align-center{text-align:center}.jsgrid-align-right{text-align:right}.jsgrid-header-row>th{padding:.5em}.jsgrid-edit-row input,.jsgrid-edit-row select,.jsgrid-edit-row textarea,.jsgrid-filter-row input,.jsgrid-filter-row select,.jsgrid-filter-row textarea,.jsgrid-insert-row input,.jsgrid-insert-row select,.jsgrid-insert-row textarea{width:90%;padding:.3em .5em}.jsgrid-edit-row input[type=checkbox],.jsgrid-filter-row input[type=checkbox],.jsgrid-insert-row input[type=checkbox]{width:auto}.jsgrid-edit-row>td,.jsgrid-filter-row>td,.jsgrid-header-row>th,.jsgrid-insert-row>td{text-align:center}.jsgrid-selected-row td{cursor:pointer}.jsgrid-nodata-row td{padding:.5em 0;text-align:center}.jsgrid-header-sort{cursor:pointer}.jsgrid-pager{padding:.5em 0}.jsgrid-pager-nav-button,.jsgrid-pager-page{padding:.2em .6em}
|
@ -0,0 +1,10 @@
|
||||
function translate_cn() {
|
||||
window.jsGrid.Grid.prototype.noDataContent = "暂无数据";
|
||||
window.jsGrid.Grid.prototype.deleteConfirm = "确认删除吗?";
|
||||
window.jsGrid.Grid.prototype.pagerFormat = "分页 = {first} {prev} {pages} {next} {last} {pageIndex} of {pageCount}";
|
||||
window.jsGrid.Grid.prototype.pagePrevText = "上一页.";
|
||||
window.jsGrid.Grid.prototype.pageNextText = "下一页";
|
||||
window.jsGrid.Grid.prototype.pageFirstText = "首页";
|
||||
window.jsGrid.Grid.prototype.pageLastText = "尾页";
|
||||
window.jsGrid.Grid.prototype.loadMessage = "加载中...";
|
||||
}
|
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,78 @@
|
||||
// DO NOT EDIT THIS FILE!!! IT WILL BE AUTOMATICALLY GENERATED FROM src/i18n
|
||||
/*global systemDictionary:true */
|
||||
'use strict';
|
||||
|
||||
systemDictionary = {
|
||||
"General": { "cn": "基本", "en": "General"},
|
||||
"Inputs": { "cn": "离散输入", "en": "Discrete Inputs"},
|
||||
"Do not align addresses to word:": { "cn": "Do not align addresses to 16 bits:", "en": "Do not align addresses to 16 bits:"},
|
||||
"Coils": { "cn": "线圈", "en": "Coils"},
|
||||
"Input Registers": { "cn": "输入寄存器", "en": "Input Registers"},
|
||||
"Holding Registers": { "cn": "保持寄存器", "en": "Holding Registers"},
|
||||
"PLC Connection:": { "cn": "PLC 连接:", "en": "PLC Connection:"},
|
||||
"PLC IP Address:": { "cn": "PLC IP Address:", "en": "PLC IP Address:"},
|
||||
"PLC Rack:": { "cn": "PLC Rack:", "en": "PLC Rack:"},
|
||||
"PLC Slot:": { "cn": "PLC Slot:", "en": "PLC Slot:"},
|
||||
"Round Real to:": { "cn": "Round real to:", "en": "Round real to:"},
|
||||
"Poll delay:": { "cn": "Poll delay:", "en": "Poll delay:"},
|
||||
"deviceId": { "cn": "Slave ID", "en": "Slave ID"},
|
||||
"Reconnect time:": { "cn": "Reconnect time:", "en": "Reconnect time:"},
|
||||
"Pulse time:": { "cn": "Pulse time:", "en": "Pulse time:"},
|
||||
"Import symbols file:": { "cn": "Import symbols file:", "en": "Import symbols file:"},
|
||||
"Import DB file:": { "cn": "Import DB file:", "en": "Import DB file:"},
|
||||
"Load Symbols": { "cn": "Load symbols", "en": "Load symbols"},
|
||||
"Add DB": { "cn": "Add DB", "en": "Add DB"},
|
||||
"Toggle poll": { "cn": "切换 poll", "en": "Toggle poll"},
|
||||
"Toggle RW": { "cn": "切换 RW", "en": "Toggle RW"},
|
||||
"Toggle WP": { "cn": "切换 WP", "en": "Toggle WP"},
|
||||
"Address": { "cn": "地址", "en": "Address"},
|
||||
"Name": { "cn": "名称", "en": "Name"},
|
||||
"Description": { "cn": "说明", "en": "Description"},
|
||||
"Type": { "cn": "类型", "en": "Type"},
|
||||
"Unit": { "cn": "单位", "en": "Unit"},
|
||||
"poll": { "cn": "poll", "en": "poll"},
|
||||
"RW": { "cn": "RW", "en": "RW"},
|
||||
"CW": { "cn": "CW", "en": "CW"},
|
||||
"WP": { "cn": "WP", "en": "WP"},
|
||||
"Role": { "cn": "规则", "en": "Role"},
|
||||
"Room": { "cn": "场景", "en": "Room"},
|
||||
"registers": { "cn": "寄存器", "en": "registers"},
|
||||
"Device ID:": { "cn": "Modbus站 ID:", "en": "Device ID:"},
|
||||
"RTU over TCP": { "cn": "RTU over TCP", "en": "RTU over TCP"},
|
||||
"Data bits:": { "cn": "数据位:", "en": "Data bits:"},
|
||||
"Stop bits:": { "cn": "停止位:", "en": "Stop bits:"},
|
||||
"Parity:": { "cn": "Parity:", "en": "Parity:"},
|
||||
"Read timeout:": { "cn": "Read timeout:", "en": "Read timeout:"},
|
||||
"Multi device IDs:": { "cn": "Multi device IDs:", "en": "Multi device IDs:"},
|
||||
"Use aliases as address:": { "cn": "Use aliases:", "en": "Use aliases:"},
|
||||
"Max read request length:": { "cn": "Max read request length:", "en": "Max read request length:"},
|
||||
"Enable polling of data point": { "cn": "Enable polling of data point", "en": "Enable polling of data point"},
|
||||
"Write access allowed": { "cn": "Write access allowed", "en": "Write access allowed"},
|
||||
"Write pulses (true=>false edge)": { "cn": "Write pulses (true=>false edge)", "en": "Write pulses (true=>false edge)"},
|
||||
"Connection parameters:": { "cn": "连接参数", "en": "Connection parameters:"},
|
||||
"Partner IP Address:": { "cn": "IP Address:", "en": "Partner IP Address:"},
|
||||
"Port:": { "cn": "端口:", "en": "Port:"},
|
||||
"Type:": { "cn": "类型:", "en": "Type:"},
|
||||
"Master": { "cn": "主机", "en": "Master"},
|
||||
"Slave": { "cn": "从机", "en": "Slave"},
|
||||
"Are you sure?": { "cn": "你确定吗?", "en": "Are you sure?"},
|
||||
"Start address:": { "cn": "开始地址:", "en": "Start address:"},
|
||||
"Text copied to clipboard. Click to close the window": {"cn": "文本已经复制到剪贴板", "en": "Text copied to clipboard. Click to close the window"},
|
||||
"Export": { "cn": "导出", "en": "Export"},
|
||||
"Import": { "cn": "导入", "en": "Import"},
|
||||
"Close": { "cn": "关闭", "en": "Close"},
|
||||
"Export to CSV": { "cn": "导出成 CSV文件", "en": "Export to CSV"},
|
||||
"Import from CSV": { "cn": "从 CSV文件导入", "en": "Import from CSV"},
|
||||
"Delete all entries": { "cn": "删除所有的点位数据", "en": "Delete all entries"},
|
||||
"Length": { "cn": "长度", "en": "Length"},
|
||||
"All entries will be deleted. Are you sure?": { "cn": "所有的点位数据都将被删除,你确定吗?", "en": "All entries will be deleted. Are you sure?"},
|
||||
"Factor": { "cn": "Factor", "en": "Factor"},
|
||||
"Offset": { "cn": "偏移", "en": "Offset"},
|
||||
"Cyclic write": { "cn": "Cyclic write", "en": "Cyclic write"},
|
||||
"TCP/Serial RTU:": { "cn": "TCP/Serial RTU:", "en": "TCP/Serial RTU:"},
|
||||
"TCP": { "cn": "TCP", "en": "TCP"},
|
||||
"Serial": { "cn": "串口", "en": "Serial"},
|
||||
"Baud rate:": { "cn": "波特率:", "en": "Baud rate:"},
|
||||
"Use direct addresses by aliases:": { "cn": "Use direct addresses by aliases:", "en": "Use direct addresses by aliases:"},
|
||||
"Select port": { "cn": "端口", "en": "Select port"}
|
||||
};
|
@ -0,0 +1,401 @@
|
||||
'use strict';
|
||||
|
||||
var gulp = require('gulp');
|
||||
var fs = require('fs');
|
||||
var pkg = require('./package.json');
|
||||
var iopackage = require('./io-package.json');
|
||||
var version = (pkg && pkg.version) ? pkg.version : iopackage.common.version;
|
||||
/*var appName = getAppName();
|
||||
|
||||
function getAppName() {
|
||||
var parts = __dirname.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 1].split('.')[0].toLowerCase();
|
||||
}
|
||||
*/
|
||||
const fileName = 'words.js';
|
||||
var languages = {
|
||||
en: {},
|
||||
de: {},
|
||||
ru: {},
|
||||
pt: {},
|
||||
nl: {},
|
||||
fr: {},
|
||||
it: {},
|
||||
es: {},
|
||||
pl: {}
|
||||
};
|
||||
|
||||
function lang2data(lang, isFlat) {
|
||||
var str = isFlat ? '' : '{\n';
|
||||
var count = 0;
|
||||
for (var w in lang) {
|
||||
if (lang.hasOwnProperty(w)) {
|
||||
count++;
|
||||
if (isFlat) {
|
||||
str += (lang[w] === '' ? (isFlat[w] || w) : lang[w]) + '\n';
|
||||
} else {
|
||||
var key = ' "' + w.replace(/"/g, '\\"') + '": ';
|
||||
str += key + '"' + lang[w].replace(/"/g, '\\"') + '",\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!count) return isFlat ? '' : '{\n}';
|
||||
if (isFlat) {
|
||||
return str;
|
||||
} else {
|
||||
return str.substring(0, str.length - 2) + '\n}';
|
||||
}
|
||||
}
|
||||
|
||||
function readWordJs(src) {
|
||||
try {
|
||||
var words;
|
||||
if (fs.existsSync(src + 'js/' + fileName)) {
|
||||
words = fs.readFileSync(src + 'js/' + fileName).toString();
|
||||
} else {
|
||||
words = fs.readFileSync(src + fileName).toString();
|
||||
}
|
||||
|
||||
var lines = words.split(/\r\n|\r|\n/g);
|
||||
var i = 0;
|
||||
while (!lines[i].match(/^systemDictionary = {/)) {
|
||||
i++;
|
||||
}
|
||||
lines.splice(0, i);
|
||||
|
||||
// remove last empty lines
|
||||
i = lines.length - 1;
|
||||
while (!lines[i]) {
|
||||
i--;
|
||||
}
|
||||
if (i < lines.length - 1) {
|
||||
lines.splice(i + 1);
|
||||
}
|
||||
|
||||
lines[0] = lines[0].replace('systemDictionary = ', '');
|
||||
lines[lines.length - 1] = lines[lines.length - 1].trim().replace(/};$/, '}');
|
||||
words = lines.join('\n');
|
||||
var resultFunc = new Function('return ' + words + ';');
|
||||
|
||||
return resultFunc();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function padRight(text, totalLength) {
|
||||
return text + (text.length < totalLength ? new Array(totalLength - text.length).join(' ') : '');
|
||||
}
|
||||
function writeWordJs(data, src) {
|
||||
var text = '// DO NOT EDIT THIS FILE!!! IT WILL BE AUTOMATICALLY GENERATED FROM src/i18n\n';
|
||||
text += '/*global systemDictionary:true */\n';
|
||||
text += '\'use strict\';\n\n';
|
||||
|
||||
text += 'systemDictionary = {\n';
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
text += ' ' + padRight('"' + word.replace(/"/g, '\\"') + '": {', 50);
|
||||
var line = '';
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
line += '"' + lang + '": "' + padRight(data[word][lang].replace(/"/g, '\\"') + '",', 50) + ' ';
|
||||
}
|
||||
}
|
||||
if (line) {
|
||||
line = line.trim();
|
||||
line = line.substring(0, line.length - 1);
|
||||
}
|
||||
text += line + '},\n';
|
||||
}
|
||||
}
|
||||
text = text.replace(/},\n$/, '}\n');
|
||||
text += '};';
|
||||
|
||||
if (fs.existsSync(src + 'js/' + fileName)) {
|
||||
fs.writeFileSync(src + 'js/' + fileName, text);
|
||||
} else {
|
||||
fs.writeFileSync(src + '' + fileName, text);
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY = '';
|
||||
|
||||
function words2languages(src) {
|
||||
var langs = Object.assign({}, languages);
|
||||
var data = readWordJs(src);
|
||||
if (data) {
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
langs[lang][word] = data[word][lang];
|
||||
// pre-fill all other languages
|
||||
for (var j in langs) {
|
||||
if (langs.hasOwnProperty(j)) {
|
||||
langs[j][word] = langs[j][word] || EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/')) {
|
||||
fs.mkdirSync(src + 'i18n/');
|
||||
}
|
||||
for (var l in langs) {
|
||||
if (!langs.hasOwnProperty(l)) continue;
|
||||
var keys = Object.keys(langs[l]);
|
||||
//keys.sort();
|
||||
var obj = {};
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
obj[keys[k]] = langs[l][keys[k]];
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/' + l)) {
|
||||
fs.mkdirSync(src + 'i18n/' + l);
|
||||
}
|
||||
|
||||
fs.writeFileSync(src + 'i18n/' + l + '/translations.json', lang2data(obj));
|
||||
}
|
||||
} else {
|
||||
console.error('Cannot read or parse ' + fileName);
|
||||
}
|
||||
}
|
||||
function words2languagesFlat(src) {
|
||||
var langs = Object.assign({}, languages);
|
||||
var data = readWordJs(src);
|
||||
if (data) {
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
langs[lang][word] = data[word][lang];
|
||||
// pre-fill all other languages
|
||||
for (var j in langs) {
|
||||
if (langs.hasOwnProperty(j)) {
|
||||
langs[j][word] = langs[j][word] || EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var keys = Object.keys(langs.en);
|
||||
//keys.sort();
|
||||
for (var l in langs) {
|
||||
if (!langs.hasOwnProperty(l)) continue;
|
||||
var obj = {};
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
obj[keys[k]] = langs[l][keys[k]];
|
||||
}
|
||||
langs[l] = obj;
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/')) {
|
||||
fs.mkdirSync(src + 'i18n/');
|
||||
}
|
||||
for (var ll in langs) {
|
||||
if (!langs.hasOwnProperty(ll)) continue;
|
||||
if (!fs.existsSync(src + 'i18n/' + ll)) {
|
||||
fs.mkdirSync(src + 'i18n/' + ll);
|
||||
}
|
||||
|
||||
fs.writeFileSync(src + 'i18n/' + ll + '/flat.txt', lang2data(langs[ll], langs.en));
|
||||
}
|
||||
fs.writeFileSync(src + 'i18n/flat.txt', keys.join('\n'));
|
||||
} else {
|
||||
console.error('Cannot read or parse ' + fileName);
|
||||
}
|
||||
}
|
||||
function languagesFlat2words(src) {
|
||||
var dirs = fs.readdirSync(src + 'i18n/');
|
||||
var langs = {};
|
||||
var bigOne = {};
|
||||
var order = Object.keys(languages);
|
||||
dirs.sort(function (a, b) {
|
||||
var posA = order.indexOf(a);
|
||||
var posB = order.indexOf(b);
|
||||
if (posA === -1 && posB === -1) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
} else if (posA === -1) {
|
||||
return -1;
|
||||
} else if (posB === -1) {
|
||||
return 1;
|
||||
} else {
|
||||
if (posA > posB) return 1;
|
||||
if (posA < posB) return -1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
var keys = fs.readFileSync(src + 'i18n/flat.txt').toString().split('\n');
|
||||
|
||||
for (var l = 0; l < dirs.length; l++) {
|
||||
if (dirs[l] === 'flat.txt') continue;
|
||||
var lang = dirs[l];
|
||||
var values = fs.readFileSync(src + 'i18n/' + lang + '/flat.txt').toString().split('\n');
|
||||
langs[lang] = {};
|
||||
keys.forEach(function (word, i) {
|
||||
langs[lang][word] = values[i].replace(/<\/ i>/g, '</i>').replace(/<\/ b>/g, '</b>').replace(/<\/ span>/g, '</span>').replace(/% s/g, ' %s');
|
||||
});
|
||||
|
||||
var words = langs[lang];
|
||||
for (var word in words) {
|
||||
if (words.hasOwnProperty(word)) {
|
||||
bigOne[word] = bigOne[word] || {};
|
||||
if (words[word] !== EMPTY) {
|
||||
bigOne[word][lang] = words[word];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// read actual words.js
|
||||
var aWords = readWordJs();
|
||||
|
||||
var temporaryIgnore = ['pt', 'fr', 'nl', 'flat.txt'];
|
||||
if (aWords) {
|
||||
// Merge words together
|
||||
for (var w in aWords) {
|
||||
if (aWords.hasOwnProperty(w)) {
|
||||
if (!bigOne[w]) {
|
||||
console.warn('Take from actual words.js: ' + w);
|
||||
bigOne[w] = aWords[w]
|
||||
}
|
||||
dirs.forEach(function (lang) {
|
||||
if (temporaryIgnore.indexOf(lang) !== -1) return;
|
||||
if (!bigOne[w][lang]) {
|
||||
console.warn('Missing "' + lang + '": ' + w);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
writeWordJs(bigOne, src);
|
||||
}
|
||||
function languages2words(src) {
|
||||
var dirs = fs.readdirSync(src + 'i18n/');
|
||||
var langs = {};
|
||||
var bigOne = {};
|
||||
var order = Object.keys(languages);
|
||||
dirs.sort(function (a, b) {
|
||||
var posA = order.indexOf(a);
|
||||
var posB = order.indexOf(b);
|
||||
if (posA === -1 && posB === -1) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
} else if (posA === -1) {
|
||||
return -1;
|
||||
} else if (posB === -1) {
|
||||
return 1;
|
||||
} else {
|
||||
if (posA > posB) return 1;
|
||||
if (posA < posB) return -1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
for (var l = 0; l < dirs.length; l++) {
|
||||
if (dirs[l] === 'flat.txt') continue;
|
||||
var lang = dirs[l];
|
||||
langs[lang] = fs.readFileSync(src + 'i18n/' + lang + '/translations.json').toString();
|
||||
langs[lang] = JSON.parse(langs[lang]);
|
||||
var words = langs[lang];
|
||||
for (var word in words) {
|
||||
if (words.hasOwnProperty(word)) {
|
||||
bigOne[word] = bigOne[word] || {};
|
||||
if (words[word] !== EMPTY) {
|
||||
bigOne[word][lang] = words[word];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// read actual words.js
|
||||
var aWords = readWordJs();
|
||||
|
||||
var temporaryIgnore = ['pt', 'fr', 'nl', 'it'];
|
||||
if (aWords) {
|
||||
// Merge words together
|
||||
for (var w in aWords) {
|
||||
if (aWords.hasOwnProperty(w)) {
|
||||
if (!bigOne[w]) {
|
||||
console.warn('Take from actual words.js: ' + w);
|
||||
bigOne[w] = aWords[w]
|
||||
}
|
||||
dirs.forEach(function (lang) {
|
||||
if (temporaryIgnore.indexOf(lang) !== -1) return;
|
||||
if (!bigOne[w][lang]) {
|
||||
console.warn('Missing "' + lang + '": ' + w);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
writeWordJs(bigOne, src);
|
||||
}
|
||||
|
||||
gulp.task('adminWords2languages', function (done) {
|
||||
words2languages('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminWords2languagesFlat', function (done) {
|
||||
words2languagesFlat('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminLanguagesFlat2words', function (done) {
|
||||
languagesFlat2words('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminLanguages2words', function (done) {
|
||||
languages2words('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
gulp.task('updatePackages', function (done) {
|
||||
iopackage.common.version = pkg.version;
|
||||
iopackage.common.news = iopackage.common.news || {};
|
||||
if (!iopackage.common.news[pkg.version]) {
|
||||
var news = iopackage.common.news;
|
||||
var newNews = {};
|
||||
|
||||
newNews[pkg.version] = {
|
||||
en: 'news',
|
||||
de: 'neues',
|
||||
ru: 'новое'
|
||||
};
|
||||
iopackage.common.news = Object.assign(newNews, news);
|
||||
}
|
||||
fs.writeFileSync('io-package.json', JSON.stringify(iopackage, null, 4));
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('updateReadme', function (done) {
|
||||
var readme = fs.readFileSync('README.md').toString();
|
||||
var pos = readme.indexOf('## Changelog\n');
|
||||
if (pos !== -1) {
|
||||
var readmeStart = readme.substring(0, pos + '## Changelog\n'.length);
|
||||
var readmeEnd = readme.substring(pos + '## Changelog\n'.length);
|
||||
|
||||
if (readme.indexOf(version) === -1) {
|
||||
var timestamp = new Date();
|
||||
var date = timestamp.getFullYear() + '-' +
|
||||
('0' + (timestamp.getMonth() + 1).toString(10)).slice(-2) + '-' +
|
||||
('0' + (timestamp.getDate()).toString(10)).slice(-2);
|
||||
|
||||
var news = '';
|
||||
if (iopackage.common.news && iopackage.common.news[pkg.version]) {
|
||||
news += '* ' + iopackage.common.news[pkg.version].en;
|
||||
}
|
||||
|
||||
fs.writeFileSync('README.md', readmeStart + '### ' + version + ' (' + date + ')\n' + (news ? news + '\n\n' : '\n') + readmeEnd);
|
||||
}
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('default', ['updatePackages', 'updateReadme']);
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 59 KiB |
@ -0,0 +1,85 @@
|
||||
{
|
||||
"common": {
|
||||
"name": "yuanqu",
|
||||
"version": "0.0.7",
|
||||
"title": "Yuanqu",
|
||||
"desc": {
|
||||
"en": "YQ connection Slave or Master",
|
||||
"cn": "智慧园区"
|
||||
},
|
||||
"license": "MIT",
|
||||
"platform": "Javascript/Node.js",
|
||||
"mode": "daemon",
|
||||
"loglevel": "info",
|
||||
"messagebox": true,
|
||||
"icon": "yuanqu.png",
|
||||
"keywords": [
|
||||
"Yuanqu"
|
||||
],
|
||||
"enabled": true,
|
||||
"extIcon": "https://git.spacen.net/yunkong2/yunkong2.yuanqu/raw/master/admin/yuanqu.png",
|
||||
"readme": "https://github.com/yunkong2/yunkong2.yuanqu/blob/master/README.md",
|
||||
"type": "protocols",
|
||||
"config": {
|
||||
"minWidth": 1024,
|
||||
"width": 1224,
|
||||
"height": 600
|
||||
}
|
||||
},
|
||||
"native": {
|
||||
"params": {
|
||||
"type": "tcp",
|
||||
"bind": "127.0.0.1",
|
||||
"port": 502,
|
||||
"comName": "",
|
||||
"baudRate": 9600,
|
||||
"dataBits": 8,
|
||||
"stopBits": 1,
|
||||
"parity": "none",
|
||||
"deviceId": 1,
|
||||
"timeout": 5000,
|
||||
"slave": 0,
|
||||
"poll": 1000,
|
||||
"recon": 60000,
|
||||
"maxBlock": 100,
|
||||
"maxBoolBlock": 128,
|
||||
"multiDeviceId": false,
|
||||
"pulsetime": 1000,
|
||||
"disInputsOffset": 10001,
|
||||
"coilsOffset": 1,
|
||||
"inputRegsOffset": 30001,
|
||||
"holdingRegsOffset": 40001,
|
||||
"showAliases": true,
|
||||
"directAddresses": false,
|
||||
"round": 2,
|
||||
"doNotRoundAddressToWord": false
|
||||
},
|
||||
"disInputs": [],
|
||||
"coils": [],
|
||||
"inputRegs": [],
|
||||
"holdingRegs": []
|
||||
},
|
||||
"instanceObjects": [
|
||||
{
|
||||
"_id": "info",
|
||||
"type": "channel",
|
||||
"common": {
|
||||
"name": "Information"
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
{
|
||||
"_id": "info.connection",
|
||||
"type": "state",
|
||||
"common": {
|
||||
"role": "indicator.connected",
|
||||
"name": "If master connected",
|
||||
"type": "boolean",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"def": false
|
||||
},
|
||||
"native": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "yunkong2.yuanqu",
|
||||
"version": "0.0.7",
|
||||
"description": "Connect devices oder yuanqu protocol to yunkong2",
|
||||
"homepage": "https://git.spacen.net/yunkong2/yunkong2.yuanqu",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"modbus",
|
||||
"Smart Home",
|
||||
"home automation"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.spacen.net/yunkong2/yunkong2.yuanqu"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"mocha": "^4.1.0"
|
||||
},
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "node node_modules/mocha/bin/mocha test/testAdapter.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/yunkong2/yunkong2.yuanqu/issues"
|
||||
},
|
||||
"readmeFilename": "README.md"
|
||||
}
|