removed backups
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
app.mqttBroker = {"192.168.9.99",inf="MQTT Broker"};
|
||||
app.mqttRoot = {"pilogi",inf="MQTT Root"};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
modules = {"panel","app","locale"};
|
||||
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {}
|
||||
require "app"
|
||||
|
||||
function app.apply()
|
||||
print(
|
||||
"<br><b><center>Apply module app !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, musste die Anwendung neu gestartet werden !</center><br>"
|
||||
);
|
||||
os.execute("/root/ctrlapp stop")
|
||||
os.execute("sleep 2")
|
||||
os.execute("/root/ctrlapp start")
|
||||
end
|
||||
|
||||
function app.validate()
|
||||
print("<br><b><center>Validate modlue app !</center></b><br>");
|
||||
end
|
||||
|
||||
---------------- Witty Administration localisation ------------------
|
||||
|
||||
locale = {}
|
||||
require "locale";
|
||||
|
||||
---------------- Witty Administration Tabs configuration ------------
|
||||
|
||||
tabs = {}
|
||||
require "tabs";
|
||||
|
||||
panel = {};
|
||||
require "panel"
|
||||
|
||||
function panel.apply()
|
||||
local mqttBroker = app.mqttBroker[1]
|
||||
local mqttRoot = app.mqttRoot[1]
|
||||
print(
|
||||
"<br><b><center>Apply module panel !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, wird die Konfiguration via MQTT publiziert !</center><br>"
|
||||
);
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m apply")
|
||||
os.execute("sleep 2")
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m publish")
|
||||
end
|
||||
@@ -1,44 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start|"")
|
||||
# Run App use default run.lua
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
stop)
|
||||
/usr/bin/killall app
|
||||
;;
|
||||
kill)
|
||||
/usr/bin/killall -kill app
|
||||
;;
|
||||
run)
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
debug)
|
||||
/usr/bin/killall app
|
||||
# /bin/app -e -r /root /root/run.lua
|
||||
# websocket fix, daq should lower permissions
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/su -p -c '/bin/app -e -r /root /root/run.lua' lua
|
||||
;;
|
||||
websocket)
|
||||
/usr/bin/killall websocketd
|
||||
/usr/bin/screen -dmS websock /bin/websocketd --staticdir=/mnt/www --port=88 /root/ctrlapp debug
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|run|debug|websocket}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,4 +0,0 @@
|
||||
[Info]
|
||||
Version = 1
|
||||
[Framebuffer]
|
||||
Device = /dev/fb0
|
||||
@@ -1,9 +0,0 @@
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {};
|
||||
require "app"
|
||||
|
||||
---------------- Application module locale configuration ---------------
|
||||
|
||||
locale = {};
|
||||
require "locale";
|
||||
BIN
3B/archive/root_10.bak/font/arial.ttf
(Stored with Git LFS)
BIN
3B/archive/root_10.bak/font/arial.ttf
(Stored with Git LFS)
Binary file not shown.
BIN
3B/archive/root_10.bak/font/mono.ttf
(Stored with Git LFS)
BIN
3B/archive/root_10.bak/font/mono.ttf
(Stored with Git LFS)
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
locale.version = {"Version 1.0",inf="Software Version"};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
PLC = require('modbus')
|
||||
socket = require('socket')
|
||||
|
||||
plc = PLC.Modbus("pi_daq",502)
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
plc:sync();
|
||||
print(plc:getReal(1))
|
||||
end
|
||||
socket.sleep(0.5)
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
MQTT = require("mosquitto")
|
||||
mqtt = MQTT.new()
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
local connected = false
|
||||
local broker = "localhost"
|
||||
|
||||
local onMessage = nil
|
||||
local onConnect = nil
|
||||
|
||||
local function publish(topic,msg,retain)
|
||||
retain = retain or false
|
||||
mqtt:publish(topic,msg, qos, retain)
|
||||
end
|
||||
|
||||
local function loop()
|
||||
local ok,err,msg
|
||||
|
||||
if connected then
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
if onError then onError(1) end
|
||||
connected = false
|
||||
end
|
||||
else
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
if onError then onError(2) end
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
mqtt:connect(broker,1883,5)
|
||||
errLog("MQTT:\t Reconnect".."\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function subscribe(msg)
|
||||
mqtt:subscribe(msg)
|
||||
end
|
||||
|
||||
mqtt.ON_CONNECT = function()
|
||||
connected = true
|
||||
if onConnect then onConnect() end
|
||||
end
|
||||
|
||||
mqtt.ON_MESSAGE = function(mid, topic, payload)
|
||||
if onMessage then onMessage(mid, topic, payload) end
|
||||
end
|
||||
|
||||
local function begin(hostname)
|
||||
broker = hostname
|
||||
mqtt:connect(broker,1883,5)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
loop = loop;
|
||||
publish = publish;
|
||||
subscribe = subscribe;
|
||||
onConnect = function(callback) onConnect = callback end;
|
||||
onMessage = function(callback) onMessage = callback end;
|
||||
onError = function(callback) onError = callback end;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
panel.Debug = {idx=2,alt={"on","off"},inf="Debug Ausgabe aktivieren, MQTT:-t <mqttRoot>/debug -m off -m on | off"};
|
||||
panel.LabelButtonSend = {"Send",inf="Beschriftung Panel Send, MQTT: -t <mqttRoot>/label/button/send -m 'Send'"};
|
||||
panel.LabelButton_1 = {"Sensor Analog",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/label/button/0 -m 'Text'"};
|
||||
panel.LabelButton_2 = {"Endpoint Logic",inf="Beschriftung Panel Button 2, MQTT: -t <mqttRoot>/label/button/1 -m 'Text'"};
|
||||
panel.LabelButton_3 = {"Kanal 3",inf="Beschriftung Panel Button 3, MQTT: -t <mqttRoot>/label/button/2 -m 'Text'"};
|
||||
panel.LabelButton_4 = {"Kanal 4",inf="Beschriftung Panel Button 4, MQTT: -t <mqttRoot>/label/button/3 -m 'Text'"};
|
||||
panel.LabelHeader = {"AL01 Datalogger",inf="Beschriftung Ueberschrift, MQTT: -t <mqttRoot>/label/header -m 'Text'"};
|
||||
panel.OptionsSamples = {100.000000,inf="Samples, MQTT: <mqttRoot>/options/samples -m 100"};
|
||||
panel.OptionsXaxisMax = {100.000000,inf="Maximum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/max -m 100"};
|
||||
panel.OptionsXaxisMin = {0.000000,inf="Minimum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/min -m 0"};
|
||||
panel.OptionsXaxis_1_Max = {15.000000,inf="Maximum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/max -m 15"};
|
||||
panel.OptionsXaxis_2_Max = {30.000000,inf="Maximum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/max -m 30"};
|
||||
panel.OptionsXaxis_2_Min = {0.000000,inf="Minimum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/min -m 0"};
|
||||
panel.OptionsYaxis_1_Min = {0.000000,inf="Minimum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/min -m 0"};
|
||||
panel.TextSendMessage = {"ping",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/message -m 'ping'"};
|
||||
panel.TextSendTopic = {"/ctrl/cmd",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/topic -m 'ctrl/cmd'"};
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
evdev = require "evdev"
|
||||
touch = evdev.Device("/dev/input/event0")
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_HOME = 0x0C
|
||||
|
||||
COMMAND_PASSWORD = 0x7F
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_ON = 0x0F
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
touchY = 0
|
||||
touchX = 0
|
||||
|
||||
LOGING = 1
|
||||
-- 1 2 3 4 5 6 7 8 9 10
|
||||
-- 11 12 13 14 15 16 17 18 19 20
|
||||
controlLabels = {"<-" ,"<<" ,"^" ,"^^" ,"vv" , "v" ,">>" ,"->" ,"Help" ,"Del",
|
||||
"Done" ," " ,"Insert","," ,"Space" , " " ,"=" ,"Remove","Enter" ," "}
|
||||
controlFonts = {"C" ,"C" ,"C" ,"C" ,"C" , "C" ,"C" ,"C" ,"T" ,"C",
|
||||
"C" ,"T" ,"T" ,"C" ,"C" , "T" ,"C" ,"T" ,"C" ,"T"}
|
||||
controlPos = {{02,06}, {01,18}, {02,02}, {01,30}, {01,22}, {18,02}, {01,34}, {02,44}, {02,10}, {02,50},
|
||||
{10,01}, {10,01}, {06,01}, {10,50}, {14,50}, {14,50}, {06,50}, {15,02}, {18,50}, {18,50}}
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
function clearAndHome(void)
|
||||
for i=1, 6, 1 do
|
||||
for j=1, 40, 1 do
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setText(" ")
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
posX = 0
|
||||
posY = 0
|
||||
end
|
||||
|
||||
|
||||
function doRead()
|
||||
local loops = 0
|
||||
while loops < 30 do
|
||||
loops = loops + 1
|
||||
if serial:poll(1) then
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
elseif cmd:byte() == COMMAND_HOME then
|
||||
clearAndHome();
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CURSOR_ON then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() == COMMAND_PASSWORD then
|
||||
c = '*'
|
||||
end
|
||||
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
--print(c.." at "..posX.." "..posY.."\n")
|
||||
local label = line[posY+1][posX+1]
|
||||
label:setText(c)
|
||||
if blinkFlag then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
label:draw()
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function doTouch()
|
||||
local x = 0;
|
||||
local y = 0;
|
||||
if touch:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = touch:read()
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 53 then
|
||||
touchX = value
|
||||
elseif eventCode == 54 then
|
||||
touchY = value
|
||||
end
|
||||
end
|
||||
if eventType == 1 then
|
||||
if eventCode == 330 then
|
||||
if touchY > 0 and touchY < 79 then
|
||||
idx = math.floor(touchX/80)+1
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl1: ",y,x,idx)
|
||||
end
|
||||
if touchY > 400 and touchY < 479 then
|
||||
idx = math.floor(touchX/80)+11
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl2: ",y,x,idx)
|
||||
end
|
||||
if touchY > 320 and touchY < 399 then
|
||||
x = 8 + math.floor(touchX/80)*4
|
||||
y = 19
|
||||
print("Numbs: ",y,x)
|
||||
end
|
||||
if touchY > 80 and touchY < 319 then
|
||||
y = math.floor((touchY-80)/240*10+6)
|
||||
x = math.floor(touchX/720*36+7)
|
||||
print("Lines: ",y,x)
|
||||
end
|
||||
if x > 0 and y > 0 then
|
||||
if value == 1 then
|
||||
print("down")
|
||||
serial:write(string.char(0x5F,y,x))
|
||||
serial:flush()
|
||||
--serial:write(string.char(0x5F,x,y))
|
||||
else
|
||||
print("up")
|
||||
serial:write(string.char(0x6F,y,x))
|
||||
serial:flush()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function setup()
|
||||
serial = Serial{device="/dev/ttyAMA0", baudrate=9600, databits=7, parity="odd", stopbits=1}
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
monoChar = HMI.Font("/root/font/mono.ttf",34)
|
||||
monoText = HMI.Font("/root/font/mono.ttf",20)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4," ");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(monoChar)
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),34,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.white);
|
||||
number[i]:setFont(monoChar)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
local idx = i+j*10
|
||||
if idx ~= 12 and idx ~= 16 and idx ~= 20 then
|
||||
if idx == 11 or idx == 15 or idx == 19 then
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,40,7,i-1);
|
||||
else
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,20,7,i-1);
|
||||
end
|
||||
if controlLabels[idx] then
|
||||
control[idx]:setText(controlLabels[idx])
|
||||
end
|
||||
control[idx]:setTextColor(HMI.Color.black);
|
||||
control[idx]:setBackground(HMI.Color.grey);
|
||||
if controlFonts[idx] == 'T' then
|
||||
control[idx]:setFont(monoText)
|
||||
else
|
||||
control[i+j*10]:setFont(monoChar)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
doRead()
|
||||
doTouch()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+1)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData then
|
||||
line[posY+1]:setText(strData);
|
||||
line[posY+1]:draw()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i]:setTextColor(HMI.Color.green);
|
||||
line[i]:setBackground(HMI.Color.black);
|
||||
line[i]:setFont(mono)
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
panel = {}
|
||||
require "panel"
|
||||
|
||||
socket = require('socket')
|
||||
PLC = require('vwago')
|
||||
Scheduler = require('scheduler')
|
||||
--I2CClass = require('periphery').I2C
|
||||
I2CDevice = nil;
|
||||
MQTT = require("mqtt")
|
||||
|
||||
daq = {};
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg)
|
||||
print(msg);
|
||||
end
|
||||
|
||||
local function pubPanelConfig()
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/send",panel.LabelButtonSend[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/0",panel.LabelButton_1[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/1",panel.LabelButton_2[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/2",panel.LabelButton_3[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/3",panel.LabelButton_4[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/header",panel.LabelHeader[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/samples",panel.OptionsSamples[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/max",panel.OptionsXaxisMax[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/min",panel.OptionsXaxisMin[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/max",panel.OptionsXaxis_1_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/max",panel.OptionsXaxis_2_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/min",panel.OptionsXaxis_2_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/min",panel.OptionsYaxis_1_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/message", panel.TextSendMessage[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/topic",panel.TextSendTopic[1])
|
||||
MQTT.publish(mqttRoot.."/panel/debug",panel.Debug["alt"][panel.Debug["idx"]])
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.publish(mqttRoot.."/info", "PIALU")
|
||||
MQTT.subscribe(mqttRoot.."/ctrl/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message "..topic, payload)
|
||||
|
||||
subTopic = string.match(topic,mqttRoot.."/ctrl/(%w+)")
|
||||
if subTopic then
|
||||
if subTopic == "cmd" then
|
||||
logPrint("MQTT:\t Command");
|
||||
analogChannel = string.match(topic,mqttRoot.."/ctrl/cmd/analog/(%w)")
|
||||
if analogChannel then
|
||||
|
||||
if analogChannel == "0" then
|
||||
logPrint("MQTT:\t Command Analog Channel "..analogChannel.." "..payload);
|
||||
if payload == "on" then
|
||||
channel_0 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
else
|
||||
channel_0 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "off",true)
|
||||
end
|
||||
elseif analogChannel == "1" then
|
||||
if payload == "on" then
|
||||
channel_1 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
else
|
||||
channel_1 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "off",true)
|
||||
end
|
||||
elseif analogChannel == "2" then
|
||||
if payload == "on" then
|
||||
channel_2 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
else
|
||||
channel_2 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "off",true)
|
||||
end
|
||||
elseif analogChannel == "3" then
|
||||
if payload == "on" then
|
||||
channel_3 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
else
|
||||
channel_3 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "off",true)
|
||||
end
|
||||
end
|
||||
elseif string.match(topic,mqttRoot.."/ctrl/cmd/panel/config") then
|
||||
if string.match(payload,"publish") then
|
||||
pubPanelConfig()
|
||||
elseif string.match(payload,"apply") then
|
||||
panel = {}
|
||||
dofile("panel.lua")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local function getInt32(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 4) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8) + bit32.lshift(bytes[offset+3],16) + bit32.lshift(bytes[offset+4],24);
|
||||
if ( num > 0x80000000 ) then
|
||||
return num - 0x100000000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getInt16(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 2) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8);
|
||||
end
|
||||
|
||||
if ( num > 0x8000 ) then
|
||||
return num - 0x10000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getUint8(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 1) then
|
||||
return bytes[offset+1];
|
||||
end
|
||||
|
||||
return 999999999;
|
||||
end
|
||||
--[[
|
||||
local function i2cBegin()
|
||||
I2CDevice = I2CClass("/dev/i2c-1")
|
||||
end
|
||||
|
||||
local function i2cRecvMsg()
|
||||
local msg = {{
|
||||
0x00, -- uint8_t hartbeat;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
flags = I2CClass.I2C_M_RD
|
||||
}}
|
||||
I2CDevice:transfer(6, msg)
|
||||
-- print(table.unpack(msg[1]));
|
||||
return msg[1]
|
||||
end
|
||||
|
||||
local function i2cSendMsg(cmd)
|
||||
local msg = {{cmd, 0x00, 0x00, 0x00, 0x00, flags = 0}}
|
||||
I2CDevice:transfer(4, msg)
|
||||
end
|
||||
--]]
|
||||
local function recv()
|
||||
--[[
|
||||
daqData = i2cRecvMsg();
|
||||
-- print(table.unpack(daqData));
|
||||
daq.hartbeat = getUint8(daqData,0);
|
||||
daq.sum0 = getInt32(daqData,1);
|
||||
daq.sum1 = getInt32(daqData,5);
|
||||
daq.sum2 = getInt32(daqData,9);
|
||||
daq.sum3 = getInt32(daqData,13);
|
||||
--]]
|
||||
daq.hartbeat = 123;
|
||||
daq.sum0 = 3;
|
||||
daq.sum1 = 1.7;
|
||||
daq.sum2 = 9;
|
||||
daq.sum3 = 5.5;
|
||||
end
|
||||
|
||||
function setup()
|
||||
mqttBroker = app.mqttBroker[1]
|
||||
mqttRoot = app.mqttRoot[1]
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,32,24);
|
||||
|
||||
label = HMI.Label(layout,0,0,32,3,"Plot");
|
||||
label:setTextColor(HMI.Color.white);
|
||||
label:setBackground(HMI.Color.blue);
|
||||
|
||||
chart = HMI.Timechart(layout,0,4,32,16)
|
||||
chart:setBaseline(0)
|
||||
chart:setValuePerDivison(2)
|
||||
chart:setSamplesPerDivison(20)
|
||||
chart:setSamplesFormat("%d Samples/Div, Samplerate 0.5s <=> 10 Sekunden/Div")
|
||||
|
||||
txt0 = HMI.Label(layout, 1,20,6,2,"Ch 0");
|
||||
txt0:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt1 = HMI.Label(layout,17,20,6,2,"Ch 1");
|
||||
txt1:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt2 = HMI.Label(layout, 1,22,6,2,"Ch 2");
|
||||
txt2:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt3 = HMI.Label(layout,17,22,6,2,"Ch 3");
|
||||
txt3:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
|
||||
out0 = HMI.Output(layout, 7,20,6,2,"0000");
|
||||
out1 = HMI.Output(layout,23,20,6,2,"0000");
|
||||
out2 = HMI.Output(layout, 7,22,6,2,"0000");
|
||||
out3 = HMI.Output(layout,23,22,6,2,"0000");
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
|
||||
-- i2cBegin()
|
||||
|
||||
if mqttBroker then
|
||||
errLog("MQTT:\t Begin\n");
|
||||
MQTT.begin(mqttBroker)
|
||||
end
|
||||
|
||||
MQTT.loop()
|
||||
|
||||
channel_0 = true;
|
||||
channel_1 = true;
|
||||
channel_2 = true;
|
||||
channel_3 = true;
|
||||
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
end
|
||||
|
||||
function loop()
|
||||
MQTT.loop()
|
||||
|
||||
if updateTimer.elapsed() then
|
||||
updateTimer.restart()
|
||||
recv()
|
||||
|
||||
val0 = daq.sum0*0.0000707750682632
|
||||
val1 = daq.sum1*0.0000707750682632
|
||||
val2 = daq.sum2*0.0000208350713273
|
||||
val3 = daq.sum3*0.0000208350713273
|
||||
|
||||
out0:setText(string.format("%5.2f",val0))
|
||||
out1:setText(string.format("%5.2f",val1))
|
||||
out2:setText(string.format("%5.2f",val2))
|
||||
out3:setText(string.format("%5.2f",val3))
|
||||
chart:plot(daq.sum0*0.0000707750682632)
|
||||
--chart:plot(daq.sum1*0.0000707750682632)
|
||||
--chart:plot(daq.sum2*0.0000208350713273)
|
||||
--chart:plot(daq.sum3*0.0000208350713273)
|
||||
|
||||
compound = ""
|
||||
|
||||
if channel_0 then
|
||||
MQTT.publish(mqttRoot.."/analog/0",val0)
|
||||
compound = compound..",0:"..val0
|
||||
end
|
||||
if channel_1 then
|
||||
MQTT.publish(mqttRoot.."/analog/1",val1)
|
||||
compound = compound..",1:"..val1
|
||||
end
|
||||
if channel_2 then
|
||||
MQTT.publish(mqttRoot.."/analog/2",val2)
|
||||
compound = compound..",2:"..val2
|
||||
end
|
||||
if channel_3 then
|
||||
MQTT.publish(mqttRoot.."/analog/3",val3)
|
||||
compound = compound..",3:"..val3
|
||||
end
|
||||
all = string.sub(compound,2)
|
||||
if string.len(all) > 0 then
|
||||
MQTT.publish(mqttRoot.."/analog/all",all)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+2)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData and attrData then
|
||||
local len = string.len(strData)
|
||||
for j=1, len, 1 do
|
||||
local label = line[posY+1][posX+j]
|
||||
if attrData:sub(j,j) == 'b' then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
label:setText(strData:sub(j,j))
|
||||
label:draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4,j%10);
|
||||
-- line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(mono)
|
||||
line[1][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
local scheduler = {}
|
||||
|
||||
socket = require('socket')
|
||||
|
||||
function scheduler.Timer(init)
|
||||
-- the new instance
|
||||
|
||||
local self = {
|
||||
-- public fields go in the instance table
|
||||
interval = init
|
||||
}
|
||||
|
||||
local function millis()
|
||||
return socket.gettime()*1000
|
||||
end
|
||||
|
||||
-- private fields are implemented using locals
|
||||
-- they are faster than table access, and are truly private,
|
||||
-- so the code that uses your class can't get them
|
||||
|
||||
local _timestamp = millis()
|
||||
local _running = true
|
||||
|
||||
function self.elapsed()
|
||||
if _running and (millis() - _timestamp ) >= self.interval then
|
||||
_running = false
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function self.running()
|
||||
return (millis() - _timestamp ) < self.interval
|
||||
end
|
||||
|
||||
function self.restart()
|
||||
_timestamp = millis()
|
||||
_running = true
|
||||
end
|
||||
|
||||
function self.count()
|
||||
return millis() - timestamp
|
||||
end
|
||||
|
||||
-- return the instance
|
||||
return self
|
||||
end
|
||||
|
||||
return scheduler
|
||||
@@ -1,599 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
struct = require('struct')
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local T1 = 300
|
||||
local T2 = 1000
|
||||
local T3 = 3000
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local serial
|
||||
local host = false
|
||||
local connected = false
|
||||
local pending = false
|
||||
local transaction_id = 1
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
|
||||
parseData(msg,buf,11,100);
|
||||
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
-- io.stderr:write("packList type("..type(l)..")\n")
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secaId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
pending = true
|
||||
transactionTimer.restart()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("SxF0\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,h.s_stream,0)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("S1F1\n----\n")
|
||||
|
||||
return {
|
||||
primaryHeader(1,1)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(ppid,mid1,mid2,mid3)
|
||||
io.stderr:write("S2F41("..ppid..","..mid1..","..mid2..","..mid3..")\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(2,41),
|
||||
packList( {
|
||||
packString("START"),
|
||||
packList( {
|
||||
packList( {
|
||||
packString("PPID"),
|
||||
packString(ppid)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID1"),
|
||||
packString(mid1)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID2"),
|
||||
packString(mid2)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID3"),
|
||||
packString(mid3)
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("S2F42\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,2,42),
|
||||
packList( {
|
||||
packBinary(4),
|
||||
packList({}) -- empty list
|
||||
} )
|
||||
}
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
|
||||
return {
|
||||
secondaryHeader(h,6,12),
|
||||
packBinary(0)
|
||||
}
|
||||
else
|
||||
secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
end
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function sendMsg(msg)
|
||||
|
||||
local buf = table.concat(msg);
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(chksum / 256))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I: NAK Received\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: AKN Timeout\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: EOT Timeout\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("receiveMsg\n----------\ncount: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
-- TODO checksum error handling
|
||||
|
||||
-- hexDumpString(buf);
|
||||
|
||||
serial:write(ASCII_ACK)
|
||||
|
||||
msg = parseMsg(buf)
|
||||
-- dumpMsg(msg)
|
||||
|
||||
return msg
|
||||
else
|
||||
io.stderr:write("SECS I: Countbyte Timeout\n")
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
local request = {}
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
|
||||
request = receiveMsg()
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
pending = false;
|
||||
end
|
||||
|
||||
msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
sendMsg(S1F2(request.header))
|
||||
SECS.onPrimary(1,1,"are you there")
|
||||
elseif isSF(request,1,2) then
|
||||
SECS.onSecondary(1,2,"are you there akn")
|
||||
elseif isSF(request,1,13) then
|
||||
sendMsg(S1F14(request.header))
|
||||
connected = true;
|
||||
SECS.onPrimary(1,13,"establish communication request")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
SECS.onSecondary(1,14,"establish communication request akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S2F42(request.header))
|
||||
SECS.onPrimary(2,41,"host command send")
|
||||
elseif isSF(request,2,42) then
|
||||
SECS.onSecondary(2,42,"host command send akn")
|
||||
elseif isSF(request,6,11) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S6F12(request.header))
|
||||
SECS.onPrimary(6,11,"event report send")
|
||||
elseif isSF(request,6,12) then
|
||||
--
|
||||
SECS.onSecondary(6,12,"event report send akn")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
sendMsg(SxF0(request.header))
|
||||
SECS.onPrimary(0,0,"abort transaction akn")
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write("loop poll:"..string.byte(c).."\n")
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("loop poll: Transaction timeout\n")
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
|
||||
end
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature= msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isPending = function() return pending end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() sendMsg(S1F13()) end;
|
||||
sendS1F1 = function() sendMsg(S1F1()) end;
|
||||
sendS2F41 = function(a1,a2,a3,a4) sendMsg(S2F41(a1,a2,a3,a4)) end;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
local T1 = 100 --300
|
||||
local T2 = 2000 --1000
|
||||
local T3 = 5000 --3000
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local pending = false
|
||||
local reading = false
|
||||
local writing = false
|
||||
|
||||
local serial
|
||||
|
||||
local onProcessRequest;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
local function hexDumpString(buf)
|
||||
if buf then
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
end
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
local function discardInput()
|
||||
hexDumpString(buf);
|
||||
io.stderr:write("SECS I:\t Discard input: ")
|
||||
while serial:poll(100) do
|
||||
c = serial:read(1)
|
||||
io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function sendMsg(buf)
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
writing = true
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(math.floor(chksum / 256)))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I:\t NAK Received\n")
|
||||
--discardInput()
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t AKN Timeout\n")
|
||||
discardInput()
|
||||
end
|
||||
writing = false
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t EOT Timeout\n")
|
||||
discardInput()
|
||||
writing = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
reading = true
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("SECS I:\t receiveMsg count: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
for i=1, #buf-2 do
|
||||
chksum = chksum + buf:byte(i)
|
||||
end
|
||||
|
||||
local msgChksum = buf:byte(#buf-1)*256 + buf:byte(#buf)
|
||||
|
||||
if msgChksum == chksum then
|
||||
serial:write(ASCII_ACK)
|
||||
return buf
|
||||
else
|
||||
io.stderr:write("SECS I:\t Checksum Error\n")
|
||||
hexDumpString(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
discardInput()
|
||||
--io.stderr:write(string.format("SECS I:\t Checksum: %04X %04X\n",chksum,msgChksum))
|
||||
io.stderr:write(string.format("SECS I:\t Bytes: %d Checksum: %04X %04X\n",#buf,chksum,msgChksum))
|
||||
return ""
|
||||
end
|
||||
reading = false
|
||||
else
|
||||
io.stderr:write("SECS I:\t Countbyte Timeout\n")
|
||||
discardInput()
|
||||
reading = false
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
local buf=receiveMsg()
|
||||
if #buf >= 11 then
|
||||
onProcessRequest(buf)
|
||||
else
|
||||
io.stderr:write("SECS I:\t Poll error bytes: "..#buf.."\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
end
|
||||
elseif c == ASCII_NAK then
|
||||
io.stderr:write("SECS I:\t Poll NAK received\n")
|
||||
--discardInput()
|
||||
pending = false
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write(string.format("SECS I:\t Poll error byte = %02X\n",string.byte(c)))
|
||||
discardInput()
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("SECS I:\t Poll transaction timeout\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
poll = poll;
|
||||
sendMsg = sendMsg;
|
||||
receiveMsg = receiveMsg;
|
||||
isReading = function() return reading end;
|
||||
isWriting = function() return writing end;
|
||||
isPending = function() return pending end;
|
||||
onProcessRequest = function(cb) onProcessRequest = cb end;
|
||||
startTransaction = function() transactionTimer.restart(); pending = true end;
|
||||
stopTransaction = function() pending = false end;
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
|
||||
SECS_IO = require('secs_i')
|
||||
struct = require('struct')
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local secsId = 0x1234
|
||||
local host = false
|
||||
local connected = false
|
||||
|
||||
local transaction_id = 1
|
||||
|
||||
local eq_online = 3 -- 1: online remote, 2: online local, 3: offline
|
||||
local eq_status = 2 -- 1: not ready, 2: ready, 3: busy, 4: process cmpl, 5: pause, 6: complete
|
||||
|
||||
local onSendEventMsg = nil
|
||||
local onPrimaryMsg = nil
|
||||
local onSecondaryMsg = nil
|
||||
local onProcessMsg = nil
|
||||
|
||||
local msgQueue = {}
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
--[[
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
--]]
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
io.stderr:write(string.format("IDX: %d\n",idx))
|
||||
num = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,num))
|
||||
len = buf:byte(idx+1);
|
||||
io.stderr:write(string.format("DATA LEN: %02X %03d\n",len,len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
parseData(msg,buf,11,#buf);
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
-- SECS_IO.startTransaction()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
function string.pop(s)
|
||||
return string.sub(s,1,1),string.sub(s,2)
|
||||
end
|
||||
|
||||
function table.pop(t)
|
||||
local i = t[1]
|
||||
table.remove(t,1)
|
||||
return i,t
|
||||
end
|
||||
|
||||
local function packData(sig,items)
|
||||
local buf = ""
|
||||
|
||||
-- print("packData sig: ",sig)
|
||||
while #sig > 0 do
|
||||
-- print("packData len1: ",#sig)
|
||||
typ, sig = string.pop(sig)
|
||||
-- print("packData len2: ",#sig,typ,sig)
|
||||
if typ == "L" then
|
||||
len , sig = string.pop(sig)
|
||||
-- print("packData len3: ",#sig,len,sig)
|
||||
buf = buf..struct.pack('BB',SF_LIST+1,len)..packData(sig,items)
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
elseif typ == "A" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packString(item)
|
||||
elseif typ == "B" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packBinary(item)
|
||||
end
|
||||
end
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
local function primaryMsg(s,f,sig,items)
|
||||
return primaryHeader(s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
local function secondaryMsg(h,s,f,sig,items)
|
||||
return secondaryHeader(h,s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("\nSECS II: SxF0\n----\n")
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("\nSECS II: S1F1\n----\n")
|
||||
return primaryHeader(1,1)
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("\nSECS II: S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,2,"L0",{})
|
||||
else
|
||||
return secondaryMsg(h,1,2,"L2AA",{MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("\nSECS II: S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return primaryMsg(1,13,"L2BL0",{0})
|
||||
else
|
||||
return primaryMsg(1,13,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("\nSECS II: S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,14,"L2BL0",{0})
|
||||
else
|
||||
return secondaryMsg(h,1,14,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(c)
|
||||
|
||||
io.stderr:write("\nSECS II: S2F41("..c..")\n----\n")
|
||||
if host then
|
||||
return onCreateMsg(2,41,c)
|
||||
else
|
||||
return "" -- host only command
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("\nSECS II: S2F42\n----\n")
|
||||
|
||||
return secondaryMsg(h,2,42,"L2BL0",{4})
|
||||
end
|
||||
|
||||
local function S5F2(h)
|
||||
io.stderr:write("\nSECS II: S5F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,5,2,"B",{0})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("\nSECS II: S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,6,12,"B",{0})
|
||||
else
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F11(e)
|
||||
io.stderr:write("\nSECS II: S6F11("..e..")\n----\n")
|
||||
|
||||
if not host then
|
||||
return onCreateMsg(6,11,e)
|
||||
else
|
||||
return "" -- equipment only command
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
local function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function isS5Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 5
|
||||
end
|
||||
|
||||
local function isS9Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 9
|
||||
end
|
||||
|
||||
SECS_IO.onProcessRequest (
|
||||
function(buf)
|
||||
local request = parseMsg(buf)
|
||||
io.stderr:write("SECS II: ID: ",request.header.secsId,"\n")
|
||||
local s = request.header.secsStream
|
||||
local f = request.header.secsFunction
|
||||
io.stderr:write("SECS II: onProcessMsg ".."S"..s.."F"..f.."\n");
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
local sig = msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
onPrimaryMsg(1,1,"are you there received")
|
||||
SECS_IO.sendMsg(S1F2(request.header))
|
||||
elseif isSF(request,1,2) then
|
||||
onSecondaryMsg(1,2,"are you there received akn")
|
||||
elseif isSF(request,1,13) then
|
||||
connected = true;
|
||||
onPrimaryMsg(1,13,"establish communication request received")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
SECS_IO.sendMsg(S1F14(request.header))
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
onSecondaryMsg(1,14,"establish communication request received akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
--print("SECS II: Message ",#request)
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(2,41,"host command received")
|
||||
SECS_IO.sendMsg(S2F42(request.header))
|
||||
elseif isSF(request,2,42) then
|
||||
onProcessMsg(request)
|
||||
onSecondaryMsg(2,42,"host command received akn")
|
||||
elseif isSF(request,6,11) then
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(6,11,"event report received")
|
||||
SECS_IO.sendMsg(S6F12(request.header))
|
||||
elseif isSF(request,6,12) then
|
||||
onSecondaryMsg(6,12,"event report received akn")
|
||||
elseif isS5Fx(request) then
|
||||
onProcessMsg(request)
|
||||
--hexDumpString(buf)
|
||||
--io.stderr:write("SIG: "..sig.."\n")
|
||||
onPrimaryMsg(5,request.header.secsFunction,"alarm received")
|
||||
SECS_IO.sendMsg(S5F2(request.header))
|
||||
elseif isS9Fx(request) then
|
||||
-- no secondary message
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(9,request.header.secsFunction,"error received")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
onPrimaryMsg(0,0,"abort transaction send")
|
||||
SECS_IO.sendMsg(SxF0(request.header))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function dequeMsg()
|
||||
local m = msgQueue[1]
|
||||
table.remove(msgQueue,1)
|
||||
return m
|
||||
end
|
||||
|
||||
local function queueMsg(msg)
|
||||
io.stderr:write("\n====\nSECS II: queueMsg\n====\n");
|
||||
table.insert(msgQueue,msg)
|
||||
end
|
||||
|
||||
local function poll()
|
||||
if not SECS_IO.isPending() and #msgQueue > 0 then
|
||||
-- if not pending and #msgQueue > 0 then
|
||||
io.stderr:write("\n====\nSECS II: dequeueMsg\n====\n");
|
||||
SECS_IO.startTransaction()
|
||||
SECS_IO.sendMsg(dequeMsg())
|
||||
end
|
||||
SECS_IO.poll()
|
||||
end;
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function setId(id)
|
||||
secsId = id
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
SECS_IO.begin(device,baud)
|
||||
io.stderr:write("begin\n")
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature = msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
--------- DEBUG only ----------------
|
||||
-- dataSignature = dataSignature;
|
||||
-- parseMsg = parseMsg;
|
||||
-- dumpData = dumpData;
|
||||
-- parseData = parseData;
|
||||
|
||||
-- packString = packString;
|
||||
-- packBinary = packBinary;
|
||||
-- packList = packList;
|
||||
-- packData = packData;
|
||||
--------------------------------------
|
||||
|
||||
primaryMsg = primaryMsg;
|
||||
secondaryMsg = secondaryMsg;
|
||||
|
||||
setId = setId;
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isReading = function() return SECS_IO.isReading() end;
|
||||
isWriting = function() return SECS_IO.isWriting() end;
|
||||
isPending = function() return SECS_IO.isPending() end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() queueMsg(S1F13()) end;
|
||||
sendS1F1 = function() queueMsg(S1F1()) end;
|
||||
sendS2F41 = function(c) queueMsg(S2F41(c)) end;
|
||||
sendS6F11 = function(e) queueMsg(S6F11(e)) end;
|
||||
|
||||
onCreateMsg = function(cb) onCreateMsg = cb end;
|
||||
onPrimaryMsg = function(cb) onPrimaryMsg = cb end;
|
||||
onSecondaryMsg = function(cb) onSecondaryMsg = cb end;
|
||||
onProcessMsg = function(cb) onProcessMsg = cb end;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
PLC = require('vwago')
|
||||
|
||||
plc = PLC.VWago("wago")
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
i = plc:getDouble(1)
|
||||
plc:setDouble(0,i)
|
||||
i = i + 1234
|
||||
if i > 2147483647 then
|
||||
i = 0
|
||||
o = plc:getDouble(2)
|
||||
plc:setDouble(2,o+1)
|
||||
end
|
||||
plc:setDouble(1,i)
|
||||
plc:update()
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,114 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
serial = Serial("/dev/ttyAMA0",9600)
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
while (1) do
|
||||
while serial:poll(100) do
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
print(c.." at "..posX.." "..posY.."\n")
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
--[[
|
||||
if ( c >= 0x20 && c < 0x7F ) {
|
||||
(c==buf_char[y_now][x_now])?(buf_chng[y_now][x_now]='n'):(buf_chng[y_now][x_now]='y');
|
||||
(BLINK_FLAG?(buf_args[y_now][x_now] = 'b'):( buf_args[y_now][x_now] = 'n'));
|
||||
buf_char[y_now][x_now] = c;
|
||||
checkX(++x_now);
|
||||
--]]
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
--
|
||||
-- io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
end
|
||||
@@ -1,197 +0,0 @@
|
||||
--[[
|
||||
* Copyright (c) 2015-2017 Iryont <https://github.com/iryont/lua-struct>
|
||||
*
|
||||
* 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.
|
||||
]]
|
||||
|
||||
struct = {}
|
||||
|
||||
function struct.pack(format, ...)
|
||||
local stream = {}
|
||||
local vars = {...}
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
|
||||
local bytes = {}
|
||||
for j = 1, n do
|
||||
table.insert(bytes, string.char(val % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt:find('[fd]') then
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
local sign = 0
|
||||
|
||||
if val < 0 then
|
||||
sign = 1
|
||||
val = -val
|
||||
end
|
||||
|
||||
local mantissa, exponent = math.frexp(val)
|
||||
if val == 0 then
|
||||
mantissa = 0
|
||||
exponent = 0
|
||||
else
|
||||
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
|
||||
exponent = exponent + ((opt == 'd') and 1022 or 126)
|
||||
end
|
||||
|
||||
local bytes = {}
|
||||
if opt == 'd' then
|
||||
val = mantissa
|
||||
for i = 1, 6 do
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
else
|
||||
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
|
||||
val = math.floor(mantissa / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
|
||||
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
|
||||
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
table.insert(stream, tostring(table.remove(vars, 1)))
|
||||
table.insert(stream, string.char(0))
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
local length = tonumber(n)
|
||||
|
||||
if length > 0 then
|
||||
local str = tostring(table.remove(vars, 1))
|
||||
if length - str:len() > 0 then
|
||||
str = str .. string.rep(' ', length - str:len())
|
||||
end
|
||||
table.insert(stream, str:sub(1, length))
|
||||
end
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(stream)
|
||||
end
|
||||
|
||||
function struct.unpack(format, stream)
|
||||
local vars = {}
|
||||
local iterator = 1
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local signed = opt:lower() == opt
|
||||
|
||||
local val = 0
|
||||
for j = 1, n do
|
||||
local byte = string.byte(stream:sub(iterator, iterator))
|
||||
if endianness then
|
||||
val = val + byte * (2 ^ ((j - 1) * 8))
|
||||
else
|
||||
val = val + byte * (2 ^ ((n - j) * 8))
|
||||
end
|
||||
iterator = iterator + 1
|
||||
end
|
||||
|
||||
if signed and val >= 2 ^ (n * 8 - 1) then
|
||||
val = val - 2 ^ (n * 8)
|
||||
end
|
||||
|
||||
table.insert(vars, val)
|
||||
elseif opt:find('[fd]') then
|
||||
local n = (opt == 'd') and 8 or 4
|
||||
local x = stream:sub(iterator, iterator + n - 1)
|
||||
iterator = iterator + n
|
||||
|
||||
if not endianness then
|
||||
x = string.reverse(x)
|
||||
end
|
||||
|
||||
local sign = 1
|
||||
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
|
||||
for i = n - 2, 1, -1 do
|
||||
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
|
||||
end
|
||||
|
||||
if string.byte(x, n) > 127 then
|
||||
sign = -1
|
||||
end
|
||||
|
||||
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
|
||||
if exponent == 0 then
|
||||
table.insert(vars, 0.0)
|
||||
else
|
||||
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
|
||||
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
local bytes = {}
|
||||
for j = iterator, stream:len() do
|
||||
if stream:sub(j, j) == string.char(0) then
|
||||
break
|
||||
end
|
||||
|
||||
table.insert(bytes, stream:sub(j, j))
|
||||
end
|
||||
|
||||
local str = table.concat(bytes)
|
||||
iterator = iterator + str:len() + 1
|
||||
table.insert(vars, str)
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)-1))
|
||||
iterator = iterator + tonumber(n)
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return unpack(vars)
|
||||
end
|
||||
|
||||
return struct
|
||||
@@ -1,18 +0,0 @@
|
||||
tabs = {
|
||||
{class="ShellCommandWidget", title="Info", args={"cat","/mnt/info.txt"} },
|
||||
{class="ConfigSystemWidget", title="System"},
|
||||
{class="ProcessStateWidget", title="ps"},
|
||||
-- {class="ShellCommandWidget", title="MB", args={"mb","-rd","localhost"} },
|
||||
-- {class="ProcessStateWidget", title="ps"},
|
||||
{class="TailFileWidget", title="Log"},
|
||||
-- {class="ScriptProgrammerWidget", title="ELFI Script"},
|
||||
-- {class="RemoteProgrammerWidget", title="AVRDude"},
|
||||
-- {class="LuaProgrammerWidget", title="LUA Script"},
|
||||
{class="LuaAdminWidget", title="LUA Admin"},
|
||||
{class="AceEditorWidget", title="Lua ACE 1"},
|
||||
{class="AceEditorWidget", title="Lua ACE 2"},
|
||||
{class="AceEditorWidget", title="Lua ACE 3"},
|
||||
{class="AceEditorWidget", title="HTML ACE 1", args={"/mnt/www","",".html","html"}},
|
||||
-- {class="RemoteContainerWidget", title="Lua Shell", args={"http://192.168.9.101:4200"}}
|
||||
{class="RemoteContainerWidget", title="Lua Shell"}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
updateTimer = Scheduler.Timer(5000)
|
||||
oneSecond = Scheduler.Timer(1000)
|
||||
|
||||
while updateTimer:running() do
|
||||
if oneSecond:elapsed() then print("1 Sekunde") end
|
||||
end
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
local evdev = require "evdev"
|
||||
|
||||
local dev = evdev.Device("/dev/input/event0")
|
||||
|
||||
local x = 0
|
||||
local y = 0
|
||||
local cnt = 0
|
||||
|
||||
|
||||
|
||||
while true do
|
||||
--local timestamp, eventType, eventCode, value = dev:read()
|
||||
--print(dev:avail())
|
||||
if dev:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = dev:read()
|
||||
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 57 then
|
||||
if value < 0 then
|
||||
if y > 0 and y < 79 then
|
||||
print("Ctrl1: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 400 and y < 479 then
|
||||
print("Ctrl2: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 320 and y < 399 then
|
||||
print("Numbs: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 80 and y < 319 then
|
||||
-- print("Lines: ",math.floor(y/((320-80)/6))-1,math.floor(x/20)+1,x,y,math.floor((y-80)/240*10+6),math.floor(x/465*23+5))
|
||||
print("Lines: ",math.floor((y-80)/240*10+6),math.floor(x/720*36+7))
|
||||
end
|
||||
end
|
||||
elseif eventCode == 0 then
|
||||
x = value
|
||||
elseif eventCode == 1 then
|
||||
y = value
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
cnt = cnt + 1
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
-- tr["<Variante>"] = "<Rezeptnummer"
|
||||
|
||||
tr["1T1"] = "20"
|
||||
tr["1T2"] = "21"
|
||||
tr["2T1"] = "22"
|
||||
tr["2T3"] = "23"
|
||||
tr["1D6"] = "65"
|
||||
tr["2D6"] = "66"
|
||||
tr["2B7"] = "63"
|
||||
@@ -1,13 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
app.mqttBroker = {"192.168.9.99",inf="MQTT Broker"};
|
||||
app.mqttRoot = {"pilogi",inf="MQTT Root"};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
modules = {"panel","app","locale"};
|
||||
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {}
|
||||
require "app"
|
||||
|
||||
function app.apply()
|
||||
print(
|
||||
"<br><b><center>Apply module app !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, musste die Anwendung neu gestartet werden !</center><br>"
|
||||
);
|
||||
os.execute("/root/ctrlapp stop")
|
||||
os.execute("sleep 2")
|
||||
os.execute("/root/ctrlapp start")
|
||||
end
|
||||
|
||||
function app.validate()
|
||||
print("<br><b><center>Validate modlue app !</center></b><br>");
|
||||
end
|
||||
|
||||
---------------- Witty Administration localisation ------------------
|
||||
|
||||
locale = {}
|
||||
require "locale";
|
||||
|
||||
---------------- Witty Administration Tabs configuration ------------
|
||||
|
||||
tabs = {}
|
||||
require "tabs";
|
||||
|
||||
panel = {};
|
||||
require "panel"
|
||||
|
||||
function panel.apply()
|
||||
local mqttBroker = app.mqttBroker[1]
|
||||
local mqttRoot = app.mqttRoot[1]
|
||||
print(
|
||||
"<br><b><center>Apply module panel !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, wird die Konfiguration via MQTT publiziert !</center><br>"
|
||||
);
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m apply")
|
||||
os.execute("sleep 2")
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m publish")
|
||||
end
|
||||
@@ -1,44 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start|"")
|
||||
# Run App use default run.lua
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
stop)
|
||||
/usr/bin/killall app
|
||||
;;
|
||||
kill)
|
||||
/usr/bin/killall -kill app
|
||||
;;
|
||||
run)
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
debug)
|
||||
/usr/bin/killall app
|
||||
# /bin/app -e -r /root /root/run.lua
|
||||
# websocket fix, daq should lower permissions
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/su -p -c '/bin/app -e -r /root /root/run.lua' lua
|
||||
;;
|
||||
websocket)
|
||||
/usr/bin/killall websocketd
|
||||
/usr/bin/screen -dmS websock /bin/websocketd --staticdir=/mnt/www --port=88 /root/ctrlapp debug
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|run|debug|websocket}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,4 +0,0 @@
|
||||
[Info]
|
||||
Version = 1
|
||||
[Framebuffer]
|
||||
Device = /dev/fb0
|
||||
@@ -1,9 +0,0 @@
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {};
|
||||
require "app"
|
||||
|
||||
---------------- Application module locale configuration ---------------
|
||||
|
||||
locale = {};
|
||||
require "locale";
|
||||
BIN
3B/archive/root_11.bak/font/arial.ttf
(Stored with Git LFS)
BIN
3B/archive/root_11.bak/font/arial.ttf
(Stored with Git LFS)
Binary file not shown.
BIN
3B/archive/root_11.bak/font/mono.ttf
(Stored with Git LFS)
BIN
3B/archive/root_11.bak/font/mono.ttf
(Stored with Git LFS)
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
locale.version = {"Version 1.0",inf="Software Version"};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
PLC = require('modbus')
|
||||
socket = require('socket')
|
||||
|
||||
plc = PLC.Modbus("pi_daq",502)
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
plc:sync();
|
||||
print(plc:getReal(1))
|
||||
end
|
||||
socket.sleep(0.5)
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
MQTT = require("mosquitto")
|
||||
mqtt = MQTT.new()
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
local connected = false
|
||||
local broker = "localhost"
|
||||
|
||||
local onMessage = nil
|
||||
local onConnect = nil
|
||||
|
||||
local function publish(topic,msg,retain)
|
||||
retain = retain or false
|
||||
mqtt:publish(topic,msg, qos, retain)
|
||||
end
|
||||
|
||||
local function loop()
|
||||
local ok,err,msg
|
||||
|
||||
if connected then
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
if onError then onError(1) end
|
||||
connected = false
|
||||
end
|
||||
else
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
if onError then onError(2) end
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
mqtt:connect(broker,1883,5)
|
||||
errLog("MQTT:\t Reconnect".."\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function subscribe(msg)
|
||||
mqtt:subscribe(msg)
|
||||
end
|
||||
|
||||
mqtt.ON_CONNECT = function()
|
||||
connected = true
|
||||
if onConnect then onConnect() end
|
||||
end
|
||||
|
||||
mqtt.ON_MESSAGE = function(mid, topic, payload)
|
||||
if onMessage then onMessage(mid, topic, payload) end
|
||||
end
|
||||
|
||||
local function begin(hostname)
|
||||
broker = hostname
|
||||
mqtt:connect(broker,1883,5)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
loop = loop;
|
||||
publish = publish;
|
||||
subscribe = subscribe;
|
||||
onConnect = function(callback) onConnect = callback end;
|
||||
onMessage = function(callback) onMessage = callback end;
|
||||
onError = function(callback) onError = callback end;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
panel.Debug = {idx=2,alt={"on","off"},inf="Debug Ausgabe aktivieren, MQTT:-t <mqttRoot>/debug -m off -m on | off"};
|
||||
panel.LabelButtonSend = {"Send",inf="Beschriftung Panel Send, MQTT: -t <mqttRoot>/label/button/send -m 'Send'"};
|
||||
panel.LabelButton_1 = {"Sensor Analog",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/label/button/0 -m 'Text'"};
|
||||
panel.LabelButton_2 = {"Endpoint Logic",inf="Beschriftung Panel Button 2, MQTT: -t <mqttRoot>/label/button/1 -m 'Text'"};
|
||||
panel.LabelButton_3 = {"Kanal 3",inf="Beschriftung Panel Button 3, MQTT: -t <mqttRoot>/label/button/2 -m 'Text'"};
|
||||
panel.LabelButton_4 = {"Kanal 4",inf="Beschriftung Panel Button 4, MQTT: -t <mqttRoot>/label/button/3 -m 'Text'"};
|
||||
panel.LabelHeader = {"AL01 Datalogger",inf="Beschriftung Ueberschrift, MQTT: -t <mqttRoot>/label/header -m 'Text'"};
|
||||
panel.OptionsSamples = {100.000000,inf="Samples, MQTT: <mqttRoot>/options/samples -m 100"};
|
||||
panel.OptionsXaxisMax = {100.000000,inf="Maximum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/max -m 100"};
|
||||
panel.OptionsXaxisMin = {0.000000,inf="Minimum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/min -m 0"};
|
||||
panel.OptionsXaxis_1_Max = {15.000000,inf="Maximum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/max -m 15"};
|
||||
panel.OptionsXaxis_2_Max = {30.000000,inf="Maximum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/max -m 30"};
|
||||
panel.OptionsXaxis_2_Min = {0.000000,inf="Minimum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/min -m 0"};
|
||||
panel.OptionsYaxis_1_Min = {0.000000,inf="Minimum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/min -m 0"};
|
||||
panel.TextSendMessage = {"ping",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/message -m 'ping'"};
|
||||
panel.TextSendTopic = {"/ctrl/cmd",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/topic -m 'ctrl/cmd'"};
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
evdev = require "evdev"
|
||||
touch = evdev.Device("/dev/input/event0")
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_HOME = 0x0C
|
||||
|
||||
COMMAND_PASSWORD = 0x7F
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_ON = 0x0F
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
touchY = 0
|
||||
touchX = 0
|
||||
|
||||
LOGING = 1
|
||||
-- 1 2 3 4 5 6 7 8 9 10
|
||||
-- 11 12 13 14 15 16 17 18 19 20
|
||||
controlLabels = {"<-" ,"<<" ,"^" ,"^^" ,"vv" , "v" ,">>" ,"->" ,"Help" ,"Del",
|
||||
"Done" ," " ,"Insert","," ,"Space" , " " ,"=" ,"Remove","Enter" ," "}
|
||||
controlFonts = {"C" ,"C" ,"C" ,"C" ,"C" , "C" ,"C" ,"C" ,"T" ,"C",
|
||||
"C" ,"T" ,"T" ,"C" ,"C" , "T" ,"C" ,"T" ,"C" ,"T"}
|
||||
controlPos = {{02,06}, {01,18}, {02,02}, {01,30}, {01,22}, {18,02}, {01,34}, {02,44}, {02,10}, {02,50},
|
||||
{10,01}, {10,01}, {06,01}, {10,50}, {14,50}, {14,50}, {06,50}, {15,02}, {18,50}, {18,50}}
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
function clearAndHome(void)
|
||||
for i=1, 6, 1 do
|
||||
for j=1, 40, 1 do
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setText(" ")
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
posX = 0
|
||||
posY = 0
|
||||
end
|
||||
|
||||
|
||||
function doRead()
|
||||
local loops = 0
|
||||
while loops < 30 do
|
||||
loops = loops + 1
|
||||
if serial:poll(1) then
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
elseif cmd:byte() == COMMAND_HOME then
|
||||
clearAndHome();
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CURSOR_ON then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() == COMMAND_PASSWORD then
|
||||
c = '*'
|
||||
end
|
||||
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
--print(c.." at "..posX.." "..posY.."\n")
|
||||
local label = line[posY+1][posX+1]
|
||||
label:setText(c)
|
||||
if blinkFlag then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
label:draw()
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function doTouch()
|
||||
local x = 0;
|
||||
local y = 0;
|
||||
if touch:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = touch:read()
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 53 then
|
||||
touchX = value
|
||||
elseif eventCode == 54 then
|
||||
touchY = value
|
||||
end
|
||||
end
|
||||
if eventType == 1 then
|
||||
if eventCode == 330 then
|
||||
if touchY > 0 and touchY < 79 then
|
||||
idx = math.floor(touchX/80)+1
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl1: ",y,x,idx)
|
||||
end
|
||||
if touchY > 400 and touchY < 479 then
|
||||
idx = math.floor(touchX/80)+11
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl2: ",y,x,idx)
|
||||
end
|
||||
if touchY > 320 and touchY < 399 then
|
||||
x = 8 + math.floor(touchX/80)*4
|
||||
y = 19
|
||||
print("Numbs: ",y,x)
|
||||
end
|
||||
if touchY > 80 and touchY < 319 then
|
||||
y = math.floor((touchY-80)/240*10+6)
|
||||
x = math.floor(touchX/720*36+7)
|
||||
print("Lines: ",y,x)
|
||||
end
|
||||
if x > 0 and y > 0 then
|
||||
if value == 1 then
|
||||
print("down")
|
||||
serial:write(string.char(0x5F,y,x))
|
||||
serial:flush()
|
||||
--serial:write(string.char(0x5F,x,y))
|
||||
else
|
||||
print("up")
|
||||
serial:write(string.char(0x6F,y,x))
|
||||
serial:flush()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function setup()
|
||||
serial = Serial{device="/dev/ttyAMA0", baudrate=9600, databits=7, parity="odd", stopbits=1}
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
monoChar = HMI.Font("/root/font/mono.ttf",34)
|
||||
monoText = HMI.Font("/root/font/mono.ttf",20)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4," ");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(monoChar)
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),34,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.white);
|
||||
number[i]:setFont(monoChar)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
local idx = i+j*10
|
||||
if idx ~= 12 and idx ~= 16 and idx ~= 20 then
|
||||
if idx == 11 or idx == 15 or idx == 19 then
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,40,7,i-1);
|
||||
else
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,20,7,i-1);
|
||||
end
|
||||
if controlLabels[idx] then
|
||||
control[idx]:setText(controlLabels[idx])
|
||||
end
|
||||
control[idx]:setTextColor(HMI.Color.black);
|
||||
control[idx]:setBackground(HMI.Color.grey);
|
||||
if controlFonts[idx] == 'T' then
|
||||
control[idx]:setFont(monoText)
|
||||
else
|
||||
control[i+j*10]:setFont(monoChar)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
doRead()
|
||||
doTouch()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+1)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData then
|
||||
line[posY+1]:setText(strData);
|
||||
line[posY+1]:draw()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i]:setTextColor(HMI.Color.green);
|
||||
line[i]:setBackground(HMI.Color.black);
|
||||
line[i]:setFont(mono)
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
panel = {}
|
||||
require "panel"
|
||||
|
||||
socket = require('socket')
|
||||
PLC = require('vwago')
|
||||
Scheduler = require('scheduler')
|
||||
--I2CClass = require('periphery').I2C
|
||||
I2CDevice = nil;
|
||||
MQTT = require("mqtt")
|
||||
|
||||
daq = {};
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg)
|
||||
print(msg);
|
||||
end
|
||||
|
||||
local function pubPanelConfig()
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/send",panel.LabelButtonSend[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/0",panel.LabelButton_1[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/1",panel.LabelButton_2[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/2",panel.LabelButton_3[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/3",panel.LabelButton_4[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/header",panel.LabelHeader[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/samples",panel.OptionsSamples[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/max",panel.OptionsXaxisMax[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/min",panel.OptionsXaxisMin[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/max",panel.OptionsXaxis_1_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/max",panel.OptionsXaxis_2_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/min",panel.OptionsXaxis_2_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/min",panel.OptionsYaxis_1_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/message", panel.TextSendMessage[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/topic",panel.TextSendTopic[1])
|
||||
MQTT.publish(mqttRoot.."/panel/debug",panel.Debug["alt"][panel.Debug["idx"]])
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.publish(mqttRoot.."/info", "PIALU")
|
||||
MQTT.subscribe(mqttRoot.."/ctrl/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message "..topic, payload)
|
||||
|
||||
subTopic = string.match(topic,mqttRoot.."/ctrl/(%w+)")
|
||||
if subTopic then
|
||||
if subTopic == "cmd" then
|
||||
logPrint("MQTT:\t Command");
|
||||
analogChannel = string.match(topic,mqttRoot.."/ctrl/cmd/analog/(%w)")
|
||||
if analogChannel then
|
||||
|
||||
if analogChannel == "0" then
|
||||
logPrint("MQTT:\t Command Analog Channel "..analogChannel.." "..payload);
|
||||
if payload == "on" then
|
||||
channel_0 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
else
|
||||
channel_0 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "off",true)
|
||||
end
|
||||
elseif analogChannel == "1" then
|
||||
if payload == "on" then
|
||||
channel_1 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
else
|
||||
channel_1 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "off",true)
|
||||
end
|
||||
elseif analogChannel == "2" then
|
||||
if payload == "on" then
|
||||
channel_2 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
else
|
||||
channel_2 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "off",true)
|
||||
end
|
||||
elseif analogChannel == "3" then
|
||||
if payload == "on" then
|
||||
channel_3 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
else
|
||||
channel_3 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "off",true)
|
||||
end
|
||||
end
|
||||
elseif string.match(topic,mqttRoot.."/ctrl/cmd/panel/config") then
|
||||
if string.match(payload,"publish") then
|
||||
pubPanelConfig()
|
||||
elseif string.match(payload,"apply") then
|
||||
panel = {}
|
||||
dofile("panel.lua")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local function getInt32(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 4) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8) + bit32.lshift(bytes[offset+3],16) + bit32.lshift(bytes[offset+4],24);
|
||||
if ( num > 0x80000000 ) then
|
||||
return num - 0x100000000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getInt16(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 2) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8);
|
||||
end
|
||||
|
||||
if ( num > 0x8000 ) then
|
||||
return num - 0x10000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getUint8(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 1) then
|
||||
return bytes[offset+1];
|
||||
end
|
||||
|
||||
return 999999999;
|
||||
end
|
||||
--[[
|
||||
local function i2cBegin()
|
||||
I2CDevice = I2CClass("/dev/i2c-1")
|
||||
end
|
||||
|
||||
local function i2cRecvMsg()
|
||||
local msg = {{
|
||||
0x00, -- uint8_t hartbeat;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
flags = I2CClass.I2C_M_RD
|
||||
}}
|
||||
I2CDevice:transfer(6, msg)
|
||||
-- print(table.unpack(msg[1]));
|
||||
return msg[1]
|
||||
end
|
||||
|
||||
local function i2cSendMsg(cmd)
|
||||
local msg = {{cmd, 0x00, 0x00, 0x00, 0x00, flags = 0}}
|
||||
I2CDevice:transfer(4, msg)
|
||||
end
|
||||
--]]
|
||||
local function recv()
|
||||
--[[
|
||||
daqData = i2cRecvMsg();
|
||||
-- print(table.unpack(daqData));
|
||||
daq.hartbeat = getUint8(daqData,0);
|
||||
daq.sum0 = getInt32(daqData,1);
|
||||
daq.sum1 = getInt32(daqData,5);
|
||||
daq.sum2 = getInt32(daqData,9);
|
||||
daq.sum3 = getInt32(daqData,13);
|
||||
--]]
|
||||
daq.hartbeat = 123;
|
||||
daq.sum0 = 3;
|
||||
daq.sum1 = 1.7;
|
||||
daq.sum2 = 9;
|
||||
daq.sum3 = 5.5;
|
||||
end
|
||||
|
||||
function setup()
|
||||
mqttBroker = app.mqttBroker[1]
|
||||
mqttRoot = app.mqttRoot[1]
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,32,24);
|
||||
|
||||
label = HMI.Label(layout,0,0,32,3,"Plot");
|
||||
label:setTextColor(HMI.Color.white);
|
||||
label:setBackground(HMI.Color.blue);
|
||||
|
||||
chart = HMI.Timechart(layout,0,4,32,16)
|
||||
chart:setBaseline(0)
|
||||
chart:setValuePerDivison(2)
|
||||
chart:setSamplesPerDivison(20)
|
||||
chart:setSamplesFormat("%d Samples/Div, Samplerate 0.5s <=> 10 Sekunden/Div")
|
||||
|
||||
txt0 = HMI.Label(layout, 1,20,6,2,"Ch 0");
|
||||
txt0:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt1 = HMI.Label(layout,17,20,6,2,"Ch 1");
|
||||
txt1:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt2 = HMI.Label(layout, 1,22,6,2,"Ch 2");
|
||||
txt2:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt3 = HMI.Label(layout,17,22,6,2,"Ch 3");
|
||||
txt3:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
|
||||
out0 = HMI.Output(layout, 7,20,6,2,"0000");
|
||||
out1 = HMI.Output(layout,23,20,6,2,"0000");
|
||||
out2 = HMI.Output(layout, 7,22,6,2,"0000");
|
||||
out3 = HMI.Output(layout,23,22,6,2,"0000");
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
|
||||
-- i2cBegin()
|
||||
|
||||
if mqttBroker then
|
||||
errLog("MQTT:\t Begin\n");
|
||||
MQTT.begin(mqttBroker)
|
||||
end
|
||||
|
||||
MQTT.loop()
|
||||
|
||||
channel_0 = true;
|
||||
channel_1 = true;
|
||||
channel_2 = true;
|
||||
channel_3 = true;
|
||||
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
end
|
||||
|
||||
function loop()
|
||||
MQTT.loop()
|
||||
|
||||
if updateTimer.elapsed() then
|
||||
updateTimer.restart()
|
||||
recv()
|
||||
|
||||
val0 = daq.sum0*0.0000707750682632
|
||||
val1 = daq.sum1*0.0000707750682632
|
||||
val2 = daq.sum2*0.0000208350713273
|
||||
val3 = daq.sum3*0.0000208350713273
|
||||
|
||||
out0:setText(string.format("%5.2f",val0))
|
||||
out1:setText(string.format("%5.2f",val1))
|
||||
out2:setText(string.format("%5.2f",val2))
|
||||
out3:setText(string.format("%5.2f",val3))
|
||||
chart:plot(daq.sum0*0.0000707750682632)
|
||||
--chart:plot(daq.sum1*0.0000707750682632)
|
||||
--chart:plot(daq.sum2*0.0000208350713273)
|
||||
--chart:plot(daq.sum3*0.0000208350713273)
|
||||
|
||||
compound = ""
|
||||
|
||||
if channel_0 then
|
||||
MQTT.publish(mqttRoot.."/analog/0",val0)
|
||||
compound = compound..",0:"..val0
|
||||
end
|
||||
if channel_1 then
|
||||
MQTT.publish(mqttRoot.."/analog/1",val1)
|
||||
compound = compound..",1:"..val1
|
||||
end
|
||||
if channel_2 then
|
||||
MQTT.publish(mqttRoot.."/analog/2",val2)
|
||||
compound = compound..",2:"..val2
|
||||
end
|
||||
if channel_3 then
|
||||
MQTT.publish(mqttRoot.."/analog/3",val3)
|
||||
compound = compound..",3:"..val3
|
||||
end
|
||||
all = string.sub(compound,2)
|
||||
if string.len(all) > 0 then
|
||||
MQTT.publish(mqttRoot.."/analog/all",all)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+2)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData and attrData then
|
||||
local len = string.len(strData)
|
||||
for j=1, len, 1 do
|
||||
local label = line[posY+1][posX+j]
|
||||
if attrData:sub(j,j) == 'b' then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
label:setText(strData:sub(j,j))
|
||||
label:draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4,j%10);
|
||||
-- line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(mono)
|
||||
line[1][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
local scheduler = {}
|
||||
|
||||
socket = require('socket')
|
||||
|
||||
function scheduler.Timer(init)
|
||||
-- the new instance
|
||||
|
||||
local self = {
|
||||
-- public fields go in the instance table
|
||||
interval = init
|
||||
}
|
||||
|
||||
local function millis()
|
||||
return socket.gettime()*1000
|
||||
end
|
||||
|
||||
-- private fields are implemented using locals
|
||||
-- they are faster than table access, and are truly private,
|
||||
-- so the code that uses your class can't get them
|
||||
|
||||
local _timestamp = millis()
|
||||
local _running = true
|
||||
|
||||
function self.elapsed()
|
||||
if _running and (millis() - _timestamp ) >= self.interval then
|
||||
_running = false
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function self.running()
|
||||
return (millis() - _timestamp ) < self.interval
|
||||
end
|
||||
|
||||
function self.restart()
|
||||
_timestamp = millis()
|
||||
_running = true
|
||||
end
|
||||
|
||||
function self.count()
|
||||
return millis() - timestamp
|
||||
end
|
||||
|
||||
-- return the instance
|
||||
return self
|
||||
end
|
||||
|
||||
return scheduler
|
||||
@@ -1,599 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
struct = require('struct')
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local T1 = 300
|
||||
local T2 = 1000
|
||||
local T3 = 3000
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local serial
|
||||
local host = false
|
||||
local connected = false
|
||||
local pending = false
|
||||
local transaction_id = 1
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
|
||||
parseData(msg,buf,11,100);
|
||||
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
-- io.stderr:write("packList type("..type(l)..")\n")
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secaId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
pending = true
|
||||
transactionTimer.restart()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("SxF0\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,h.s_stream,0)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("S1F1\n----\n")
|
||||
|
||||
return {
|
||||
primaryHeader(1,1)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(ppid,mid1,mid2,mid3)
|
||||
io.stderr:write("S2F41("..ppid..","..mid1..","..mid2..","..mid3..")\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(2,41),
|
||||
packList( {
|
||||
packString("START"),
|
||||
packList( {
|
||||
packList( {
|
||||
packString("PPID"),
|
||||
packString(ppid)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID1"),
|
||||
packString(mid1)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID2"),
|
||||
packString(mid2)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID3"),
|
||||
packString(mid3)
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("S2F42\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,2,42),
|
||||
packList( {
|
||||
packBinary(4),
|
||||
packList({}) -- empty list
|
||||
} )
|
||||
}
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
|
||||
return {
|
||||
secondaryHeader(h,6,12),
|
||||
packBinary(0)
|
||||
}
|
||||
else
|
||||
secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
end
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function sendMsg(msg)
|
||||
|
||||
local buf = table.concat(msg);
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(chksum / 256))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I: NAK Received\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: AKN Timeout\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: EOT Timeout\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("receiveMsg\n----------\ncount: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
-- TODO checksum error handling
|
||||
|
||||
-- hexDumpString(buf);
|
||||
|
||||
serial:write(ASCII_ACK)
|
||||
|
||||
msg = parseMsg(buf)
|
||||
-- dumpMsg(msg)
|
||||
|
||||
return msg
|
||||
else
|
||||
io.stderr:write("SECS I: Countbyte Timeout\n")
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
local request = {}
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
|
||||
request = receiveMsg()
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
pending = false;
|
||||
end
|
||||
|
||||
msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
sendMsg(S1F2(request.header))
|
||||
SECS.onPrimary(1,1,"are you there")
|
||||
elseif isSF(request,1,2) then
|
||||
SECS.onSecondary(1,2,"are you there akn")
|
||||
elseif isSF(request,1,13) then
|
||||
sendMsg(S1F14(request.header))
|
||||
connected = true;
|
||||
SECS.onPrimary(1,13,"establish communication request")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
SECS.onSecondary(1,14,"establish communication request akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S2F42(request.header))
|
||||
SECS.onPrimary(2,41,"host command send")
|
||||
elseif isSF(request,2,42) then
|
||||
SECS.onSecondary(2,42,"host command send akn")
|
||||
elseif isSF(request,6,11) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S6F12(request.header))
|
||||
SECS.onPrimary(6,11,"event report send")
|
||||
elseif isSF(request,6,12) then
|
||||
--
|
||||
SECS.onSecondary(6,12,"event report send akn")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
sendMsg(SxF0(request.header))
|
||||
SECS.onPrimary(0,0,"abort transaction akn")
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write("loop poll:"..string.byte(c).."\n")
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("loop poll: Transaction timeout\n")
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
|
||||
end
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature= msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isPending = function() return pending end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() sendMsg(S1F13()) end;
|
||||
sendS1F1 = function() sendMsg(S1F1()) end;
|
||||
sendS2F41 = function(a1,a2,a3,a4) sendMsg(S2F41(a1,a2,a3,a4)) end;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
local T1 = 100 --300
|
||||
local T2 = 2000 --1000
|
||||
local T3 = 5000 --3000
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local pending = false
|
||||
local reading = false
|
||||
local writing = false
|
||||
|
||||
local serial
|
||||
|
||||
local onProcessRequest;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
local function hexDumpString(buf)
|
||||
if buf then
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
end
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
local function discardInput()
|
||||
hexDumpString(buf);
|
||||
io.stderr:write("SECS I:\t Discard input: ")
|
||||
while serial:poll(100) do
|
||||
c = serial:read(1)
|
||||
io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function sendMsg(buf)
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
writing = true
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(math.floor(chksum / 256)))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I:\t NAK Received\n")
|
||||
--discardInput()
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t AKN Timeout\n")
|
||||
discardInput()
|
||||
end
|
||||
writing = false
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t EOT Timeout\n")
|
||||
discardInput()
|
||||
writing = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
reading = true
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("SECS I:\t receiveMsg count: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
for i=1, #buf-2 do
|
||||
chksum = chksum + buf:byte(i)
|
||||
end
|
||||
|
||||
local msgChksum = buf:byte(#buf-1)*256 + buf:byte(#buf)
|
||||
|
||||
if msgChksum == chksum then
|
||||
serial:write(ASCII_ACK)
|
||||
return buf
|
||||
else
|
||||
io.stderr:write("SECS I:\t Checksum Error\n")
|
||||
hexDumpString(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
discardInput()
|
||||
--io.stderr:write(string.format("SECS I:\t Checksum: %04X %04X\n",chksum,msgChksum))
|
||||
io.stderr:write(string.format("SECS I:\t Bytes: %d Checksum: %04X %04X\n",#buf,chksum,msgChksum))
|
||||
return ""
|
||||
end
|
||||
reading = false
|
||||
else
|
||||
io.stderr:write("SECS I:\t Countbyte Timeout\n")
|
||||
discardInput()
|
||||
reading = false
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
local buf=receiveMsg()
|
||||
if #buf >= 11 then
|
||||
onProcessRequest(buf)
|
||||
else
|
||||
io.stderr:write("SECS I:\t Poll error bytes: "..#buf.."\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
end
|
||||
elseif c == ASCII_NAK then
|
||||
io.stderr:write("SECS I:\t Poll NAK received\n")
|
||||
--discardInput()
|
||||
pending = false
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write(string.format("SECS I:\t Poll error byte = %02X\n",string.byte(c)))
|
||||
discardInput()
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("SECS I:\t Poll transaction timeout\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
poll = poll;
|
||||
sendMsg = sendMsg;
|
||||
receiveMsg = receiveMsg;
|
||||
isReading = function() return reading end;
|
||||
isWriting = function() return writing end;
|
||||
isPending = function() return pending end;
|
||||
onProcessRequest = function(cb) onProcessRequest = cb end;
|
||||
startTransaction = function() transactionTimer.restart(); pending = true end;
|
||||
stopTransaction = function() pending = false end;
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
|
||||
SECS_IO = require('secs_i')
|
||||
struct = require('struct')
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local secsId = 0x1234
|
||||
local host = false
|
||||
local connected = false
|
||||
|
||||
local transaction_id = 1
|
||||
|
||||
local eq_online = 3 -- 1: online remote, 2: online local, 3: offline
|
||||
local eq_status = 2 -- 1: not ready, 2: ready, 3: busy, 4: process cmpl, 5: pause, 6: complete
|
||||
|
||||
local onSendEventMsg = nil
|
||||
local onPrimaryMsg = nil
|
||||
local onSecondaryMsg = nil
|
||||
local onProcessMsg = nil
|
||||
|
||||
local msgQueue = {}
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
--[[
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
--]]
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
io.stderr:write(string.format("IDX: %d\n",idx))
|
||||
num = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,num))
|
||||
len = buf:byte(idx+1);
|
||||
io.stderr:write(string.format("DATA LEN: %02X %03d\n",len,len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
parseData(msg,buf,11,#buf);
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
-- SECS_IO.startTransaction()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
function string.pop(s)
|
||||
return string.sub(s,1,1),string.sub(s,2)
|
||||
end
|
||||
|
||||
function table.pop(t)
|
||||
local i = t[1]
|
||||
table.remove(t,1)
|
||||
return i,t
|
||||
end
|
||||
|
||||
local function packData(sig,items)
|
||||
local buf = ""
|
||||
|
||||
-- print("packData sig: ",sig)
|
||||
while #sig > 0 do
|
||||
-- print("packData len1: ",#sig)
|
||||
typ, sig = string.pop(sig)
|
||||
-- print("packData len2: ",#sig,typ,sig)
|
||||
if typ == "L" then
|
||||
len , sig = string.pop(sig)
|
||||
-- print("packData len3: ",#sig,len,sig)
|
||||
buf = buf..struct.pack('BB',SF_LIST+1,len)..packData(sig,items)
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
elseif typ == "A" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packString(item)
|
||||
elseif typ == "B" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packBinary(item)
|
||||
end
|
||||
end
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
local function primaryMsg(s,f,sig,items)
|
||||
return primaryHeader(s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
local function secondaryMsg(h,s,f,sig,items)
|
||||
return secondaryHeader(h,s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("\nSECS II: SxF0\n----\n")
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("\nSECS II: S1F1\n----\n")
|
||||
return primaryHeader(1,1)
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("\nSECS II: S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,2,"L0",{})
|
||||
else
|
||||
return secondaryMsg(h,1,2,"L2AA",{MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("\nSECS II: S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return primaryMsg(1,13,"L2BL0",{0})
|
||||
else
|
||||
return primaryMsg(1,13,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("\nSECS II: S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,14,"L2BL0",{0})
|
||||
else
|
||||
return secondaryMsg(h,1,14,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(c)
|
||||
|
||||
io.stderr:write("\nSECS II: S2F41("..c..")\n----\n")
|
||||
if host then
|
||||
return onCreateMsg(2,41,c)
|
||||
else
|
||||
return "" -- host only command
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("\nSECS II: S2F42\n----\n")
|
||||
|
||||
return secondaryMsg(h,2,42,"L2BL0",{4})
|
||||
end
|
||||
|
||||
local function S5F2(h)
|
||||
io.stderr:write("\nSECS II: S5F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,5,2,"B",{0})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("\nSECS II: S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,6,12,"B",{0})
|
||||
else
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F11(e)
|
||||
io.stderr:write("\nSECS II: S6F11("..e..")\n----\n")
|
||||
|
||||
if not host then
|
||||
return onCreateMsg(6,11,e)
|
||||
else
|
||||
return "" -- equipment only command
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
local function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function isS5Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 5
|
||||
end
|
||||
|
||||
local function isS9Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 9
|
||||
end
|
||||
|
||||
SECS_IO.onProcessRequest (
|
||||
function(buf)
|
||||
local request = parseMsg(buf)
|
||||
io.stderr:write("SECS II: ID: ",request.header.secsId,"\n")
|
||||
local s = request.header.secsStream
|
||||
local f = request.header.secsFunction
|
||||
io.stderr:write("SECS II: onProcessMsg ".."S"..s.."F"..f.."\n");
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
local sig = msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
onPrimaryMsg(1,1,"are you there received")
|
||||
SECS_IO.sendMsg(S1F2(request.header))
|
||||
elseif isSF(request,1,2) then
|
||||
onSecondaryMsg(1,2,"are you there received akn")
|
||||
elseif isSF(request,1,13) then
|
||||
connected = true;
|
||||
onPrimaryMsg(1,13,"establish communication request received")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
SECS_IO.sendMsg(S1F14(request.header))
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
onSecondaryMsg(1,14,"establish communication request received akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
--print("SECS II: Message ",#request)
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(2,41,"host command received")
|
||||
SECS_IO.sendMsg(S2F42(request.header))
|
||||
elseif isSF(request,2,42) then
|
||||
onProcessMsg(request)
|
||||
onSecondaryMsg(2,42,"host command received akn")
|
||||
elseif isSF(request,6,11) then
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(6,11,"event report received")
|
||||
SECS_IO.sendMsg(S6F12(request.header))
|
||||
elseif isSF(request,6,12) then
|
||||
onSecondaryMsg(6,12,"event report received akn")
|
||||
elseif isS5Fx(request) then
|
||||
onProcessMsg(request)
|
||||
--hexDumpString(buf)
|
||||
--io.stderr:write("SIG: "..sig.."\n")
|
||||
onPrimaryMsg(5,request.header.secsFunction,"alarm received")
|
||||
SECS_IO.sendMsg(S5F2(request.header))
|
||||
elseif isS9Fx(request) then
|
||||
-- no secondary message
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(9,request.header.secsFunction,"error received")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
onPrimaryMsg(0,0,"abort transaction send")
|
||||
SECS_IO.sendMsg(SxF0(request.header))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function dequeMsg()
|
||||
local m = msgQueue[1]
|
||||
table.remove(msgQueue,1)
|
||||
return m
|
||||
end
|
||||
|
||||
local function queueMsg(msg)
|
||||
io.stderr:write("\n====\nSECS II: queueMsg\n====\n");
|
||||
table.insert(msgQueue,msg)
|
||||
end
|
||||
|
||||
local function poll()
|
||||
if not SECS_IO.isPending() and #msgQueue > 0 then
|
||||
-- if not pending and #msgQueue > 0 then
|
||||
io.stderr:write("\n====\nSECS II: dequeueMsg\n====\n");
|
||||
SECS_IO.startTransaction()
|
||||
SECS_IO.sendMsg(dequeMsg())
|
||||
end
|
||||
SECS_IO.poll()
|
||||
end;
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function setId(id)
|
||||
secsId = id
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
SECS_IO.begin(device,baud)
|
||||
io.stderr:write("begin\n")
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature = msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
--------- DEBUG only ----------------
|
||||
-- dataSignature = dataSignature;
|
||||
-- parseMsg = parseMsg;
|
||||
-- dumpData = dumpData;
|
||||
-- parseData = parseData;
|
||||
|
||||
-- packString = packString;
|
||||
-- packBinary = packBinary;
|
||||
-- packList = packList;
|
||||
-- packData = packData;
|
||||
--------------------------------------
|
||||
|
||||
primaryMsg = primaryMsg;
|
||||
secondaryMsg = secondaryMsg;
|
||||
|
||||
setId = setId;
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isReading = function() return SECS_IO.isReading() end;
|
||||
isWriting = function() return SECS_IO.isWriting() end;
|
||||
isPending = function() return SECS_IO.isPending() end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() queueMsg(S1F13()) end;
|
||||
sendS1F1 = function() queueMsg(S1F1()) end;
|
||||
sendS2F41 = function(c) queueMsg(S2F41(c)) end;
|
||||
sendS6F11 = function(e) queueMsg(S6F11(e)) end;
|
||||
|
||||
onCreateMsg = function(cb) onCreateMsg = cb end;
|
||||
onPrimaryMsg = function(cb) onPrimaryMsg = cb end;
|
||||
onSecondaryMsg = function(cb) onSecondaryMsg = cb end;
|
||||
onProcessMsg = function(cb) onProcessMsg = cb end;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
PLC = require('vwago')
|
||||
|
||||
plc = PLC.VWago("wago")
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
i = plc:getDouble(1)
|
||||
plc:setDouble(0,i)
|
||||
i = i + 1234
|
||||
if i > 2147483647 then
|
||||
i = 0
|
||||
o = plc:getDouble(2)
|
||||
plc:setDouble(2,o+1)
|
||||
end
|
||||
plc:setDouble(1,i)
|
||||
plc:update()
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,114 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
serial = Serial("/dev/ttyAMA0",9600)
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
while (1) do
|
||||
while serial:poll(100) do
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
print(c.." at "..posX.." "..posY.."\n")
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
--[[
|
||||
if ( c >= 0x20 && c < 0x7F ) {
|
||||
(c==buf_char[y_now][x_now])?(buf_chng[y_now][x_now]='n'):(buf_chng[y_now][x_now]='y');
|
||||
(BLINK_FLAG?(buf_args[y_now][x_now] = 'b'):( buf_args[y_now][x_now] = 'n'));
|
||||
buf_char[y_now][x_now] = c;
|
||||
checkX(++x_now);
|
||||
--]]
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
--
|
||||
-- io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
end
|
||||
@@ -1,197 +0,0 @@
|
||||
--[[
|
||||
* Copyright (c) 2015-2017 Iryont <https://github.com/iryont/lua-struct>
|
||||
*
|
||||
* 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.
|
||||
]]
|
||||
|
||||
struct = {}
|
||||
|
||||
function struct.pack(format, ...)
|
||||
local stream = {}
|
||||
local vars = {...}
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
|
||||
local bytes = {}
|
||||
for j = 1, n do
|
||||
table.insert(bytes, string.char(val % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt:find('[fd]') then
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
local sign = 0
|
||||
|
||||
if val < 0 then
|
||||
sign = 1
|
||||
val = -val
|
||||
end
|
||||
|
||||
local mantissa, exponent = math.frexp(val)
|
||||
if val == 0 then
|
||||
mantissa = 0
|
||||
exponent = 0
|
||||
else
|
||||
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
|
||||
exponent = exponent + ((opt == 'd') and 1022 or 126)
|
||||
end
|
||||
|
||||
local bytes = {}
|
||||
if opt == 'd' then
|
||||
val = mantissa
|
||||
for i = 1, 6 do
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
else
|
||||
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
|
||||
val = math.floor(mantissa / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
|
||||
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
|
||||
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
table.insert(stream, tostring(table.remove(vars, 1)))
|
||||
table.insert(stream, string.char(0))
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
local length = tonumber(n)
|
||||
|
||||
if length > 0 then
|
||||
local str = tostring(table.remove(vars, 1))
|
||||
if length - str:len() > 0 then
|
||||
str = str .. string.rep(' ', length - str:len())
|
||||
end
|
||||
table.insert(stream, str:sub(1, length))
|
||||
end
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(stream)
|
||||
end
|
||||
|
||||
function struct.unpack(format, stream)
|
||||
local vars = {}
|
||||
local iterator = 1
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local signed = opt:lower() == opt
|
||||
|
||||
local val = 0
|
||||
for j = 1, n do
|
||||
local byte = string.byte(stream:sub(iterator, iterator))
|
||||
if endianness then
|
||||
val = val + byte * (2 ^ ((j - 1) * 8))
|
||||
else
|
||||
val = val + byte * (2 ^ ((n - j) * 8))
|
||||
end
|
||||
iterator = iterator + 1
|
||||
end
|
||||
|
||||
if signed and val >= 2 ^ (n * 8 - 1) then
|
||||
val = val - 2 ^ (n * 8)
|
||||
end
|
||||
|
||||
table.insert(vars, val)
|
||||
elseif opt:find('[fd]') then
|
||||
local n = (opt == 'd') and 8 or 4
|
||||
local x = stream:sub(iterator, iterator + n - 1)
|
||||
iterator = iterator + n
|
||||
|
||||
if not endianness then
|
||||
x = string.reverse(x)
|
||||
end
|
||||
|
||||
local sign = 1
|
||||
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
|
||||
for i = n - 2, 1, -1 do
|
||||
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
|
||||
end
|
||||
|
||||
if string.byte(x, n) > 127 then
|
||||
sign = -1
|
||||
end
|
||||
|
||||
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
|
||||
if exponent == 0 then
|
||||
table.insert(vars, 0.0)
|
||||
else
|
||||
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
|
||||
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
local bytes = {}
|
||||
for j = iterator, stream:len() do
|
||||
if stream:sub(j, j) == string.char(0) then
|
||||
break
|
||||
end
|
||||
|
||||
table.insert(bytes, stream:sub(j, j))
|
||||
end
|
||||
|
||||
local str = table.concat(bytes)
|
||||
iterator = iterator + str:len() + 1
|
||||
table.insert(vars, str)
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)-1))
|
||||
iterator = iterator + tonumber(n)
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return unpack(vars)
|
||||
end
|
||||
|
||||
return struct
|
||||
@@ -1,18 +0,0 @@
|
||||
tabs = {
|
||||
{class="ShellCommandWidget", title="Info", args={"cat","/mnt/info.txt"} },
|
||||
{class="ConfigSystemWidget", title="System"},
|
||||
{class="ProcessStateWidget", title="ps"},
|
||||
-- {class="ShellCommandWidget", title="MB", args={"mb","-rd","localhost"} },
|
||||
-- {class="ProcessStateWidget", title="ps"},
|
||||
{class="TailFileWidget", title="Log"},
|
||||
-- {class="ScriptProgrammerWidget", title="ELFI Script"},
|
||||
-- {class="RemoteProgrammerWidget", title="AVRDude"},
|
||||
-- {class="LuaProgrammerWidget", title="LUA Script"},
|
||||
{class="LuaAdminWidget", title="LUA Admin"},
|
||||
{class="AceEditorWidget", title="Lua ACE 1"},
|
||||
{class="AceEditorWidget", title="Lua ACE 2"},
|
||||
{class="AceEditorWidget", title="Lua ACE 3"},
|
||||
{class="AceEditorWidget", title="HTML ACE 1", args={"/mnt/www","",".html","html"}},
|
||||
-- {class="RemoteContainerWidget", title="Lua Shell", args={"http://192.168.9.101:4200"}}
|
||||
{class="RemoteContainerWidget", title="Lua Shell"}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
updateTimer = Scheduler.Timer(5000)
|
||||
oneSecond = Scheduler.Timer(1000)
|
||||
|
||||
while updateTimer:running() do
|
||||
if oneSecond:elapsed() then print("1 Sekunde") end
|
||||
end
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
local evdev = require "evdev"
|
||||
|
||||
local dev = evdev.Device("/dev/input/event0")
|
||||
|
||||
local x = 0
|
||||
local y = 0
|
||||
local cnt = 0
|
||||
|
||||
|
||||
|
||||
while true do
|
||||
--local timestamp, eventType, eventCode, value = dev:read()
|
||||
--print(dev:avail())
|
||||
if dev:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = dev:read()
|
||||
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 57 then
|
||||
if value < 0 then
|
||||
if y > 0 and y < 79 then
|
||||
print("Ctrl1: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 400 and y < 479 then
|
||||
print("Ctrl2: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 320 and y < 399 then
|
||||
print("Numbs: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 80 and y < 319 then
|
||||
-- print("Lines: ",math.floor(y/((320-80)/6))-1,math.floor(x/20)+1,x,y,math.floor((y-80)/240*10+6),math.floor(x/465*23+5))
|
||||
print("Lines: ",math.floor((y-80)/240*10+6),math.floor(x/720*36+7))
|
||||
end
|
||||
end
|
||||
elseif eventCode == 0 then
|
||||
x = value
|
||||
elseif eventCode == 1 then
|
||||
y = value
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
cnt = cnt + 1
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
-- tr["<Variante>"] = "<Rezeptnummer"
|
||||
|
||||
tr["1T1"] = "20"
|
||||
tr["1T2"] = "21"
|
||||
tr["2T1"] = "22"
|
||||
tr["2T3"] = "23"
|
||||
tr["1D6"] = "65"
|
||||
tr["2D6"] = "66"
|
||||
tr["2B7"] = "63"
|
||||
@@ -1,13 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
app.mqttBroker = {"192.168.9.99",inf="MQTT Broker"};
|
||||
app.mqttRoot = {"pilogi",inf="MQTT Root"};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
modules = {"panel","app","locale"};
|
||||
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {}
|
||||
require "app"
|
||||
|
||||
function app.apply()
|
||||
print(
|
||||
"<br><b><center>Apply module app !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, musste die Anwendung neu gestartet werden !</center><br>"
|
||||
);
|
||||
os.execute("/root/ctrlapp stop")
|
||||
os.execute("sleep 2")
|
||||
os.execute("/root/ctrlapp start")
|
||||
end
|
||||
|
||||
function app.validate()
|
||||
print("<br><b><center>Validate modlue app !</center></b><br>");
|
||||
end
|
||||
|
||||
---------------- Witty Administration localisation ------------------
|
||||
|
||||
locale = {}
|
||||
require "locale";
|
||||
|
||||
---------------- Witty Administration Tabs configuration ------------
|
||||
|
||||
tabs = {}
|
||||
require "tabs";
|
||||
|
||||
panel = {};
|
||||
require "panel"
|
||||
|
||||
function panel.apply()
|
||||
local mqttBroker = app.mqttBroker[1]
|
||||
local mqttRoot = app.mqttRoot[1]
|
||||
print(
|
||||
"<br><b><center>Apply module panel !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, wird die Konfiguration via MQTT publiziert !</center><br>"
|
||||
);
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m apply")
|
||||
os.execute("sleep 2")
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m publish")
|
||||
end
|
||||
@@ -1,44 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start|"")
|
||||
# Run App use default run.lua
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
stop)
|
||||
/usr/bin/killall app
|
||||
;;
|
||||
kill)
|
||||
/usr/bin/killall -kill app
|
||||
;;
|
||||
run)
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
debug)
|
||||
/usr/bin/killall app
|
||||
# /bin/app -e -r /root /root/run.lua
|
||||
# websocket fix, daq should lower permissions
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/su -p -c '/bin/app -e -r /root /root/run.lua' lua
|
||||
;;
|
||||
websocket)
|
||||
/usr/bin/killall websocketd
|
||||
/usr/bin/screen -dmS websock /bin/websocketd --staticdir=/mnt/www --port=88 /root/ctrlapp debug
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|run|debug|websocket}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,4 +0,0 @@
|
||||
[Info]
|
||||
Version = 1
|
||||
[Framebuffer]
|
||||
Device = /dev/fb0
|
||||
@@ -1,9 +0,0 @@
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {};
|
||||
require "app"
|
||||
|
||||
---------------- Application module locale configuration ---------------
|
||||
|
||||
locale = {};
|
||||
require "locale";
|
||||
BIN
3B/archive/root_12.bak/font/arial.ttf
(Stored with Git LFS)
BIN
3B/archive/root_12.bak/font/arial.ttf
(Stored with Git LFS)
Binary file not shown.
BIN
3B/archive/root_12.bak/font/mono.ttf
(Stored with Git LFS)
BIN
3B/archive/root_12.bak/font/mono.ttf
(Stored with Git LFS)
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
locale.version = {"Version 1.0",inf="Software Version"};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
PLC = require('modbus')
|
||||
socket = require('socket')
|
||||
|
||||
plc = PLC.Modbus("pi_daq",502)
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
plc:sync();
|
||||
print(plc:getReal(1))
|
||||
end
|
||||
socket.sleep(0.5)
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
MQTT = require("mosquitto")
|
||||
mqtt = MQTT.new()
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
local connected = false
|
||||
local broker = "localhost"
|
||||
|
||||
local onMessage = nil
|
||||
local onConnect = nil
|
||||
|
||||
local function publish(topic,msg,retain)
|
||||
retain = retain or false
|
||||
mqtt:publish(topic,msg, qos, retain)
|
||||
end
|
||||
|
||||
local function loop()
|
||||
local ok,err,msg
|
||||
|
||||
if connected then
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
if onError then onError(1) end
|
||||
connected = false
|
||||
end
|
||||
else
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
if onError then onError(2) end
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
mqtt:connect(broker,1883,5)
|
||||
errLog("MQTT:\t Reconnect".."\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function subscribe(msg)
|
||||
mqtt:subscribe(msg)
|
||||
end
|
||||
|
||||
mqtt.ON_CONNECT = function()
|
||||
connected = true
|
||||
if onConnect then onConnect() end
|
||||
end
|
||||
|
||||
mqtt.ON_MESSAGE = function(mid, topic, payload)
|
||||
if onMessage then onMessage(mid, topic, payload) end
|
||||
end
|
||||
|
||||
local function begin(hostname)
|
||||
broker = hostname
|
||||
mqtt:connect(broker,1883,5)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
loop = loop;
|
||||
publish = publish;
|
||||
subscribe = subscribe;
|
||||
onConnect = function(callback) onConnect = callback end;
|
||||
onMessage = function(callback) onMessage = callback end;
|
||||
onError = function(callback) onError = callback end;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
panel.Debug = {idx=2,alt={"on","off"},inf="Debug Ausgabe aktivieren, MQTT:-t <mqttRoot>/debug -m off -m on | off"};
|
||||
panel.LabelButtonSend = {"Send",inf="Beschriftung Panel Send, MQTT: -t <mqttRoot>/label/button/send -m 'Send'"};
|
||||
panel.LabelButton_1 = {"Sensor Analog",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/label/button/0 -m 'Text'"};
|
||||
panel.LabelButton_2 = {"Endpoint Logic",inf="Beschriftung Panel Button 2, MQTT: -t <mqttRoot>/label/button/1 -m 'Text'"};
|
||||
panel.LabelButton_3 = {"Kanal 3",inf="Beschriftung Panel Button 3, MQTT: -t <mqttRoot>/label/button/2 -m 'Text'"};
|
||||
panel.LabelButton_4 = {"Kanal 4",inf="Beschriftung Panel Button 4, MQTT: -t <mqttRoot>/label/button/3 -m 'Text'"};
|
||||
panel.LabelHeader = {"AL01 Datalogger",inf="Beschriftung Ueberschrift, MQTT: -t <mqttRoot>/label/header -m 'Text'"};
|
||||
panel.OptionsSamples = {100.000000,inf="Samples, MQTT: <mqttRoot>/options/samples -m 100"};
|
||||
panel.OptionsXaxisMax = {100.000000,inf="Maximum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/max -m 100"};
|
||||
panel.OptionsXaxisMin = {0.000000,inf="Minimum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/min -m 0"};
|
||||
panel.OptionsXaxis_1_Max = {15.000000,inf="Maximum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/max -m 15"};
|
||||
panel.OptionsXaxis_2_Max = {30.000000,inf="Maximum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/max -m 30"};
|
||||
panel.OptionsXaxis_2_Min = {0.000000,inf="Minimum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/min -m 0"};
|
||||
panel.OptionsYaxis_1_Min = {0.000000,inf="Minimum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/min -m 0"};
|
||||
panel.TextSendMessage = {"ping",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/message -m 'ping'"};
|
||||
panel.TextSendTopic = {"/ctrl/cmd",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/topic -m 'ctrl/cmd'"};
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
evdev = require "evdev"
|
||||
touch = evdev.Device("/dev/input/event0")
|
||||
|
||||
socket = require('socket')
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_HOME = 0x0C
|
||||
|
||||
COMMAND_PASSWORD = 0x7F
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_ON = 0x0F
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
touchY = 0
|
||||
touchX = 0
|
||||
|
||||
LOGING = 1
|
||||
-- 1 2 3 4 5 6 7 8 9 10
|
||||
-- 11 12 13 14 15 16 17 18 19 20
|
||||
controlLabels = {"<-" ,"<<" ,"^" ,"^^" ,"vv" , "v" ,">>" ,"->" ,"Help" ,"Del",
|
||||
"Done" ," " ,"Insert","," ,"Space" , " " ,"=" ,"Remove","Enter" ," "}
|
||||
controlFonts = {"C" ,"C" ,"C" ,"C" ,"C" , "C" ,"C" ,"C" ,"T" ,"C",
|
||||
"C" ,"T" ,"T" ,"C" ,"C" , "T" ,"C" ,"T" ,"C" ,"T"}
|
||||
controlPos = {{02,06}, {01,18}, {02,02}, {01,30}, {01,22}, {18,02}, {01,34}, {02,44}, {02,10}, {02,50},
|
||||
{10,01}, {10,01}, {06,01}, {10,50}, {14,50}, {14,50}, {06,50}, {15,02}, {18,50}, {18,50}}
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
function clearAndHome(void)
|
||||
for i=1, 6, 1 do
|
||||
for j=1, 40, 1 do
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setText(" ")
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
posX = 0
|
||||
posY = 0
|
||||
end
|
||||
|
||||
|
||||
function doRead()
|
||||
local timestamp = socket.gettime()*1000
|
||||
|
||||
while socket.gettime()*1000 - timestamp < 100 do
|
||||
if serial:poll(0.01) then
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
elseif cmd:byte() == COMMAND_HOME then
|
||||
clearAndHome();
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CURSOR_ON then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() == COMMAND_PASSWORD then
|
||||
c = '*'
|
||||
end
|
||||
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
--print(c.." at "..posX.." "..posY.."\n")
|
||||
local label = line[posY+1][posX+1]
|
||||
label:setText(c)
|
||||
if blinkFlag then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
label:draw()
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function doTouch()
|
||||
local x = 0;
|
||||
local y = 0;
|
||||
if touch:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = touch:read()
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 53 then
|
||||
touchX = value
|
||||
elseif eventCode == 54 then
|
||||
touchY = value
|
||||
end
|
||||
end
|
||||
if eventType == 1 then
|
||||
if eventCode == 330 then
|
||||
if touchY > 0 and touchY < 79 then
|
||||
idx = math.floor(touchX/80)+1
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl1: ",y,x,idx)
|
||||
end
|
||||
if touchY > 400 and touchY < 479 then
|
||||
idx = math.floor(touchX/80)+11
|
||||
x = controlPos[idx][2]
|
||||
y = controlPos[idx][1]
|
||||
print("Ctrl2: ",y,x,idx)
|
||||
end
|
||||
if touchY > 320 and touchY < 399 then
|
||||
x = 8 + math.floor(touchX/80)*4
|
||||
y = 19
|
||||
print("Numbs: ",y,x)
|
||||
end
|
||||
if touchY > 80 and touchY < 319 then
|
||||
y = math.floor((touchY-80)/240*10+6)
|
||||
x = math.floor(touchX/720*36+7)
|
||||
print("Lines: ",y,x)
|
||||
end
|
||||
if x > 0 and y > 0 then
|
||||
if value == 1 then
|
||||
print("down")
|
||||
serial:write(string.char(0x5F,y,x))
|
||||
serial:flush()
|
||||
--serial:write(string.char(0x5F,x,y))
|
||||
else
|
||||
print("up")
|
||||
serial:write(string.char(0x6F,y,x))
|
||||
serial:flush()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function setup()
|
||||
serial = Serial{device="/dev/ttyAMA0", baudrate=9600, databits=7, parity="odd", stopbits=1}
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
monoChar = HMI.Font("/root/font/mono.ttf",34)
|
||||
monoText = HMI.Font("/root/font/mono.ttf",20)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4," ");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(monoChar)
|
||||
line[i][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),34,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.white);
|
||||
number[i]:setFont(monoChar)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
local idx = i+j*10
|
||||
if idx ~= 12 and idx ~= 16 and idx ~= 20 then
|
||||
if idx == 11 or idx == 15 or idx == 19 then
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,40,7,i-1);
|
||||
else
|
||||
control[idx] = HMI.Cell(layout,1+20*(i-1),j*41,20,7,i-1);
|
||||
end
|
||||
if controlLabels[idx] then
|
||||
control[idx]:setText(controlLabels[idx])
|
||||
end
|
||||
control[idx]:setTextColor(HMI.Color.black);
|
||||
control[idx]:setBackground(HMI.Color.grey);
|
||||
if controlFonts[idx] == 'T' then
|
||||
control[idx]:setFont(monoText)
|
||||
else
|
||||
control[i+j*10]:setFont(monoChar)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
doRead()
|
||||
doTouch()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+1)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData then
|
||||
line[posY+1]:setText(strData);
|
||||
line[posY+1]:draw()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i]:setTextColor(HMI.Color.green);
|
||||
line[i]:setBackground(HMI.Color.black);
|
||||
line[i]:setFont(mono)
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
panel = {}
|
||||
require "panel"
|
||||
|
||||
socket = require('socket')
|
||||
PLC = require('vwago')
|
||||
Scheduler = require('scheduler')
|
||||
--I2CClass = require('periphery').I2C
|
||||
I2CDevice = nil;
|
||||
MQTT = require("mqtt")
|
||||
|
||||
daq = {};
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg)
|
||||
print(msg);
|
||||
end
|
||||
|
||||
local function pubPanelConfig()
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/send",panel.LabelButtonSend[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/0",panel.LabelButton_1[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/1",panel.LabelButton_2[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/2",panel.LabelButton_3[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/3",panel.LabelButton_4[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/header",panel.LabelHeader[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/samples",panel.OptionsSamples[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/max",panel.OptionsXaxisMax[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/min",panel.OptionsXaxisMin[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/max",panel.OptionsXaxis_1_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/max",panel.OptionsXaxis_2_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/min",panel.OptionsXaxis_2_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/min",panel.OptionsYaxis_1_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/message", panel.TextSendMessage[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/topic",panel.TextSendTopic[1])
|
||||
MQTT.publish(mqttRoot.."/panel/debug",panel.Debug["alt"][panel.Debug["idx"]])
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.publish(mqttRoot.."/info", "PIALU")
|
||||
MQTT.subscribe(mqttRoot.."/ctrl/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message "..topic, payload)
|
||||
|
||||
subTopic = string.match(topic,mqttRoot.."/ctrl/(%w+)")
|
||||
if subTopic then
|
||||
if subTopic == "cmd" then
|
||||
logPrint("MQTT:\t Command");
|
||||
analogChannel = string.match(topic,mqttRoot.."/ctrl/cmd/analog/(%w)")
|
||||
if analogChannel then
|
||||
|
||||
if analogChannel == "0" then
|
||||
logPrint("MQTT:\t Command Analog Channel "..analogChannel.." "..payload);
|
||||
if payload == "on" then
|
||||
channel_0 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
else
|
||||
channel_0 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "off",true)
|
||||
end
|
||||
elseif analogChannel == "1" then
|
||||
if payload == "on" then
|
||||
channel_1 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
else
|
||||
channel_1 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "off",true)
|
||||
end
|
||||
elseif analogChannel == "2" then
|
||||
if payload == "on" then
|
||||
channel_2 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
else
|
||||
channel_2 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "off",true)
|
||||
end
|
||||
elseif analogChannel == "3" then
|
||||
if payload == "on" then
|
||||
channel_3 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
else
|
||||
channel_3 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "off",true)
|
||||
end
|
||||
end
|
||||
elseif string.match(topic,mqttRoot.."/ctrl/cmd/panel/config") then
|
||||
if string.match(payload,"publish") then
|
||||
pubPanelConfig()
|
||||
elseif string.match(payload,"apply") then
|
||||
panel = {}
|
||||
dofile("panel.lua")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local function getInt32(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 4) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8) + bit32.lshift(bytes[offset+3],16) + bit32.lshift(bytes[offset+4],24);
|
||||
if ( num > 0x80000000 ) then
|
||||
return num - 0x100000000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getInt16(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 2) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8);
|
||||
end
|
||||
|
||||
if ( num > 0x8000 ) then
|
||||
return num - 0x10000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getUint8(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 1) then
|
||||
return bytes[offset+1];
|
||||
end
|
||||
|
||||
return 999999999;
|
||||
end
|
||||
--[[
|
||||
local function i2cBegin()
|
||||
I2CDevice = I2CClass("/dev/i2c-1")
|
||||
end
|
||||
|
||||
local function i2cRecvMsg()
|
||||
local msg = {{
|
||||
0x00, -- uint8_t hartbeat;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
flags = I2CClass.I2C_M_RD
|
||||
}}
|
||||
I2CDevice:transfer(6, msg)
|
||||
-- print(table.unpack(msg[1]));
|
||||
return msg[1]
|
||||
end
|
||||
|
||||
local function i2cSendMsg(cmd)
|
||||
local msg = {{cmd, 0x00, 0x00, 0x00, 0x00, flags = 0}}
|
||||
I2CDevice:transfer(4, msg)
|
||||
end
|
||||
--]]
|
||||
local function recv()
|
||||
--[[
|
||||
daqData = i2cRecvMsg();
|
||||
-- print(table.unpack(daqData));
|
||||
daq.hartbeat = getUint8(daqData,0);
|
||||
daq.sum0 = getInt32(daqData,1);
|
||||
daq.sum1 = getInt32(daqData,5);
|
||||
daq.sum2 = getInt32(daqData,9);
|
||||
daq.sum3 = getInt32(daqData,13);
|
||||
--]]
|
||||
daq.hartbeat = 123;
|
||||
daq.sum0 = 3;
|
||||
daq.sum1 = 1.7;
|
||||
daq.sum2 = 9;
|
||||
daq.sum3 = 5.5;
|
||||
end
|
||||
|
||||
function setup()
|
||||
mqttBroker = app.mqttBroker[1]
|
||||
mqttRoot = app.mqttRoot[1]
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,32,24);
|
||||
|
||||
label = HMI.Label(layout,0,0,32,3,"Plot");
|
||||
label:setTextColor(HMI.Color.white);
|
||||
label:setBackground(HMI.Color.blue);
|
||||
|
||||
chart = HMI.Timechart(layout,0,4,32,16)
|
||||
chart:setBaseline(0)
|
||||
chart:setValuePerDivison(2)
|
||||
chart:setSamplesPerDivison(20)
|
||||
chart:setSamplesFormat("%d Samples/Div, Samplerate 0.5s <=> 10 Sekunden/Div")
|
||||
|
||||
txt0 = HMI.Label(layout, 1,20,6,2,"Ch 0");
|
||||
txt0:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt1 = HMI.Label(layout,17,20,6,2,"Ch 1");
|
||||
txt1:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt2 = HMI.Label(layout, 1,22,6,2,"Ch 2");
|
||||
txt2:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt3 = HMI.Label(layout,17,22,6,2,"Ch 3");
|
||||
txt3:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
|
||||
out0 = HMI.Output(layout, 7,20,6,2,"0000");
|
||||
out1 = HMI.Output(layout,23,20,6,2,"0000");
|
||||
out2 = HMI.Output(layout, 7,22,6,2,"0000");
|
||||
out3 = HMI.Output(layout,23,22,6,2,"0000");
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
|
||||
-- i2cBegin()
|
||||
|
||||
if mqttBroker then
|
||||
errLog("MQTT:\t Begin\n");
|
||||
MQTT.begin(mqttBroker)
|
||||
end
|
||||
|
||||
MQTT.loop()
|
||||
|
||||
channel_0 = true;
|
||||
channel_1 = true;
|
||||
channel_2 = true;
|
||||
channel_3 = true;
|
||||
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
end
|
||||
|
||||
function loop()
|
||||
MQTT.loop()
|
||||
|
||||
if updateTimer.elapsed() then
|
||||
updateTimer.restart()
|
||||
recv()
|
||||
|
||||
val0 = daq.sum0*0.0000707750682632
|
||||
val1 = daq.sum1*0.0000707750682632
|
||||
val2 = daq.sum2*0.0000208350713273
|
||||
val3 = daq.sum3*0.0000208350713273
|
||||
|
||||
out0:setText(string.format("%5.2f",val0))
|
||||
out1:setText(string.format("%5.2f",val1))
|
||||
out2:setText(string.format("%5.2f",val2))
|
||||
out3:setText(string.format("%5.2f",val3))
|
||||
chart:plot(daq.sum0*0.0000707750682632)
|
||||
--chart:plot(daq.sum1*0.0000707750682632)
|
||||
--chart:plot(daq.sum2*0.0000208350713273)
|
||||
--chart:plot(daq.sum3*0.0000208350713273)
|
||||
|
||||
compound = ""
|
||||
|
||||
if channel_0 then
|
||||
MQTT.publish(mqttRoot.."/analog/0",val0)
|
||||
compound = compound..",0:"..val0
|
||||
end
|
||||
if channel_1 then
|
||||
MQTT.publish(mqttRoot.."/analog/1",val1)
|
||||
compound = compound..",1:"..val1
|
||||
end
|
||||
if channel_2 then
|
||||
MQTT.publish(mqttRoot.."/analog/2",val2)
|
||||
compound = compound..",2:"..val2
|
||||
end
|
||||
if channel_3 then
|
||||
MQTT.publish(mqttRoot.."/analog/3",val3)
|
||||
compound = compound..",3:"..val3
|
||||
end
|
||||
all = string.sub(compound,2)
|
||||
if string.len(all) > 0 then
|
||||
MQTT.publish(mqttRoot.."/analog/all",all)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+2)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData and attrData then
|
||||
local len = string.len(strData)
|
||||
for j=1, len, 1 do
|
||||
local label = line[posY+1][posX+j]
|
||||
if attrData:sub(j,j) == 'b' then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
label:setText(strData:sub(j,j))
|
||||
label:draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4,j%10);
|
||||
-- line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(mono)
|
||||
line[1][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
local scheduler = {}
|
||||
|
||||
socket = require('socket')
|
||||
|
||||
function scheduler.Timer(init)
|
||||
-- the new instance
|
||||
|
||||
local self = {
|
||||
-- public fields go in the instance table
|
||||
interval = init
|
||||
}
|
||||
|
||||
local function millis()
|
||||
return socket.gettime()*1000
|
||||
end
|
||||
|
||||
-- private fields are implemented using locals
|
||||
-- they are faster than table access, and are truly private,
|
||||
-- so the code that uses your class can't get them
|
||||
|
||||
local _timestamp = millis()
|
||||
local _running = true
|
||||
|
||||
function self.elapsed()
|
||||
if _running and (millis() - _timestamp ) >= self.interval then
|
||||
_running = false
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function self.running()
|
||||
return (millis() - _timestamp ) < self.interval
|
||||
end
|
||||
|
||||
function self.restart()
|
||||
_timestamp = millis()
|
||||
_running = true
|
||||
end
|
||||
|
||||
function self.count()
|
||||
return millis() - timestamp
|
||||
end
|
||||
|
||||
-- return the instance
|
||||
return self
|
||||
end
|
||||
|
||||
return scheduler
|
||||
@@ -1,599 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
struct = require('struct')
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local T1 = 300
|
||||
local T2 = 1000
|
||||
local T3 = 3000
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local serial
|
||||
local host = false
|
||||
local connected = false
|
||||
local pending = false
|
||||
local transaction_id = 1
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
|
||||
parseData(msg,buf,11,100);
|
||||
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
-- io.stderr:write("packList type("..type(l)..")\n")
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secaId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
pending = true
|
||||
transactionTimer.restart()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("SxF0\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,h.s_stream,0)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("S1F1\n----\n")
|
||||
|
||||
return {
|
||||
primaryHeader(1,1)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(ppid,mid1,mid2,mid3)
|
||||
io.stderr:write("S2F41("..ppid..","..mid1..","..mid2..","..mid3..")\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(2,41),
|
||||
packList( {
|
||||
packString("START"),
|
||||
packList( {
|
||||
packList( {
|
||||
packString("PPID"),
|
||||
packString(ppid)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID1"),
|
||||
packString(mid1)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID2"),
|
||||
packString(mid2)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID3"),
|
||||
packString(mid3)
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("S2F42\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,2,42),
|
||||
packList( {
|
||||
packBinary(4),
|
||||
packList({}) -- empty list
|
||||
} )
|
||||
}
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
|
||||
return {
|
||||
secondaryHeader(h,6,12),
|
||||
packBinary(0)
|
||||
}
|
||||
else
|
||||
secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
end
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function sendMsg(msg)
|
||||
|
||||
local buf = table.concat(msg);
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(chksum / 256))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I: NAK Received\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: AKN Timeout\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: EOT Timeout\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("receiveMsg\n----------\ncount: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
-- TODO checksum error handling
|
||||
|
||||
-- hexDumpString(buf);
|
||||
|
||||
serial:write(ASCII_ACK)
|
||||
|
||||
msg = parseMsg(buf)
|
||||
-- dumpMsg(msg)
|
||||
|
||||
return msg
|
||||
else
|
||||
io.stderr:write("SECS I: Countbyte Timeout\n")
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
local request = {}
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
|
||||
request = receiveMsg()
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
pending = false;
|
||||
end
|
||||
|
||||
msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
sendMsg(S1F2(request.header))
|
||||
SECS.onPrimary(1,1,"are you there")
|
||||
elseif isSF(request,1,2) then
|
||||
SECS.onSecondary(1,2,"are you there akn")
|
||||
elseif isSF(request,1,13) then
|
||||
sendMsg(S1F14(request.header))
|
||||
connected = true;
|
||||
SECS.onPrimary(1,13,"establish communication request")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
SECS.onSecondary(1,14,"establish communication request akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S2F42(request.header))
|
||||
SECS.onPrimary(2,41,"host command send")
|
||||
elseif isSF(request,2,42) then
|
||||
SECS.onSecondary(2,42,"host command send akn")
|
||||
elseif isSF(request,6,11) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S6F12(request.header))
|
||||
SECS.onPrimary(6,11,"event report send")
|
||||
elseif isSF(request,6,12) then
|
||||
--
|
||||
SECS.onSecondary(6,12,"event report send akn")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
sendMsg(SxF0(request.header))
|
||||
SECS.onPrimary(0,0,"abort transaction akn")
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write("loop poll:"..string.byte(c).."\n")
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("loop poll: Transaction timeout\n")
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
|
||||
end
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature= msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isPending = function() return pending end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() sendMsg(S1F13()) end;
|
||||
sendS1F1 = function() sendMsg(S1F1()) end;
|
||||
sendS2F41 = function(a1,a2,a3,a4) sendMsg(S2F41(a1,a2,a3,a4)) end;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
local T1 = 100 --300
|
||||
local T2 = 2000 --1000
|
||||
local T3 = 5000 --3000
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local pending = false
|
||||
local reading = false
|
||||
local writing = false
|
||||
|
||||
local serial
|
||||
|
||||
local onProcessRequest;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
local function hexDumpString(buf)
|
||||
if buf then
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
end
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
local function discardInput()
|
||||
hexDumpString(buf);
|
||||
io.stderr:write("SECS I:\t Discard input: ")
|
||||
while serial:poll(100) do
|
||||
c = serial:read(1)
|
||||
io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function sendMsg(buf)
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
writing = true
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(math.floor(chksum / 256)))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I:\t NAK Received\n")
|
||||
--discardInput()
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t AKN Timeout\n")
|
||||
discardInput()
|
||||
end
|
||||
writing = false
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t EOT Timeout\n")
|
||||
discardInput()
|
||||
writing = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
reading = true
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("SECS I:\t receiveMsg count: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
for i=1, #buf-2 do
|
||||
chksum = chksum + buf:byte(i)
|
||||
end
|
||||
|
||||
local msgChksum = buf:byte(#buf-1)*256 + buf:byte(#buf)
|
||||
|
||||
if msgChksum == chksum then
|
||||
serial:write(ASCII_ACK)
|
||||
return buf
|
||||
else
|
||||
io.stderr:write("SECS I:\t Checksum Error\n")
|
||||
hexDumpString(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
discardInput()
|
||||
--io.stderr:write(string.format("SECS I:\t Checksum: %04X %04X\n",chksum,msgChksum))
|
||||
io.stderr:write(string.format("SECS I:\t Bytes: %d Checksum: %04X %04X\n",#buf,chksum,msgChksum))
|
||||
return ""
|
||||
end
|
||||
reading = false
|
||||
else
|
||||
io.stderr:write("SECS I:\t Countbyte Timeout\n")
|
||||
discardInput()
|
||||
reading = false
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
local buf=receiveMsg()
|
||||
if #buf >= 11 then
|
||||
onProcessRequest(buf)
|
||||
else
|
||||
io.stderr:write("SECS I:\t Poll error bytes: "..#buf.."\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
end
|
||||
elseif c == ASCII_NAK then
|
||||
io.stderr:write("SECS I:\t Poll NAK received\n")
|
||||
--discardInput()
|
||||
pending = false
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write(string.format("SECS I:\t Poll error byte = %02X\n",string.byte(c)))
|
||||
discardInput()
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("SECS I:\t Poll transaction timeout\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
poll = poll;
|
||||
sendMsg = sendMsg;
|
||||
receiveMsg = receiveMsg;
|
||||
isReading = function() return reading end;
|
||||
isWriting = function() return writing end;
|
||||
isPending = function() return pending end;
|
||||
onProcessRequest = function(cb) onProcessRequest = cb end;
|
||||
startTransaction = function() transactionTimer.restart(); pending = true end;
|
||||
stopTransaction = function() pending = false end;
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
|
||||
SECS_IO = require('secs_i')
|
||||
struct = require('struct')
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local secsId = 0x1234
|
||||
local host = false
|
||||
local connected = false
|
||||
|
||||
local transaction_id = 1
|
||||
|
||||
local eq_online = 3 -- 1: online remote, 2: online local, 3: offline
|
||||
local eq_status = 2 -- 1: not ready, 2: ready, 3: busy, 4: process cmpl, 5: pause, 6: complete
|
||||
|
||||
local onSendEventMsg = nil
|
||||
local onPrimaryMsg = nil
|
||||
local onSecondaryMsg = nil
|
||||
local onProcessMsg = nil
|
||||
|
||||
local msgQueue = {}
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
--[[
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
--]]
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
io.stderr:write(string.format("IDX: %d\n",idx))
|
||||
num = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,num))
|
||||
len = buf:byte(idx+1);
|
||||
io.stderr:write(string.format("DATA LEN: %02X %03d\n",len,len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
parseData(msg,buf,11,#buf);
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
-- SECS_IO.startTransaction()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
function string.pop(s)
|
||||
return string.sub(s,1,1),string.sub(s,2)
|
||||
end
|
||||
|
||||
function table.pop(t)
|
||||
local i = t[1]
|
||||
table.remove(t,1)
|
||||
return i,t
|
||||
end
|
||||
|
||||
local function packData(sig,items)
|
||||
local buf = ""
|
||||
|
||||
-- print("packData sig: ",sig)
|
||||
while #sig > 0 do
|
||||
-- print("packData len1: ",#sig)
|
||||
typ, sig = string.pop(sig)
|
||||
-- print("packData len2: ",#sig,typ,sig)
|
||||
if typ == "L" then
|
||||
len , sig = string.pop(sig)
|
||||
-- print("packData len3: ",#sig,len,sig)
|
||||
buf = buf..struct.pack('BB',SF_LIST+1,len)..packData(sig,items)
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
elseif typ == "A" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packString(item)
|
||||
elseif typ == "B" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packBinary(item)
|
||||
end
|
||||
end
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
local function primaryMsg(s,f,sig,items)
|
||||
return primaryHeader(s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
local function secondaryMsg(h,s,f,sig,items)
|
||||
return secondaryHeader(h,s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("\nSECS II: SxF0\n----\n")
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("\nSECS II: S1F1\n----\n")
|
||||
return primaryHeader(1,1)
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("\nSECS II: S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,2,"L0",{})
|
||||
else
|
||||
return secondaryMsg(h,1,2,"L2AA",{MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("\nSECS II: S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return primaryMsg(1,13,"L2BL0",{0})
|
||||
else
|
||||
return primaryMsg(1,13,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("\nSECS II: S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,14,"L2BL0",{0})
|
||||
else
|
||||
return secondaryMsg(h,1,14,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(c)
|
||||
|
||||
io.stderr:write("\nSECS II: S2F41("..c..")\n----\n")
|
||||
if host then
|
||||
return onCreateMsg(2,41,c)
|
||||
else
|
||||
return "" -- host only command
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("\nSECS II: S2F42\n----\n")
|
||||
|
||||
return secondaryMsg(h,2,42,"L2BL0",{4})
|
||||
end
|
||||
|
||||
local function S5F2(h)
|
||||
io.stderr:write("\nSECS II: S5F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,5,2,"B",{0})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("\nSECS II: S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,6,12,"B",{0})
|
||||
else
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F11(e)
|
||||
io.stderr:write("\nSECS II: S6F11("..e..")\n----\n")
|
||||
|
||||
if not host then
|
||||
return onCreateMsg(6,11,e)
|
||||
else
|
||||
return "" -- equipment only command
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
local function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function isS5Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 5
|
||||
end
|
||||
|
||||
local function isS9Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 9
|
||||
end
|
||||
|
||||
SECS_IO.onProcessRequest (
|
||||
function(buf)
|
||||
local request = parseMsg(buf)
|
||||
io.stderr:write("SECS II: ID: ",request.header.secsId,"\n")
|
||||
local s = request.header.secsStream
|
||||
local f = request.header.secsFunction
|
||||
io.stderr:write("SECS II: onProcessMsg ".."S"..s.."F"..f.."\n");
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
local sig = msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
onPrimaryMsg(1,1,"are you there received")
|
||||
SECS_IO.sendMsg(S1F2(request.header))
|
||||
elseif isSF(request,1,2) then
|
||||
onSecondaryMsg(1,2,"are you there received akn")
|
||||
elseif isSF(request,1,13) then
|
||||
connected = true;
|
||||
onPrimaryMsg(1,13,"establish communication request received")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
SECS_IO.sendMsg(S1F14(request.header))
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
onSecondaryMsg(1,14,"establish communication request received akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
--print("SECS II: Message ",#request)
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(2,41,"host command received")
|
||||
SECS_IO.sendMsg(S2F42(request.header))
|
||||
elseif isSF(request,2,42) then
|
||||
onProcessMsg(request)
|
||||
onSecondaryMsg(2,42,"host command received akn")
|
||||
elseif isSF(request,6,11) then
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(6,11,"event report received")
|
||||
SECS_IO.sendMsg(S6F12(request.header))
|
||||
elseif isSF(request,6,12) then
|
||||
onSecondaryMsg(6,12,"event report received akn")
|
||||
elseif isS5Fx(request) then
|
||||
onProcessMsg(request)
|
||||
--hexDumpString(buf)
|
||||
--io.stderr:write("SIG: "..sig.."\n")
|
||||
onPrimaryMsg(5,request.header.secsFunction,"alarm received")
|
||||
SECS_IO.sendMsg(S5F2(request.header))
|
||||
elseif isS9Fx(request) then
|
||||
-- no secondary message
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(9,request.header.secsFunction,"error received")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
onPrimaryMsg(0,0,"abort transaction send")
|
||||
SECS_IO.sendMsg(SxF0(request.header))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function dequeMsg()
|
||||
local m = msgQueue[1]
|
||||
table.remove(msgQueue,1)
|
||||
return m
|
||||
end
|
||||
|
||||
local function queueMsg(msg)
|
||||
io.stderr:write("\n====\nSECS II: queueMsg\n====\n");
|
||||
table.insert(msgQueue,msg)
|
||||
end
|
||||
|
||||
local function poll()
|
||||
if not SECS_IO.isPending() and #msgQueue > 0 then
|
||||
-- if not pending and #msgQueue > 0 then
|
||||
io.stderr:write("\n====\nSECS II: dequeueMsg\n====\n");
|
||||
SECS_IO.startTransaction()
|
||||
SECS_IO.sendMsg(dequeMsg())
|
||||
end
|
||||
SECS_IO.poll()
|
||||
end;
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function setId(id)
|
||||
secsId = id
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
SECS_IO.begin(device,baud)
|
||||
io.stderr:write("begin\n")
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature = msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
--------- DEBUG only ----------------
|
||||
-- dataSignature = dataSignature;
|
||||
-- parseMsg = parseMsg;
|
||||
-- dumpData = dumpData;
|
||||
-- parseData = parseData;
|
||||
|
||||
-- packString = packString;
|
||||
-- packBinary = packBinary;
|
||||
-- packList = packList;
|
||||
-- packData = packData;
|
||||
--------------------------------------
|
||||
|
||||
primaryMsg = primaryMsg;
|
||||
secondaryMsg = secondaryMsg;
|
||||
|
||||
setId = setId;
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isReading = function() return SECS_IO.isReading() end;
|
||||
isWriting = function() return SECS_IO.isWriting() end;
|
||||
isPending = function() return SECS_IO.isPending() end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() queueMsg(S1F13()) end;
|
||||
sendS1F1 = function() queueMsg(S1F1()) end;
|
||||
sendS2F41 = function(c) queueMsg(S2F41(c)) end;
|
||||
sendS6F11 = function(e) queueMsg(S6F11(e)) end;
|
||||
|
||||
onCreateMsg = function(cb) onCreateMsg = cb end;
|
||||
onPrimaryMsg = function(cb) onPrimaryMsg = cb end;
|
||||
onSecondaryMsg = function(cb) onSecondaryMsg = cb end;
|
||||
onProcessMsg = function(cb) onProcessMsg = cb end;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
PLC = require('vwago')
|
||||
|
||||
plc = PLC.VWago("wago")
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
i = plc:getDouble(1)
|
||||
plc:setDouble(0,i)
|
||||
i = i + 1234
|
||||
if i > 2147483647 then
|
||||
i = 0
|
||||
o = plc:getDouble(2)
|
||||
plc:setDouble(2,o+1)
|
||||
end
|
||||
plc:setDouble(1,i)
|
||||
plc:update()
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,114 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
serial = Serial("/dev/ttyAMA0",9600)
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
while (1) do
|
||||
while serial:poll(100) do
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
print(c.." at "..posX.." "..posY.."\n")
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
--[[
|
||||
if ( c >= 0x20 && c < 0x7F ) {
|
||||
(c==buf_char[y_now][x_now])?(buf_chng[y_now][x_now]='n'):(buf_chng[y_now][x_now]='y');
|
||||
(BLINK_FLAG?(buf_args[y_now][x_now] = 'b'):( buf_args[y_now][x_now] = 'n'));
|
||||
buf_char[y_now][x_now] = c;
|
||||
checkX(++x_now);
|
||||
--]]
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
--
|
||||
-- io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
end
|
||||
@@ -1,197 +0,0 @@
|
||||
--[[
|
||||
* Copyright (c) 2015-2017 Iryont <https://github.com/iryont/lua-struct>
|
||||
*
|
||||
* 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.
|
||||
]]
|
||||
|
||||
struct = {}
|
||||
|
||||
function struct.pack(format, ...)
|
||||
local stream = {}
|
||||
local vars = {...}
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
|
||||
local bytes = {}
|
||||
for j = 1, n do
|
||||
table.insert(bytes, string.char(val % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt:find('[fd]') then
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
local sign = 0
|
||||
|
||||
if val < 0 then
|
||||
sign = 1
|
||||
val = -val
|
||||
end
|
||||
|
||||
local mantissa, exponent = math.frexp(val)
|
||||
if val == 0 then
|
||||
mantissa = 0
|
||||
exponent = 0
|
||||
else
|
||||
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
|
||||
exponent = exponent + ((opt == 'd') and 1022 or 126)
|
||||
end
|
||||
|
||||
local bytes = {}
|
||||
if opt == 'd' then
|
||||
val = mantissa
|
||||
for i = 1, 6 do
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
else
|
||||
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
|
||||
val = math.floor(mantissa / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
|
||||
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
|
||||
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
table.insert(stream, tostring(table.remove(vars, 1)))
|
||||
table.insert(stream, string.char(0))
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
local length = tonumber(n)
|
||||
|
||||
if length > 0 then
|
||||
local str = tostring(table.remove(vars, 1))
|
||||
if length - str:len() > 0 then
|
||||
str = str .. string.rep(' ', length - str:len())
|
||||
end
|
||||
table.insert(stream, str:sub(1, length))
|
||||
end
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(stream)
|
||||
end
|
||||
|
||||
function struct.unpack(format, stream)
|
||||
local vars = {}
|
||||
local iterator = 1
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local signed = opt:lower() == opt
|
||||
|
||||
local val = 0
|
||||
for j = 1, n do
|
||||
local byte = string.byte(stream:sub(iterator, iterator))
|
||||
if endianness then
|
||||
val = val + byte * (2 ^ ((j - 1) * 8))
|
||||
else
|
||||
val = val + byte * (2 ^ ((n - j) * 8))
|
||||
end
|
||||
iterator = iterator + 1
|
||||
end
|
||||
|
||||
if signed and val >= 2 ^ (n * 8 - 1) then
|
||||
val = val - 2 ^ (n * 8)
|
||||
end
|
||||
|
||||
table.insert(vars, val)
|
||||
elseif opt:find('[fd]') then
|
||||
local n = (opt == 'd') and 8 or 4
|
||||
local x = stream:sub(iterator, iterator + n - 1)
|
||||
iterator = iterator + n
|
||||
|
||||
if not endianness then
|
||||
x = string.reverse(x)
|
||||
end
|
||||
|
||||
local sign = 1
|
||||
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
|
||||
for i = n - 2, 1, -1 do
|
||||
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
|
||||
end
|
||||
|
||||
if string.byte(x, n) > 127 then
|
||||
sign = -1
|
||||
end
|
||||
|
||||
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
|
||||
if exponent == 0 then
|
||||
table.insert(vars, 0.0)
|
||||
else
|
||||
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
|
||||
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
local bytes = {}
|
||||
for j = iterator, stream:len() do
|
||||
if stream:sub(j, j) == string.char(0) then
|
||||
break
|
||||
end
|
||||
|
||||
table.insert(bytes, stream:sub(j, j))
|
||||
end
|
||||
|
||||
local str = table.concat(bytes)
|
||||
iterator = iterator + str:len() + 1
|
||||
table.insert(vars, str)
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)-1))
|
||||
iterator = iterator + tonumber(n)
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return unpack(vars)
|
||||
end
|
||||
|
||||
return struct
|
||||
@@ -1,18 +0,0 @@
|
||||
tabs = {
|
||||
{class="ShellCommandWidget", title="Info", args={"cat","/mnt/info.txt"} },
|
||||
{class="ConfigSystemWidget", title="System"},
|
||||
{class="ProcessStateWidget", title="ps"},
|
||||
-- {class="ShellCommandWidget", title="MB", args={"mb","-rd","localhost"} },
|
||||
-- {class="ProcessStateWidget", title="ps"},
|
||||
{class="TailFileWidget", title="Log"},
|
||||
-- {class="ScriptProgrammerWidget", title="ELFI Script"},
|
||||
-- {class="RemoteProgrammerWidget", title="AVRDude"},
|
||||
-- {class="LuaProgrammerWidget", title="LUA Script"},
|
||||
{class="LuaAdminWidget", title="LUA Admin"},
|
||||
{class="AceEditorWidget", title="Lua ACE 1"},
|
||||
{class="AceEditorWidget", title="Lua ACE 2"},
|
||||
{class="AceEditorWidget", title="Lua ACE 3"},
|
||||
{class="AceEditorWidget", title="HTML ACE 1", args={"/mnt/www","",".html","html"}},
|
||||
-- {class="RemoteContainerWidget", title="Lua Shell", args={"http://192.168.9.101:4200"}}
|
||||
{class="RemoteContainerWidget", title="Lua Shell"}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
updateTimer = Scheduler.Timer(5000)
|
||||
oneSecond = Scheduler.Timer(1000)
|
||||
|
||||
while updateTimer:running() do
|
||||
if oneSecond:elapsed() then print("1 Sekunde") end
|
||||
end
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
local evdev = require "evdev"
|
||||
|
||||
local dev = evdev.Device("/dev/input/event0")
|
||||
|
||||
local x = 0
|
||||
local y = 0
|
||||
local cnt = 0
|
||||
|
||||
|
||||
|
||||
while true do
|
||||
--local timestamp, eventType, eventCode, value = dev:read()
|
||||
--print(dev:avail())
|
||||
if dev:avail() > 0 then
|
||||
local timestamp, eventType, eventCode, value = dev:read()
|
||||
|
||||
if eventType == evdev.EV_ABS then
|
||||
if eventCode == 57 then
|
||||
if value < 0 then
|
||||
if y > 0 and y < 79 then
|
||||
print("Ctrl1: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 400 and y < 479 then
|
||||
print("Ctrl2: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 320 and y < 399 then
|
||||
print("Numbs: ",math.floor(x/80)+1)
|
||||
end
|
||||
if y > 80 and y < 319 then
|
||||
-- print("Lines: ",math.floor(y/((320-80)/6))-1,math.floor(x/20)+1,x,y,math.floor((y-80)/240*10+6),math.floor(x/465*23+5))
|
||||
print("Lines: ",math.floor((y-80)/240*10+6),math.floor(x/720*36+7))
|
||||
end
|
||||
end
|
||||
elseif eventCode == 0 then
|
||||
x = value
|
||||
elseif eventCode == 1 then
|
||||
y = value
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
cnt = cnt + 1
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
-- tr["<Variante>"] = "<Rezeptnummer"
|
||||
|
||||
tr["1T1"] = "20"
|
||||
tr["1T2"] = "21"
|
||||
tr["2T1"] = "22"
|
||||
tr["2T3"] = "23"
|
||||
tr["1D6"] = "65"
|
||||
tr["2D6"] = "66"
|
||||
tr["2B7"] = "63"
|
||||
@@ -1,13 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
app.mqttBroker = {"192.168.9.99",inf="MQTT Broker"};
|
||||
app.mqttRoot = {"pilogi",inf="MQTT Root"};
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
modules = {"panel","app","locale"};
|
||||
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {}
|
||||
require "app"
|
||||
|
||||
function app.apply()
|
||||
print(
|
||||
"<br><b><center>Apply module app !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, musste die Anwendung neu gestartet werden !</center><br>"
|
||||
);
|
||||
os.execute("/root/ctrlapp stop")
|
||||
os.execute("sleep 2")
|
||||
os.execute("/root/ctrlapp start")
|
||||
end
|
||||
|
||||
function app.validate()
|
||||
print("<br><b><center>Validate modlue app !</center></b><br>");
|
||||
end
|
||||
|
||||
---------------- Witty Administration localisation ------------------
|
||||
|
||||
locale = {}
|
||||
require "locale";
|
||||
|
||||
---------------- Witty Administration Tabs configuration ------------
|
||||
|
||||
tabs = {}
|
||||
require "tabs";
|
||||
|
||||
panel = {};
|
||||
require "panel"
|
||||
|
||||
function panel.apply()
|
||||
local mqttBroker = app.mqttBroker[1]
|
||||
local mqttRoot = app.mqttRoot[1]
|
||||
print(
|
||||
"<br><b><center>Apply module panel !</center></b><br>"..
|
||||
"<center>Damit die Änderungen wirksam werden, wird die Konfiguration via MQTT publiziert !</center><br>"
|
||||
);
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m apply")
|
||||
os.execute("sleep 2")
|
||||
os.execute("mosquitto_pub -h "..mqttBroker.. " -t "..mqttRoot.."/ctrl/cmd/panel/config -m publish")
|
||||
end
|
||||
@@ -1,44 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start|"")
|
||||
# Run App use default run.lua
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
stop)
|
||||
/usr/bin/killall app
|
||||
;;
|
||||
kill)
|
||||
/usr/bin/killall -kill app
|
||||
;;
|
||||
run)
|
||||
/usr/bin/killall app
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/app -d -r /root -l /tmp/lotlog.txt 2>/dev/null
|
||||
;;
|
||||
debug)
|
||||
/usr/bin/killall app
|
||||
# /bin/app -e -r /root /root/run.lua
|
||||
# websocket fix, daq should lower permissions
|
||||
if [ -f /mnt/app.ini ] ; then
|
||||
source /mnt/app.ini
|
||||
fi
|
||||
/bin/su -p -c '/bin/app -e -r /root /root/run.lua' lua
|
||||
;;
|
||||
websocket)
|
||||
/usr/bin/killall websocketd
|
||||
/usr/bin/screen -dmS websock /bin/websocketd --staticdir=/mnt/www --port=88 /root/ctrlapp debug
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|run|debug|websocket}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,4 +0,0 @@
|
||||
[Info]
|
||||
Version = 1
|
||||
[Framebuffer]
|
||||
Device = /dev/fb0
|
||||
@@ -1,9 +0,0 @@
|
||||
---------------- Application module app configuration ---------------
|
||||
|
||||
app = {};
|
||||
require "app"
|
||||
|
||||
---------------- Application module locale configuration ---------------
|
||||
|
||||
locale = {};
|
||||
require "locale";
|
||||
BIN
3B/archive/root_3.bak/font/arial.ttf
(Stored with Git LFS)
BIN
3B/archive/root_3.bak/font/arial.ttf
(Stored with Git LFS)
Binary file not shown.
BIN
3B/archive/root_3.bak/font/mono.ttf
(Stored with Git LFS)
BIN
3B/archive/root_3.bak/font/mono.ttf
(Stored with Git LFS)
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
locale.version = {"Version 1.0",inf="Software Version"};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
PLC = require('modbus')
|
||||
socket = require('socket')
|
||||
|
||||
plc = PLC.Modbus("pi_daq",502)
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
plc:sync();
|
||||
print(plc:getReal(1))
|
||||
end
|
||||
socket.sleep(0.5)
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
MQTT = require("mosquitto")
|
||||
mqtt = MQTT.new()
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
local connected = false
|
||||
local broker = "localhost"
|
||||
|
||||
local onMessage = nil
|
||||
local onConnect = nil
|
||||
|
||||
local function publish(topic,msg,retain)
|
||||
retain = retain or false
|
||||
mqtt:publish(topic,msg, qos, retain)
|
||||
end
|
||||
|
||||
local function loop()
|
||||
local ok,err,msg
|
||||
|
||||
if connected then
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
if onError then onError(1) end
|
||||
connected = false
|
||||
end
|
||||
else
|
||||
ok,err,msg = mqtt:loop(0)
|
||||
if not ok then
|
||||
if onError then onError(2) end
|
||||
errLog("MQTT:\t "..msg.."\n")
|
||||
mqtt:connect(broker,1883,5)
|
||||
errLog("MQTT:\t Reconnect".."\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function subscribe(msg)
|
||||
mqtt:subscribe(msg)
|
||||
end
|
||||
|
||||
mqtt.ON_CONNECT = function()
|
||||
connected = true
|
||||
if onConnect then onConnect() end
|
||||
end
|
||||
|
||||
mqtt.ON_MESSAGE = function(mid, topic, payload)
|
||||
if onMessage then onMessage(mid, topic, payload) end
|
||||
end
|
||||
|
||||
local function begin(hostname)
|
||||
broker = hostname
|
||||
mqtt:connect(broker,1883,5)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
loop = loop;
|
||||
publish = publish;
|
||||
subscribe = subscribe;
|
||||
onConnect = function(callback) onConnect = callback end;
|
||||
onMessage = function(callback) onMessage = callback end;
|
||||
onError = function(callback) onError = callback end;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
----------------- Configuration LUA -----------------------
|
||||
--
|
||||
-- Text in ""
|
||||
-- Zahlen ohne ""
|
||||
-- Komentare mit --
|
||||
--
|
||||
-- Achtung Gross/Kleinschreibung ist wichtig !
|
||||
--
|
||||
-----------------------------------------------------------
|
||||
|
||||
panel.Debug = {idx=2,alt={"on","off"},inf="Debug Ausgabe aktivieren, MQTT:-t <mqttRoot>/debug -m off -m on | off"};
|
||||
panel.LabelButtonSend = {"Send",inf="Beschriftung Panel Send, MQTT: -t <mqttRoot>/label/button/send -m 'Send'"};
|
||||
panel.LabelButton_1 = {"Sensor Analog",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/label/button/0 -m 'Text'"};
|
||||
panel.LabelButton_2 = {"Endpoint Logic",inf="Beschriftung Panel Button 2, MQTT: -t <mqttRoot>/label/button/1 -m 'Text'"};
|
||||
panel.LabelButton_3 = {"Kanal 3",inf="Beschriftung Panel Button 3, MQTT: -t <mqttRoot>/label/button/2 -m 'Text'"};
|
||||
panel.LabelButton_4 = {"Kanal 4",inf="Beschriftung Panel Button 4, MQTT: -t <mqttRoot>/label/button/3 -m 'Text'"};
|
||||
panel.LabelHeader = {"AL01 Datalogger",inf="Beschriftung Ueberschrift, MQTT: -t <mqttRoot>/label/header -m 'Text'"};
|
||||
panel.OptionsSamples = {100.000000,inf="Samples, MQTT: <mqttRoot>/options/samples -m 100"};
|
||||
panel.OptionsXaxisMax = {100.000000,inf="Maximum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/max -m 100"};
|
||||
panel.OptionsXaxisMin = {0.000000,inf="Minimum X-Achse, MQTT: -t <mqttRoot>/options/xaxis/min -m 0"};
|
||||
panel.OptionsXaxis_1_Max = {15.000000,inf="Maximum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/max -m 15"};
|
||||
panel.OptionsXaxis_2_Max = {30.000000,inf="Maximum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/max -m 30"};
|
||||
panel.OptionsXaxis_2_Min = {0.000000,inf="Minimum Y-Achse 2, MQTT: -t <mqttRoot>/options/yaxis/1/min -m 0"};
|
||||
panel.OptionsYaxis_1_Min = {0.000000,inf="Minimum Y-Achse 1, MQTT: -t <mqttRoot>/options/yaxis/0/min -m 0"};
|
||||
panel.TextSendMessage = {"ping",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/message -m 'ping'"};
|
||||
panel.TextSendTopic = {"/ctrl/cmd",inf="Beschriftung Panel Button 1, MQTT: -t <mqttRoot>/text/send/topic -m 'ctrl/cmd'"};
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
function doRead()
|
||||
local loops = 0
|
||||
while loops < 100 do
|
||||
loops = loops + 1
|
||||
if serial:poll(1) then
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
--print(c.." at "..posX.." "..posY.."\n")
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
local label = line[posY+1][posX+1]
|
||||
label:setText(c)
|
||||
label:draw()
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function setup()
|
||||
serial = Serial("/dev/ttyAMA0",19200)
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4," ");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(mono)
|
||||
line[1][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
doRead()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+1)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData then
|
||||
line[posY+1]:setText(strData);
|
||||
line[posY+1]:draw()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i]:setTextColor(HMI.Color.green);
|
||||
line[i]:setBackground(HMI.Color.black);
|
||||
line[i]:setFont(mono)
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
panel = {}
|
||||
require "panel"
|
||||
|
||||
socket = require('socket')
|
||||
PLC = require('vwago')
|
||||
Scheduler = require('scheduler')
|
||||
--I2CClass = require('periphery').I2C
|
||||
I2CDevice = nil;
|
||||
MQTT = require("mqtt")
|
||||
|
||||
daq = {};
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg)
|
||||
print(msg);
|
||||
end
|
||||
|
||||
local function pubPanelConfig()
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/send",panel.LabelButtonSend[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/0",panel.LabelButton_1[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/1",panel.LabelButton_2[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/2",panel.LabelButton_3[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/button/3",panel.LabelButton_4[1])
|
||||
MQTT.publish(mqttRoot.."/panel/label/header",panel.LabelHeader[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/samples",panel.OptionsSamples[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/max",panel.OptionsXaxisMax[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/xaxis/min",panel.OptionsXaxisMin[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/max",panel.OptionsXaxis_1_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/max",panel.OptionsXaxis_2_Max[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/1/min",panel.OptionsXaxis_2_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/options/yaxis/0/min",panel.OptionsYaxis_1_Min[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/message", panel.TextSendMessage[1])
|
||||
MQTT.publish(mqttRoot.."/panel/text/send/topic",panel.TextSendTopic[1])
|
||||
MQTT.publish(mqttRoot.."/panel/debug",panel.Debug["alt"][panel.Debug["idx"]])
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.publish(mqttRoot.."/info", "PIALU")
|
||||
MQTT.subscribe(mqttRoot.."/ctrl/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message "..topic, payload)
|
||||
|
||||
subTopic = string.match(topic,mqttRoot.."/ctrl/(%w+)")
|
||||
if subTopic then
|
||||
if subTopic == "cmd" then
|
||||
logPrint("MQTT:\t Command");
|
||||
analogChannel = string.match(topic,mqttRoot.."/ctrl/cmd/analog/(%w)")
|
||||
if analogChannel then
|
||||
|
||||
if analogChannel == "0" then
|
||||
logPrint("MQTT:\t Command Analog Channel "..analogChannel.." "..payload);
|
||||
if payload == "on" then
|
||||
channel_0 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
else
|
||||
channel_0 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "off",true)
|
||||
end
|
||||
elseif analogChannel == "1" then
|
||||
if payload == "on" then
|
||||
channel_1 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
else
|
||||
channel_1 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "off",true)
|
||||
end
|
||||
elseif analogChannel == "2" then
|
||||
if payload == "on" then
|
||||
channel_2 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
else
|
||||
channel_2 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "off",true)
|
||||
end
|
||||
elseif analogChannel == "3" then
|
||||
if payload == "on" then
|
||||
channel_3 = true
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
else
|
||||
channel_3 = false
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "off",true)
|
||||
end
|
||||
end
|
||||
elseif string.match(topic,mqttRoot.."/ctrl/cmd/panel/config") then
|
||||
if string.match(payload,"publish") then
|
||||
pubPanelConfig()
|
||||
elseif string.match(payload,"apply") then
|
||||
panel = {}
|
||||
dofile("panel.lua")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local function getInt32(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 4) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8) + bit32.lshift(bytes[offset+3],16) + bit32.lshift(bytes[offset+4],24);
|
||||
if ( num > 0x80000000 ) then
|
||||
return num - 0x100000000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getInt16(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 2) then
|
||||
num = bytes[offset+1] + bit32.lshift(bytes[offset+2],8);
|
||||
end
|
||||
|
||||
if ( num > 0x8000 ) then
|
||||
return num - 0x10000;
|
||||
else
|
||||
return num;
|
||||
end
|
||||
|
||||
return 9999999999;
|
||||
end
|
||||
|
||||
local function getUint8(bytes,offset)
|
||||
if (offset >= 0) and ((#bytes-offset) >= 1) then
|
||||
return bytes[offset+1];
|
||||
end
|
||||
|
||||
return 999999999;
|
||||
end
|
||||
--[[
|
||||
local function i2cBegin()
|
||||
I2CDevice = I2CClass("/dev/i2c-1")
|
||||
end
|
||||
|
||||
local function i2cRecvMsg()
|
||||
local msg = {{
|
||||
0x00, -- uint8_t hartbeat;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
0x00, 0x00, 0x00, 0x00, -- int32_t data_32;
|
||||
flags = I2CClass.I2C_M_RD
|
||||
}}
|
||||
I2CDevice:transfer(6, msg)
|
||||
-- print(table.unpack(msg[1]));
|
||||
return msg[1]
|
||||
end
|
||||
|
||||
local function i2cSendMsg(cmd)
|
||||
local msg = {{cmd, 0x00, 0x00, 0x00, 0x00, flags = 0}}
|
||||
I2CDevice:transfer(4, msg)
|
||||
end
|
||||
--]]
|
||||
local function recv()
|
||||
--[[
|
||||
daqData = i2cRecvMsg();
|
||||
-- print(table.unpack(daqData));
|
||||
daq.hartbeat = getUint8(daqData,0);
|
||||
daq.sum0 = getInt32(daqData,1);
|
||||
daq.sum1 = getInt32(daqData,5);
|
||||
daq.sum2 = getInt32(daqData,9);
|
||||
daq.sum3 = getInt32(daqData,13);
|
||||
--]]
|
||||
daq.hartbeat = 123;
|
||||
daq.sum0 = 3;
|
||||
daq.sum1 = 1.7;
|
||||
daq.sum2 = 9;
|
||||
daq.sum3 = 5.5;
|
||||
end
|
||||
|
||||
function setup()
|
||||
mqttBroker = app.mqttBroker[1]
|
||||
mqttRoot = app.mqttRoot[1]
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,32,24);
|
||||
|
||||
label = HMI.Label(layout,0,0,32,3,"Plot");
|
||||
label:setTextColor(HMI.Color.white);
|
||||
label:setBackground(HMI.Color.blue);
|
||||
|
||||
chart = HMI.Timechart(layout,0,4,32,16)
|
||||
chart:setBaseline(0)
|
||||
chart:setValuePerDivison(2)
|
||||
chart:setSamplesPerDivison(20)
|
||||
chart:setSamplesFormat("%d Samples/Div, Samplerate 0.5s <=> 10 Sekunden/Div")
|
||||
|
||||
txt0 = HMI.Label(layout, 1,20,6,2,"Ch 0");
|
||||
txt0:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt1 = HMI.Label(layout,17,20,6,2,"Ch 1");
|
||||
txt1:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt2 = HMI.Label(layout, 1,22,6,2,"Ch 2");
|
||||
txt2:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
txt3 = HMI.Label(layout,17,22,6,2,"Ch 3");
|
||||
txt3:getTextObject():setAlign(HMI.ALIGN_LEFT);
|
||||
|
||||
out0 = HMI.Output(layout, 7,20,6,2,"0000");
|
||||
out1 = HMI.Output(layout,23,20,6,2,"0000");
|
||||
out2 = HMI.Output(layout, 7,22,6,2,"0000");
|
||||
out3 = HMI.Output(layout,23,22,6,2,"0000");
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
|
||||
-- i2cBegin()
|
||||
|
||||
if mqttBroker then
|
||||
errLog("MQTT:\t Begin\n");
|
||||
MQTT.begin(mqttBroker)
|
||||
end
|
||||
|
||||
MQTT.loop()
|
||||
|
||||
channel_0 = true;
|
||||
channel_1 = true;
|
||||
channel_2 = true;
|
||||
channel_3 = true;
|
||||
|
||||
MQTT.publish(mqttRoot.."/status/analog/0", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/1", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/2", "on",true)
|
||||
MQTT.publish(mqttRoot.."/status/analog/3", "on",true)
|
||||
end
|
||||
|
||||
function loop()
|
||||
MQTT.loop()
|
||||
|
||||
if updateTimer.elapsed() then
|
||||
updateTimer.restart()
|
||||
recv()
|
||||
|
||||
val0 = daq.sum0*0.0000707750682632
|
||||
val1 = daq.sum1*0.0000707750682632
|
||||
val2 = daq.sum2*0.0000208350713273
|
||||
val3 = daq.sum3*0.0000208350713273
|
||||
|
||||
out0:setText(string.format("%5.2f",val0))
|
||||
out1:setText(string.format("%5.2f",val1))
|
||||
out2:setText(string.format("%5.2f",val2))
|
||||
out3:setText(string.format("%5.2f",val3))
|
||||
chart:plot(daq.sum0*0.0000707750682632)
|
||||
--chart:plot(daq.sum1*0.0000707750682632)
|
||||
--chart:plot(daq.sum2*0.0000208350713273)
|
||||
--chart:plot(daq.sum3*0.0000208350713273)
|
||||
|
||||
compound = ""
|
||||
|
||||
if channel_0 then
|
||||
MQTT.publish(mqttRoot.."/analog/0",val0)
|
||||
compound = compound..",0:"..val0
|
||||
end
|
||||
if channel_1 then
|
||||
MQTT.publish(mqttRoot.."/analog/1",val1)
|
||||
compound = compound..",1:"..val1
|
||||
end
|
||||
if channel_2 then
|
||||
MQTT.publish(mqttRoot.."/analog/2",val2)
|
||||
compound = compound..",2:"..val2
|
||||
end
|
||||
if channel_3 then
|
||||
MQTT.publish(mqttRoot.."/analog/3",val3)
|
||||
compound = compound..",3:"..val3
|
||||
end
|
||||
all = string.sub(compound,2)
|
||||
if string.len(all) > 0 then
|
||||
MQTT.publish(mqttRoot.."/analog/all",all)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
-- LUA default run file
|
||||
|
||||
-- LUA default run file
|
||||
|
||||
require "env"
|
||||
MQTT = require("mqtt")
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
LOGING = 1
|
||||
|
||||
local function errLog(msg)
|
||||
io.stderr:write(msg)
|
||||
end
|
||||
|
||||
function logPrint(msg,aux)
|
||||
if ( LOGING ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dbgPrint(msg,aux)
|
||||
if ( DEBUG ) then
|
||||
if aux then
|
||||
print(msg.." , "..aux)
|
||||
else
|
||||
print(msg);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MQTT.onConnect (
|
||||
function()
|
||||
errLog("MQTT:\t Connect\n");
|
||||
MQTT.subscribe("+/#")
|
||||
end
|
||||
)
|
||||
|
||||
MQTT.onMessage (
|
||||
function(mid, topic, payload)
|
||||
logPrint("MQTT:\t Message <"..topic..">", payload)
|
||||
--posY,posX,strData,attrData = string.match(payload,"(%d+)|(%d+)|([^|])|([^|])")
|
||||
posY,posX,rawData = string.match(payload,"(%d+)|(%d+)|(.+)")
|
||||
strData=string.sub(rawData,1,string.len(rawData)/2)
|
||||
attrData=string.sub(rawData,string.len(rawData)/2+2)
|
||||
print(posY.."|"..posX.."|"..strData.."|"..attrData.."\n")
|
||||
if posY and posX and strData and attrData then
|
||||
local len = string.len(strData)
|
||||
for j=1, len, 1 do
|
||||
local label = line[posY+1][posX+j]
|
||||
if attrData:sub(j,j) == 'b' then
|
||||
label:setTextColor(HMI.Color.black);
|
||||
label:setBackground(HMI.Color.green);
|
||||
else
|
||||
label:setTextColor(HMI.Color.green);
|
||||
label:setBackground(HMI.Color.black);
|
||||
end
|
||||
label:setText(strData:sub(j,j))
|
||||
label:draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function setup()
|
||||
|
||||
if app.mqttBroker then
|
||||
MQTT.begin(app.mqttBroker[1])
|
||||
end
|
||||
MQTT.loop()
|
||||
|
||||
instance = HMI.App.instance;
|
||||
layout = HMI.Layout(instance,200,48);
|
||||
|
||||
mono = HMI.Font("/root/font/mono.ttf",34)
|
||||
|
||||
line = {}
|
||||
for i=1, 6, 1 do
|
||||
line[i] = {}
|
||||
for j=1, 40, 1 do
|
||||
line[i][j] = HMI.Label(layout,5*(j-1),8+4*(i-1),5,4,j%10);
|
||||
-- line[i] = HMI.Label(layout,0,8+4*(i-1),200,4,"1234567890123456789012345678901234567890");
|
||||
line[i][j]:setTextColor(HMI.Color.green);
|
||||
line[i][j]:setBackground(HMI.Color.black);
|
||||
line[i][j]:setFont(mono)
|
||||
line[1][j]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
number = {}
|
||||
for i=1, 10, 1 do
|
||||
number[i] = HMI.Cell(layout,1+20*(i-1),0,20,7,i-1);
|
||||
number[i]:setTextColor(HMI.Color.black);
|
||||
number[i]:setBackground(HMI.Color.grey);
|
||||
number[i]:setFont(mono)
|
||||
end
|
||||
|
||||
control = {}
|
||||
for j=0, 1, 1 do
|
||||
for i=1, 10, 1 do
|
||||
control[i+j] = HMI.Cell(layout,1+20*(i-1),34+j*7,20,7,i-1);
|
||||
control[i+j]:setTextColor(HMI.Color.black);
|
||||
control[i+j]:setBackground(HMI.Color.grey);
|
||||
control[i+j]:setFont(mono)
|
||||
end
|
||||
end
|
||||
|
||||
updateTimer = Scheduler.Timer(500)
|
||||
cnt = 0;
|
||||
end
|
||||
|
||||
function loop()
|
||||
--[[
|
||||
if updateTimer.elapsed() then
|
||||
line[1]:setText(string.format("%5.2f",cnt))
|
||||
line[1]:draw()
|
||||
cnt = cnt + 1
|
||||
updateTimer.restart()
|
||||
end
|
||||
--]]
|
||||
MQTT.loop()
|
||||
end
|
||||
|
||||
io.stderr:write("Run LUA\n");
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
local scheduler = {}
|
||||
|
||||
socket = require('socket')
|
||||
|
||||
function scheduler.Timer(init)
|
||||
-- the new instance
|
||||
|
||||
local self = {
|
||||
-- public fields go in the instance table
|
||||
interval = init
|
||||
}
|
||||
|
||||
local function millis()
|
||||
return socket.gettime()*1000
|
||||
end
|
||||
|
||||
-- private fields are implemented using locals
|
||||
-- they are faster than table access, and are truly private,
|
||||
-- so the code that uses your class can't get them
|
||||
|
||||
local _timestamp = millis()
|
||||
local _running = true
|
||||
|
||||
function self.elapsed()
|
||||
if _running and (millis() - _timestamp ) >= self.interval then
|
||||
_running = false
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function self.running()
|
||||
return (millis() - _timestamp ) < self.interval
|
||||
end
|
||||
|
||||
function self.restart()
|
||||
_timestamp = millis()
|
||||
_running = true
|
||||
end
|
||||
|
||||
function self.count()
|
||||
return millis() - timestamp
|
||||
end
|
||||
|
||||
-- return the instance
|
||||
return self
|
||||
end
|
||||
|
||||
return scheduler
|
||||
@@ -1,599 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
struct = require('struct')
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local T1 = 300
|
||||
local T2 = 1000
|
||||
local T3 = 3000
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local serial
|
||||
local host = false
|
||||
local connected = false
|
||||
local pending = false
|
||||
local transaction_id = 1
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
|
||||
parseData(msg,buf,11,100);
|
||||
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
-- io.stderr:write("packList type("..type(l)..")\n")
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secaId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
pending = true
|
||||
transactionTimer.restart()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = 0; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("SxF0\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,h.s_stream,0)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("S1F1\n----\n")
|
||||
|
||||
return {
|
||||
primaryHeader(1,1)
|
||||
}
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,2),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
primaryHeader(1,13),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {
|
||||
secondaryHeader(h,1,14),
|
||||
packList( {
|
||||
packBinary(0),
|
||||
packList( {
|
||||
packString(MDLN),
|
||||
packString(SOFTREV)
|
||||
} )
|
||||
} )
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(ppid,mid1,mid2,mid3)
|
||||
io.stderr:write("S2F41("..ppid..","..mid1..","..mid2..","..mid3..")\n----\n")
|
||||
|
||||
if host then
|
||||
return {
|
||||
primaryHeader(2,41),
|
||||
packList( {
|
||||
packString("START"),
|
||||
packList( {
|
||||
packList( {
|
||||
packString("PPID"),
|
||||
packString(ppid)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID1"),
|
||||
packString(mid1)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID2"),
|
||||
packString(mid2)
|
||||
} ),
|
||||
packList( {
|
||||
packString("MID3"),
|
||||
packString(mid3)
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
}
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("S2F42\n----\n")
|
||||
|
||||
return {
|
||||
secondaryHeader(h,2,42),
|
||||
packList( {
|
||||
packBinary(4),
|
||||
packList({}) -- empty list
|
||||
} )
|
||||
}
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
|
||||
return {
|
||||
secondaryHeader(h,6,12),
|
||||
packBinary(0)
|
||||
}
|
||||
else
|
||||
secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
end
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function sendMsg(msg)
|
||||
|
||||
local buf = table.concat(msg);
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(chksum / 256))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I: NAK Received\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: AKN Timeout\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I: EOT Timeout\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("receiveMsg\n----------\ncount: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
-- TODO checksum error handling
|
||||
|
||||
-- hexDumpString(buf);
|
||||
|
||||
serial:write(ASCII_ACK)
|
||||
|
||||
msg = parseMsg(buf)
|
||||
-- dumpMsg(msg)
|
||||
|
||||
return msg
|
||||
else
|
||||
io.stderr:write("SECS I: Countbyte Timeout\n")
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
local request = {}
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
|
||||
request = receiveMsg()
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
pending = false;
|
||||
end
|
||||
|
||||
msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
sendMsg(S1F2(request.header))
|
||||
SECS.onPrimary(1,1,"are you there")
|
||||
elseif isSF(request,1,2) then
|
||||
SECS.onSecondary(1,2,"are you there akn")
|
||||
elseif isSF(request,1,13) then
|
||||
sendMsg(S1F14(request.header))
|
||||
connected = true;
|
||||
SECS.onPrimary(1,13,"establish communication request")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
SECS.onSecondary(1,14,"establish communication request akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S2F42(request.header))
|
||||
SECS.onPrimary(2,41,"host command send")
|
||||
elseif isSF(request,2,42) then
|
||||
SECS.onSecondary(2,42,"host command send akn")
|
||||
elseif isSF(request,6,11) then
|
||||
SECS.onProcessMsg(msg)
|
||||
sendMsg(S6F12(request.header))
|
||||
SECS.onPrimary(6,11,"event report send")
|
||||
elseif isSF(request,6,12) then
|
||||
--
|
||||
SECS.onSecondary(6,12,"event report send akn")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
sendMsg(SxF0(request.header))
|
||||
SECS.onPrimary(0,0,"abort transaction akn")
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write("loop poll:"..string.byte(c).."\n")
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("loop poll: Transaction timeout\n")
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
|
||||
end
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature= msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isPending = function() return pending end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() sendMsg(S1F13()) end;
|
||||
sendS1F1 = function() sendMsg(S1F1()) end;
|
||||
sendS2F41 = function(a1,a2,a3,a4) sendMsg(S2F41(a1,a2,a3,a4)) end;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
|
||||
Serial = periphery.Serial
|
||||
|
||||
Scheduler = require('scheduler')
|
||||
|
||||
local T1 = 100 --300
|
||||
local T2 = 2000 --1000
|
||||
local T3 = 5000 --3000
|
||||
|
||||
local ASCII_EOT = "\x04" -- end of transmission
|
||||
local ASCII_ENQ = "\x05" -- enquiary
|
||||
local ASCII_ACK = "\x06" -- acknowledge
|
||||
local ASCII_NAK = "\x15" -- negative acknowledge
|
||||
|
||||
local pending = false
|
||||
local reading = false
|
||||
local writing = false
|
||||
|
||||
local serial
|
||||
|
||||
local onProcessRequest;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
local function hexDumpString(buf)
|
||||
if buf then
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
end
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
function begin(device, baud)
|
||||
serial = Serial(device,baud)
|
||||
transactionTimer = Scheduler.Timer(T3)
|
||||
end
|
||||
|
||||
local function discardInput()
|
||||
hexDumpString(buf);
|
||||
io.stderr:write("SECS I:\t Discard input: ")
|
||||
while serial:poll(100) do
|
||||
c = serial:read(1)
|
||||
io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function sendMsg(buf)
|
||||
|
||||
-- hexDumpString(buf)
|
||||
|
||||
writing = true
|
||||
serial:write(ASCII_ENQ)
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
|
||||
if c == ASCII_EOT then
|
||||
serial:write(string.char(#buf))
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
|
||||
for i=1, #buf do
|
||||
serial:write(string.char(buf:byte(i)))
|
||||
chksum = chksum + buf:byte(i);
|
||||
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
|
||||
end
|
||||
|
||||
serial:write(string.char(math.floor(chksum / 256)))
|
||||
serial:write(string.char(chksum % 256))
|
||||
|
||||
if serial:poll(T1) then
|
||||
c = serial:read(1)
|
||||
if not (c == ASCII_ACK) then
|
||||
io.stderr:write("SECS I:\t NAK Received\n")
|
||||
--discardInput()
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t AKN Timeout\n")
|
||||
discardInput()
|
||||
end
|
||||
writing = false
|
||||
end
|
||||
else
|
||||
io.stderr:write("SECS I:\t EOT Timeout\n")
|
||||
discardInput()
|
||||
writing = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function receiveMsg()
|
||||
serial:write(ASCII_EOT)
|
||||
|
||||
reading = true
|
||||
if serial:poll(T1) then
|
||||
local cnt = string.byte(serial:read(1))
|
||||
io.stderr:write("SECS I:\t receiveMsg count: "..cnt.."\n")
|
||||
|
||||
local buf = serial:read(cnt+2,10*T1)
|
||||
|
||||
local chksum = 0 -- 0 normal, 1 force error
|
||||
for i=1, #buf-2 do
|
||||
chksum = chksum + buf:byte(i)
|
||||
end
|
||||
|
||||
local msgChksum = buf:byte(#buf-1)*256 + buf:byte(#buf)
|
||||
|
||||
if msgChksum == chksum then
|
||||
serial:write(ASCII_ACK)
|
||||
return buf
|
||||
else
|
||||
io.stderr:write("SECS I:\t Checksum Error\n")
|
||||
hexDumpString(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
discardInput()
|
||||
--io.stderr:write(string.format("SECS I:\t Checksum: %04X %04X\n",chksum,msgChksum))
|
||||
io.stderr:write(string.format("SECS I:\t Bytes: %d Checksum: %04X %04X\n",#buf,chksum,msgChksum))
|
||||
return ""
|
||||
end
|
||||
reading = false
|
||||
else
|
||||
io.stderr:write("SECS I:\t Countbyte Timeout\n")
|
||||
discardInput()
|
||||
reading = false
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function poll()
|
||||
|
||||
if ( serial:poll(T1) ) then
|
||||
c = serial:read(1)
|
||||
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
|
||||
if c == ASCII_ENQ then
|
||||
local buf=receiveMsg()
|
||||
if #buf >= 11 then
|
||||
onProcessRequest(buf)
|
||||
else
|
||||
io.stderr:write("SECS I:\t Poll error bytes: "..#buf.."\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
end
|
||||
elseif c == ASCII_NAK then
|
||||
io.stderr:write("SECS I:\t Poll NAK received\n")
|
||||
--discardInput()
|
||||
pending = false
|
||||
else
|
||||
---- TODO: Illegal byte, skip input send NAK ----
|
||||
io.stderr:write(string.format("SECS I:\t Poll error byte = %02X\n",string.byte(c)))
|
||||
discardInput()
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false
|
||||
end
|
||||
else
|
||||
if pending and transactionTimer.elapsed() then
|
||||
---- TODO: Timeout, skip input send NAK ----
|
||||
io.stderr:write("SECS I:\t Poll transaction timeout\n")
|
||||
discardInput(buf)
|
||||
serial:write(ASCII_NAK)
|
||||
pending = false;
|
||||
end
|
||||
end
|
||||
|
||||
io.stderr:flush();
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
poll = poll;
|
||||
sendMsg = sendMsg;
|
||||
receiveMsg = receiveMsg;
|
||||
isReading = function() return reading end;
|
||||
isWriting = function() return writing end;
|
||||
isPending = function() return pending end;
|
||||
onProcessRequest = function(cb) onProcessRequest = cb end;
|
||||
startTransaction = function() transactionTimer.restart(); pending = true end;
|
||||
stopTransaction = function() pending = false end;
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
---------------------------- SECS I / SECS II ----------------------------------
|
||||
|
||||
SECS_IO = require('secs_i')
|
||||
struct = require('struct')
|
||||
|
||||
local SF_LIST = 0x00
|
||||
local SF_NITEMS = 0x1F
|
||||
local SF_BINARY = 0x20
|
||||
local SF_BOOLEAN = 0x24
|
||||
local SF_ASCII = 0x40
|
||||
local SF_JIS_8 = 0x44
|
||||
local SF_INT8 = 0x60
|
||||
local SF_INT1 = 0x64
|
||||
local SF_INT2 = 0x68
|
||||
local SF_INT4 = 0x70
|
||||
local SF_FLOAT8 = 0x80
|
||||
local SF_FLOAT4 = 0x90
|
||||
local SF_UINT8 = 0xA0
|
||||
local SF_UINT1 = 0xA4
|
||||
local SF_UINT2 = 0xA8
|
||||
local SF_UINT4 = 0xB0
|
||||
|
||||
local MDLN = "DS-80B"
|
||||
local SOFTREV = "MI370E"
|
||||
|
||||
local secsId = 0x1234
|
||||
local host = false
|
||||
local connected = false
|
||||
|
||||
local transaction_id = 1
|
||||
|
||||
local eq_online = 3 -- 1: online remote, 2: online local, 3: offline
|
||||
local eq_status = 2 -- 1: not ready, 2: ready, 3: busy, 4: process cmpl, 5: pause, 6: complete
|
||||
|
||||
local onSendEventMsg = nil
|
||||
local onPrimaryMsg = nil
|
||||
local onSecondaryMsg = nil
|
||||
local onProcessMsg = nil
|
||||
|
||||
local msgQueue = {}
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
local function hexDumpString(buf)
|
||||
for i=1,math.ceil(#buf/16) * 16 do
|
||||
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
|
||||
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
|
||||
if i % 8 == 0 then io.stderr:write(' ') end
|
||||
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
|
||||
end
|
||||
io.stderr:write("\n");
|
||||
end
|
||||
|
||||
local function dumpData(items)
|
||||
if items.list then
|
||||
io.stderr:write(string.format("list: %d\n",#items))
|
||||
end
|
||||
for i=1, #items do
|
||||
if not items.list then
|
||||
if i == 1 then
|
||||
io.stderr:write(string.format("type: "..items[1].."\n"));
|
||||
io.stderr:write(string.format("value: "..items[2].."\n"));
|
||||
end
|
||||
else
|
||||
dumpData(items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dumpMsg(msg)
|
||||
io.stderr:write("dumpMsg\n-------\n")
|
||||
io.stderr:write(string.format("id: %02X\n", msg.header.secsId))
|
||||
io.stderr:write(string.format("reverse:%s\n", msg.header.secsReverse))
|
||||
io.stderr:write(string.format("stream: %02X\n", msg.header.secsStream))
|
||||
io.stderr:write(string.format("func: %02X\n", msg.header.secsFunction))
|
||||
io.stderr:write(string.format("blkn: %02X\n", msg.header.secsBlock))
|
||||
io.stderr:write(string.format("sys1: %04X\n", msg.header.secsSys1))
|
||||
io.stderr:write(string.format("sys2: %04X\n", msg.header.secsSys2))
|
||||
if #msg > 0 then
|
||||
dumpData(msg[1])
|
||||
end
|
||||
io.stderr:write("\n")
|
||||
end
|
||||
|
||||
local function appendData(values,types,items)
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
appendData(values,types,items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
table.insert(types,items[i])
|
||||
else
|
||||
table.insert(values,items[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function msgData(msg)
|
||||
local values = {}
|
||||
local types = {}
|
||||
|
||||
if #msg > 0 then
|
||||
appendData(values,types,msg[1])
|
||||
end
|
||||
|
||||
return values,types;
|
||||
end
|
||||
|
||||
local function dataSignature(items)
|
||||
local sig = ""
|
||||
|
||||
if items.list then
|
||||
sig = string.format("L%d",#items)
|
||||
end
|
||||
|
||||
for i=1, #items do
|
||||
if items.list then
|
||||
sig = sig..dataSignature(items[i])
|
||||
else
|
||||
if i == 1 then
|
||||
sig = sig..string.format(items[i]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
|
||||
local function msgSignature(msg)
|
||||
local sig = ""
|
||||
|
||||
if #msg > 0 then
|
||||
sig = dataSignature(msg[1])
|
||||
end
|
||||
|
||||
return sig
|
||||
end
|
||||
--[[
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
-- io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
len = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
-- io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,len))
|
||||
len = buf:byte(idx+1);
|
||||
-- io.stderr:write(string.format("DATA LEN: %02X\n",len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + 2;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + 4;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + 8;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
-- io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
--]]
|
||||
|
||||
local function parseData(items,buf,idx,cnt)
|
||||
local len ;
|
||||
local code;
|
||||
|
||||
io.stderr:write(string.format("IN: %d\n",idx))
|
||||
while (idx < #buf - 2) and (cnt>0) do
|
||||
io.stderr:write(string.format("IDX: %d\n",idx))
|
||||
num = bit32.band(buf:byte(idx),0x03);
|
||||
code = bit32.band(buf:byte(idx),0xFC);
|
||||
io.stderr:write(string.format("CODE: %02X LEN: %02X\n",code,num))
|
||||
len = buf:byte(idx+1);
|
||||
io.stderr:write(string.format("DATA LEN: %02X %03d\n",len,len))
|
||||
cnt = cnt - 1;
|
||||
if code == SF_LIST then
|
||||
local list = {}
|
||||
list.list = true
|
||||
idx = parseData(list,buf,idx+2,len)
|
||||
table.insert(items,list)
|
||||
elseif code == SF_ASCII then
|
||||
table.insert(items,{"A",buf:sub(idx+2,idx+1+len)})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT1 then
|
||||
table.insert(items,{"I1",struct.unpack(">b",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT2 then
|
||||
table.insert(items,{"I2",struct.unpack(">h",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"I4",struct.unpack(">i",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT8 then
|
||||
table.insert(items,{"I8",struct.unpack(">l",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT1 then
|
||||
table.insert(items,{"U1",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT2 then
|
||||
table.insert(items,{"U2",struct.unpack(">H",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_INT4 then
|
||||
table.insert(items,{"U4",struct.unpack(">I",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_UINT8 then
|
||||
table.insert(items,{"U8",struct.unpack(">L",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BOOLEAN then
|
||||
table.insert(items,{"BOOL",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
elseif code == SF_BINARY then
|
||||
table.insert(items,{"B",struct.unpack(">B",buf:sub(idx+2))})
|
||||
idx = idx + len + num + 1;
|
||||
-- elseif TODO more formats
|
||||
end
|
||||
end
|
||||
io.stderr:write(string.format("OUT: %d\n",idx))
|
||||
return idx;
|
||||
end
|
||||
|
||||
local function unpackHeader(b)
|
||||
local h = {}
|
||||
h.secsId, h.secsStream, h.secsFunction, h.secsBlock, h.secsSys1, h.secsSys2 = struct.unpack('>HBBHHH',b)
|
||||
h.secsReverse = h.secsId > 0x8000;
|
||||
h.secsId = bit32.band(h.secsId,0x7FFF);
|
||||
h.secsWait = h.secsStream > 0x80;
|
||||
h.secsStream = bit32.band(h.secsStream,0x7F);
|
||||
h.secsEnd = h.secsBlock > 0x8000;
|
||||
h.secsBlock = bit32.band(h.secsBlock,0x7FFF);
|
||||
|
||||
return h;
|
||||
end
|
||||
|
||||
local function parseMsg(buf)
|
||||
local msg = {};
|
||||
local len = 0;
|
||||
local code = 0;
|
||||
|
||||
msg.header = unpackHeader(buf);
|
||||
msg.list = false;
|
||||
parseData(msg,buf,11,#buf);
|
||||
return msg;
|
||||
end
|
||||
|
||||
local function packHeader(h)
|
||||
return struct.pack('>HBBHHH',
|
||||
( h.secsReverse and bit32.bor(h.secsId, 0x8000) or h.secsId ),
|
||||
( h.secsWait and bit32.bor(h.secsStream, 0x80) or h.secsStream ),
|
||||
h.secsFunction,
|
||||
( h.secsEnd and bit32.bor(h.secsBlock, 0x8000) or h.secsBlock),
|
||||
h.secsSys1,
|
||||
h.secsSys2
|
||||
)
|
||||
end
|
||||
|
||||
local function packString(s)
|
||||
return struct.pack('BB',SF_ASCII+1,#s)..s
|
||||
end
|
||||
|
||||
local function packBinary(b)
|
||||
return struct.pack('BBB',SF_BINARY+1,1,b)
|
||||
end
|
||||
|
||||
local function packList(l)
|
||||
return struct.pack('BB',SF_LIST+1,#l)..table.concat(l)
|
||||
end
|
||||
|
||||
local function secondaryHeader(h,s,f)
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- secondary Message SsFf
|
||||
h.secsWait = false; -- no reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
local function primaryHeader(s,f)
|
||||
-- SECS_IO.startTransaction()
|
||||
|
||||
local h = {}
|
||||
|
||||
h.secsId = secsId; --
|
||||
h.secsReverse = not host -- false: host --> equipment
|
||||
|
||||
h.secsStream = s;
|
||||
h.secsFunction = f; -- primary Message SsFf
|
||||
h.secsWait = true; -- reply
|
||||
|
||||
h.secsBlock = 1;
|
||||
h.secsEnd = true; -- last block
|
||||
h.secsSys1 = 0
|
||||
h.secsSys2 = transaction_id;
|
||||
|
||||
transaction_id = transaction_id + 1
|
||||
|
||||
return packHeader(h);
|
||||
end
|
||||
|
||||
function string.pop(s)
|
||||
return string.sub(s,1,1),string.sub(s,2)
|
||||
end
|
||||
|
||||
function table.pop(t)
|
||||
local i = t[1]
|
||||
table.remove(t,1)
|
||||
return i,t
|
||||
end
|
||||
|
||||
local function packData(sig,items)
|
||||
local buf = ""
|
||||
|
||||
-- print("packData sig: ",sig)
|
||||
while #sig > 0 do
|
||||
-- print("packData len1: ",#sig)
|
||||
typ, sig = string.pop(sig)
|
||||
-- print("packData len2: ",#sig,typ,sig)
|
||||
if typ == "L" then
|
||||
len , sig = string.pop(sig)
|
||||
-- print("packData len3: ",#sig,len,sig)
|
||||
buf = buf..struct.pack('BB',SF_LIST+1,len)..packData(sig,items)
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
elseif typ == "A" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packString(item)
|
||||
elseif typ == "B" then
|
||||
item, items = table.pop(items)
|
||||
buf = buf..packBinary(item)
|
||||
end
|
||||
end
|
||||
-- hexDumpString(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
local function primaryMsg(s,f,sig,items)
|
||||
return primaryHeader(s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
local function secondaryMsg(h,s,f,sig,items)
|
||||
return secondaryHeader(h,s,f)..packData(sig,items)
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function SxF0(h)
|
||||
io.stderr:write("\nSECS II: SxF0\n----\n")
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
local function S1F1()
|
||||
io.stderr:write("\nSECS II: S1F1\n----\n")
|
||||
return primaryHeader(1,1)
|
||||
end
|
||||
|
||||
local function S1F2(h)
|
||||
io.stderr:write("\nSECS II: S1F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,2,"L0",{})
|
||||
else
|
||||
return secondaryMsg(h,1,2,"L2AA",{MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F13()
|
||||
io.stderr:write("\nSECS II: S1F13\n----\n")
|
||||
|
||||
if host then
|
||||
return primaryMsg(1,13,"L2BL0",{0})
|
||||
else
|
||||
return primaryMsg(1,13,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S1F14(h)
|
||||
io.stderr:write("\nSECS II: S1F14\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,1,14,"L2BL0",{0})
|
||||
else
|
||||
return secondaryMsg(h,1,14,"L2BL2AA",{0,MDLN,SOFTREV})
|
||||
end
|
||||
end
|
||||
|
||||
local function S2F41(c)
|
||||
|
||||
io.stderr:write("\nSECS II: S2F41("..c..")\n----\n")
|
||||
if host then
|
||||
return onCreateMsg(2,41,c)
|
||||
else
|
||||
return "" -- host only command
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S2F42(h)
|
||||
io.stderr:write("\nSECS II: S2F42\n----\n")
|
||||
|
||||
return secondaryMsg(h,2,42,"L2BL0",{4})
|
||||
end
|
||||
|
||||
local function S5F2(h)
|
||||
io.stderr:write("\nSECS II: S5F2\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,5,2,"B",{0})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F12(h)
|
||||
io.stderr:write("\nSECS II: S6F12\n----\n")
|
||||
|
||||
if host then
|
||||
return secondaryMsg(h,6,12,"B",{0})
|
||||
else
|
||||
return secondaryHeader(h,h.secsStream,0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function S6F11(e)
|
||||
io.stderr:write("\nSECS II: S6F11("..e..")\n----\n")
|
||||
|
||||
if not host then
|
||||
return onCreateMsg(6,11,e)
|
||||
else
|
||||
return "" -- equipment only command
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------
|
||||
|
||||
local function isSF(msg,s,f)
|
||||
return msg.header.secsStream == s and msg.header.secsFunction == f
|
||||
end
|
||||
|
||||
local function isSxF0(msg)
|
||||
return msg.header.secsFunction == 0
|
||||
end
|
||||
|
||||
local function isS5Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 5
|
||||
end
|
||||
|
||||
local function isS9Fx(msg)
|
||||
dumpMsg(msg)
|
||||
return msg.header.secsStream == 9
|
||||
end
|
||||
|
||||
SECS_IO.onProcessRequest (
|
||||
function(buf)
|
||||
local request = parseMsg(buf)
|
||||
io.stderr:write("SECS II: ID: ",request.header.secsId,"\n")
|
||||
local s = request.header.secsStream
|
||||
local f = request.header.secsFunction
|
||||
io.stderr:write("SECS II: onProcessMsg ".."S"..s.."F"..f.."\n");
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
if not request.header.wait then
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
local sig = msgSignature(request)
|
||||
|
||||
if isSF(request,1,1) then
|
||||
onPrimaryMsg(1,1,"are you there received")
|
||||
SECS_IO.sendMsg(S1F2(request.header))
|
||||
elseif isSF(request,1,2) then
|
||||
onSecondaryMsg(1,2,"are you there received akn")
|
||||
elseif isSF(request,1,13) then
|
||||
connected = true;
|
||||
onPrimaryMsg(1,13,"establish communication request received")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
SECS_IO.sendMsg(S1F14(request.header))
|
||||
elseif isSF(request,1,14) then
|
||||
connected = true;
|
||||
onSecondaryMsg(1,14,"establish communication request received akn")
|
||||
--io.stderr:write(string.format("CONNECTED %d\n",request[1][1][2]));
|
||||
elseif isSF(request,2,41) then
|
||||
--print("SECS II: Message ",#request)
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(2,41,"host command received")
|
||||
SECS_IO.sendMsg(S2F42(request.header))
|
||||
elseif isSF(request,2,42) then
|
||||
onProcessMsg(request)
|
||||
onSecondaryMsg(2,42,"host command received akn")
|
||||
elseif isSF(request,6,11) then
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(6,11,"event report received")
|
||||
SECS_IO.sendMsg(S6F12(request.header))
|
||||
elseif isSF(request,6,12) then
|
||||
onSecondaryMsg(6,12,"event report received akn")
|
||||
elseif isS5Fx(request) then
|
||||
onProcessMsg(request)
|
||||
--hexDumpString(buf)
|
||||
--io.stderr:write("SIG: "..sig.."\n")
|
||||
onPrimaryMsg(5,request.header.secsFunction,"alarm received")
|
||||
SECS_IO.sendMsg(S5F2(request.header))
|
||||
elseif isS9Fx(request) then
|
||||
-- no secondary message
|
||||
onProcessMsg(request)
|
||||
onPrimaryMsg(9,request.header.secsFunction,"error received")
|
||||
else
|
||||
if not isSxF0(request) then
|
||||
onPrimaryMsg(0,0,"abort transaction send")
|
||||
SECS_IO.sendMsg(SxF0(request.header))
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function dequeMsg()
|
||||
local m = msgQueue[1]
|
||||
table.remove(msgQueue,1)
|
||||
return m
|
||||
end
|
||||
|
||||
local function queueMsg(msg)
|
||||
io.stderr:write("\n====\nSECS II: queueMsg\n====\n");
|
||||
table.insert(msgQueue,msg)
|
||||
end
|
||||
|
||||
local function poll()
|
||||
if not SECS_IO.isPending() and #msgQueue > 0 then
|
||||
-- if not pending and #msgQueue > 0 then
|
||||
io.stderr:write("\n====\nSECS II: dequeueMsg\n====\n");
|
||||
SECS_IO.startTransaction()
|
||||
SECS_IO.sendMsg(dequeMsg())
|
||||
end
|
||||
SECS_IO.poll()
|
||||
end;
|
||||
|
||||
local function setHost(mode)
|
||||
host = mode
|
||||
end
|
||||
|
||||
local function setId(id)
|
||||
secsId = id
|
||||
end
|
||||
|
||||
local function begin(device, baud)
|
||||
SECS_IO.begin(device,baud)
|
||||
io.stderr:write("begin\n")
|
||||
SECS_IO.stopTransaction()
|
||||
end
|
||||
|
||||
return {
|
||||
begin = begin;
|
||||
sendMsg = sendMsg;
|
||||
dumpMsg = dumpMsg;
|
||||
msgSignature = msgSignature;
|
||||
msgData = msgData;
|
||||
|
||||
--------- DEBUG only ----------------
|
||||
-- dataSignature = dataSignature;
|
||||
-- parseMsg = parseMsg;
|
||||
-- dumpData = dumpData;
|
||||
-- parseData = parseData;
|
||||
|
||||
-- packString = packString;
|
||||
-- packBinary = packBinary;
|
||||
-- packList = packList;
|
||||
-- packData = packData;
|
||||
--------------------------------------
|
||||
|
||||
primaryMsg = primaryMsg;
|
||||
secondaryMsg = secondaryMsg;
|
||||
|
||||
setId = setId;
|
||||
setHost = setHost;
|
||||
isHost = function() return host end;
|
||||
|
||||
isConnected = function() return connected end;
|
||||
isReading = function() return SECS_IO.isReading() end;
|
||||
isWriting = function() return SECS_IO.isWriting() end;
|
||||
isPending = function() return SECS_IO.isPending() end;
|
||||
|
||||
poll = poll;
|
||||
|
||||
sendS1F13 = function() queueMsg(S1F13()) end;
|
||||
sendS1F1 = function() queueMsg(S1F1()) end;
|
||||
sendS2F41 = function(c) queueMsg(S2F41(c)) end;
|
||||
sendS6F11 = function(e) queueMsg(S6F11(e)) end;
|
||||
|
||||
onCreateMsg = function(cb) onCreateMsg = cb end;
|
||||
onPrimaryMsg = function(cb) onPrimaryMsg = cb end;
|
||||
onSecondaryMsg = function(cb) onSecondaryMsg = cb end;
|
||||
onProcessMsg = function(cb) onProcessMsg = cb end;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
PLC = require('vwago')
|
||||
|
||||
plc = PLC.VWago("wago")
|
||||
|
||||
function setup()
|
||||
if ( plc ) then
|
||||
print("OK")
|
||||
end
|
||||
end
|
||||
|
||||
function loop()
|
||||
if ( plc ) then
|
||||
i = plc:getDouble(1)
|
||||
plc:setDouble(0,i)
|
||||
i = i + 1234
|
||||
if i > 2147483647 then
|
||||
i = 0
|
||||
o = plc:getDouble(2)
|
||||
plc:setDouble(2,o+1)
|
||||
end
|
||||
plc:setDouble(1,i)
|
||||
plc:update()
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
while 1 do
|
||||
loop()
|
||||
end
|
||||
@@ -1,114 +0,0 @@
|
||||
periphery = require('periphery')
|
||||
Serial = periphery.Serial
|
||||
|
||||
serial = Serial("/dev/ttyAMA0",9600)
|
||||
|
||||
COMMAND_POSITION = 0x19
|
||||
COMMAND_POSITION_X = 0x13
|
||||
COMMAND_POSITION_Y = 0x11
|
||||
|
||||
COMMAND_01H = 0x01
|
||||
COMMAND_03H = 0x03
|
||||
|
||||
COMMAND_CURSOR_OFF = 0x0E
|
||||
|
||||
COMMAND_BLINK = 0x0B
|
||||
COMMAND_UNBLINK = 0x0C
|
||||
|
||||
COMMAND_CR = 0x0D
|
||||
COMMAND_LF = 0x0A
|
||||
|
||||
blinkFlag = false
|
||||
|
||||
posX = 0
|
||||
posY = 0
|
||||
|
||||
function checkY(y)
|
||||
if y < 0 then
|
||||
y = 0
|
||||
end
|
||||
if y > 5 then
|
||||
y = 5
|
||||
end
|
||||
posY = y
|
||||
return y
|
||||
end
|
||||
|
||||
function checkX(x)
|
||||
if x < 0 then
|
||||
x = 39;
|
||||
posY = posY - 1
|
||||
checkY(posY)
|
||||
end
|
||||
if x > 39 then
|
||||
if posY == 5 then
|
||||
x = 39;
|
||||
else
|
||||
x = 0;
|
||||
posY = posY + 1
|
||||
checkY(posY);
|
||||
end
|
||||
end
|
||||
posX = x
|
||||
return x
|
||||
end
|
||||
|
||||
function gotoXY(x,y)
|
||||
checkX(x);
|
||||
checkY(y);
|
||||
end
|
||||
|
||||
function lineFeed(void)
|
||||
posY = posY + 1
|
||||
gotoXY(posX, checkY(posY));
|
||||
end
|
||||
|
||||
function carriageReturn(void)
|
||||
gotoXY(0, posY);
|
||||
end
|
||||
|
||||
while (1) do
|
||||
while serial:poll(100) do
|
||||
local c = serial:read(1)
|
||||
if c:byte() == COMMAND_POSITION then
|
||||
local cmd = serial:read(1)
|
||||
if cmd:byte() == COMMAND_POSITION_X then
|
||||
local x = string.byte(serial:read(1))
|
||||
gotoXY(x,posY)
|
||||
elseif cmd:byte() == COMMAND_POSITION_Y then
|
||||
local y = string.byte(serial:read(1))
|
||||
gotoXY(posX,y)
|
||||
end
|
||||
elseif c:byte() == COMMAND_03H then
|
||||
serial:read(1)
|
||||
serial:read(1)
|
||||
elseif c:byte() == COMMAND_BLINK then
|
||||
blinkFlag = true
|
||||
elseif c:byte() == COMMAND_UNBLINK then
|
||||
blinkFlag = false
|
||||
elseif c:byte() == COMMAND_CURSOR_OFF then
|
||||
-- curs_set(0);
|
||||
elseif c:byte() == COMMAND_CR then
|
||||
carriageReturn()
|
||||
elseif c:byte() == COMMAND_LF then
|
||||
lineFeed()
|
||||
else
|
||||
if c:byte() >= 0x20 and c:byte() < 0x7F then
|
||||
print(c.." at "..posX.." "..posY.."\n")
|
||||
posX = posX + 1
|
||||
checkX(posX)
|
||||
--[[
|
||||
if ( c >= 0x20 && c < 0x7F ) {
|
||||
(c==buf_char[y_now][x_now])?(buf_chng[y_now][x_now]='n'):(buf_chng[y_now][x_now]='y');
|
||||
(BLINK_FLAG?(buf_args[y_now][x_now] = 'b'):( buf_args[y_now][x_now] = 'n'));
|
||||
buf_char[y_now][x_now] = c;
|
||||
checkX(++x_now);
|
||||
--]]
|
||||
else
|
||||
print("Unknown: "..c:byte().."\n");
|
||||
end
|
||||
end
|
||||
--
|
||||
-- io.stderr:write(string.format('%02X ',c:byte(1)));
|
||||
end
|
||||
end
|
||||
@@ -1,197 +0,0 @@
|
||||
--[[
|
||||
* Copyright (c) 2015-2017 Iryont <https://github.com/iryont/lua-struct>
|
||||
*
|
||||
* 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.
|
||||
]]
|
||||
|
||||
struct = {}
|
||||
|
||||
function struct.pack(format, ...)
|
||||
local stream = {}
|
||||
local vars = {...}
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
|
||||
local bytes = {}
|
||||
for j = 1, n do
|
||||
table.insert(bytes, string.char(val % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt:find('[fd]') then
|
||||
local val = tonumber(table.remove(vars, 1))
|
||||
local sign = 0
|
||||
|
||||
if val < 0 then
|
||||
sign = 1
|
||||
val = -val
|
||||
end
|
||||
|
||||
local mantissa, exponent = math.frexp(val)
|
||||
if val == 0 then
|
||||
mantissa = 0
|
||||
exponent = 0
|
||||
else
|
||||
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
|
||||
exponent = exponent + ((opt == 'd') and 1022 or 126)
|
||||
end
|
||||
|
||||
local bytes = {}
|
||||
if opt == 'd' then
|
||||
val = mantissa
|
||||
for i = 1, 6 do
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
else
|
||||
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
|
||||
val = math.floor(mantissa / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
|
||||
val = math.floor(val / (2 ^ 8))
|
||||
end
|
||||
|
||||
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
|
||||
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
|
||||
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
|
||||
val = math.floor((sign * 128 + val) / (2 ^ 8))
|
||||
|
||||
if not endianness then
|
||||
table.insert(stream, string.reverse(table.concat(bytes)))
|
||||
else
|
||||
table.insert(stream, table.concat(bytes))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
table.insert(stream, tostring(table.remove(vars, 1)))
|
||||
table.insert(stream, string.char(0))
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
local length = tonumber(n)
|
||||
|
||||
if length > 0 then
|
||||
local str = tostring(table.remove(vars, 1))
|
||||
if length - str:len() > 0 then
|
||||
str = str .. string.rep(' ', length - str:len())
|
||||
end
|
||||
table.insert(stream, str:sub(1, length))
|
||||
end
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(stream)
|
||||
end
|
||||
|
||||
function struct.unpack(format, stream)
|
||||
local vars = {}
|
||||
local iterator = 1
|
||||
local endianness = true
|
||||
|
||||
for i = 1, format:len() do
|
||||
local opt = format:sub(i, i)
|
||||
|
||||
if opt == '<' then
|
||||
endianness = true
|
||||
elseif opt == '>' then
|
||||
endianness = false
|
||||
elseif opt:find('[bBhHiIlL]') then
|
||||
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
|
||||
local signed = opt:lower() == opt
|
||||
|
||||
local val = 0
|
||||
for j = 1, n do
|
||||
local byte = string.byte(stream:sub(iterator, iterator))
|
||||
if endianness then
|
||||
val = val + byte * (2 ^ ((j - 1) * 8))
|
||||
else
|
||||
val = val + byte * (2 ^ ((n - j) * 8))
|
||||
end
|
||||
iterator = iterator + 1
|
||||
end
|
||||
|
||||
if signed and val >= 2 ^ (n * 8 - 1) then
|
||||
val = val - 2 ^ (n * 8)
|
||||
end
|
||||
|
||||
table.insert(vars, val)
|
||||
elseif opt:find('[fd]') then
|
||||
local n = (opt == 'd') and 8 or 4
|
||||
local x = stream:sub(iterator, iterator + n - 1)
|
||||
iterator = iterator + n
|
||||
|
||||
if not endianness then
|
||||
x = string.reverse(x)
|
||||
end
|
||||
|
||||
local sign = 1
|
||||
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
|
||||
for i = n - 2, 1, -1 do
|
||||
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
|
||||
end
|
||||
|
||||
if string.byte(x, n) > 127 then
|
||||
sign = -1
|
||||
end
|
||||
|
||||
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
|
||||
if exponent == 0 then
|
||||
table.insert(vars, 0.0)
|
||||
else
|
||||
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
|
||||
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
|
||||
end
|
||||
elseif opt == 's' then
|
||||
local bytes = {}
|
||||
for j = iterator, stream:len() do
|
||||
if stream:sub(j, j) == string.char(0) then
|
||||
break
|
||||
end
|
||||
|
||||
table.insert(bytes, stream:sub(j, j))
|
||||
end
|
||||
|
||||
local str = table.concat(bytes)
|
||||
iterator = iterator + str:len() + 1
|
||||
table.insert(vars, str)
|
||||
elseif opt == 'c' then
|
||||
local n = format:sub(i + 1):match('%d+')
|
||||
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)-1))
|
||||
iterator = iterator + tonumber(n)
|
||||
i = i + n:len()
|
||||
end
|
||||
end
|
||||
|
||||
return unpack(vars)
|
||||
end
|
||||
|
||||
return struct
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user