Closed tukusejssirs closed 1 year ago
I struggle a bit with processing the data
fanuc-driver
provides (via MQTT). I think it would be very useful to document this.
- Get the machine metadata (model, spindles, servos, etc). This is a one time job. TODO
Some Focas calls could be executed only once upon first connection and never called again, like system info, number of axes/spindles. Last time I checked the packet capture, some of these calls don't even make it across the wire, which would mean that fwlib
holds the info in memory anyway.
Spindles and axes for each execution path is captured in $model
topic.
Execution path level l99.driver.fanuc.veneers.SysInfo
observation provides model information. This observation is per path. In a multi-path machine, the number of axes per path could be different fanuc/{id}/sys_info/1
, fanuc/{id}/sys_info/2
, ...
Similarly, l99.driver.fanuc.veneers.RdAxisname
and l99.driver.fanuc.veneers.RdSpindlename
observations are path level. Each path can have a different number and names of axes/spindles. fanuc/{id}/axis_names/1
, fanuc/{id}/axis_names/2
, ..., fanuc/{id}/spindle_names/1
, fanuc/{id}/spindle_names/2
, ...
- Get the current data and process it. This is a one time job on each
fanuc-driver
start.- Check if the machine is still up. This should be done continually. I think we should use
fanuc/$disco
for this, using thepayload
value. TODOExample
payload
:payload: '{\n' + ' "m9_doosan_puma": {\n' + ' "added": 1627374718761,\n' + ' "seen": 1627374726936,\n' + ' "machineId": "m9_doosan_puma",\n' + ' "arrivalTopic": "fanuc/m9_doosan_puma-all",\n' + ' "changeTopic": "fanuc/m9_doosan_puma"\n' + ' }\n' + '}',
Or the ping
topic where state.data
is the result of the last Focas connection success/failure.
- Check alarm codes and messages. This should be done continually. It requires to check multiple topics.
- The code and message can be acquired using
cnc_rdopmsg
. (What are thecnc_rdopmsg2
andcnc_rdopmsg3
for? Are they ever used/needed?).
See https://www.inventcom.net/fanuc-focas-library/misc/cnc_rdopmsg, https://www.inventcom.net/fanuc-focas-library/misc/cnc_rdopmsg2, https://www.inventcom.net/fanuc-focas-library/misc/cnc_rdopmsg3.
And the support matrix https://github.com/Ladder99/fanuc-driver/blob/main/FOCAS_FUNCTION_MATRIX.md.
Of course, it might be a good idea to process the timestamp in
observation.time
as the alarm start time (it is in UNIX Epoch and in milliseconds); this should be always process in any packet. When a particular alarm is dismissed, it should not be output in thestate.data.msgs[]
array—@MRIIOT, actually, no packet is sent to MQTT broker; is it a bug or feature? @MRIIOT, what doesstate.data.msgs[].type
mean? Some kind of alarm severity (like error/warning/info)?
This needs to be investigated. Try changing https://github.com/Ladder99/fanuc-driver/blob/31c6ad63482f939be7261494efc789f163b2f99c/fanuc/veneers/OpMsgs.cs#L14 to msgs = new List<dynamic>() { -1 }
. Need to implement a null object pattern.
type
Kind of operator's message is stored.
Series 15/15i
0 to 3 : 1st to 4th message
4 : macro message
Series 16/18/21, 16i/18i/21i, 0i, 30i, Power Mate i, PMi-A
0 : 1st message
Series 16i/18i-W
0 to 3 : 1st to 4th message
Example
payload
for pressed emergency stop (message instate.data.msgs[].data
and code2001
instate.data.msgs[].datano
):payload: '{\n' + ' "observation": {\n' + ' "time": 1627374719725,\n' + ' "machine": "m9_doosan_puma",\n' + ' "type": "source",\n' + ' "name": "message1",\n' + ' "marker": {}\n' + ' },\n' + ' "source": {\n' + ' "method": "cnc_rdopmsg",\n' + ' "invocationMs": 6,\n' + ' "data": {\n' + ' "type": 0,\n' + ' "length": 262\n' + ' }\n' + ' },\n' + ' "state": {\n' + ' "time": "00:00:03.3303133",\n' + ' "data": {\n' + ' "msgs": [\n' + ' {\n' + ' "data": " STLACENO NOUZOVE TLACITKO EMERGENCY STOP NEBO OSA V PREJEZDU.",\n' + ' "datano": 2001,\n' + ' "type": 0\n' + ' }\n' + ' ]\n' + ' }\n' + ' }\n' + '}',
- @MRIIOT, what kind of data can be received using
cnc_rdalmmsg_ALL
method (fanuc/{machine}/alarms
topic)? I did not receive any alarm there, but it’s true that I am testingfanuc-driver
on an idle machine.
Alarms!
...
"alarms": [
{
"alm_no": 100,
"type": 0,
"axis": 0,
"alm_msg": "PARAMETER ENABLE SWITCH ON\u0010\f\u0001h"
}
]
...
- @MRIIOT, is it necessary / a good idea to process
fanuc/{machine}/alarms/$schema
andfanuc/{machine}/$model
? Does it ever change on different Fanuc models and versions?
Yes, it does. $model
is dependent on observations defined in the collector and number of paths/axes/spindles. It will vary from machine to machine, and collector to collector (eg. UseCase01
vs Basic01
). $schema
for each observation defines the data structure for that observation, and should not change, unless we change the veneer code or use a different Handler
. The idea behind $model
and $schema
is to create an intermediate data model to help with configuring MTConnect devices on the fly, see #12.
- Get number of pieces produced. This should be done continually. @MRIIOT, could the
topic
name be (later on) abstracted a bit? Like can we name itfanuc/{machine}/numberOfPieces
or whatever and we would get there all three values (6711
,6712
and6713
)?
- number of pieces already produced:
fanuc/{machine}/6711/1
;- number of pieces produced since last machine refresh [like an OS (re)installation]:
fanuc/{machine}/6712/1
;- number of pieces set by an operator to be produced:
fanuc/{machine}/6713/1
.
Something like this? I don't remember if these parameters are global or if each execution path has their own counts (TODO). If each path holds their own counts then it would become fanuc/{machine}/numberOfPieces/1
, fanuc/{machine}/numberOfPieces/2
, ...
await Peel("numberOfPieces",
await SetNative("produced", await platform.RdParamDoubleWordNoAxisAsync(6711)),
await SetNative("producedLife", await platform.RdParamDoubleWordNoAxisAsync(6712)),
await SetNative("remaining", await platform.RdParamDoubleWordNoAxisAsync(6713)));
- @MRIIOT, is it necessary / a good idea to process
fanuc/{machine}/alarms/$schema
andfanuc/{machine}/$model
? Does it ever change on different Fanuc models and versions?Yes, it does.
$model
is dependent on observations defined in the collector and number of paths/axes/spindles. It will vary from machine to machine, and collector to collector (eg.UseCase01
vsBasic01
).$schema
for each observation defines the data structure for that observation, and should not change, unless we change the veneer code or use a differentHandler
. The idea behind$model
and$schema
is to create an intermediate data model to help with configuring MTConnect devices on the fly, see #12.
I see. As I basically only need to gather the data and insert it into a database, I think I won’t need to parse neither $model
nor $schema
. Or is there any usefulness in that? I understand I could use $schema
to validate the JSONs in payloads.
OT: What is the advantage to configure MTConnect devices? Does it mean to use fanuc-driver
as an adapter (backend) in order to create MTConnect XML? I somewhat don’t see any usefulness in that unless you want to use MTConnect for machines of multiple vendors/manufacturers (like Fanucs and Mazaks). IMHO this would create some overhead b/c of processing the same data twice.
- @MRIIOT, what kind of data can be received using
cnc_rdalmmsg_ALL
method (fanuc/{machine}/alarms
topic)? I did not receive any alarm there, but it’s true that I am testingfanuc-driver
on an idle machine.Alarms!
... "alarms": [ { "alm_no": 100, "type": 0, "axis": 0, "alm_msg": "PARAMETER ENABLE SWITCH ON\u0010\f\u0001h" } ] ...
Well, the thing is I didn’t receive any alarms in there (just an empty array in fanuc/{machine}/alarms
and fanuc/{machine}/alarms2
), only in fanuc/{machine}/message1
. In Fanucs, is there any difference between alarms and messages? From my point of view, they are the same (as in alarm messages/codes).
Something like this? I don't remember if these parameters are global or if each execution path has their own counts (TODO). If each path holds their own counts then it would become
fanuc/{machine}/numberOfPieces/1
,fanuc/{machine}/numberOfPieces/2
, ...await Peel("numberOfPieces", await SetNative("produced", await platform.RdParamDoubleWordNoAxisAsync(6711)), await SetNative("producedLife", await platform.RdParamDoubleWordNoAxisAsync(6712)), await SetNative("remaining", await platform.RdParamDoubleWordNoAxisAsync(6713)));
I think yes, something like this.
As for the question if these params are global, IMHO yes, because one machine can produce only a single piece at a time, but I haven’t checked it anywhere.
I see. As I basically only need to gather the data and insert it into a database, I think I won’t need to parse neither
$model
nor$schema
. Or is there any usefulness in that? I understand I could use$schema
to validate the JSONs in payloads.
The $model
is useful in that it tells you how many paths/axes/spindles there are.
OT: What is the advantage to configure MTConnect devices? Does it mean to use
fanuc-driver
as an adapter (backend) in order to create MTConnect XML? I somewhat don’t see any usefulness in that unless you want to use MTConnect for machines of multiple vendors/manufacturers (like Fanucs and Mazaks). IMHO this would create some overhead b/c of processing the same data twice.
fanuc-driver
will be used as a data feed to an MTConnect adapter which will generate a devices.xml for Agent. fanuc-driver
Native handler outputs proprietary data format. SparkplugB handler adheres to SpB data format. MTConnect is there as a semantic gateway. Nothing is stopping you from adding data from MES, in-process quality checks, etc to build a more complete model of the asset/process, Fanuc or other. Then again, nothing is stopping you from doing the same without MTConnect. To me, MTConnect is all about ease of interoperability and higher level reasoning ability.
Well, the thing is I didn’t receive any alarms in there (just an empty array in
fanuc/{machine}/alarms
andfanuc/{machine}/alarms2
), only infanuc/{machine}/message1
. In Fanucs, is there any difference between alarms and messages? From my point of view, they are the same (as in alarm messages/codes).
Alarms and Messages are two different things. https://www.youtube.com/watch?v=-3Na1_t1W8A
Something like this? I don't remember if these parameters are global or if each execution path has their own counts (TODO). If each path holds their own counts then it would become
fanuc/{machine}/numberOfPieces/1
,fanuc/{machine}/numberOfPieces/2
, ...await Peel("numberOfPieces", await SetNative("produced", await platform.RdParamDoubleWordNoAxisAsync(6711)), await SetNative("producedLife", await platform.RdParamDoubleWordNoAxisAsync(6712)), await SetNative("remaining", await platform.RdParamDoubleWordNoAxisAsync(6713)));
I think yes, something like this.
What is your db structure and data type to hold this? Would you still be breaking out each piece count from the single json?
As for the question if these params are global, IMHO yes, because one machine can produce only a single piece at a time, but I haven’t checked it anywhere.
Unless the machine has multiple and independent execution paths, then each one should be able to produce at its own takt.
The
$model
is useful in that it tells you how many paths/axes/spindles there are.
All I need from $model
is in structure
, right? Namely:
name
is the path name (an integer);observations
what data I could gather from a particular machine;axis
and spindles
array list of names of axes/spindles and observations
I could gather from a particular machine.To me, MTConnect is all about ease of interoperability and higher level reasoning ability.
This might be interesting to us in the future. For now, we need to gather the data. Thanks for the explanation.
Alarms and Messages are two different things. https://www.youtube.com/watch?v=-3Na1_t1W8A
So by message Fanuc means a message created by a user/operator/programmer (it is not considered an error, just an info message), while by alarm they mean one from the alarm list published by Fanuc in the manuals (it is considered an error), right? However, that does not makes sense with the 2360
(spindle clamping loosened), which comes from fanuc/{machine}/message1
, but IMO it is considered an error (and a red light is lit/blinking on the light indicator) and therefore it is an alarm. Here is an example payload:
payload: '{"observation":{"time":1627466563564,"machine":"m9_doosan_puma","type":"source","name":"message1","marker":{}},"source":{"method":"cnc_rdopmsg","invocationMs":7,"data":{"type":0,"length":262}},"state":{"time":"00:00:03.3303999","data":{"msgs":[{"data":" 2360 UVOLNENE UPNUTI VRETENE.","datano":2360,"type":0}]}}}',
Something like this? I don't remember if these parameters are global or if each execution path has their own counts (TODO). If each path holds their own counts then it would become
fanuc/{machine}/numberOfPieces/1
,fanuc/{machine}/numberOfPieces/2
, ...await Peel("numberOfPieces", await SetNative("produced", await platform.RdParamDoubleWordNoAxisAsync(6711)), await SetNative("producedLife", await platform.RdParamDoubleWordNoAxisAsync(6712)), await SetNative("remaining", await platform.RdParamDoubleWordNoAxisAsync(6713)));
I think yes, something like this.
What is your db structure and data type to hold this?
The DB structure is not yet decided; it heavily depends on the data we can gather via fanuc-driver
, but basically each machine will have a separate schema with the following tables:
production
:
id
;start_time
;end_time
;program_name
;parts_count
(how many pieces were produced with a particular program);alarms
:
id
;start_time
;end_time
;code
;message
;level
(severity, like info, warning, error);MACHINE
, NC
, OPERATE
, PROGRAM
, SERVO
, SPINDLE
, SYSTEM
);status
:
status
table.Anyway, we use PostgreSQL.
Would you still be breaking out each piece count from the single json?
Well, all in all, we only need the number of pieces produced with a particular program, but sometimes the operators don’t provide how many pieces they need to produce, as they sometimes produce only one piece. In that situation, the pieces to be produced parameter is 0
, but the total number produced [since last Fanuc OS (re-) installation] is incremented. If fanuc-driver
would take of of this, it would be awesome, but I think the client app should take care of this.
As for the question if these params are global, IMHO yes, because one machine can produce only a single piece at a time, but I haven’t checked it anywhere.
Unless the machine has multiple and independent execution paths, then each one should be able to produce at its own takt.
I see. Then my production
table should include a path ID, right?
The
$model
is useful in that it tells you how many paths/axes/spindles there are.All I need from
$model
is instructure
, right? Namely:
name
is the path name (an integer);observations
what data I could gather from a particular machine;axis
andspindles
array list of names of axes/spindles andobservations
I could gather from a particular machine.
Correct.
To me, MTConnect is all about ease of interoperability and higher level reasoning ability.
This might be interesting to us in the future. For now, we need to gather the data. Thanks for the explanation.
The future is now :)
Alarms and Messages are two different things. https://www.youtube.com/watch?v=-3Na1_t1W8A
So by message Fanuc means a message created by a user/operator/programmer (it is not considered an error, just an info message), while by alarm they mean one from the alarm list published by Fanuc in the manuals (it is considered an error), right? However, that does not makes sense with the
2360
(spindle clamping loosened), which comes fromfanuc/{machine}/message1
, but IMO it is considered an error (and a red light is lit/blinking on the light indicator) and therefore it is an alarm. Here is an example payload:payload: '{"observation":{"time":1627466563564,"machine":"m9_doosan_puma","type":"source","name":"message1","marker":{}},"source":{"method":"cnc_rdopmsg","invocationMs":7,"data":{"type":0,"length":262}},"state":{"time":"00:00:03.3303999","data":{"msgs":[{"data":" 2360 UVOLNENE UPNUTI VRETENE.","datano":2360,"type":0}]}}}',
We could eventually merge alarms and messages into a single observation... but we would need to know the severity and impact of each alarm and message.
The future is now :)
True, but some stuff is out of my hands. I need to finish off some stuff, after which we need to optimise + refactor some of the code, and only afterwards I am able to implement MTConect.
We could eventually merge alarms and messages into a single observation... but we would need to know the severity and impact of each alarm and message.
From my point of view, they are still the same; the only difference being the severity. Mazaks have only one type of alarms and two levels of severity, error and warning, as I call it. Errors are always red alarms (i.e. with red background and usually white foreground), others have different fg/bg colours.
What is fanuc/{machine}/connect
all about? Is its purpose to connect to the machine via FOCAS and report if the connection was successful?
I have noticed that I always receive fanuc/{machine}/paths/$schema
after fanuc/{machine}/paths
. Is there anything we could do to send it right after the connection is made (together with all other machine metadata)?
Actually: how should I process the fanuc/{machine}/paths
? As I understand it, it reports the currently used path and the path number (maxpath_no
), right? Do I actually need to process fanuc/{machine}/paths/$schema
? Actually, now I think that all schemas should be sent to the subscribers in fanuc/{machine}/schemas
once fanuc-driver
is connected to the machine/FOCAS. Then all schemas would be sent in one packet/topic. Or are the schemas used with each packet/topic separately?
What about fanuc/{machine}/alarms/$schema
? Is it changing from machine to machine? As I understand it, it does not change; it only changes when you change it in fanuc-driver
, therefore there is no need to process this, right?
Could you define the sys_info
payload properties please?
"state": {
"time": "00:00:04.6447356",
"data": {
"loader_control": false,
"i_series": true,
"compound_machining": false,
"transfer_line": false,
"model": "MODEL F",
"max_axis": 32,
"cnc_type": "Series 0i",
"mt_type": "Lathe",
"series": "D6G1",
"version": "34.0",
"axes": 2
}
}
My understanding:
- `loader_control`, `compound_machining`, `transfer_line`: ???;
- `i_series`, `model`, `max_axis`, `cnc_type`, `mt_type`, `series`, `version`, `axes`:
- self-evident, mostly model definition (except for `max_axis` and `axes`).
On a machine I get the following cnc_statinfo
:
"state": {
"time": "00:00:04.7472348",
"data": {
"mode": {
"automatic": "****(No selection)"
},
"status": {
"run": "STOP",
"edit": "****(Not editing)",
"motion": "***",
"mstb": "***",
"emergency": "EMerGency",
"alarm": "ALarM"
}
}
}
The state.data.mode.automatic
property seems to be incorrect. The machine is in MDI mode (set before machine reboot), but FOCAS/fanuc-driver
reports it ****(No selection)
. Granted, I haven’t been doing anything with the machine, apart from booting it up. Is it a bug or feature?
Anyway, what is that mstb
? I see in fanuc/veneers/StatInfoText.cs
that the only possible values are ***
and FIN
, but what does it mean?
Also: why is state.data.mode.automatic
property called automatic
? Because the mode is evaluated automatically?
What is fanuc/{machine}/figures/1
for? Could you describe its payload please?
Latest version of the algorithm description/documentation.
@MRIIOT, it might be a good idea to create a separate collector for this (to gather initial machine metadata). I think that it should automatically quit when all information was gathered or when a error occured (like when the connection failed).
@MRIIOT, do I need to know the order of paths/axes/spindles or their names are enough?
Gather machine metadata:
fanuc/{machine}/sys_info/1
{"observation":{"time":1627983214926,"machine":"m21_xxx","type":"source","name":"sys_info","marker":{"path_no":1}},"source":{"method":"cnc_sysinfo","invocationMs":0,"data":{}},"state":{"time":"00:00:04.6447356","data":{"loader_control":false,"i_series":true,"compound_machining":false,"transfer_line":false,"model":"MODEL F","max_axis":32,"cnc_type":"Series 0i","mt_type":"Lathe","series":"D6G1","version":"34.0","axes":2}}}
fanuc/{machine}/paths/$schema
{"observation":{"time":1627983213244,"machine":"m21_xxx","type":"source","name":"paths","marker":{}},"source":{"method":"cnc_getpath","invocationMs":0,"data":{"path_no":0}},"state":{"time":"00:00:03.0311346","data":{"path_no":1,"maxpath_no":1}}}
fanuc/{machine}/axis_names/$schema
+ fanuc/{machine}/axis_names/1
(1
is based on path number)@MRIIOT, what does that source.data.data_num
mean?
{"observation":{"time":1627983214677,"machine":"m21_xxx","type":"source","name":"axis_names","marker":{"path_no":1}},"source":{"method":"cnc_rdaxisname","invocationMs":20,"data":{"data_num":8}},"state":{"time":"00:00:04.3788431","data":{"axes":[{"name":"X","suff":""},{"name":"Z","suff":""}]}}}
fanuc/{machine}/spindle_names/$schema
+ fanuc/{machine}/spindle_names/1
(1
is based on path number)@MRIIOT, what do the following values mean?
source.data.data_num
;state.data.loader_control
;state.data.compound_machining
;state.data.transfer_line
.{"observation":{"time":1627983214777,"machine":"m21_xxx","type":"source","name":"spindle_names","marker":{"path_no":1}},"source":{"method":"cnc_rdspdlname","invocationMs":11,"data":{"data_num":4}},"state":{"time":"00:00:04.4763858","data":{"spindles":[{"name":"S","suff1":"1","suff2":""}]}}}
-- Fanuc-specific machine metadata
CREATE TABLE md.machines_fanuc (
id SERIAL PRIMARY KEY,
machine_id INT NOT NULL REFERENCES md.machines (machine),
loader_control BOOLEAN NOT NULL -- state.data.loader_control
i_series BOOLEAN NOT NULL -- state.data.i_series
compound_machining BOOLEAN NOT NULL -- state.data.compound_machining
transfer_line BOOLEAN NOT NULL -- state.data.transfer_line
model VARCHAR -- state.data.model
max_axis SMALLINT NOT NULL -- state.data.max_axis
cnc_type VARCHAR -- state.data.cnc_type
mt_type VARCHAR -- state.data.mt_type
series VARCHAR -- state.data.series
version VARCHAR -- state.data.version
axes_num SMALLINT NOT NULL -- state.data.axes; TODO: I might want to remove this in favour of `axes` below.
-- Note: I might want to change the arrays to tables.
paths VARCHAR[] NOT NULL,
axes VARCHAR[] NOT NULL,
spindles VARCHAR[] NOT NULL,
);
REVOKE ALL ON TABLE md.machines_fanuc FROM PUBLIC;
GRANT ALL ON TABLE md.machines_fanuc TO machinescs;
ALTER TABLE md.machines_fanuc OWNER TO machinescs;
Note: Always process the timestamp in observation.time
(it is in UNIX Epoch and in milliseconds).
fanuc/$disco
and fanuc/{machine}/ping
.
'{\n' +
' "m21_xxx": {\n' +
' "added": 1627983212722,\n' +
' "seen": 1627983212804,\n' +
' "machineId": "m21_xxx",\n' +
' "arrivalTopic": "fanuc/m21_xxx-all",\n' +
' "changeTopic": "fanuc/m21_xxx"\n' +
' }\n' +
'}',
{"observation":{"time":1627983215759,"machine":"m21_xxx","name":"ping"},"source":{"data":{"_id":"m21_xxx","IPAddress":"10.14.7.42","Port":8193,"ConnectionTimeout":10}},"state":{"data":"OK"}}
fanuc/{machine}/alarms
;fanuc/{machine}/alarms2
;fanuc/{machine}/message1
;alarms
/messages
with different integer suffixes;Note: Process observation.time
as start time when an alarm first shows up, and as end time when it disappears.
{"observation":{"time":1627983213872,"machine":"m21_xxx","type":"source","name":"alarms","marker":{}},"source":{"method":"cnc_rdalmmsg_ALL","invocationMs":266,"data":{"minType":0,"maxType":20,"count":10}},"state":{"time":"00:00:03.6566516","data":{"alarms":[{"alm_no":1401,"type":15,"axis":0,"alm_msg":" AFTER EMG PLS.PUSH\\"EMG RESET\\" "}]}}}
{"observation":{"time":1627983214368,"machine":"m21_xxx","type":"source","name":"alarms2","marker":{}},"source":{"method":"cnc_rdalmmsg2_ALL","invocationMs":332,"data":{"minType":0,"maxType":20,"count":10}},"state":{"time":"00:00:04.1515902","data":{"alarms":[{"alm_no":1401,"type":15,"axis":0,"alm_msg":" AFTER EMG PLS.PUSH\\"EMG RESET\\" BUTTON(A14.1)"}]}}}
{"observation":{"time":1627983214510,"machine":"m21_xxx","type":"source","name":"message1","marker":{}},"source":{"method":"cnc_rdopmsg","invocationMs":30,"data":{"type":0,"length":262}},"state":{"time":"00:00:04.2931885","data":{"msgs":[{"data":" AL2174 WHEN POWER ON, MCC OFF TEST REQUEST(A17.4) 1.ALL AXES NEED STOP. 2.CLOSE THE DOOR. 3.SELECT MPG MODE. 4.PUSH FEED HOLD BUTTON. 5.CYCLE START ENABLE AFTER MCC TEST COMPLETE.","datano":2174,"type":0}]}}}
-- Fanuc-specific alarms table
CREATE TABLE mx.alarms (
id SERIAL PRIMARY KEY,
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
level md.alarm_types NOT NULL,
code SMALLINT NOT NULL,
message VARCHAR NOT NULL,
-- extra_info VARCHAR(59),
-- head VARCHAR(3),
-- place VARCHAR(8) NOT NULL,
);
REVOKE ALL ON TABLE md.machines_fanuc FROM PUBLIC;
GRANT ALL ON TABLE md.machines_fanuc TO machinescs;
ALTER TABLE md.machines_fanuc OWNER TO machinescs;
machine state (mode, alarm, emergency, etc): fanuc/{machine}/stat_info/1
{"observation":{"time":1627983215037,"machine":"m21_xxx","type":"source","name":"stat_info","marker":{"path_no":1}},"source":{"method":"cnc_statinfo","invocationMs":8,"data":{}},"state":{"time":"00:00:04.7472348","data":{"mode":{"automatic":"****(No selection)"},"status":{"run":"STOP","edit":"****(Not editing)","motion":"***","mstb":"***","emergency":"EMerGency","alarm":"ALarM"}}}}
-- Fanuc-specific status table
CREATE TABLE mx.status (
id SERIAL PRIMARY KEY,
date_time TIMESTAMP WITH TIME ZONE NOT NULL,
-- TODO: Fix the constrait, as `paths` column will be an array.
path_id INT NOT NULL REFERENCES md.machines_fanuc (paths),
green BOOLEAN NOT NULL,
orange BOOLEAN NOT NULL,
red BOOLEAN NOT NULL,
turned_off BOOLEAN NOT NULL,
-- Note: For available values, see `fanuc/veneers/StatInfoText.cs`.
-- TODO: Define column data types.
mode -- state.data.mode.automatic
run -- state.data.status.run
edit -- state.data.status.edit
motion -- state.data.status.motion
mstb -- state.data.status.mstb
emergency -- state.data.status.emergency
alarm -- state.data.status.alarm
);
REVOKE ALL ON TABLE md.machines_fanuc FROM PUBLIC;
GRANT ALL ON TABLE md.machines_fanuc TO machinescs;
ALTER TABLE md.machines_fanuc OWNER TO machinescs;
fanuc/{machine}/6711/1
(number of pieces produced);fanuc/{machine}/6713/1
(number of pieces to be produced)fanuc/{machine}/6712/1
(total number of pieces produced);{"observation":{"time":1627983215483,"machine":"m21_xxx","type":"source","name":"6711","marker":{"path_no":1}},"source":{"method":"cnc_rdparam","invocationMs":38,"data":{"number":6711,"axis":0,"length":8,"IODBPSD_type":1}},"state":{"time":"00:00:05.1866236","data":{"ldata":107}}}
{"observation":{"time":1627983215522,"machine":"m21_xxx","type":"source","name":"6712","marker":{"path_no":1}},"source":{"method":"cnc_rdparam","invocationMs":16,"data":{"number":6712,"axis":0,"length":8,"IODBPSD_type":1}},"state":{"time":"00:00:05.2240095","data":{"ldata":105214}}}
{"observation":{"time":1627983215556,"machine":"m21_xxx","type":"source","name":"6713","marker":{"path_no":1}},"source":{"method":"cnc_rdparam","invocationMs":12,"data":{"number":6713,"axis":0,"length":8,"IODBPSD_type":1}},"state":{"time":"00:00:05.2578817","data":{"ldata":0}}}
-- Fanuc-specific production table
CREATE TABLE mx.production (
id SERIAL PRIMARY KEY,
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
path_id INT NOT NULL REFERENCES md.machines_fanuc (paths), -- TODO: Fix the constrait, as `paths` column will be an array.
program_name VARCHAR,
parts_produced SMALLINT,
parts_to_produce SMALLINT,
total_parts_produced INT
);
REVOKE ALL ON TABLE md.machines_fanuc FROM PUBLIC;
GRANT ALL ON TABLE md.machines_fanuc TO machinescs;
ALTER TABLE md.machines_fanuc OWNER TO machinescs;
What is
fanuc/{machine}/connect
all about? Is its purpose to connect to the machine via FOCAS and report if the connection was successful?
Yes. If we fail to connect, we don't collect data. Connect -> collect data -> disconnect.
I have noticed that I always receive
fanuc/{machine}/paths/$schema
afterfanuc/{machine}/paths
. Is there anything we could do to send it right after the connection is made (together with all other machine metadata)?
It would have to all be in the same topic. It is possible, but see my note about $schema in the next comment.
Actually: how should I process the
fanuc/{machine}/paths
? As I understand it, it reports the currently used path and the path number (maxpath_no
), right? Do I actually need to processfanuc/{machine}/paths/$schema
? Actually, now I think that all schemas should be sent to the subscribers infanuc/{machine}/schemas
oncefanuc-driver
is connected to the machine/FOCAS. Then all schemas would be sent in one packet/topic. Or are the schemas used with each packet/topic separately?
Correct, current path and max paths. I don't think this packet is very valuable.
Do you have an example how you would use the $schema payloads?
What about
fanuc/{machine}/alarms/$schema
? Is it changing from machine to machine? As I understand it, it does not change; it only changes when you change it infanuc-driver
, therefore there is no need to process this, right?
You bring up a good point. So the issue is that I did not statically type a lot of the code, this would take forever. Instead I used the 'dynamic' .NET type. Alarms for example, when the payload is empty, the published schema will look different than when a JSON schema is built from a payload where alarms are present. I'm not sure how to handle this, but I don't think I'll be creating static types for every data structure.
Could you define the
sys_info
payload properties please?"state": { "time": "00:00:04.6447356", "data": { "loader_control": false, "i_series": true, "compound_machining": false, "transfer_line": false, "model": "MODEL F", "max_axis": 32, "cnc_type": "Series 0i", "mt_type": "Lathe", "series": "D6G1", "version": "34.0", "axes": 2 } } My understanding: - `loader_control`, `compound_machining`, `transfer_line`: ???; - `i_series`, `model`, `max_axis`, `cnc_type`, `mt_type`, `series`, `version`, `axes`: - self-evident, mostly model definition (except for `max_axis` and `axes`).
https://www.inventcom.net/fanuc-focas-library/misc/cnc_sysinfo
On a machine I get the following
cnc_statinfo
:"state": { "time": "00:00:04.7472348", "data": { "mode": { "automatic": "****(No selection)" }, "status": { "run": "STOP", "edit": "****(Not editing)", "motion": "***", "mstb": "***", "emergency": "EMerGency", "alarm": "ALarM" } } }
The
state.data.mode.automatic
property seems to be incorrect. The machine is in MDI mode (set before machine reboot), but FOCAS/fanuc-driver
reports it****(No selection)
. Granted, I haven’t been doing anything with the machine, apart from booting it up. Is it a bug or feature?
Bug. 0i aut=0 is MDI. Look at all the lists for every different controller model. https://www.inventcom.net/fanuc-focas-library/misc/cnc_statinfo
I would say for now use StatInfo instead StatInfoText. We will need to pass cnc_sysinfo response into StatInfoText to make decision on the text based on controller model.
Anyway, what is that
mstb
? I see infanuc/veneers/StatInfoText.cs
that the only possible values are***
andFIN
, but what does it mean?
Don't know.
Also: why is
state.data.mode.automatic
property calledautomatic
? Because the mode is evaluated automatically?
That's a bug. Should be just state.data.mode
.
What is
fanuc/{machine}/figures/1
for? Could you describe its payload please?
https://www.inventcom.net/fanuc-focas-library/misc/cnc_getfigure
number of decimal places under the input/output unit, which is related to various data of CNC.
Used to put the decimal point in the correct place for axis position.
Latest version of the algorithm description/documentation.
Adding a new Fanuc machine
@MRIIOT, it might be a good idea to create a separate collector for this (to gather initial machine metadata). I think that it should automatically quit when all information was gathered or when a error occured (like when the connection failed).
Why?
@MRIIOT, do I need to know the order of paths/axes/spindles or their names are enough?
I guess you want to know which axis belongs to which path...
@MRIIOT, what does that
source.data.data_num
mean?@MRIIOT, what do the following values mean?
source.data.data_num
;state.data.loader_control
;state.data.compound_machining
;state.data.transfer_line
.
You'll have to look these up in the Focas docs.
- If the machine is online:
fanuc/$disco
andfanuc/{machine}/ping
.
$disco - discovery endpoint and last time Focas interrogated the machine ping - updated every sweep with state.data OK/NOK depending if any Focas errors were encountered during collection
- TODO: Which one is a better approach?
'{\n' + ' "m21_xxx": {\n' + ' "added": 1627983212722,\n' + ' "seen": 1627983212804,\n' + ' "machineId": "m21_xxx",\n' + ' "arrivalTopic": "fanuc/m21_xxx-all",\n' + ' "changeTopic": "fanuc/m21_xxx"\n' + ' }\n' + '}', {"observation":{"time":1627983215759,"machine":"m21_xxx","name":"ping"},"source":{"data":{"_id":"m21_xxx","IPAddress":"10.14.7.42","Port":8193,"ConnectionTimeout":10}},"state":{"data":"OK"}}
I don't see anymore work to be done on this. Closing.
I struggle a bit with processing the data
fanuc-driver
provides (via MQTT). I think it would be very useful to document this.Get the machine metadata (model, spindles, servos, etc). This is a one time job. TODO
Get the current data and process it. This is a one time job on each
fanuc-driver
start.Check if the machine is still up. This should be done continually. I think we should use
fanuc/$disco
for this, using thepayload
value. TODOExample
payload
:cnc_rdopmsg
. (What are thecnc_rdopmsg2
andcnc_rdopmsg3
for? Are they ever used/needed?). Of course, it might be a good idea to process the timestamp inobservation.time
as the alarm start time (it is in UNIX Epoch and in milliseconds); this should be always process in any packet. When a particular alarm is dismissed, it should not be output in thestate.data.msgs[]
array—@MRIIOT, actually, no packet is sent to MQTT broker; is it a bug or feature? @MRIIOT, what doesstate.data.msgs[].type
mean? Some kind of alarm severity (like error/warning/info)?Example
payload
for pressed emergency stop (message instate.data.msgs[].data
and code2001
instate.data.msgs[].datano
):@MRIIOT, what kind of data can be received using
cnc_rdalmmsg_ALL
method (fanuc/{machine}/alarms
topic)? I did not receive any alarm there, but it’s true that I am testingfanuc-driver
on an idle machine.@MRIIOT, is it necessary / a good idea to process
fanuc/{machine}/alarms/$schema
andfanuc/{machine}/$model
? Does it ever change on different Fanuc models and versions?topic
name be (later on) abstracted a bit? Like can we name itfanuc/{machine}/numberOfPieces
or whatever and we would get there all three values (6711
,6712
and6713
)?fanuc/{machine}/6711/1
;fanuc/{machine}/6712/1
;fanuc/{machine}/6713/1
.